@controlvector/cv-agent 1.4.0 → 1.5.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.
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * Git Safety Net
4
+ *
5
+ * Runs AFTER Claude Code exits, BEFORE task is reported as complete.
6
+ * Ensures all changes are committed and pushed, because Claude Code
7
+ * cannot be trusted to do this reliably.
8
+ *
9
+ * Evidence: ANAX Artifact Registry task (2026-04-03) — Claude Code wrote
10
+ * an entire module and didn't git-add a single file.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.gitSafetyNet = gitSafetyNet;
14
+ const node_child_process_1 = require("node:child_process");
15
+ /**
16
+ * Execute a git command, return stdout or throw.
17
+ */
18
+ function git(cmd, cwd) {
19
+ return (0, node_child_process_1.execSync)(cmd, { cwd, encoding: 'utf8', timeout: 30_000 }).trim();
20
+ }
21
+ /**
22
+ * Ensure all changes are committed and pushed after Claude Code exits.
23
+ *
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
28
+ */
29
+ function gitSafetyNet(workspaceRoot, taskTitle, taskId, branch) {
30
+ const targetBranch = branch || 'main';
31
+ try {
32
+ // 1. Check for ANY uncommitted changes
33
+ let statusOutput;
34
+ try {
35
+ statusOutput = git('git status --porcelain', workspaceRoot);
36
+ }
37
+ catch {
38
+ return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: false, error: 'git status failed' };
39
+ }
40
+ const lines = statusOutput.split('\n').filter(Boolean);
41
+ if (lines.length === 0) {
42
+ // No local changes — check for unpushed commits
43
+ try {
44
+ const unpushed = git(`git log origin/${targetBranch}..HEAD --oneline 2>/dev/null`, workspaceRoot);
45
+ if (unpushed) {
46
+ console.log(` [git-safety] Found unpushed commits — pushing now`);
47
+ git(`git push origin ${targetBranch}`, workspaceRoot);
48
+ return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: true };
49
+ }
50
+ }
51
+ catch {
52
+ // No remote tracking or push failed — not critical
53
+ }
54
+ return { hadChanges: false, filesAdded: 0, filesModified: 0, filesDeleted: 0, pushed: false };
55
+ }
56
+ // 2. Parse what Claude Code left behind
57
+ let added = 0, modified = 0, deleted = 0;
58
+ for (const line of lines) {
59
+ const code = line.substring(0, 2);
60
+ if (code.includes('?'))
61
+ added++;
62
+ else if (code.includes('D'))
63
+ deleted++;
64
+ else if (code.includes('M') || code.includes('A'))
65
+ modified++;
66
+ else
67
+ added++; // Treat unknown status as added
68
+ }
69
+ console.log(` [git-safety] ${lines.length} uncommitted changes ` +
70
+ `(${added} new, ${modified} modified, ${deleted} deleted) — committing now`);
71
+ // 3. Stage everything
72
+ git('git add -A', workspaceRoot);
73
+ // 4. Commit with task metadata
74
+ const shortId = taskId.substring(0, 8);
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`;
76
+ let commitSha;
77
+ try {
78
+ const commitOutput = git(`git commit -m ${JSON.stringify(commitMsg)}`, workspaceRoot);
79
+ const shaMatch = commitOutput.match(/\[[\w/]+ ([a-f0-9]+)\]/);
80
+ commitSha = shaMatch ? shaMatch[1] : undefined;
81
+ }
82
+ catch (e) {
83
+ // Commit may fail if there's nothing to commit after add
84
+ if (!e.message?.includes('nothing to commit')) {
85
+ return {
86
+ hadChanges: true, filesAdded: added, filesModified: modified,
87
+ filesDeleted: deleted, pushed: false, error: `Commit failed: ${e.message}`,
88
+ };
89
+ }
90
+ }
91
+ // 5. Push
92
+ try {
93
+ git(`git push origin ${targetBranch}`, workspaceRoot);
94
+ console.log(` [git-safety] Committed and pushed: ${commitSha || 'ok'}`);
95
+ }
96
+ catch (pushErr) {
97
+ console.log(` [git-safety] Push failed: ${pushErr.message}`);
98
+ return {
99
+ hadChanges: true, filesAdded: added, filesModified: modified,
100
+ filesDeleted: deleted, commitSha, pushed: false,
101
+ error: `Push failed: ${pushErr.message}`,
102
+ };
103
+ }
104
+ return {
105
+ hadChanges: true, filesAdded: added, filesModified: modified,
106
+ filesDeleted: deleted, commitSha, pushed: true,
107
+ };
108
+ }
109
+ catch (err) {
110
+ return {
111
+ hadChanges: false, filesAdded: 0, filesModified: 0,
112
+ filesDeleted: 0, pushed: false, error: err.message,
113
+ };
114
+ }
115
+ }
116
+ //# sourceMappingURL=git-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-safety.js","sourceRoot":"","sources":["../../src/commands/git-safety.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@controlvector/cv-agent",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Standalone agent daemon for CV-Hub — bridges Claude Code with CV-Hub task dispatch",
5
5
  "bin": {
6
6
  "cva": "./dist/bundle.cjs"