@controlvector/cv-agent 1.9.2 → 1.10.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/dist/bundle.cjs +255 -574
- package/dist/bundle.cjs.map +4 -4
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +104 -133
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/git-safety.d.ts +6 -12
- package/dist/commands/git-safety.d.ts.map +1 -1
- package/dist/commands/git-safety.js +22 -114
- package/dist/commands/git-safety.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +45 -361
- package/dist/commands/setup.js.map +1 -1
- package/dist/utils/api.d.ts +1 -0
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/event-queue.d.ts +66 -0
- package/dist/utils/event-queue.d.ts.map +1 -0
- package/dist/utils/event-queue.js +193 -0
- package/dist/utils/event-queue.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-safety.d.ts","sourceRoot":"","sources":["../../src/commands/git-safety.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"git-safety.d.ts","sourceRoot":"","sources":["../../src/commands/git-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,eAAe,CA0FjB"}
|
|
@@ -6,106 +6,30 @@
|
|
|
6
6
|
* Ensures all changes are committed and pushed, because Claude Code
|
|
7
7
|
* cannot be trusted to do this reliably.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - REFUSES to run if workspace has no .git directory
|
|
12
|
-
* - Filters out sensitive files from staging (.claude/, .zsh_history, etc.)
|
|
13
|
-
* - Logs warnings instead of silently committing dangerous paths
|
|
9
|
+
* Evidence: ANAX Artifact Registry task (2026-04-03) — Claude Code wrote
|
|
10
|
+
* an entire module and didn't git-add a single file.
|
|
14
11
|
*/
|
|
15
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
13
|
exports.gitSafetyNet = gitSafetyNet;
|
|
17
14
|
const node_child_process_1 = require("node:child_process");
|
|
18
|
-
const node_fs_1 = require("node:fs");
|
|
19
|
-
const node_path_1 = require("node:path");
|
|
20
|
-
const node_os_1 = require("node:os");
|
|
21
|
-
/** Files/directories that must NEVER be committed by the safety net */
|
|
22
|
-
const DANGEROUS_PATTERNS = [
|
|
23
|
-
'.claude/',
|
|
24
|
-
'.claude.json',
|
|
25
|
-
'.credentials',
|
|
26
|
-
'.zsh_history',
|
|
27
|
-
'.bash_history',
|
|
28
|
-
'.zsh_sessions/',
|
|
29
|
-
'.ssh/',
|
|
30
|
-
'.gnupg/',
|
|
31
|
-
'.npm/',
|
|
32
|
-
'.config/',
|
|
33
|
-
'.CFUserTextEncoding',
|
|
34
|
-
'Library/',
|
|
35
|
-
'Applications/',
|
|
36
|
-
'.Trash/',
|
|
37
|
-
'.DS_Store',
|
|
38
|
-
'node_modules/',
|
|
39
|
-
'.env',
|
|
40
|
-
'.env.local',
|
|
41
|
-
'.env.production',
|
|
42
|
-
];
|
|
43
|
-
function git(cmd, cwd) {
|
|
44
|
-
return (0, node_child_process_1.execSync)(cmd, { cwd, encoding: 'utf8', timeout: 30_000 }).trim();
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Check if a workspace is safe for auto-commit operations.
|
|
48
|
-
* Returns an error string if unsafe, null if safe.
|
|
49
|
-
*/
|
|
50
|
-
function checkWorkspaceSafety(workspaceRoot) {
|
|
51
|
-
const resolved = (0, node_path_1.resolve)(workspaceRoot);
|
|
52
|
-
const home = (0, node_path_1.resolve)((0, node_os_1.homedir)());
|
|
53
|
-
// NEVER auto-commit from user's HOME directory
|
|
54
|
-
if (resolved === home) {
|
|
55
|
-
return `Workspace is user HOME directory (${home}). Refusing to auto-commit to prevent indexing personal files.`;
|
|
56
|
-
}
|
|
57
|
-
// NEVER auto-commit from a parent of HOME (e.g., /Users or /)
|
|
58
|
-
if (home.startsWith(resolved + '/')) {
|
|
59
|
-
return `Workspace (${resolved}) is a parent of HOME. Refusing to auto-commit.`;
|
|
60
|
-
}
|
|
61
|
-
// Must have a .git directory
|
|
62
|
-
if (!(0, node_fs_1.existsSync)((0, node_path_1.join)(resolved, '.git'))) {
|
|
63
|
-
return `No .git directory in ${resolved}. Not a git repository.`;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
15
|
/**
|
|
68
|
-
*
|
|
69
|
-
* Returns only the safe lines.
|
|
16
|
+
* Execute a git command, return stdout or throw.
|
|
70
17
|
*/
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
const blocked = [];
|
|
74
|
-
for (const line of statusLines) {
|
|
75
|
-
const filePath = line.substring(3).trim(); // Remove status prefix (e.g., "?? " or " M ")
|
|
76
|
-
const isDangerous = DANGEROUS_PATTERNS.some(pattern => filePath.startsWith(pattern) || filePath.includes('/' + pattern));
|
|
77
|
-
if (isDangerous) {
|
|
78
|
-
blocked.push(filePath);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
safe.push(line);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return { safe, blocked };
|
|
18
|
+
function git(cmd, cwd) {
|
|
19
|
+
return (0, node_child_process_1.execSync)(cmd, { cwd, encoding: 'utf8', timeout: 30_000 }).trim();
|
|
85
20
|
}
|
|
86
21
|
/**
|
|
87
22
|
* Ensure all changes are committed and pushed after Claude Code exits.
|
|
88
23
|
*
|
|
89
|
-
*
|
|
90
|
-
* -
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* - Only stages files that pass the safety filter
|
|
24
|
+
* 1. Check for uncommitted changes (untracked, modified, deleted)
|
|
25
|
+
* 2. If any: git add -A, commit with task metadata, push
|
|
26
|
+
* 3. If no local changes but unpushed commits: push them
|
|
27
|
+
* 4. Return structured result for task reporting
|
|
94
28
|
*/
|
|
95
29
|
function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
96
30
|
const targetBranch = branch || 'main';
|
|
97
|
-
// ── Safety check: refuse to run in dangerous directories ──────────
|
|
98
|
-
const safetyError = checkWorkspaceSafety(workspaceRoot);
|
|
99
|
-
if (safetyError) {
|
|
100
|
-
console.log(` [git-safety] BLOCKED: ${safetyError}`);
|
|
101
|
-
return {
|
|
102
|
-
hadChanges: false, filesAdded: 0, filesModified: 0,
|
|
103
|
-
filesDeleted: 0, pushed: false, skipped: true,
|
|
104
|
-
skipReason: safetyError,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
31
|
try {
|
|
108
|
-
// 1. Check for uncommitted changes
|
|
32
|
+
// 1. Check for ANY uncommitted changes
|
|
109
33
|
let statusOutput;
|
|
110
34
|
try {
|
|
111
35
|
statusOutput = git('git status --porcelain', workspaceRoot);
|
|
@@ -113,8 +37,8 @@ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
|
113
37
|
catch {
|
|
114
38
|
return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: false, error: 'git status failed' };
|
|
115
39
|
}
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
40
|
+
const lines = statusOutput.split('\n').filter(Boolean);
|
|
41
|
+
if (lines.length === 0) {
|
|
118
42
|
// No local changes — check for unpushed commits
|
|
119
43
|
try {
|
|
120
44
|
const unpushed = git(`git log origin/${targetBranch}..HEAD --oneline 2>/dev/null`, workspaceRoot);
|
|
@@ -125,22 +49,13 @@ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
|
125
49
|
}
|
|
126
50
|
}
|
|
127
51
|
catch {
|
|
128
|
-
// No remote tracking or push failed
|
|
52
|
+
// No remote tracking or push failed — not critical
|
|
129
53
|
}
|
|
130
54
|
return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: false };
|
|
131
55
|
}
|
|
132
|
-
// 2.
|
|
133
|
-
const { safe: safeLines, blocked } = filterDangerousFiles(allLines);
|
|
134
|
-
if (blocked.length > 0) {
|
|
135
|
-
console.log(` [git-safety] Blocked ${blocked.length} sensitive file(s) from staging: ${blocked.slice(0, 5).join(', ')}${blocked.length > 5 ? '...' : ''}`);
|
|
136
|
-
}
|
|
137
|
-
if (safeLines.length === 0) {
|
|
138
|
-
console.log(` [git-safety] All ${allLines.length} changed files were blocked by safety filter`);
|
|
139
|
-
return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: false };
|
|
140
|
-
}
|
|
141
|
-
// 3. Parse safe changes
|
|
56
|
+
// 2. Parse what Claude Code left behind
|
|
142
57
|
let added = 0, modified = 0, deleted = 0;
|
|
143
|
-
for (const line of
|
|
58
|
+
for (const line of lines) {
|
|
144
59
|
const code = line.substring(0, 2);
|
|
145
60
|
if (code.includes('?'))
|
|
146
61
|
added++;
|
|
@@ -149,21 +64,13 @@ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
|
149
64
|
else if (code.includes('M') || code.includes('A'))
|
|
150
65
|
modified++;
|
|
151
66
|
else
|
|
152
|
-
added++;
|
|
67
|
+
added++; // Treat unknown status as added
|
|
153
68
|
}
|
|
154
|
-
console.log(` [git-safety] ${
|
|
69
|
+
console.log(` [git-safety] ${lines.length} uncommitted changes ` +
|
|
155
70
|
`(${added} new, ${modified} modified, ${deleted} deleted) — committing now`);
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
try {
|
|
160
|
-
git(`git add -- ${JSON.stringify(filePath)}`, workspaceRoot);
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
// Individual file add failed — skip it
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// 5. Commit with task metadata
|
|
71
|
+
// 3. Stage everything
|
|
72
|
+
git('git add -A', workspaceRoot);
|
|
73
|
+
// 4. Commit with task metadata
|
|
167
74
|
const shortId = taskId.substring(0, 8);
|
|
168
75
|
const commitMsg = `task: ${taskTitle} [${shortId}]\n\nAuto-committed by cv-agent git safety net.\nTask ID: ${taskId}\nFiles: ${added} added, ${modified} modified, ${deleted} deleted`;
|
|
169
76
|
let commitSha;
|
|
@@ -173,6 +80,7 @@ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
|
173
80
|
commitSha = shaMatch ? shaMatch[1] : undefined;
|
|
174
81
|
}
|
|
175
82
|
catch (e) {
|
|
83
|
+
// Commit may fail if there's nothing to commit after add
|
|
176
84
|
if (!e.message?.includes('nothing to commit')) {
|
|
177
85
|
return {
|
|
178
86
|
hadChanges: true, filesAdded: added, filesModified: modified,
|
|
@@ -180,7 +88,7 @@ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
|
|
|
180
88
|
};
|
|
181
89
|
}
|
|
182
90
|
}
|
|
183
|
-
//
|
|
91
|
+
// 5. Push
|
|
184
92
|
try {
|
|
185
93
|
git(`git push origin ${targetBranch}`, workspaceRoot);
|
|
186
94
|
console.log(` [git-safety] Committed and pushed: ${commitSha || 'ok'}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-safety.js","sourceRoot":"","sources":["../../src/commands/git-safety.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"git-safety.js","sourceRoot":"","sources":["../../src/commands/git-safety.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AA6BH,oCA+FC;AA1HD,2DAA8C;AAY9C;;GAEG;AACH,SAAS,GAAG,CAAC,GAAW,EAAE,GAAW;IACnC,OAAO,IAAA,6BAAQ,EAAC,GAAG,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAC1B,aAAqB,EACrB,SAAiB,EACjB,MAAc,EACd,MAAe;IAEf,MAAM,YAAY,GAAG,MAAM,IAAI,MAAM,CAAC;IAEtC,IAAI,CAAC;QACH,uCAAuC;QACvC,IAAI,YAAoB,CAAC;QACzB,IAAI,CAAC;YACH,YAAY,GAAG,GAAG,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;QAC5H,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,gDAAgD;YAChD,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,GAAG,CAAC,kBAAkB,YAAY,8BAA8B,EAAE,aAAa,CAAC,CAAC;gBAClG,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;oBACnE,GAAG,CAAC,mBAAmB,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;oBACtD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBAC/F,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,mDAAmD;YACrD,CAAC;YACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAChG,CAAC;QAED,wCAAwC;QACxC,IAAI,KAAK,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,KAAK,EAAE,CAAC;iBAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,EAAE,CAAC;iBAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,QAAQ,EAAE,CAAC;;gBACzD,KAAK,EAAE,CAAC,CAAC,gCAAgC;QAChD,CAAC;QAED,OAAO,CAAC,GAAG,CACT,kBAAkB,KAAK,CAAC,MAAM,uBAAuB;YACrD,IAAI,KAAK,SAAS,QAAQ,cAAc,OAAO,4BAA4B,CAC5E,CAAC;QAEF,sBAAsB;QACtB,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAEjC,+BAA+B;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,SAAS,SAAS,KAAK,OAAO,6DAA6D,MAAM,YAAY,KAAK,WAAW,QAAQ,cAAc,OAAO,UAAU,CAAC;QAEvL,IAAI,SAA6B,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;YACtF,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAC9D,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,yDAAyD;YACzD,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC9C,OAAO;oBACL,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ;oBAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE;iBAC3E,CAAC;YACJ,CAAC;QACH,CAAC;QAED,UAAU;QACV,IAAI,CAAC;YACH,GAAG,CAAC,mBAAmB,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,wCAAwC,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,OAAY,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO;gBACL,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ;gBAC5D,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK;gBAC/C,KAAK,EAAE,gBAAgB,OAAO,CAAC,OAAO,EAAE;aACzC,CAAC;QACJ,CAAC;QAED,OAAO;YACL,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ;YAC5D,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI;SAC/C,CAAC;IAEJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO;YACL,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;YAClD,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO;SACnD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmQpC,wBAAgB,YAAY,IAAI,OAAO,CAKtC"}
|