@ttfw/envoi 1.0.0
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 +238 -0
- package/dist/commands/app.d.ts +2 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +31 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/autonomy.d.ts +6 -0
- package/dist/commands/autonomy.d.ts.map +1 -0
- package/dist/commands/autonomy.js +89 -0
- package/dist/commands/autonomy.js.map +1 -0
- package/dist/commands/builder.d.ts +13 -0
- package/dist/commands/builder.d.ts.map +1 -0
- package/dist/commands/builder.js +142 -0
- package/dist/commands/builder.js.map +1 -0
- package/dist/commands/idea.d.ts +12 -0
- package/dist/commands/idea.d.ts.map +1 -0
- package/dist/commands/idea.js +79 -0
- package/dist/commands/idea.js.map +1 -0
- package/dist/commands/init.d.ts +18 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +423 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mode.d.ts +13 -0
- package/dist/commands/mode.d.ts.map +1 -0
- package/dist/commands/mode.js +96 -0
- package/dist/commands/mode.js.map +1 -0
- package/dist/commands/onboard.d.ts +37 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +743 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/pr-note.d.ts +8 -0
- package/dist/commands/pr-note.d.ts.map +1 -0
- package/dist/commands/pr-note.js +27 -0
- package/dist/commands/pr-note.js.map +1 -0
- package/dist/commands/undo.d.ts +7 -0
- package/dist/commands/undo.d.ts.map +1 -0
- package/dist/commands/undo.js +59 -0
- package/dist/commands/undo.js.map +1 -0
- package/dist/commands/update.d.ts +24 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +248 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/constants/report_codes.d.ts +29 -0
- package/dist/constants/report_codes.d.ts.map +1 -0
- package/dist/constants/report_codes.js +69 -0
- package/dist/constants/report_codes.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +675 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/autonomy.d.ts +16 -0
- package/dist/lib/autonomy.d.ts.map +1 -0
- package/dist/lib/autonomy.js +38 -0
- package/dist/lib/autonomy.js.map +1 -0
- package/dist/lib/blocked.d.ts +87 -0
- package/dist/lib/blocked.d.ts.map +1 -0
- package/dist/lib/blocked.js +134 -0
- package/dist/lib/blocked.js.map +1 -0
- package/dist/lib/branding.d.ts +13 -0
- package/dist/lib/branding.d.ts.map +1 -0
- package/dist/lib/branding.js +19 -0
- package/dist/lib/branding.js.map +1 -0
- package/dist/lib/claude.d.ts +42 -0
- package/dist/lib/claude.d.ts.map +1 -0
- package/dist/lib/claude.js +291 -0
- package/dist/lib/claude.js.map +1 -0
- package/dist/lib/config.d.ts +71 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +410 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/diff.d.ts +150 -0
- package/dist/lib/diff.d.ts.map +1 -0
- package/dist/lib/diff.js +257 -0
- package/dist/lib/diff.js.map +1 -0
- package/dist/lib/doctor.d.ts +67 -0
- package/dist/lib/doctor.d.ts.map +1 -0
- package/dist/lib/doctor.js +211 -0
- package/dist/lib/doctor.js.map +1 -0
- package/dist/lib/fingerprint.d.ts +27 -0
- package/dist/lib/fingerprint.d.ts.map +1 -0
- package/dist/lib/fingerprint.js +116 -0
- package/dist/lib/fingerprint.js.map +1 -0
- package/dist/lib/fs.d.ts +93 -0
- package/dist/lib/fs.d.ts.map +1 -0
- package/dist/lib/fs.js +179 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/lib/git.d.ts +177 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +355 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/git_branching.d.ts +84 -0
- package/dist/lib/git_branching.d.ts.map +1 -0
- package/dist/lib/git_branching.js +327 -0
- package/dist/lib/git_branching.js.map +1 -0
- package/dist/lib/gitignore.d.ts +26 -0
- package/dist/lib/gitignore.d.ts.map +1 -0
- package/dist/lib/gitignore.js +119 -0
- package/dist/lib/gitignore.js.map +1 -0
- package/dist/lib/guardrails.d.ts +232 -0
- package/dist/lib/guardrails.d.ts.map +1 -0
- package/dist/lib/guardrails.js +323 -0
- package/dist/lib/guardrails.js.map +1 -0
- package/dist/lib/history.d.ts +110 -0
- package/dist/lib/history.d.ts.map +1 -0
- package/dist/lib/history.js +236 -0
- package/dist/lib/history.js.map +1 -0
- package/dist/lib/index.d.ts +29 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +29 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/json-extract.d.ts +42 -0
- package/dist/lib/json-extract.d.ts.map +1 -0
- package/dist/lib/json-extract.js +201 -0
- package/dist/lib/json-extract.js.map +1 -0
- package/dist/lib/judge.d.ts +237 -0
- package/dist/lib/judge.d.ts.map +1 -0
- package/dist/lib/judge.js +501 -0
- package/dist/lib/judge.js.map +1 -0
- package/dist/lib/lock.d.ts +79 -0
- package/dist/lib/lock.d.ts.map +1 -0
- package/dist/lib/lock.js +254 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/migration.d.ts +9 -0
- package/dist/lib/migration.d.ts.map +1 -0
- package/dist/lib/migration.js +74 -0
- package/dist/lib/migration.js.map +1 -0
- package/dist/lib/paths.d.ts +18 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +27 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/preflight.d.ts +33 -0
- package/dist/lib/preflight.d.ts.map +1 -0
- package/dist/lib/preflight.js +177 -0
- package/dist/lib/preflight.js.map +1 -0
- package/dist/lib/prompt_budget.d.ts +18 -0
- package/dist/lib/prompt_budget.d.ts.map +1 -0
- package/dist/lib/prompt_budget.js +36 -0
- package/dist/lib/prompt_budget.js.map +1 -0
- package/dist/lib/report.d.ts +102 -0
- package/dist/lib/report.d.ts.map +1 -0
- package/dist/lib/report.js +347 -0
- package/dist/lib/report.js.map +1 -0
- package/dist/lib/reviewer-flow.d.ts +80 -0
- package/dist/lib/reviewer-flow.d.ts.map +1 -0
- package/dist/lib/reviewer-flow.js +138 -0
- package/dist/lib/reviewer-flow.js.map +1 -0
- package/dist/lib/reviewer.d.ts +53 -0
- package/dist/lib/reviewer.d.ts.map +1 -0
- package/dist/lib/reviewer.js +199 -0
- package/dist/lib/reviewer.js.map +1 -0
- package/dist/lib/risk.d.ts +127 -0
- package/dist/lib/risk.d.ts.map +1 -0
- package/dist/lib/risk.js +192 -0
- package/dist/lib/risk.js.map +1 -0
- package/dist/lib/rollback.d.ts +143 -0
- package/dist/lib/rollback.d.ts.map +1 -0
- package/dist/lib/rollback.js +244 -0
- package/dist/lib/rollback.js.map +1 -0
- package/dist/lib/schema.d.ts +47 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +91 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/scope.d.ts +89 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +135 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/self_update.d.ts +13 -0
- package/dist/lib/self_update.d.ts.map +1 -0
- package/dist/lib/self_update.js +172 -0
- package/dist/lib/self_update.js.map +1 -0
- package/dist/lib/state.d.ts +143 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +258 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/tick.d.ts +310 -0
- package/dist/lib/tick.d.ts.map +1 -0
- package/dist/lib/tick.js +424 -0
- package/dist/lib/tick.js.map +1 -0
- package/dist/lib/transport.d.ts +145 -0
- package/dist/lib/transport.d.ts.map +1 -0
- package/dist/lib/transport.js +237 -0
- package/dist/lib/transport.js.map +1 -0
- package/dist/lib/verdict_labels.d.ts +5 -0
- package/dist/lib/verdict_labels.d.ts.map +1 -0
- package/dist/lib/verdict_labels.js +25 -0
- package/dist/lib/verdict_labels.js.map +1 -0
- package/dist/lib/verify-safety.d.ts +63 -0
- package/dist/lib/verify-safety.d.ts.map +1 -0
- package/dist/lib/verify-safety.js +123 -0
- package/dist/lib/verify-safety.js.map +1 -0
- package/dist/lib/verify.d.ts +139 -0
- package/dist/lib/verify.d.ts.map +1 -0
- package/dist/lib/verify.js +311 -0
- package/dist/lib/verify.js.map +1 -0
- package/dist/lib/workspace_state.d.ts +79 -0
- package/dist/lib/workspace_state.d.ts.map +1 -0
- package/dist/lib/workspace_state.js +283 -0
- package/dist/lib/workspace_state.js.map +1 -0
- package/dist/runner/builder.d.ts +58 -0
- package/dist/runner/builder.d.ts.map +1 -0
- package/dist/runner/builder.js +775 -0
- package/dist/runner/builder.js.map +1 -0
- package/dist/runner/builder_parse.d.ts +37 -0
- package/dist/runner/builder_parse.d.ts.map +1 -0
- package/dist/runner/builder_parse.js +76 -0
- package/dist/runner/builder_parse.js.map +1 -0
- package/dist/runner/index.d.ts +9 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +7 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/loop.d.ts +51 -0
- package/dist/runner/loop.d.ts.map +1 -0
- package/dist/runner/loop.js +221 -0
- package/dist/runner/loop.js.map +1 -0
- package/dist/runner/orchestrator.d.ts +67 -0
- package/dist/runner/orchestrator.d.ts.map +1 -0
- package/dist/runner/orchestrator.js +376 -0
- package/dist/runner/orchestrator.js.map +1 -0
- package/dist/runner/tick.d.ts +10 -0
- package/dist/runner/tick.d.ts.map +1 -0
- package/dist/runner/tick.js +1639 -0
- package/dist/runner/tick.js.map +1 -0
- package/dist/types/blocked.d.ts +52 -0
- package/dist/types/blocked.d.ts.map +1 -0
- package/dist/types/blocked.js +8 -0
- package/dist/types/blocked.js.map +1 -0
- package/dist/types/builder.d.ts +25 -0
- package/dist/types/builder.d.ts.map +1 -0
- package/dist/types/builder.js +7 -0
- package/dist/types/builder.js.map +1 -0
- package/dist/types/claude.d.ts +86 -0
- package/dist/types/claude.d.ts.map +1 -0
- package/dist/types/claude.js +48 -0
- package/dist/types/claude.js.map +1 -0
- package/dist/types/config.d.ts +384 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lock.d.ts +21 -0
- package/dist/types/lock.d.ts.map +1 -0
- package/dist/types/lock.js +8 -0
- package/dist/types/lock.js.map +1 -0
- package/dist/types/preflight.d.ts +49 -0
- package/dist/types/preflight.d.ts.map +1 -0
- package/dist/types/preflight.js +8 -0
- package/dist/types/preflight.js.map +1 -0
- package/dist/types/report.d.ts +161 -0
- package/dist/types/report.d.ts.map +1 -0
- package/dist/types/report.js +8 -0
- package/dist/types/report.js.map +1 -0
- package/dist/types/reviewer.d.ts +66 -0
- package/dist/types/reviewer.d.ts.map +1 -0
- package/dist/types/reviewer.js +5 -0
- package/dist/types/reviewer.js.map +1 -0
- package/dist/types/state.d.ts +124 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +20 -0
- package/dist/types/state.js.map +1 -0
- package/dist/types/task.d.ts +117 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +7 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/workspace_state.d.ts +125 -0
- package/dist/types/workspace_state.d.ts.map +1 -0
- package/dist/types/workspace_state.js +10 -0
- package/dist/types/workspace_state.js.map +1 -0
- package/envoi.config.json +191 -0
- package/package.json +52 -0
- package/relais/prompts/.gitkeep +0 -0
- package/relais/prompts/builder.system.txt +13 -0
- package/relais/prompts/builder.user.txt +15 -0
- package/relais/prompts/orchestrator.system.txt +37 -0
- package/relais/prompts/orchestrator.user.txt +34 -0
- package/relais/prompts/reviewer.system.txt +33 -0
- package/relais/prompts/reviewer.user.txt +35 -0
- package/relais/schemas/.gitkeep +0 -0
- package/relais/schemas/builder_result.schema.json +29 -0
- package/relais/schemas/report.schema.json +195 -0
- package/relais/schemas/reviewer_result.schema.json +70 -0
- package/relais/schemas/task.schema.json +155 -0
package/dist/lib/diff.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git diff analysis functions for computing touched set.
|
|
3
|
+
*
|
|
4
|
+
* Used by Judge phase to compute the touched set (all files modified by builder)
|
|
5
|
+
* based on git reality, not builder's self-report.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
/**
|
|
9
|
+
* Gets tracked files that have changed since a base commit.
|
|
10
|
+
*
|
|
11
|
+
* Uses `git diff --name-status` to get all tracked changes.
|
|
12
|
+
* Parses status codes: A=added, M=modified, D=deleted, R=renamed.
|
|
13
|
+
*
|
|
14
|
+
* @param baseCommit - The base commit SHA to diff against
|
|
15
|
+
* @returns Array of file paths that have changed
|
|
16
|
+
* @throws {Error} If the diff operation fails
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const paths = getTouchedTracked('abc123');
|
|
21
|
+
* console.log(`${paths.length} tracked files changed`);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function getTouchedTracked(baseCommit) {
|
|
25
|
+
try {
|
|
26
|
+
const output = execSync(`git diff --name-status ${baseCommit}..HEAD`, {
|
|
27
|
+
encoding: 'utf-8',
|
|
28
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
29
|
+
});
|
|
30
|
+
if (!output.trim()) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return output
|
|
34
|
+
.trim()
|
|
35
|
+
.split('\n')
|
|
36
|
+
.map((line) => {
|
|
37
|
+
// Parse format: STATUS\tpath or STATUS\told_path\tnew_path (for renames)
|
|
38
|
+
const parts = line.split('\t');
|
|
39
|
+
if (parts.length >= 2) {
|
|
40
|
+
// For renames (R), return the new path
|
|
41
|
+
// For others, return the path
|
|
42
|
+
return parts.length === 3 ? parts[2] : parts[1];
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
})
|
|
46
|
+
.filter((path) => path.length > 0);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw new Error(`Failed to get touched tracked files from ${baseCommit}: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets untracked files that are new or modified.
|
|
54
|
+
*
|
|
55
|
+
* Uses `git status --porcelain` and filters for:
|
|
56
|
+
* - Lines starting with `??` (untracked files)
|
|
57
|
+
* - Lines starting with `A` (added files in index, but also catches untracked)
|
|
58
|
+
*
|
|
59
|
+
* @returns Array of untracked file paths
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const untracked = getTouchedUntracked();
|
|
64
|
+
* console.log(`${untracked.length} untracked files`);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export function getTouchedUntracked() {
|
|
68
|
+
try {
|
|
69
|
+
const output = execSync('git status --porcelain', {
|
|
70
|
+
encoding: 'utf-8',
|
|
71
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
72
|
+
});
|
|
73
|
+
if (!output.trim()) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
return output
|
|
77
|
+
.trim()
|
|
78
|
+
.split('\n')
|
|
79
|
+
.filter((line) => {
|
|
80
|
+
// Filter for untracked files (??) or added files (A)
|
|
81
|
+
const status = line.substring(0, 2);
|
|
82
|
+
return status === '??' || status.startsWith('A');
|
|
83
|
+
})
|
|
84
|
+
.map((line) => {
|
|
85
|
+
// Remove status prefix (2 chars + space)
|
|
86
|
+
return line.substring(3);
|
|
87
|
+
})
|
|
88
|
+
.filter((path) => path.length > 0);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// If git status fails, return empty array
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Gets line statistics (added/deleted) for changes since a base commit.
|
|
97
|
+
*
|
|
98
|
+
* Uses `git diff --numstat` to get line counts.
|
|
99
|
+
* Handles binary files which show `- -` instead of numbers.
|
|
100
|
+
*
|
|
101
|
+
* @param baseCommit - The base commit SHA to diff against
|
|
102
|
+
* @returns Object with lines_added and lines_deleted totals
|
|
103
|
+
* @throws {Error} If the diff operation fails
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const stats = getDiffStats('abc123');
|
|
108
|
+
* console.log(`Added: ${stats.lines_added}, Deleted: ${stats.lines_deleted}`);
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function getDiffStats(baseCommit) {
|
|
112
|
+
try {
|
|
113
|
+
const output = execSync(`git diff --numstat ${baseCommit}..HEAD`, {
|
|
114
|
+
encoding: 'utf-8',
|
|
115
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
116
|
+
});
|
|
117
|
+
if (!output.trim()) {
|
|
118
|
+
return { lines_added: 0, lines_deleted: 0 };
|
|
119
|
+
}
|
|
120
|
+
let lines_added = 0;
|
|
121
|
+
let lines_deleted = 0;
|
|
122
|
+
output
|
|
123
|
+
.trim()
|
|
124
|
+
.split('\n')
|
|
125
|
+
.forEach((line) => {
|
|
126
|
+
const parts = line.split('\t');
|
|
127
|
+
if (parts.length >= 2) {
|
|
128
|
+
const added = parts[0];
|
|
129
|
+
const deleted = parts[1];
|
|
130
|
+
// Handle binary files which show "-" instead of numbers
|
|
131
|
+
if (added !== '-' && !isNaN(Number(added))) {
|
|
132
|
+
lines_added += Number(added);
|
|
133
|
+
}
|
|
134
|
+
if (deleted !== '-' && !isNaN(Number(deleted))) {
|
|
135
|
+
lines_deleted += Number(deleted);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return { lines_added, lines_deleted };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
throw new Error(`Failed to get diff stats from ${baseCommit}: ${error instanceof Error ? error.message : String(error)}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Analyzes git diff to compute the complete touched set.
|
|
147
|
+
*
|
|
148
|
+
* Combines tracked changes, untracked files, and line statistics
|
|
149
|
+
* into a complete DiffAnalysis object.
|
|
150
|
+
*
|
|
151
|
+
* @param baseCommit - The base commit SHA to diff against
|
|
152
|
+
* @returns Complete DiffAnalysis with all metrics
|
|
153
|
+
* @throws {Error} If any git operation fails
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const analysis = analyzeDiff('abc123');
|
|
158
|
+
* console.log(`Touched ${analysis.files_touched} files`);
|
|
159
|
+
* console.log(`Added ${analysis.lines_added} lines`);
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
export function analyzeDiff(baseCommit) {
|
|
163
|
+
const trackedPaths = getTouchedTracked(baseCommit);
|
|
164
|
+
const untrackedPaths = getTouchedUntracked();
|
|
165
|
+
const stats = getDiffStats(baseCommit);
|
|
166
|
+
// Combine all touched paths
|
|
167
|
+
const allPaths = [...new Set([...trackedPaths, ...untrackedPaths])];
|
|
168
|
+
// Count new files: files that are added (A) in tracked changes
|
|
169
|
+
// plus all untracked files
|
|
170
|
+
let newFilesCount = untrackedPaths.length;
|
|
171
|
+
try {
|
|
172
|
+
const nameStatusOutput = execSync(`git diff --name-status ${baseCommit}..HEAD`, {
|
|
173
|
+
encoding: 'utf-8',
|
|
174
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
175
|
+
});
|
|
176
|
+
if (nameStatusOutput.trim()) {
|
|
177
|
+
const addedFiles = nameStatusOutput
|
|
178
|
+
.trim()
|
|
179
|
+
.split('\n')
|
|
180
|
+
.filter((line) => line.startsWith('A\t') || line.startsWith('A\t'))
|
|
181
|
+
.length;
|
|
182
|
+
newFilesCount += addedFiles;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// If this fails, we already have untracked count
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
files_touched: allPaths.length,
|
|
190
|
+
lines_added: stats.lines_added,
|
|
191
|
+
lines_deleted: stats.lines_deleted,
|
|
192
|
+
new_files: newFilesCount,
|
|
193
|
+
touched_paths: allPaths.sort(),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Checks if diff analysis exceeds task diff limits.
|
|
198
|
+
*
|
|
199
|
+
* Compares files_touched against max_files_touched and lines_changed
|
|
200
|
+
* (added + deleted) against max_lines_changed.
|
|
201
|
+
*
|
|
202
|
+
* @param analysis - The diff analysis result
|
|
203
|
+
* @param limits - The diff limits from the task
|
|
204
|
+
* @returns DiffLimitCheckResult with ok status and violation details
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* const analysis = analyzeDiff('abc123');
|
|
209
|
+
* const limits = { max_files_touched: 10, max_lines_changed: 100 };
|
|
210
|
+
* const result = checkDiffLimits(analysis, limits);
|
|
211
|
+
* if (!result.ok) {
|
|
212
|
+
* console.error(`Violation: ${result.violation}`);
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export function checkDiffLimits(analysis, limits) {
|
|
217
|
+
const lines_changed = analysis.lines_added + analysis.lines_deleted;
|
|
218
|
+
const filesExceeded = analysis.files_touched > limits.max_files_touched;
|
|
219
|
+
const linesExceeded = lines_changed > limits.max_lines_changed;
|
|
220
|
+
let violation = null;
|
|
221
|
+
if (filesExceeded && linesExceeded) {
|
|
222
|
+
violation = `Files touched (${analysis.files_touched}) exceeds limit (${limits.max_files_touched}) and lines changed (${lines_changed}) exceeds limit (${limits.max_lines_changed})`;
|
|
223
|
+
}
|
|
224
|
+
else if (filesExceeded) {
|
|
225
|
+
violation = `Files touched (${analysis.files_touched}) exceeds limit (${limits.max_files_touched})`;
|
|
226
|
+
}
|
|
227
|
+
else if (linesExceeded) {
|
|
228
|
+
violation = `Lines changed (${lines_changed}) exceeds limit (${limits.max_lines_changed})`;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
ok: !filesExceeded && !linesExceeded,
|
|
232
|
+
files_touched: analysis.files_touched,
|
|
233
|
+
lines_changed,
|
|
234
|
+
max_files: limits.max_files_touched,
|
|
235
|
+
max_lines: limits.max_lines_changed,
|
|
236
|
+
violation,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Formats blast radius summary string from diff analysis.
|
|
241
|
+
*
|
|
242
|
+
* Format: "<files_touched> files, +<lines_added>/-<lines_deleted>, <new_files> new"
|
|
243
|
+
*
|
|
244
|
+
* @param analysis - The diff analysis result
|
|
245
|
+
* @returns Formatted blast radius summary string
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```typescript
|
|
249
|
+
* const analysis = analyzeDiff('abc123');
|
|
250
|
+
* const summary = formatBlastRadius(analysis);
|
|
251
|
+
* // "5 files, +120/-30, 2 new"
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export function formatBlastRadius(analysis) {
|
|
255
|
+
return `${analysis.files_touched} files, +${analysis.lines_added}/-${analysis.lines_deleted}, ${analysis.new_files} new`;
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor checks for Envoi configuration and environment.
|
|
3
|
+
*
|
|
4
|
+
* Provides functions to verify system health and configuration correctness.
|
|
5
|
+
*/
|
|
6
|
+
import type { EnvoiConfig } from '../types/config.js';
|
|
7
|
+
/**
|
|
8
|
+
* Result of Codex CLI reviewer doctor check.
|
|
9
|
+
*/
|
|
10
|
+
export interface ReviewerDoctorResult {
|
|
11
|
+
/** Whether the Codex CLI is available */
|
|
12
|
+
cli_available: boolean;
|
|
13
|
+
/** Authentication status: 'api_key_present' if CODEX_API_KEY is set, 'unknown' otherwise */
|
|
14
|
+
auth_status: 'api_key_present' | 'unknown';
|
|
15
|
+
/** Version string from codex --version, if available */
|
|
16
|
+
version?: string;
|
|
17
|
+
/** Reviewer mode: 'enabled' if reviewer.enabled is true, 'disabled' otherwise */
|
|
18
|
+
reviewer_mode: 'enabled' | 'disabled';
|
|
19
|
+
/** Auth mode from config: reviewer.auth.mode, or 'unknown' if not configured */
|
|
20
|
+
auth_mode: 'auto' | 'api_key' | 'login' | 'unknown';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of Cursor Agent doctor check.
|
|
24
|
+
*/
|
|
25
|
+
export interface CursorAgentDoctorResult {
|
|
26
|
+
/** Whether the Cursor CLI command is available */
|
|
27
|
+
cli_available: boolean;
|
|
28
|
+
/** Cursor CLI version output, if available */
|
|
29
|
+
version?: string;
|
|
30
|
+
/** Whether `cursor agent` subcommand appears available */
|
|
31
|
+
agent_available: boolean;
|
|
32
|
+
/** Auth status for Cursor Agent */
|
|
33
|
+
auth_status: 'authenticated' | 'unauthenticated' | 'api_key_present' | 'unknown';
|
|
34
|
+
/** Optional details for debugging auth / CLI failures */
|
|
35
|
+
details?: string;
|
|
36
|
+
/** The command that was checked (e.g. "cursor") */
|
|
37
|
+
command: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Checks Codex CLI availability and authentication status.
|
|
41
|
+
*
|
|
42
|
+
* Performs the following checks:
|
|
43
|
+
* 1. Spawns 'codex --version' to verify CLI is available
|
|
44
|
+
* 2. Checks CODEX_API_KEY environment variable presence
|
|
45
|
+
* 3. Reads reviewer configuration from config (enabled, auth.mode)
|
|
46
|
+
*
|
|
47
|
+
* @param config - Envoi configuration (optional, for reading reviewer settings)
|
|
48
|
+
* @returns Promise resolving to ReviewerDoctorResult with check results
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const result = await checkCodexCli(config);
|
|
53
|
+
* if (result.cli_available) {
|
|
54
|
+
* console.log(`Codex CLI available: ${result.version}`);
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function checkCodexCli(config?: EnvoiConfig): Promise<ReviewerDoctorResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Checks Cursor CLI + Cursor Agent availability and basic authentication status.
|
|
61
|
+
*
|
|
62
|
+
* Heuristics:
|
|
63
|
+
* - If CURSOR_API_KEY is set, treat as "api_key_present" (preferred: do not store secrets in config)
|
|
64
|
+
* - Otherwise, attempt `cursor agent whoami` to detect authenticated vs unauthenticated
|
|
65
|
+
*/
|
|
66
|
+
export declare function checkCursorAgent(config?: EnvoiConfig): Promise<CursorAgentDoctorResult>;
|
|
67
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,4FAA4F;IAC5F,WAAW,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,aAAa,EAAE,SAAS,GAAG,UAAU,CAAC;IACtC,gFAAgF;IAChF,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,eAAe,EAAE,OAAO,CAAC;IACzB,mCAAmC;IACnC,WAAW,EAAE,eAAe,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACjF,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AA8DD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,aAAa,CACjC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CA8D/B;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA4E7F"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor checks for Envoi configuration and environment.
|
|
3
|
+
*
|
|
4
|
+
* Provides functions to verify system health and configuration correctness.
|
|
5
|
+
*/
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
async function spawnAndCapture(command, args, timeoutMs) {
|
|
8
|
+
return await new Promise((resolve) => {
|
|
9
|
+
let child = null;
|
|
10
|
+
const stdoutChunks = [];
|
|
11
|
+
const stderrChunks = [];
|
|
12
|
+
let timeout = null;
|
|
13
|
+
try {
|
|
14
|
+
child = spawn(command, args, { shell: false, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
resolve({
|
|
18
|
+
ok: false,
|
|
19
|
+
code: null,
|
|
20
|
+
stdout: '',
|
|
21
|
+
stderr: '',
|
|
22
|
+
error: error instanceof Error ? error.message : String(error),
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
child.stdout?.on('data', (chunk) => stdoutChunks.push(chunk));
|
|
27
|
+
child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
|
|
28
|
+
timeout = setTimeout(() => {
|
|
29
|
+
try {
|
|
30
|
+
child?.kill('SIGTERM');
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// ignore
|
|
34
|
+
}
|
|
35
|
+
}, timeoutMs);
|
|
36
|
+
const finish = (result) => {
|
|
37
|
+
if (timeout)
|
|
38
|
+
clearTimeout(timeout);
|
|
39
|
+
resolve(result);
|
|
40
|
+
};
|
|
41
|
+
child.on('error', (error) => {
|
|
42
|
+
finish({
|
|
43
|
+
ok: false,
|
|
44
|
+
code: null,
|
|
45
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf-8'),
|
|
46
|
+
stderr: Buffer.concat(stderrChunks).toString('utf-8'),
|
|
47
|
+
error: error.message,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
child.on('exit', (code) => {
|
|
51
|
+
const stdout = Buffer.concat(stdoutChunks).toString('utf-8').trim();
|
|
52
|
+
const stderr = Buffer.concat(stderrChunks).toString('utf-8').trim();
|
|
53
|
+
finish({ ok: code === 0, code, stdout, stderr });
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Checks Codex CLI availability and authentication status.
|
|
59
|
+
*
|
|
60
|
+
* Performs the following checks:
|
|
61
|
+
* 1. Spawns 'codex --version' to verify CLI is available
|
|
62
|
+
* 2. Checks CODEX_API_KEY environment variable presence
|
|
63
|
+
* 3. Reads reviewer configuration from config (enabled, auth.mode)
|
|
64
|
+
*
|
|
65
|
+
* @param config - Envoi configuration (optional, for reading reviewer settings)
|
|
66
|
+
* @returns Promise resolving to ReviewerDoctorResult with check results
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const result = await checkCodexCli(config);
|
|
71
|
+
* if (result.cli_available) {
|
|
72
|
+
* console.log(`Codex CLI available: ${result.version}`);
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export async function checkCodexCli(config) {
|
|
77
|
+
let cli_available = false;
|
|
78
|
+
let version;
|
|
79
|
+
// Check CLI availability by spawning 'codex --version'
|
|
80
|
+
try {
|
|
81
|
+
const child = spawn('codex', ['--version'], {
|
|
82
|
+
shell: false,
|
|
83
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
84
|
+
});
|
|
85
|
+
const stdoutChunks = [];
|
|
86
|
+
const stderrChunks = [];
|
|
87
|
+
child.stdout?.on('data', (chunk) => {
|
|
88
|
+
stdoutChunks.push(chunk);
|
|
89
|
+
});
|
|
90
|
+
child.stderr?.on('data', (chunk) => {
|
|
91
|
+
stderrChunks.push(chunk);
|
|
92
|
+
});
|
|
93
|
+
await new Promise((resolve, reject) => {
|
|
94
|
+
child.on('error', (error) => {
|
|
95
|
+
reject(error);
|
|
96
|
+
});
|
|
97
|
+
child.on('exit', (code) => {
|
|
98
|
+
if (code === 0) {
|
|
99
|
+
cli_available = true;
|
|
100
|
+
const output = Buffer.concat(stdoutChunks).toString('utf-8').trim();
|
|
101
|
+
// Extract version from output (e.g., "codex 1.2.3" or just "1.2.3")
|
|
102
|
+
version = output || undefined;
|
|
103
|
+
resolve();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
reject(new Error(`codex --version exited with code ${code}`));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// CLI not available or failed to execute
|
|
113
|
+
cli_available = false;
|
|
114
|
+
}
|
|
115
|
+
// Check auth status: look for CODEX_API_KEY environment variable
|
|
116
|
+
const apiKey = process.env.CODEX_API_KEY;
|
|
117
|
+
const auth_status = apiKey && apiKey.trim().length > 0
|
|
118
|
+
? 'api_key_present'
|
|
119
|
+
: 'unknown';
|
|
120
|
+
// Read reviewer configuration
|
|
121
|
+
const reviewer_enabled = config?.reviewer?.enabled ?? false;
|
|
122
|
+
const reviewer_mode = reviewer_enabled ? 'enabled' : 'disabled';
|
|
123
|
+
const auth_mode = config?.reviewer?.auth?.mode ?? 'unknown';
|
|
124
|
+
return {
|
|
125
|
+
cli_available,
|
|
126
|
+
auth_status,
|
|
127
|
+
version,
|
|
128
|
+
reviewer_mode,
|
|
129
|
+
auth_mode,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Checks Cursor CLI + Cursor Agent availability and basic authentication status.
|
|
134
|
+
*
|
|
135
|
+
* Heuristics:
|
|
136
|
+
* - If CURSOR_API_KEY is set, treat as "api_key_present" (preferred: do not store secrets in config)
|
|
137
|
+
* - Otherwise, attempt `cursor agent whoami` to detect authenticated vs unauthenticated
|
|
138
|
+
*/
|
|
139
|
+
export async function checkCursorAgent(config) {
|
|
140
|
+
const command = config?.builder?.cursor?.command ?? 'cursor';
|
|
141
|
+
// 1) Cursor CLI availability + version
|
|
142
|
+
let version;
|
|
143
|
+
let cli_available = false;
|
|
144
|
+
const versionTry1 = await spawnAndCapture(command, ['--version'], 2000);
|
|
145
|
+
if (versionTry1.ok) {
|
|
146
|
+
cli_available = true;
|
|
147
|
+
version = versionTry1.stdout || undefined;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const versionTry2 = await spawnAndCapture(command, ['-v'], 2000);
|
|
151
|
+
if (versionTry2.ok) {
|
|
152
|
+
cli_available = true;
|
|
153
|
+
version = versionTry2.stdout || undefined;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!cli_available) {
|
|
157
|
+
const details = versionTry1.error ?? versionTry1.stderr ?? versionTry1.stdout;
|
|
158
|
+
return {
|
|
159
|
+
cli_available: false,
|
|
160
|
+
version: undefined,
|
|
161
|
+
agent_available: false,
|
|
162
|
+
auth_status: 'unknown',
|
|
163
|
+
details: details ? String(details).trim() : undefined,
|
|
164
|
+
command,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// 2) Agent subcommand availability
|
|
168
|
+
const agentHelp = await spawnAndCapture(command, ['agent', '--help'], 2000);
|
|
169
|
+
const agent_available = agentHelp.ok;
|
|
170
|
+
if (!agent_available) {
|
|
171
|
+
return {
|
|
172
|
+
cli_available: true,
|
|
173
|
+
version,
|
|
174
|
+
agent_available: false,
|
|
175
|
+
auth_status: 'unknown',
|
|
176
|
+
details: [agentHelp.stderr, agentHelp.stdout].filter(Boolean).join('\n').trim() || undefined,
|
|
177
|
+
command,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// 3) Auth status
|
|
181
|
+
const apiKey = process.env.CURSOR_API_KEY;
|
|
182
|
+
if (apiKey && apiKey.trim().length > 0) {
|
|
183
|
+
return {
|
|
184
|
+
cli_available: true,
|
|
185
|
+
version,
|
|
186
|
+
agent_available: true,
|
|
187
|
+
auth_status: 'api_key_present',
|
|
188
|
+
command,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const whoami = await spawnAndCapture(command, ['agent', 'whoami'], 5000);
|
|
192
|
+
if (whoami.ok) {
|
|
193
|
+
return {
|
|
194
|
+
cli_available: true,
|
|
195
|
+
version,
|
|
196
|
+
agent_available: true,
|
|
197
|
+
auth_status: 'authenticated',
|
|
198
|
+
command,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const details = [whoami.stderr, whoami.stdout, whoami.error].filter(Boolean).join('\n').trim();
|
|
202
|
+
return {
|
|
203
|
+
cli_available: true,
|
|
204
|
+
version,
|
|
205
|
+
agent_available: true,
|
|
206
|
+
auth_status: 'unauthenticated',
|
|
207
|
+
details: details || undefined,
|
|
208
|
+
command,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task fingerprinting utilities.
|
|
3
|
+
*
|
|
4
|
+
* Task fingerprint is used to detect identical re-dispatch loops.
|
|
5
|
+
* If orchestrator 'retries' without changing the plan, fingerprint stays same and runner stops.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Canonicalizes a task object to a stable JSON string.
|
|
9
|
+
*
|
|
10
|
+
* The canonical form:
|
|
11
|
+
* - Has sorted keys (alphabetical order)
|
|
12
|
+
* - Has trimmed strings
|
|
13
|
+
* - Excludes task_id, id, v, milestone, and context fields
|
|
14
|
+
* - Only includes fingerprint-relevant fields
|
|
15
|
+
*
|
|
16
|
+
* @param task - The task object to canonicalize
|
|
17
|
+
* @returns A canonical JSON string representation
|
|
18
|
+
*/
|
|
19
|
+
export declare function canonicalizeTask(task: Record<string, unknown>): string;
|
|
20
|
+
/**
|
|
21
|
+
* Computes a SHA-256 fingerprint of a task.
|
|
22
|
+
*
|
|
23
|
+
* @param task - The task object to fingerprint
|
|
24
|
+
* @returns A 64-character hexadecimal SHA-256 hash string
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeFingerprint(task: Record<string, unknown>): string;
|
|
27
|
+
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/lib/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2FH;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAUtE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAKxE"}
|