# Aaden CLI Development Guidelines

This document provides guidelines and instructions for developing and maintaining the Aaden CLI project.

## Special Note from Human
1. don't create test script if not asked to.

## Build and Configuration

### Prerequisites

- Node.js (v12 or higher recommended)
- npm (v6 or higher recommended)
- Git

### Build Process

The project uses [@vercel/ncc](https://github.com/vercel/ncc) to compile the application into a single file. This process is automatically triggered during the release process, but can also be run manually:

```bash
# Install dependencies if not already installed
npm install

# Build the project manually
npx ncc build index.js -o dist -C
```

The `-C` flag ensures that assets are copied to the dist directory.

### Release Process

The project uses [release-it](https://github.com/release-it/release-it) for versioning and releasing. The release process is configured in the `package.json` file:

```json
"release-it": {
  "hooks": {
    "after:bump": "ncc build index.js -o dist -C"
  },
  "github.release": true,
  "git": {
    "commitMessage": "aaden-cli: release v${version}",
    "requireCleanWorkingDir": false
  }
}
```

To create a new release:

```bash
npm run update
```

This will:
1. Add all changes to git
2. Bump the version according to release-it's prompts
3. Build the project using ncc
4. Create a git commit with the new version
5. Create a GitHub release

## Testing

### Running Existing Tests

The project includes a basic test script that can be run with:

```bash
npm test
```

### Creating New Tests

For more comprehensive testing, a structured approach is recommended. Here's an example of how to create and run tests:

1. Create a test file (e.g., `my-test.js`) with the following structure:

```javascript
const assert = require('assert');
const path = require('path');
const fs = require('fs');

// Test suite
const tests = {
  // Test function
  testSomething: () => {
    console.log('Testing something...');
    
    // Your test logic here
    assert.strictEqual(true, true, 'This should be true');
    
    console.log('✅ Test passed');
    return true;
  }
};

// Run all tests
console.log('Running tests...\n');
let passedTests = 0;
let failedTests = 0;

for (const [testName, testFunction] of Object.entries(tests)) {
  try {
    const result = testFunction();
    if (result) {
      passedTests++;
    } else {
      failedTests++;
      console.error(`❌ Test ${testName} failed`);
    }
  } catch (error) {
    failedTests++;
    console.error(`❌ Test ${testName} failed with error: ${error.message}`);
  }
  console.log(''); // Add a newline between tests
}

// Print test summary
console.log(`\nTest summary: ${passedTests} passed, ${failedTests} failed`);

// Exit with appropriate code
process.exit(failedTests > 0 ? 1 : 0);
```

2. Run the test:

```bash
node my-test.js
```

### Testing Best Practices

- Use Node.js's built-in `assert` module for assertions
- Group related tests in a test suite
- Provide clear error messages
- Test both success and failure cases
- Test edge cases
- Use descriptive test names

## Code Style and Development Guidelines

### Code Style

- Use CommonJS module system (require/module.exports)
- No semicolons at the end of statements
- Use single quotes for strings
- Use 4 spaces for indentation
- Use descriptive function and variable names
- Use color coding for console output (via the colors package)

### Error Handling

- Use try/catch blocks for error handling
- Log errors with color highlighting
- Return objects with result status

### Shell Command Execution

The project includes utility functions for executing shell commands in `modules/cli-utils.js`:

```javascript
// Execute a shell command asynchronously
executeInShell(cmd, debug = false)

// Execute a shell command synchronously
executeInShellSync(cmd)
```

Example usage:

```javascript
const cli = require('./modules/cli-utils');

// Asynchronous execution
async function runCommand() {
  const { result, code } = await cli.executeInShell(['command1', 'command2'], false);
  if (result) {
    console.log('Command executed successfully');
  } else {
    console.log('Command failed');
  }
}

// Synchronous execution
function runCommandSync() {
  const { result, output } = cli.executeInShellSync('command');
  if (result) {
    console.log('Output:', output);
  } else {
    console.log('Command failed');
  }
}
```

### Adding New Commands

To add a new command to the CLI:

1. Define the command in `index.js`:

```javascript
program.command('new-command').action(newCommandFunction)
```

2. Implement the command function:

```javascript
function newCommandFunction() {
  // Command implementation
}
```

3. If the command requires shell execution, use the cli-utils module:

```javascript
async function newCommandFunction() {
  const command = [
    'command1',
    'command2'
  ]
  await cli.executeInShell(command, program.debug)
}
```

## Deployment

The project includes deployment scripts in the `AadenDeploy` directory:

- `aadensetup.sh`: Main installation script
- `update.sh`: For updating the system
- `upgrade.sh`: For upgrading components
- `mountTSE.sh`: For mounting the TSE device

To deploy the application:

```bash
# Install on a new device
./AadenDeploy/aadensetup.sh <deviceId> <channel>

# Update an existing installation
./AadenDeploy/update.sh

# Upgrade the CLI itself
./AadenDeploy/upgrade.sh
```

## Project Structure

- `index.js`: Main entry point
- `dist/index.js`: Compiled version (generated by ncc)
- `modules/`: Utility modules
- `AadenDeploy/`: Deployment scripts
  - `files/`: Files needed for deployment
  - `ngrok/`: Ngrok service configuration
  - `Utils/`: Utility scripts
- `package.json`: Project configuration and dependencies

## Additional Resources

- [Commander.js Documentation](https://github.com/tj/commander.js)
- [Vercel NCC Documentation](https://github.com/vercel/ncc)
- [Release-It Documentation](https://github.com/release-it/release-it)
