@traisetech/autopilot 0.1.4 → 0.1.7
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 +49 -44
- package/bin/autopilot.js +5 -1
- package/docs/TROUBLESHOOTING.md +21 -40
- package/package.json +2 -2
- package/src/commands/init.js +37 -0
- package/src/config/defaults.js +2 -0
- package/src/config/ignore.js +136 -37
- package/src/core/commit.js +275 -83
- package/src/core/git.js +24 -1
- package/src/core/watcher.js +93 -135
- package/src/utils/update-check.js +151 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,62 +1,67 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- Renamed package to scoped `@praisetechzw/autopilot`
|
|
6
|
-
- Excluded unnecessary development files from distribution
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
This project follows [Semantic Versioning](https://semver.org).
|
|
7
5
|
|
|
8
|
-
##
|
|
6
|
+
## [0.1.7] - 2026-02-01
|
|
9
7
|
|
|
10
8
|
### Added
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
9
|
+
- **CLI Update Notifier**:
|
|
10
|
+
- Automatically checks for new versions on npm registry (once every 24 hours).
|
|
11
|
+
- Zero-dependency implementation using native Node.js `https`.
|
|
12
|
+
- Non-intrusive visual notification box on startup when updates are available.
|
|
13
|
+
- **Documentation**:
|
|
14
|
+
- Added live NPM download statistics to landing page and documentation sidebar.
|
|
15
|
+
- Enhanced install command widget with one-click copy.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
# Changelog
|
|
17
|
+
## [0.1.6] - 2026-02-01
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
### Added
|
|
20
|
+
- **Smart Commit Generator 2.0**:
|
|
21
|
+
- Offline diff parsing using `git diff` (no external APIs).
|
|
22
|
+
- Conventional Commits compliance (`feat`, `fix`, `docs`, `style`, `test`).
|
|
23
|
+
- Intelligent scope detection for UI, Theme, Search, and Docs.
|
|
24
|
+
- Golden Test Suite with 10 fixtures for guaranteed message quality.
|
|
25
|
+
- **Developer Experience**:
|
|
26
|
+
- Added `npm run verify` script for pre-release checks.
|
|
27
|
+
- Improved Windows path normalization for reliable cross-platform usage.
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
### Changed
|
|
30
|
+
- **Performance**: Switched from file-based status checks to staged diff analysis for commit messages.
|
|
31
|
+
- **Logic**: Reordered commit type priority (Style > Src > Test > Docs) to prevent misclassification of mixed changes.
|
|
32
|
+
- **Fix**: Resolved issue where new files were incorrectly flagged as `fix` instead of `feat`.
|
|
24
33
|
|
|
25
|
-
## [0.1.4]
|
|
34
|
+
## [0.1.4] - 2026-02-01
|
|
26
35
|
|
|
27
36
|
### Fixed
|
|
28
|
-
- Fixed
|
|
29
|
-
-
|
|
30
|
-
-
|
|
37
|
+
- **Windows Compatibility**: Fixed critical issue where absolute paths on Windows caused ignore rules to fail.
|
|
38
|
+
- **Watcher Noise**: Fixed infinite commit loops caused by `.vscode/time-analytics.json` and self-logging.
|
|
39
|
+
- **CLI Crash**: Resolved `autopilot start` failure due to miswired Commander action handlers.
|
|
31
40
|
|
|
32
41
|
### Added
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
42
|
+
- **Release Gates**: Added `npm run verify` and `prepublishOnly` hooks to prevent broken releases.
|
|
43
|
+
- **Integration Tests**: Added full end-to-end test suite using `node:test`.
|
|
44
|
+
- **Smart Init**: `autopilot init` now automatically adds `autopilot.log` to `.gitignore`.
|
|
45
|
+
- **Diagnostics**: Added `autopilot doctor` for environment health checks.
|
|
37
46
|
|
|
38
|
-
|
|
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.
|
|
47
|
+
## [0.1.3] - 2026-01-31
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
### Added
|
|
50
|
+
- **Initial Public Release**: First stable release on npm as `@traisetech/autopilot`.
|
|
51
|
+
- **Core Features**:
|
|
52
|
+
- Intelligent auto commit & push.
|
|
53
|
+
- Background watcher with debouncing.
|
|
54
|
+
- Branch protection (blocks commits to `main`/`master` by default).
|
|
55
|
+
- Remote-ahead safety checks.
|
|
56
|
+
- Per-project configuration via `.autopilotrc.json`.
|
|
48
57
|
|
|
49
|
-
## [0.1.
|
|
58
|
+
## [0.1.1]
|
|
50
59
|
|
|
51
|
-
###
|
|
52
|
-
-
|
|
53
|
-
-
|
|
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`.
|
|
60
|
+
### Changed
|
|
61
|
+
- **Package Hygiene**: Renamed package scope.
|
|
62
|
+
- **Distribution**: Added `files` whitelist to `package.json` to reduce install size.
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
## [0.1.0]
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
-
|
|
66
|
+
### Added
|
|
67
|
+
- **Prototype**: Initial development release with core architecture.
|
package/bin/autopilot.js
CHANGED
|
@@ -8,6 +8,7 @@ const statusWatcher = require('../src/commands/status');
|
|
|
8
8
|
const doctor = require('../src/commands/doctor');
|
|
9
9
|
const pkg = require('../package.json');
|
|
10
10
|
const logger = require('../src/utils/logger');
|
|
11
|
+
const { checkForUpdate } = require('../src/utils/update-check');
|
|
11
12
|
|
|
12
13
|
// Validate command handlers
|
|
13
14
|
const commands = {
|
|
@@ -65,4 +66,7 @@ program
|
|
|
65
66
|
.addHelpCommand(true, 'Show help for command')
|
|
66
67
|
.showHelpAfterError('(add --help for command information)');
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
(async () => {
|
|
70
|
+
await checkForUpdate();
|
|
71
|
+
program.parse(process.argv);
|
|
72
|
+
})();
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -1,40 +1,21 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## It won’t push
|
|
26
|
-
|
|
27
|
-
- Verify `autoPush` is true
|
|
28
|
-
- Check your `origin` remote and authentication
|
|
29
|
-
- Ensure you have access to the remote
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Logs
|
|
34
|
-
|
|
35
|
-
- `autopilot.log` is created in the repo root
|
|
36
|
-
- `autopilot status` shows the last log line
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
**Built by Praise Masunga (PraiseTechzw)**
|
|
1
|
+
# TROUBLESHOOTING
|
|
2
|
+
|
|
3
|
+
## Common Issues
|
|
4
|
+
|
|
5
|
+
### Watcher Loop / High CPU Usage (Windows)
|
|
6
|
+
If Autopilot seems to be constantly triggering or consuming high CPU on Windows, it is likely due to "noisy" files that change frequently but should be ignored.
|
|
7
|
+
|
|
8
|
+
**Common Culprits:**
|
|
9
|
+
- `.vscode/time-analytics.json`: Some VS Code extensions write to this file constantly.
|
|
10
|
+
- `autopilot.log`: If the watcher logs to a file that it is also watching, it creates a feedback loop.
|
|
11
|
+
|
|
12
|
+
**Solution:**
|
|
13
|
+
Autopilot v0.1.4+ includes enhanced Windows path handling to automatically ignore these files. If you still see issues:
|
|
14
|
+
1. Ensure `.vscode/` and `*.log` are in your `.autopilotignore` file.
|
|
15
|
+
2. Run `autopilot doctor` to verify your configuration.
|
|
16
|
+
|
|
17
|
+
### "git.status is not a function"
|
|
18
|
+
This was a known issue in older versions. Please upgrade to the latest version.
|
|
19
|
+
|
|
20
|
+
### Permissions Errors
|
|
21
|
+
Ensure you have write access to the repository and that no other process has locked the files (common on Windows with anti-virus software).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@traisetech/autopilot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"dev": "node bin/autopilot.js",
|
|
35
35
|
"test": "node --test",
|
|
36
36
|
"lint": "node -c bin/autopilot.js && node -c src/index.js",
|
|
37
|
-
"verify": "
|
|
37
|
+
"verify": "node --test && node bin/autopilot.js --help",
|
|
38
38
|
"prepublishOnly": "npm run verify",
|
|
39
39
|
"release:patch": "npm run verify && npm version patch && git push --follow-tags && echo \"\n🚀 Ready to publish! Run: npm publish --access public\""
|
|
40
40
|
},
|
package/src/commands/init.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const fs = require('fs-extra');
|
|
7
|
+
const path = require('path');
|
|
7
8
|
const logger = require('../utils/logger');
|
|
8
9
|
const { getConfigPath, getIgnorePath, getGitPath } = require('../utils/paths');
|
|
9
10
|
const { DEFAULT_CONFIG, DEFAULT_IGNORE_PATTERNS } = require('../config/defaults');
|
|
@@ -54,6 +55,41 @@ async function createConfigFile(repoPath) {
|
|
|
54
55
|
return true;
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Update .gitignore with Autopilot specific files
|
|
60
|
+
* @param {string} repoPath
|
|
61
|
+
*/
|
|
62
|
+
async function updateGitIgnore(repoPath) {
|
|
63
|
+
const gitIgnorePath = path.join(repoPath, '.gitignore');
|
|
64
|
+
const toIgnore = ['autopilot.log', '.autopilot.pid', '.vscode/'];
|
|
65
|
+
let content = '';
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
if (await fs.pathExists(gitIgnorePath)) {
|
|
69
|
+
content = await fs.readFile(gitIgnorePath, 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const lines = content.split('\n').map(l => l.trim());
|
|
73
|
+
const newLines = [];
|
|
74
|
+
let added = false;
|
|
75
|
+
|
|
76
|
+
for (const item of toIgnore) {
|
|
77
|
+
if (!lines.includes(item)) {
|
|
78
|
+
newLines.push(item);
|
|
79
|
+
added = true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (added) {
|
|
84
|
+
const newContent = content + (content && !content.endsWith('\n') ? '\n' : '') + newLines.join('\n') + '\n';
|
|
85
|
+
await fs.writeFile(gitIgnorePath, newContent);
|
|
86
|
+
logger.success('Updated .gitignore');
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
logger.warn(`Could not update .gitignore: ${error.message}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
57
93
|
/**
|
|
58
94
|
* Initialize Autopilot in current repository
|
|
59
95
|
*/
|
|
@@ -76,6 +112,7 @@ async function initRepo() {
|
|
|
76
112
|
// Create files
|
|
77
113
|
await createIgnoreFile(repoPath);
|
|
78
114
|
await createConfigFile(repoPath);
|
|
115
|
+
await updateGitIgnore(repoPath);
|
|
79
116
|
|
|
80
117
|
logger.section('✨ Initialization Complete');
|
|
81
118
|
logger.info('Next steps:');
|
package/src/config/defaults.js
CHANGED
package/src/config/ignore.js
CHANGED
|
@@ -1,37 +1,136 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const logger = require('../utils/logger');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const logger = require('../utils/logger');
|
|
4
|
+
const { getIgnorePath } = require('../utils/paths');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Standardize path to use forward slashes
|
|
8
|
+
* @param {string} p - Path to normalize
|
|
9
|
+
* @returns {string} Normalized path
|
|
10
|
+
*/
|
|
11
|
+
const normalizePath = (p) => p.replace(/\\/g, '/');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read ignore file patterns
|
|
15
|
+
* @param {string} repoPath
|
|
16
|
+
* @returns {Promise<string[]>} Array of ignore patterns
|
|
17
|
+
*/
|
|
18
|
+
const readIgnoreFile = async (repoPath) => {
|
|
19
|
+
const ignorePath = getIgnorePath(repoPath);
|
|
20
|
+
try {
|
|
21
|
+
if (await fs.pathExists(ignorePath)) {
|
|
22
|
+
const content = await fs.readFile(ignorePath, 'utf-8');
|
|
23
|
+
return content
|
|
24
|
+
.split('\n')
|
|
25
|
+
.map((line) => line.trim())
|
|
26
|
+
.filter((line) => line && !line.startsWith('#'));
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
logger.debug(`Error reading ignore file: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
return [];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create ignore file
|
|
36
|
+
*/
|
|
37
|
+
const createIgnoreFile = async (repoPath, patterns = []) => {
|
|
38
|
+
const ignorePath = getIgnorePath(repoPath);
|
|
39
|
+
try {
|
|
40
|
+
const content =
|
|
41
|
+
`# Autopilot Ignore File\n# Add patterns to exclude from autopilot watching\n\n` +
|
|
42
|
+
patterns.join('\n');
|
|
43
|
+
await fs.writeFile(ignorePath, content);
|
|
44
|
+
logger.success('Created .autopilotignore file');
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error(`Failed to create ignore file: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create a filter function for Chokidar
|
|
52
|
+
* @param {string} repoPath - Root of the repository
|
|
53
|
+
* @param {string[]} userPatterns - Custom ignore patterns
|
|
54
|
+
* @returns {function} Filter function (path => boolean)
|
|
55
|
+
*/
|
|
56
|
+
const createIgnoredFilter = (repoPath, userPatterns = []) => {
|
|
57
|
+
const normalizedRepoPath = normalizePath(repoPath);
|
|
58
|
+
|
|
59
|
+
// Always ignore these critical paths to prevent loops and noise
|
|
60
|
+
const criticalIgnores = [
|
|
61
|
+
'.git',
|
|
62
|
+
'node_modules',
|
|
63
|
+
'.vscode',
|
|
64
|
+
'.idea',
|
|
65
|
+
'dist',
|
|
66
|
+
'build',
|
|
67
|
+
'coverage',
|
|
68
|
+
'.next'
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const criticalFiles = [
|
|
72
|
+
'autopilot.log',
|
|
73
|
+
'.autopilot.pid',
|
|
74
|
+
'.DS_Store'
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
return (absolutePath) => {
|
|
78
|
+
// 1. Normalize paths
|
|
79
|
+
const normalizedAbs = normalizePath(absolutePath);
|
|
80
|
+
|
|
81
|
+
// 2. Get relative path
|
|
82
|
+
let relativePath = normalizedAbs;
|
|
83
|
+
if (normalizedAbs.startsWith(normalizedRepoPath)) {
|
|
84
|
+
relativePath = normalizedAbs.slice(normalizedRepoPath.length);
|
|
85
|
+
if (relativePath.startsWith('/')) {
|
|
86
|
+
relativePath = relativePath.slice(1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Handle root path case
|
|
91
|
+
if (!relativePath) return false;
|
|
92
|
+
|
|
93
|
+
// 3. Check critical directory prefixes
|
|
94
|
+
// We check if any path segment matches a critical ignore
|
|
95
|
+
const parts = relativePath.split('/');
|
|
96
|
+
for (const part of parts) {
|
|
97
|
+
if (criticalIgnores.includes(part)) return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 4. Check file extensions and exact matches
|
|
101
|
+
if (relativePath.endsWith('.log')) return true;
|
|
102
|
+
if (criticalFiles.some(f => relativePath.endsWith(f))) return true;
|
|
103
|
+
|
|
104
|
+
// 5. Check user patterns (simple prefix/suffix matching for now)
|
|
105
|
+
// For robust glob support without adding dependencies, we rely on basic checks
|
|
106
|
+
// Most users use simple dir/ or *.ext patterns
|
|
107
|
+
for (const pattern of userPatterns) {
|
|
108
|
+
// Remove leading/trailing slashes for comparison
|
|
109
|
+
const cleanPattern = pattern.replace(/^\/+|\/+$/g, '');
|
|
110
|
+
|
|
111
|
+
// Directory match (e.g., "temp/")
|
|
112
|
+
if (pattern.endsWith('/') && (relativePath === cleanPattern || relativePath.startsWith(cleanPattern + '/'))) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Extension match (e.g., "*.tmp")
|
|
117
|
+
if (pattern.startsWith('*.') && relativePath.endsWith(pattern.slice(1))) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Exact match
|
|
122
|
+
if (relativePath === cleanPattern) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return false;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
module.exports = {
|
|
132
|
+
readIgnoreFile,
|
|
133
|
+
createIgnoreFile,
|
|
134
|
+
createIgnoredFilter,
|
|
135
|
+
normalizePath
|
|
136
|
+
};
|