@traisetech/autopilot 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +36 -19
- package/bin/autopilot.js +25 -5
- package/package.json +5 -6
- package/src/commands/init.js +1 -1
- package/src/config/loader.js +47 -47
- package/src/core/watcher.js +10 -0
- package/src/utils/logger.js +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -15,3 +15,48 @@
|
|
|
15
15
|
- Per-repo config and ignore rules
|
|
16
16
|
|
|
17
17
|
Built by Praise Masunga (PraiseTechzw).
|
|
18
|
+
# Changelog
|
|
19
|
+
|
|
20
|
+
All notable changes to this project will be documented in this file.
|
|
21
|
+
This project follows Semantic Versioning (https://semver.org).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [0.1.4] – 2026-02-01
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Fixed a critical CLI crash where `autopilot start` failed due to miswired Commander action handlers.
|
|
29
|
+
- Improved command registration to ensure all CLI commands are correctly bound and validated at runtime.
|
|
30
|
+
- Prevented undefined command handlers from causing runtime exceptions.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- Pre-publish verification pipeline to block publishing broken builds.
|
|
34
|
+
- CLI smoke tests to ensure core commands (`init`, `start`, `status`, `doctor`) do not crash.
|
|
35
|
+
- Test-only dry-run mode for watcher to allow safe automated testing.
|
|
36
|
+
- Additional configuration and commit logic unit tests.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Standardized command exports across all CLI commands.
|
|
40
|
+
- Improved error messages for misconfigured or invalid commands.
|
|
41
|
+
- Strengthened release hygiene and stability guarantees.
|
|
42
|
+
|
|
43
|
+
### Developer Experience
|
|
44
|
+
- Added `prepublishOnly` guard to prevent accidental publishing of failing builds.
|
|
45
|
+
- Improved Windows compatibility during testing and CLI execution.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## [0.1.3] – 2026-01-31
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- Initial public release of Autopilot CLI.
|
|
53
|
+
- Intelligent Git automation with smart commit messages.
|
|
54
|
+
- Background watcher with debouncing and safety rails.
|
|
55
|
+
- Branch protection and remote-ahead detection.
|
|
56
|
+
- `doctor` command for environment diagnostics.
|
|
57
|
+
- Per-project configuration via `.autopilotrc.json`.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## [0.1.0] – Initial Development
|
|
62
|
+
- Core architecture and foundational CLI commands.
|
package/README.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
# 🚀 Autopilot
|
|
1
|
+
# 🚀 Autopilot
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
**Intelligent Git automation that commits and pushes your code, so you can focus on building.**
|
|
8
8
|
|
|
9
|
-
[](https://www.npmjs.com/package/@traisetech/autopilot)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
11
|
[](https://nodejs.org)
|
|
12
|
-
[](https://www.npmjs.com/package/@traisetech/autopilot)
|
|
13
|
+
[](https://github.com/PraiseTechzw/autopilot/stargazers)
|
|
14
|
+
[](https://github.com/PraiseTechzw/autopilot/actions)
|
|
15
15
|
[](http://makeapullrequest.com)
|
|
16
16
|
|
|
17
17
|
**Built by [Praise Masunga](https://github.com/PraiseTechzw) (PraiseTechzw)**
|
|
18
18
|
|
|
19
|
-
[Features](#-features) • [Quick Start](#-quick-start) • [Configuration](#-configuration) • [Commands](#-commands)
|
|
19
|
+
[Features](#-features) • [Installation](#-installation) • [Quick Start](#-quick-start) • [Configuration](#-configuration) • [Commands](#-commands)
|
|
20
20
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
- [Why Autopilot?](#-why-autopilot)
|
|
28
28
|
- [Features](#-features)
|
|
29
|
-
- [Quick Start](#-quick-start)
|
|
30
29
|
- [Installation](#-installation)
|
|
30
|
+
- [Quick Start](#-quick-start)
|
|
31
31
|
- [Commands](#-commands)
|
|
32
32
|
- [Configuration](#-configuration)
|
|
33
33
|
- [Safety Features](#-safety-features)
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
|
|
40
40
|
## 🎯 Why Autopilot?
|
|
41
41
|
|
|
42
|
+
Autopilot is designed for developers who want to stay in the flow. It solves manual Git workflow fatigue by handling the repetitive cycle of staging, committing, and pushing changes, allowing you to focus entirely on writing code.
|
|
43
|
+
|
|
42
44
|
<table>
|
|
43
45
|
<tr>
|
|
44
46
|
<td width="50%">
|
|
@@ -90,29 +92,44 @@ autopilot start
|
|
|
90
92
|
|
|
91
93
|
---
|
|
92
94
|
|
|
93
|
-
##
|
|
95
|
+
## ⬇️ Installation
|
|
94
96
|
|
|
95
|
-
|
|
97
|
+
Install Autopilot globally using npm:
|
|
96
98
|
|
|
97
99
|
```bash
|
|
98
|
-
|
|
99
|
-
npm install -g autopilot-cli
|
|
100
|
+
npm install -g @traisetech/autopilot
|
|
100
101
|
```
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 🚀 Quick Start
|
|
106
|
+
|
|
107
|
+
### 1. Initialize
|
|
108
|
+
Navigate to your Git repository and initialize Autopilot:
|
|
103
109
|
|
|
104
110
|
```bash
|
|
105
|
-
# 1. Initialize in your project
|
|
106
111
|
cd my-project
|
|
107
112
|
autopilot init
|
|
113
|
+
```
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
### 2. Start Watching
|
|
116
|
+
Start the background daemon to begin monitoring your files:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
110
119
|
autopilot start
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. Check Status
|
|
123
|
+
Verify that Autopilot is running:
|
|
111
124
|
|
|
112
|
-
|
|
125
|
+
```bash
|
|
113
126
|
autopilot status
|
|
127
|
+
```
|
|
114
128
|
|
|
115
|
-
|
|
129
|
+
### 4. Stop
|
|
130
|
+
When you're done for the day:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
116
133
|
autopilot stop
|
|
117
134
|
```
|
|
118
135
|
|
|
@@ -133,7 +150,7 @@ autopilot stop
|
|
|
133
150
|
|
|
134
151
|
## ⚙️ Configuration
|
|
135
152
|
|
|
136
|
-
Autopilot uses a `.autopilotrc.json` file for configuration.
|
|
153
|
+
Autopilot uses a `.autopilotrc.json` file for configuration. It is created automatically when you run `autopilot init`.
|
|
137
154
|
|
|
138
155
|
```json
|
|
139
156
|
{
|
|
@@ -206,5 +223,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
206
223
|
---
|
|
207
224
|
|
|
208
225
|
<div align="center">
|
|
209
|
-
<b>Built
|
|
226
|
+
<b>Built by <a href="https://github.com/PraiseTechzw">Praise Masunga (PraiseTechzw)</a></b>
|
|
210
227
|
</div>
|
package/bin/autopilot.js
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { Command } = require('commander');
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
4
|
+
const initRepo = require('../src/commands/init');
|
|
5
|
+
const startWatcher = require('../src/commands/start');
|
|
6
|
+
const stopWatcher = require('../src/commands/stop');
|
|
7
|
+
const statusWatcher = require('../src/commands/status');
|
|
8
|
+
const doctor = require('../src/commands/doctor');
|
|
9
9
|
const pkg = require('../package.json');
|
|
10
|
+
const logger = require('../src/utils/logger');
|
|
11
|
+
|
|
12
|
+
// Validate command handlers
|
|
13
|
+
const commands = {
|
|
14
|
+
init: initRepo,
|
|
15
|
+
start: startWatcher,
|
|
16
|
+
stop: stopWatcher,
|
|
17
|
+
status: statusWatcher,
|
|
18
|
+
doctor: doctor
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Runtime assertion to prevent wiring errors
|
|
22
|
+
Object.entries(commands).forEach(([name, handler]) => {
|
|
23
|
+
if (typeof handler !== 'function') {
|
|
24
|
+
console.error(`\n❌ FATAL ERROR: Command handler for '${name}' is not a function.`);
|
|
25
|
+
console.error(`Received: ${typeof handler}`);
|
|
26
|
+
console.error('Please report this issue to the maintainer.\n');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
10
30
|
|
|
11
31
|
const program = new Command();
|
|
12
32
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@traisetech/autopilot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -32,12 +32,11 @@
|
|
|
32
32
|
"main": "src/index.js",
|
|
33
33
|
"scripts": {
|
|
34
34
|
"dev": "node bin/autopilot.js",
|
|
35
|
-
"lint": "echo \"No lint configured\"",
|
|
36
35
|
"test": "node --test",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"release:
|
|
36
|
+
"lint": "node -c bin/autopilot.js && node -c src/index.js",
|
|
37
|
+
"verify": "npm run test && npm run lint && node bin/autopilot.js --help",
|
|
38
|
+
"prepublishOnly": "npm run verify",
|
|
39
|
+
"release:patch": "npm run verify && npm version patch && git push --follow-tags && echo \"\n🚀 Ready to publish! Run: npm publish --access public\""
|
|
41
40
|
},
|
|
42
41
|
"engines": {
|
|
43
42
|
"node": ">=18.0.0"
|
package/src/commands/init.js
CHANGED
package/src/config/loader.js
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const logger = require('../utils/logger');
|
|
4
|
-
const
|
|
5
|
-
const { getConfigPath } = require('../utils/paths');
|
|
6
|
-
|
|
7
|
-
const loadConfig = async (repoPath) => {
|
|
8
|
-
const configPath = getConfigPath(repoPath);
|
|
9
|
-
try {
|
|
10
|
-
if (await fs.pathExists(configPath)) {
|
|
11
|
-
const config = await fs.readJson(configPath);
|
|
12
|
-
logger.debug(`Loaded config from ${configPath}`);
|
|
13
|
-
return { ...
|
|
14
|
-
}
|
|
15
|
-
} catch (error) {
|
|
16
|
-
logger.warn(`Error loading config: ${error.message}`);
|
|
17
|
-
}
|
|
18
|
-
return
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const saveConfig = async (repoPath, config) => {
|
|
22
|
-
const configPath = getConfigPath(repoPath);
|
|
23
|
-
try {
|
|
24
|
-
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
25
|
-
logger.success(`Config saved to ${configPath}`);
|
|
26
|
-
} catch (error) {
|
|
27
|
-
logger.error(`Failed to save config: ${error.message}`);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const createDefaultConfig = async (repoPath) => {
|
|
32
|
-
const configPath = getConfigPath(repoPath);
|
|
33
|
-
try {
|
|
34
|
-
if (!(await fs.pathExists(configPath))) {
|
|
35
|
-
await fs.writeJson(configPath,
|
|
36
|
-
logger.success(`Created default config at ${configPath}`);
|
|
37
|
-
}
|
|
38
|
-
} catch (error) {
|
|
39
|
-
logger.error(`Failed to create config: ${error.message}`);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
module.exports = {
|
|
44
|
-
loadConfig,
|
|
45
|
-
saveConfig,
|
|
46
|
-
createDefaultConfig,
|
|
47
|
-
};
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const logger = require('../utils/logger');
|
|
4
|
+
const { DEFAULT_CONFIG } = require('./defaults');
|
|
5
|
+
const { getConfigPath } = require('../utils/paths');
|
|
6
|
+
|
|
7
|
+
const loadConfig = async (repoPath) => {
|
|
8
|
+
const configPath = getConfigPath(repoPath);
|
|
9
|
+
try {
|
|
10
|
+
if (await fs.pathExists(configPath)) {
|
|
11
|
+
const config = await fs.readJson(configPath);
|
|
12
|
+
logger.debug(`Loaded config from ${configPath}`);
|
|
13
|
+
return { ...DEFAULT_CONFIG, ...config };
|
|
14
|
+
}
|
|
15
|
+
} catch (error) {
|
|
16
|
+
logger.warn(`Error loading config: ${error.message}`);
|
|
17
|
+
}
|
|
18
|
+
return { ...DEFAULT_CONFIG };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const saveConfig = async (repoPath, config) => {
|
|
22
|
+
const configPath = getConfigPath(repoPath);
|
|
23
|
+
try {
|
|
24
|
+
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
25
|
+
logger.success(`Config saved to ${configPath}`);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
logger.error(`Failed to save config: ${error.message}`);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const createDefaultConfig = async (repoPath) => {
|
|
32
|
+
const configPath = getConfigPath(repoPath);
|
|
33
|
+
try {
|
|
34
|
+
if (!(await fs.pathExists(configPath))) {
|
|
35
|
+
await fs.writeJson(configPath, DEFAULT_CONFIG, { spaces: 2 });
|
|
36
|
+
logger.success(`Created default config at ${configPath}`);
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
logger.error(`Failed to create config: ${error.message}`);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
loadConfig,
|
|
45
|
+
saveConfig,
|
|
46
|
+
createDefaultConfig,
|
|
47
|
+
};
|
package/src/core/watcher.js
CHANGED
|
@@ -91,6 +91,16 @@ class Watcher {
|
|
|
91
91
|
logger.success(`Autopilot is watching ${this.repoPath}`);
|
|
92
92
|
logger.info(`Logs: ${this.logFilePath}`);
|
|
93
93
|
|
|
94
|
+
// Test Mode Support
|
|
95
|
+
if (process.env.AUTOPILOT_TEST_MODE) {
|
|
96
|
+
logger.warn('TEST MODE: Running in dry-run mode for 3 seconds...');
|
|
97
|
+
setTimeout(async () => {
|
|
98
|
+
logger.info('TEST MODE: Auto-stopping watcher...');
|
|
99
|
+
await this.stop();
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}, 3000);
|
|
102
|
+
}
|
|
103
|
+
|
|
94
104
|
} catch (error) {
|
|
95
105
|
logger.error(`Failed to start watcher: ${error.message}`);
|
|
96
106
|
this.logVerbose(`Start error: ${error.stack}`);
|
package/src/utils/logger.js
CHANGED
|
@@ -12,6 +12,16 @@ const logger = {
|
|
|
12
12
|
console.log(`ℹ️ ${message}`);
|
|
13
13
|
},
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Log debug message (only visible if DEBUG env var is set)
|
|
17
|
+
* @param {string} message - Message to log
|
|
18
|
+
*/
|
|
19
|
+
debug: (message) => {
|
|
20
|
+
if (process.env.DEBUG) {
|
|
21
|
+
console.log(`🔍 ${message}`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
15
25
|
/**
|
|
16
26
|
* Log success message
|
|
17
27
|
* @param {string} message - Message to log
|