agentxchain 0.8.6 → 0.8.8
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/README.md +36 -38
- package/bin/agentxchain.js +62 -3
- package/package.json +3 -2
- package/scripts/agentxchain-autonudge.applescript +49 -10
- package/scripts/run-autonudge.sh +1 -1
- package/src/adapters/claude-code.js +7 -14
- package/src/adapters/cursor-local.js +26 -29
- package/src/commands/branch.js +2 -2
- package/src/commands/claim.js +86 -15
- package/src/commands/config.js +16 -0
- package/src/commands/doctor.js +9 -1
- package/src/commands/init.js +24 -5
- package/src/commands/rebind.js +77 -0
- package/src/commands/stop.js +65 -33
- package/src/commands/update.js +24 -3
- package/src/commands/watch.js +115 -34
- package/src/lib/config.js +47 -12
- package/src/lib/filter-agents.js +12 -0
- package/src/lib/generate-vscode.js +158 -51
- package/src/lib/next-owner.js +116 -0
- package/src/lib/notify.js +14 -12
- package/src/lib/prompt-core.js +108 -0
- package/src/lib/safe-write.js +44 -0
- package/src/lib/schema.js +68 -0
- package/src/lib/seed-prompt-polling.js +21 -83
- package/src/lib/seed-prompt.js +17 -63
- package/src/lib/validation.js +30 -19
- package/src/lib/verify-command.js +72 -0
package/src/lib/validation.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
|
|
4
|
+
const DEFAULT_REQUIRED_FILES = [
|
|
5
|
+
'.planning/PROJECT.md',
|
|
6
|
+
'.planning/REQUIREMENTS.md',
|
|
7
|
+
'.planning/ROADMAP.md',
|
|
8
|
+
'.planning/PM_SIGNOFF.md',
|
|
9
|
+
'.planning/qa/TEST-COVERAGE.md',
|
|
10
|
+
'.planning/qa/BUGS.md',
|
|
11
|
+
'.planning/qa/UX-AUDIT.md',
|
|
12
|
+
'.planning/qa/ACCEPTANCE-MATRIX.md',
|
|
13
|
+
'.planning/qa/REGRESSION-LOG.md',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const PROTOCOL_FILES = [
|
|
17
|
+
'lock.json',
|
|
18
|
+
'state.json'
|
|
19
|
+
];
|
|
20
|
+
|
|
4
21
|
export function validateProject(root, config, opts = {}) {
|
|
5
22
|
const mode = opts.mode || 'full';
|
|
6
23
|
const expectedAgent = opts.expectedAgent || null;
|
|
@@ -9,23 +26,17 @@ export function validateProject(root, config, opts = {}) {
|
|
|
9
26
|
const errors = [];
|
|
10
27
|
const warnings = [];
|
|
11
28
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
'.planning/PM_SIGNOFF.md',
|
|
17
|
-
'.planning/qa/TEST-COVERAGE.md',
|
|
18
|
-
'.planning/qa/BUGS.md',
|
|
19
|
-
'.planning/qa/UX-AUDIT.md',
|
|
20
|
-
'.planning/qa/ACCEPTANCE-MATRIX.md',
|
|
21
|
-
'.planning/qa/REGRESSION-LOG.md',
|
|
29
|
+
const customRequired = config.rules?.required_files;
|
|
30
|
+
const planningFiles = Array.isArray(customRequired) ? customRequired : DEFAULT_REQUIRED_FILES;
|
|
31
|
+
|
|
32
|
+
const dynamicFiles = [
|
|
22
33
|
talkFile,
|
|
23
|
-
'state.md',
|
|
24
|
-
'history.jsonl',
|
|
25
|
-
'lock.json',
|
|
26
|
-
'state.json'
|
|
34
|
+
config.state_file || 'state.md',
|
|
35
|
+
config.history_file || 'history.jsonl',
|
|
27
36
|
];
|
|
28
37
|
|
|
38
|
+
const mustExist = [...planningFiles, ...dynamicFiles, ...PROTOCOL_FILES];
|
|
39
|
+
|
|
29
40
|
for (const rel of mustExist) {
|
|
30
41
|
if (!existsSync(join(root, rel))) {
|
|
31
42
|
errors.push(`Missing required file: ${rel}`);
|
|
@@ -98,9 +109,9 @@ function validatePhaseArtifacts(root) {
|
|
|
98
109
|
|
|
99
110
|
function validateHistory(root, config, opts) {
|
|
100
111
|
const result = { errors: [], warnings: [] };
|
|
101
|
-
const historyPath = join(root, 'history.jsonl');
|
|
112
|
+
const historyPath = join(root, config.history_file || 'history.jsonl');
|
|
102
113
|
if (!existsSync(historyPath)) {
|
|
103
|
-
result.errors.push('history.jsonl is missing
|
|
114
|
+
result.errors.push(`${config.history_file || 'history.jsonl'} is missing.`);
|
|
104
115
|
return result;
|
|
105
116
|
}
|
|
106
117
|
|
|
@@ -111,9 +122,9 @@ function validateHistory(root, config, opts) {
|
|
|
111
122
|
|
|
112
123
|
if (lines.length === 0) {
|
|
113
124
|
if (opts.requireEntry) {
|
|
114
|
-
result.errors.push('history.jsonl has no entries
|
|
125
|
+
result.errors.push(`${config.history_file || 'history.jsonl'} has no entries.`);
|
|
115
126
|
} else {
|
|
116
|
-
result.warnings.push('history.jsonl has no entries yet
|
|
127
|
+
result.warnings.push(`${config.history_file || 'history.jsonl'} has no entries yet.`);
|
|
117
128
|
}
|
|
118
129
|
return result;
|
|
119
130
|
}
|
|
@@ -123,7 +134,7 @@ function validateHistory(root, config, opts) {
|
|
|
123
134
|
try {
|
|
124
135
|
last = JSON.parse(lastRaw);
|
|
125
136
|
} catch {
|
|
126
|
-
result.errors.push(
|
|
137
|
+
result.errors.push(`Last ${config.history_file || 'history.jsonl'} entry is not valid JSON.`);
|
|
127
138
|
return result;
|
|
128
139
|
}
|
|
129
140
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
|
|
3
|
+
export function parseCommandArgs(input) {
|
|
4
|
+
if (Array.isArray(input)) {
|
|
5
|
+
return input.filter(part => typeof part === 'string' && part.length > 0);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (typeof input !== 'string' || !input.trim()) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const out = [];
|
|
13
|
+
let current = '';
|
|
14
|
+
let quote = null;
|
|
15
|
+
let escape = false;
|
|
16
|
+
|
|
17
|
+
for (const char of input.trim()) {
|
|
18
|
+
if (escape) {
|
|
19
|
+
current += char;
|
|
20
|
+
escape = false;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (char === '\\') {
|
|
24
|
+
escape = true;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (quote) {
|
|
28
|
+
if (char === quote) {
|
|
29
|
+
quote = null;
|
|
30
|
+
} else {
|
|
31
|
+
current += char;
|
|
32
|
+
}
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (char === '"' || char === "'") {
|
|
36
|
+
quote = char;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (/\s/.test(char)) {
|
|
40
|
+
if (current) {
|
|
41
|
+
out.push(current);
|
|
42
|
+
current = '';
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
current += char;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (current) {
|
|
50
|
+
out.push(current);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function runConfiguredVerify(config, root) {
|
|
57
|
+
const args = parseCommandArgs(config?.rules?.verify_command);
|
|
58
|
+
if (args.length === 0) {
|
|
59
|
+
return { ok: true, skipped: true, command: null };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const result = spawnSync(args[0], args.slice(1), {
|
|
63
|
+
cwd: root,
|
|
64
|
+
stdio: 'inherit'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
ok: result.status === 0,
|
|
69
|
+
skipped: false,
|
|
70
|
+
command: args.join(' ')
|
|
71
|
+
};
|
|
72
|
+
}
|