duocode 0.1.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.
Files changed (220) hide show
  1. package/.env.example +36 -0
  2. package/LICENSE +21 -0
  3. package/README.md +52 -0
  4. package/dist/ast/context.d.ts +16 -0
  5. package/dist/ast/context.js +37 -0
  6. package/dist/ast/context.js.map +1 -0
  7. package/dist/ast/diff.d.ts +27 -0
  8. package/dist/ast/diff.js +44 -0
  9. package/dist/ast/diff.js.map +1 -0
  10. package/dist/ast/locks.d.ts +47 -0
  11. package/dist/ast/locks.js +88 -0
  12. package/dist/ast/locks.js.map +1 -0
  13. package/dist/ast/merge.d.ts +22 -0
  14. package/dist/ast/merge.js +120 -0
  15. package/dist/ast/merge.js.map +1 -0
  16. package/dist/ast/ownership.d.ts +31 -0
  17. package/dist/ast/ownership.js +111 -0
  18. package/dist/ast/ownership.js.map +1 -0
  19. package/dist/ast/parser.d.ts +44 -0
  20. package/dist/ast/parser.js +134 -0
  21. package/dist/ast/parser.js.map +1 -0
  22. package/dist/cli.d.ts +2 -0
  23. package/dist/cli.js +423 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/commands/doctor.d.ts +5 -0
  26. package/dist/commands/doctor.js +63 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/duo.d.ts +9 -0
  29. package/dist/commands/duo.js +285 -0
  30. package/dist/commands/duo.js.map +1 -0
  31. package/dist/commands/github.d.ts +2 -0
  32. package/dist/commands/github.js +85 -0
  33. package/dist/commands/github.js.map +1 -0
  34. package/dist/commands/init.d.ts +2 -0
  35. package/dist/commands/init.js +33 -0
  36. package/dist/commands/init.js.map +1 -0
  37. package/dist/commands/negotiation.d.ts +2 -0
  38. package/dist/commands/negotiation.js +160 -0
  39. package/dist/commands/negotiation.js.map +1 -0
  40. package/dist/commands/repl_commands.d.ts +26 -0
  41. package/dist/commands/repl_commands.js +226 -0
  42. package/dist/commands/repl_commands.js.map +1 -0
  43. package/dist/commands/shell.d.ts +1 -0
  44. package/dist/commands/shell.js +110 -0
  45. package/dist/commands/shell.js.map +1 -0
  46. package/dist/commands/start.d.ts +2 -0
  47. package/dist/commands/start.js +231 -0
  48. package/dist/commands/start.js.map +1 -0
  49. package/dist/commands/task.d.ts +2 -0
  50. package/dist/commands/task.js +215 -0
  51. package/dist/commands/task.js.map +1 -0
  52. package/dist/config/loader.d.ts +193 -0
  53. package/dist/config/loader.js +106 -0
  54. package/dist/config/loader.js.map +1 -0
  55. package/dist/context/project_context.d.ts +79 -0
  56. package/dist/context/project_context.js +292 -0
  57. package/dist/context/project_context.js.map +1 -0
  58. package/dist/context/token_budget.d.ts +35 -0
  59. package/dist/context/token_budget.js +81 -0
  60. package/dist/context/token_budget.js.map +1 -0
  61. package/dist/db/queries.d.ts +121 -0
  62. package/dist/db/queries.js +109 -0
  63. package/dist/db/queries.js.map +1 -0
  64. package/dist/db/schema.d.ts +110 -0
  65. package/dist/db/schema.js +346 -0
  66. package/dist/db/schema.js.map +1 -0
  67. package/dist/duo/duo_orchestrator.d.ts +50 -0
  68. package/dist/duo/duo_orchestrator.js +510 -0
  69. package/dist/duo/duo_orchestrator.js.map +1 -0
  70. package/dist/duo/duo_session.d.ts +47 -0
  71. package/dist/duo/duo_session.js +127 -0
  72. package/dist/duo/duo_session.js.map +1 -0
  73. package/dist/duo/duo_types.d.ts +168 -0
  74. package/dist/duo/duo_types.js +53 -0
  75. package/dist/duo/duo_types.js.map +1 -0
  76. package/dist/duo/session_store.d.ts +71 -0
  77. package/dist/duo/session_store.js +177 -0
  78. package/dist/duo/session_store.js.map +1 -0
  79. package/dist/git/worktree.d.ts +21 -0
  80. package/dist/git/worktree.js +86 -0
  81. package/dist/git/worktree.js.map +1 -0
  82. package/dist/github/cache.d.ts +23 -0
  83. package/dist/github/cache.js +67 -0
  84. package/dist/github/cache.js.map +1 -0
  85. package/dist/github/issues.d.ts +17 -0
  86. package/dist/github/issues.js +93 -0
  87. package/dist/github/issues.js.map +1 -0
  88. package/dist/github/mcp_client.d.ts +57 -0
  89. package/dist/github/mcp_client.js +214 -0
  90. package/dist/github/mcp_client.js.map +1 -0
  91. package/dist/github/sync.d.ts +11 -0
  92. package/dist/github/sync.js +65 -0
  93. package/dist/github/sync.js.map +1 -0
  94. package/dist/github/webhook.d.ts +25 -0
  95. package/dist/github/webhook.js +197 -0
  96. package/dist/github/webhook.js.map +1 -0
  97. package/dist/negotiation/index.d.ts +1 -0
  98. package/dist/negotiation/index.js +2 -0
  99. package/dist/negotiation/index.js.map +1 -0
  100. package/dist/negotiation/protocol.d.ts +62 -0
  101. package/dist/negotiation/protocol.js +188 -0
  102. package/dist/negotiation/protocol.js.map +1 -0
  103. package/dist/orchestrator/complexity_scorer.d.ts +2 -0
  104. package/dist/orchestrator/complexity_scorer.js +79 -0
  105. package/dist/orchestrator/complexity_scorer.js.map +1 -0
  106. package/dist/orchestrator/dependency_graph.d.ts +7 -0
  107. package/dist/orchestrator/dependency_graph.js +73 -0
  108. package/dist/orchestrator/dependency_graph.js.map +1 -0
  109. package/dist/orchestrator/intent_parser.d.ts +11 -0
  110. package/dist/orchestrator/intent_parser.js +116 -0
  111. package/dist/orchestrator/intent_parser.js.map +1 -0
  112. package/dist/orchestrator/task_runner.d.ts +56 -0
  113. package/dist/orchestrator/task_runner.js +181 -0
  114. package/dist/orchestrator/task_runner.js.map +1 -0
  115. package/dist/orchestrator/types.d.ts +44 -0
  116. package/dist/orchestrator/types.js +21 -0
  117. package/dist/orchestrator/types.js.map +1 -0
  118. package/dist/providers/anthropic.d.ts +12 -0
  119. package/dist/providers/anthropic.js +258 -0
  120. package/dist/providers/anthropic.js.map +1 -0
  121. package/dist/providers/auction.d.ts +42 -0
  122. package/dist/providers/auction.js +190 -0
  123. package/dist/providers/auction.js.map +1 -0
  124. package/dist/providers/base.d.ts +103 -0
  125. package/dist/providers/base.js +2 -0
  126. package/dist/providers/base.js.map +1 -0
  127. package/dist/providers/cost_tracker.d.ts +45 -0
  128. package/dist/providers/cost_tracker.js +111 -0
  129. package/dist/providers/cost_tracker.js.map +1 -0
  130. package/dist/providers/duo_pair_router.d.ts +11 -0
  131. package/dist/providers/duo_pair_router.js +67 -0
  132. package/dist/providers/duo_pair_router.js.map +1 -0
  133. package/dist/providers/factory.d.ts +7 -0
  134. package/dist/providers/factory.js +130 -0
  135. package/dist/providers/factory.js.map +1 -0
  136. package/dist/providers/grading_rubric.d.ts +37 -0
  137. package/dist/providers/grading_rubric.js +238 -0
  138. package/dist/providers/grading_rubric.js.map +1 -0
  139. package/dist/providers/openai.d.ts +12 -0
  140. package/dist/providers/openai.js +229 -0
  141. package/dist/providers/openai.js.map +1 -0
  142. package/dist/providers/openrouter.d.ts +14 -0
  143. package/dist/providers/openrouter.js +178 -0
  144. package/dist/providers/openrouter.js.map +1 -0
  145. package/dist/providers/performance_tracker.d.ts +21 -0
  146. package/dist/providers/performance_tracker.js +63 -0
  147. package/dist/providers/performance_tracker.js.map +1 -0
  148. package/dist/providers/registry_loader.d.ts +6 -0
  149. package/dist/providers/registry_loader.js +54 -0
  150. package/dist/providers/registry_loader.js.map +1 -0
  151. package/dist/providers/retry.d.ts +66 -0
  152. package/dist/providers/retry.js +203 -0
  153. package/dist/providers/retry.js.map +1 -0
  154. package/dist/providers/role_scorer.d.ts +16 -0
  155. package/dist/providers/role_scorer.js +16 -0
  156. package/dist/providers/role_scorer.js.map +1 -0
  157. package/dist/providers/router.d.ts +84 -0
  158. package/dist/providers/router.js +542 -0
  159. package/dist/providers/router.js.map +1 -0
  160. package/dist/security/credentials.d.ts +6 -0
  161. package/dist/security/credentials.js +16 -0
  162. package/dist/security/credentials.js.map +1 -0
  163. package/dist/setup/browser.d.ts +1 -0
  164. package/dist/setup/browser.js +12 -0
  165. package/dist/setup/browser.js.map +1 -0
  166. package/dist/setup/global_config.d.ts +14 -0
  167. package/dist/setup/global_config.js +54 -0
  168. package/dist/setup/global_config.js.map +1 -0
  169. package/dist/setup/wizard.d.ts +2 -0
  170. package/dist/setup/wizard.js +206 -0
  171. package/dist/setup/wizard.js.map +1 -0
  172. package/dist/tools/agent_loop.d.ts +38 -0
  173. package/dist/tools/agent_loop.js +72 -0
  174. package/dist/tools/agent_loop.js.map +1 -0
  175. package/dist/tools/approval.d.ts +64 -0
  176. package/dist/tools/approval.js +172 -0
  177. package/dist/tools/approval.js.map +1 -0
  178. package/dist/tools/checkpoint.d.ts +65 -0
  179. package/dist/tools/checkpoint.js +342 -0
  180. package/dist/tools/checkpoint.js.map +1 -0
  181. package/dist/tools/definitions.d.ts +13 -0
  182. package/dist/tools/definitions.js +103 -0
  183. package/dist/tools/definitions.js.map +1 -0
  184. package/dist/tools/diff_display.d.ts +46 -0
  185. package/dist/tools/diff_display.js +298 -0
  186. package/dist/tools/diff_display.js.map +1 -0
  187. package/dist/tools/executor.d.ts +12 -0
  188. package/dist/tools/executor.js +340 -0
  189. package/dist/tools/executor.js.map +1 -0
  190. package/dist/tools/permissions.d.ts +17 -0
  191. package/dist/tools/permissions.js +139 -0
  192. package/dist/tools/permissions.js.map +1 -0
  193. package/dist/tools/tool_types.d.ts +48 -0
  194. package/dist/tools/tool_types.js +7 -0
  195. package/dist/tools/tool_types.js.map +1 -0
  196. package/dist/ui/banner.d.ts +4 -0
  197. package/dist/ui/banner.js +104 -0
  198. package/dist/ui/banner.js.map +1 -0
  199. package/dist/ui/callbacks.d.ts +30 -0
  200. package/dist/ui/callbacks.js +132 -0
  201. package/dist/ui/callbacks.js.map +1 -0
  202. package/dist/ui/colors.d.ts +14 -0
  203. package/dist/ui/colors.js +28 -0
  204. package/dist/ui/colors.js.map +1 -0
  205. package/dist/ui/dashboard.d.ts +51 -0
  206. package/dist/ui/dashboard.js +181 -0
  207. package/dist/ui/dashboard.js.map +1 -0
  208. package/dist/ui/leaderboard.d.ts +16 -0
  209. package/dist/ui/leaderboard.js +43 -0
  210. package/dist/ui/leaderboard.js.map +1 -0
  211. package/dist/ui/logger.d.ts +28 -0
  212. package/dist/ui/logger.js +117 -0
  213. package/dist/ui/logger.js.map +1 -0
  214. package/dist/ui/progress.d.ts +16 -0
  215. package/dist/ui/progress.js +62 -0
  216. package/dist/ui/progress.js.map +1 -0
  217. package/dist/ui/tokenizer.d.ts +5 -0
  218. package/dist/ui/tokenizer.js +54 -0
  219. package/dist/ui/tokenizer.js.map +1 -0
  220. package/package.json +63 -0
@@ -0,0 +1,172 @@
1
+ import { renderFileChange } from "./diff_display.js";
2
+ /**
3
+ * Sensible default: reads auto-approved, writes/executes require user approval.
4
+ */
5
+ export const DEFAULT_APPROVAL_POLICY = {
6
+ defaultDecision: "ask",
7
+ categoryDefaults: {
8
+ read: "allow",
9
+ search: "allow",
10
+ ask: "allow",
11
+ write: "ask",
12
+ execute: "ask",
13
+ },
14
+ rules: [
15
+ // Never allow writing to sensitive paths
16
+ { tool: "*", category: "write", decision: "deny", pathPattern: "**.env" },
17
+ { tool: "*", category: "write", decision: "deny", pathPattern: "**.pem" },
18
+ { tool: "*", category: "write", decision: "deny", pathPattern: "**credentials**" },
19
+ { tool: "*", category: "write", decision: "deny", pathPattern: "**secret**" },
20
+ // Deny dangerous commands
21
+ { tool: "run_command", decision: "deny", pathPattern: "rm -rf *" },
22
+ ],
23
+ };
24
+ // ── Glob Matching ─────────────────────────────────────────────────
25
+ function matchesGlob(value, pattern) {
26
+ // Simple glob: * matches any sequence, ** matches across slashes
27
+ const regex = pattern
28
+ .replace(/[.+^${}()|[\]\\]/g, "\\$&")
29
+ .replace(/\*\*/g, "{{DOUBLESTAR}}")
30
+ .replace(/\*/g, "[^/]*")
31
+ .replace(/\{\{DOUBLESTAR\}\}/g, ".*");
32
+ return new RegExp(`^${regex}$`).test(value);
33
+ }
34
+ export class ApprovalEngine {
35
+ policy;
36
+ sessionOverrides = new Map();
37
+ autoApproveAll = false;
38
+ constructor(policy = DEFAULT_APPROVAL_POLICY) {
39
+ this.policy = { ...policy };
40
+ }
41
+ /**
42
+ * Toggle auto-approve mode (skips all checks, allows everything).
43
+ */
44
+ setAutoApprove(value) {
45
+ this.autoApproveAll = value;
46
+ }
47
+ getAutoApprove() {
48
+ return this.autoApproveAll;
49
+ }
50
+ /**
51
+ * Set a session-level override for a specific tool.
52
+ * "allow-always" persists for the session.
53
+ */
54
+ setToolOverride(toolName, decision) {
55
+ this.sessionOverrides.set(toolName, decision);
56
+ }
57
+ clearOverrides() {
58
+ this.sessionOverrides.clear();
59
+ }
60
+ getPolicy() {
61
+ return this.policy;
62
+ }
63
+ updatePolicy(patch) {
64
+ if (patch.defaultDecision !== undefined)
65
+ this.policy.defaultDecision = patch.defaultDecision;
66
+ if (patch.categoryDefaults !== undefined)
67
+ this.policy.categoryDefaults = patch.categoryDefaults;
68
+ if (patch.rules !== undefined)
69
+ this.policy.rules = patch.rules;
70
+ }
71
+ /**
72
+ * Evaluate whether an action should proceed without asking the user.
73
+ * Returns the decision without prompting.
74
+ */
75
+ evaluate(action) {
76
+ if (this.autoApproveAll)
77
+ return "allow";
78
+ // Session override for this exact tool
79
+ const override = this.sessionOverrides.get(action.tool);
80
+ if (override)
81
+ return override;
82
+ // Check rules in order
83
+ for (const rule of this.policy.rules) {
84
+ if (rule.tool !== "*" && rule.tool !== action.tool)
85
+ continue;
86
+ if (rule.category && rule.category !== action.category)
87
+ continue;
88
+ if (rule.pathPattern) {
89
+ const pathValue = extractPathFromAction(action);
90
+ if (pathValue && matchesGlob(pathValue, rule.pathPattern)) {
91
+ return rule.decision;
92
+ }
93
+ // Rule has pathPattern but action has no path — skip
94
+ continue;
95
+ }
96
+ return rule.decision;
97
+ }
98
+ // Category default
99
+ const catDefault = this.policy.categoryDefaults[action.category];
100
+ if (catDefault)
101
+ return catDefault;
102
+ return this.policy.defaultDecision;
103
+ }
104
+ /**
105
+ * Check approval and prompt user if needed.
106
+ * Returns true if the action should proceed, false if denied.
107
+ */
108
+ async check(action, promptFn, fileChange, renderOpts) {
109
+ const decision = this.evaluate(action);
110
+ if (decision === "allow")
111
+ return true;
112
+ if (decision === "deny")
113
+ return false;
114
+ // decision === "ask" — prompt the user
115
+ let displayText = formatActionSummary(action);
116
+ if (fileChange) {
117
+ displayText += "\n\n" + renderFileChange(fileChange, renderOpts);
118
+ }
119
+ return promptFn(action, displayText);
120
+ }
121
+ }
122
+ // ── Display Helpers ───────────────────────────────────────────────
123
+ const R = "\x1b[0m";
124
+ const B = "\x1b[1m";
125
+ const DM = "\x1b[2m";
126
+ const YLW = "\x1b[93m";
127
+ const CYN = "\x1b[96m";
128
+ function extractPathFromAction(action) {
129
+ const input = action.input;
130
+ if (typeof input.path === "string")
131
+ return input.path;
132
+ if (typeof input.filePath === "string")
133
+ return input.filePath;
134
+ if (typeof input.file_path === "string")
135
+ return input.file_path;
136
+ if (typeof input.command === "string")
137
+ return input.command;
138
+ return null;
139
+ }
140
+ export function formatActionSummary(action) {
141
+ const icon = categoryIcon(action.category);
142
+ const path = extractPathFromAction(action);
143
+ const pathStr = path ? ` ${DM}${path}${R}` : "";
144
+ return `${YLW}${B}${icon} ${action.tool}${R}${pathStr}\n ${DM}${action.summary}${R}`;
145
+ }
146
+ function categoryIcon(category) {
147
+ switch (category) {
148
+ case "read": return "[R]";
149
+ case "write": return "[W]";
150
+ case "execute": return "[X]";
151
+ case "search": return "[S]";
152
+ case "ask": return "[?]";
153
+ }
154
+ }
155
+ /**
156
+ * Format a batch of actions into a compact approval prompt.
157
+ */
158
+ export function formatBatchSummary(actions) {
159
+ const lines = [
160
+ `${CYN}${B}Pending actions${R} ${DM}(${actions.length})${R}`,
161
+ "",
162
+ ];
163
+ for (let i = 0; i < actions.length; i++) {
164
+ const a = actions[i];
165
+ const icon = categoryIcon(a.category);
166
+ const path = extractPathFromAction(a);
167
+ lines.push(` ${B}${i + 1}.${R} ${YLW}${icon}${R} ${a.tool}${path ? ` ${DM}${path}${R}` : ""}`);
168
+ lines.push(` ${DM}${a.summary}${R}`);
169
+ }
170
+ return lines.join("\n");
171
+ }
172
+ //# sourceMappingURL=approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../src/tools/approval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Checkpoint system: snapshot working directory before tool execution.
3
+ * Supports git-based (stash create) and copy-based fallback.
4
+ * Also provides /undo and /undo list commands.
5
+ */
6
+ export interface CheckpointEntry {
7
+ id: number;
8
+ timestamp: number;
9
+ strategy: "git" | "copy";
10
+ /** Git stash ref (for git strategy) */
11
+ stashRef?: string;
12
+ /** Copy directory path (for copy strategy) */
13
+ copyDir?: string;
14
+ /** Files that were affected */
15
+ files: string[];
16
+ /** Human-readable label */
17
+ label: string;
18
+ }
19
+ export declare class CheckpointManager {
20
+ private readonly projectRoot;
21
+ private readonly checkpointDir;
22
+ private stack;
23
+ private redoStack;
24
+ private nextId;
25
+ private gitRepoCache;
26
+ constructor(projectRoot: string);
27
+ private isGitRepo;
28
+ /**
29
+ * Create a checkpoint of the current working directory state.
30
+ * Uses git stash create if in a git repo, otherwise copies files.
31
+ */
32
+ create(label: string): CheckpointEntry | null;
33
+ private createGitCheckpoint;
34
+ private createCopyCheckpoint;
35
+ private cleanupRedoStack;
36
+ private pushCheckpoint;
37
+ /**
38
+ * Undo to the most recent checkpoint (or N steps back).
39
+ */
40
+ undo(steps?: number): CheckpointEntry | null;
41
+ /**
42
+ * Redo the most recently undone checkpoint.
43
+ */
44
+ redo(): CheckpointEntry | null;
45
+ private restoreCheckpoint;
46
+ private restoreGitCheckpoint;
47
+ private restoreCopyCheckpoint;
48
+ private cleanupCopyDir;
49
+ /**
50
+ * Get the checkpoint history (most recent first).
51
+ */
52
+ getHistory(): readonly CheckpointEntry[];
53
+ /**
54
+ * Get the redo stack (most recent first).
55
+ */
56
+ getRedoHistory(): readonly CheckpointEntry[];
57
+ /**
58
+ * Number of checkpoints available for undo.
59
+ */
60
+ get undoCount(): number;
61
+ /**
62
+ * Number of checkpoints available for redo.
63
+ */
64
+ get redoCount(): number;
65
+ }
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Checkpoint system: snapshot working directory before tool execution.
3
+ * Supports git-based (stash create) and copy-based fallback.
4
+ * Also provides /undo and /undo list commands.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { execSync, execFileSync } from "node:child_process";
9
+ // ── Helpers ─────────────────────────────────────────────────────
10
+ function isGitRepo(cwd) {
11
+ try {
12
+ execSync("git rev-parse --is-inside-work-tree", {
13
+ cwd,
14
+ stdio: "pipe",
15
+ timeout: 5000,
16
+ });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ function getGitChangedFiles(cwd) {
24
+ try {
25
+ const out = execSync("git diff --name-only HEAD 2>/dev/null || git diff --name-only", {
26
+ cwd,
27
+ stdio: "pipe",
28
+ timeout: 5000,
29
+ }).toString().trim();
30
+ if (!out)
31
+ return [];
32
+ return out.split("\n").filter(Boolean);
33
+ }
34
+ catch {
35
+ return [];
36
+ }
37
+ }
38
+ function getGitUntrackedFiles(cwd) {
39
+ try {
40
+ const out = execSync("git ls-files --others --exclude-standard", {
41
+ cwd,
42
+ stdio: "pipe",
43
+ timeout: 5000,
44
+ }).toString().trim();
45
+ if (!out)
46
+ return [];
47
+ return out.split("\n").filter(Boolean);
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ /** Validate a path stays within the project root (prevents traversal). */
54
+ function isWithinRoot(root, filePath) {
55
+ const resolved = path.resolve(root, filePath);
56
+ return resolved.startsWith(root + path.sep) || resolved === root;
57
+ }
58
+ // ── CheckpointManager ──────────────────────────────────────────
59
+ const MAX_CHECKPOINTS = 20;
60
+ export class CheckpointManager {
61
+ projectRoot;
62
+ checkpointDir;
63
+ stack = [];
64
+ redoStack = [];
65
+ nextId = 1;
66
+ gitRepoCache = null;
67
+ constructor(projectRoot) {
68
+ this.projectRoot = projectRoot;
69
+ this.checkpointDir = path.join(projectRoot, ".duocode", "checkpoints");
70
+ }
71
+ isGitRepo() {
72
+ if (this.gitRepoCache === null) {
73
+ this.gitRepoCache = isGitRepo(this.projectRoot);
74
+ }
75
+ return this.gitRepoCache;
76
+ }
77
+ /**
78
+ * Create a checkpoint of the current working directory state.
79
+ * Uses git stash create if in a git repo, otherwise copies files.
80
+ */
81
+ create(label) {
82
+ if (this.isGitRepo()) {
83
+ return this.createGitCheckpoint(label);
84
+ }
85
+ return this.createCopyCheckpoint(label);
86
+ }
87
+ createGitCheckpoint(label) {
88
+ const changedFiles = getGitChangedFiles(this.projectRoot);
89
+ const untrackedFiles = getGitUntrackedFiles(this.projectRoot);
90
+ const allFiles = [...changedFiles, ...untrackedFiles];
91
+ if (allFiles.length === 0)
92
+ return null; // Nothing to checkpoint
93
+ // Stage untracked files temporarily for stash to capture them
94
+ let addedUntracked = false;
95
+ if (untrackedFiles.length > 0) {
96
+ try {
97
+ // Use execFileSync to prevent command injection via filenames
98
+ execFileSync("git", ["add", "--intent-to-add", ...untrackedFiles], {
99
+ cwd: this.projectRoot,
100
+ stdio: "pipe",
101
+ timeout: 5000,
102
+ });
103
+ addedUntracked = true;
104
+ }
105
+ catch {
106
+ // Continue without untracked files in stash
107
+ }
108
+ }
109
+ try {
110
+ // git stash create — creates a stash ref without modifying working tree
111
+ const ref = execSync("git stash create", {
112
+ cwd: this.projectRoot,
113
+ stdio: "pipe",
114
+ timeout: 10000,
115
+ }).toString().trim();
116
+ if (!ref)
117
+ return null; // No changes to stash
118
+ const entry = {
119
+ id: this.nextId++,
120
+ timestamp: Date.now(),
121
+ strategy: "git",
122
+ stashRef: ref,
123
+ files: allFiles,
124
+ label,
125
+ };
126
+ this.pushCheckpoint(entry);
127
+ return entry;
128
+ }
129
+ catch {
130
+ // Fall back to copy-based
131
+ return this.createCopyCheckpoint(label);
132
+ }
133
+ finally {
134
+ // Undo the intent-to-add for untracked files
135
+ if (addedUntracked) {
136
+ try {
137
+ execFileSync("git", ["reset", "HEAD", ...untrackedFiles], {
138
+ cwd: this.projectRoot,
139
+ stdio: "pipe",
140
+ timeout: 5000,
141
+ });
142
+ }
143
+ catch {
144
+ // Best effort
145
+ }
146
+ }
147
+ }
148
+ }
149
+ createCopyCheckpoint(label) {
150
+ const timestamp = Date.now();
151
+ const copyDir = path.join(this.checkpointDir, String(timestamp));
152
+ if (!fs.existsSync(this.checkpointDir)) {
153
+ fs.mkdirSync(this.checkpointDir, { recursive: true });
154
+ }
155
+ fs.mkdirSync(copyDir, { recursive: true });
156
+ // Get list of files to copy from git (if available)
157
+ let files;
158
+ if (this.isGitRepo()) {
159
+ files = [...getGitChangedFiles(this.projectRoot), ...getGitUntrackedFiles(this.projectRoot)];
160
+ }
161
+ else {
162
+ // Without git, no reliable way to know which files are "changed"
163
+ // Return null to avoid creating an empty checkpoint
164
+ return null;
165
+ }
166
+ if (files.length === 0)
167
+ return null;
168
+ for (const relFile of files) {
169
+ // Guard against path traversal
170
+ if (!isWithinRoot(this.projectRoot, relFile))
171
+ continue;
172
+ const srcPath = path.join(this.projectRoot, relFile);
173
+ if (!fs.existsSync(srcPath))
174
+ continue;
175
+ const destPath = path.join(copyDir, relFile);
176
+ const destDir = path.dirname(destPath);
177
+ if (!fs.existsSync(destDir)) {
178
+ fs.mkdirSync(destDir, { recursive: true });
179
+ }
180
+ fs.copyFileSync(srcPath, destPath);
181
+ }
182
+ const entry = {
183
+ id: this.nextId++,
184
+ timestamp,
185
+ strategy: "copy",
186
+ copyDir,
187
+ files,
188
+ label,
189
+ };
190
+ this.pushCheckpoint(entry);
191
+ return entry;
192
+ }
193
+ cleanupRedoStack() {
194
+ for (const entry of this.redoStack) {
195
+ if (entry.strategy === "copy" && entry.copyDir) {
196
+ this.cleanupCopyDir(entry.copyDir);
197
+ }
198
+ }
199
+ this.redoStack = [];
200
+ }
201
+ pushCheckpoint(entry) {
202
+ this.stack.push(entry);
203
+ // Clear redo stack (with cleanup) when a new checkpoint is created
204
+ this.cleanupRedoStack();
205
+ // Enforce max size
206
+ while (this.stack.length > MAX_CHECKPOINTS) {
207
+ const removed = this.stack.shift();
208
+ if (removed?.strategy === "copy" && removed.copyDir) {
209
+ this.cleanupCopyDir(removed.copyDir);
210
+ }
211
+ }
212
+ }
213
+ /**
214
+ * Undo to the most recent checkpoint (or N steps back).
215
+ */
216
+ undo(steps = 1) {
217
+ if (steps < 1 || this.stack.length === 0)
218
+ return null;
219
+ const actualSteps = Math.min(steps, this.stack.length);
220
+ let restored = null;
221
+ for (let i = 0; i < actualSteps; i++) {
222
+ const entry = this.stack.pop();
223
+ if (!entry)
224
+ break;
225
+ this.redoStack.push(entry);
226
+ restored = entry;
227
+ }
228
+ if (!restored)
229
+ return null;
230
+ this.restoreCheckpoint(restored);
231
+ return restored;
232
+ }
233
+ /**
234
+ * Redo the most recently undone checkpoint.
235
+ */
236
+ redo() {
237
+ if (this.redoStack.length === 0)
238
+ return null;
239
+ // Pop the redo entry BEFORE create() clears the redo stack
240
+ const entry = this.redoStack.pop();
241
+ // Save remaining redo stack — create() will clear it
242
+ const savedRedo = [...this.redoStack];
243
+ this.create("pre-redo");
244
+ // Restore the redo stack (create → pushCheckpoint cleared it)
245
+ this.redoStack = savedRedo;
246
+ this.restoreCheckpoint(entry);
247
+ return entry;
248
+ }
249
+ restoreCheckpoint(entry) {
250
+ if (entry.strategy === "git" && entry.stashRef) {
251
+ this.restoreGitCheckpoint(entry);
252
+ }
253
+ else if (entry.strategy === "copy" && entry.copyDir) {
254
+ this.restoreCopyCheckpoint(entry);
255
+ }
256
+ }
257
+ restoreGitCheckpoint(entry) {
258
+ // Validate stash ref is a hex SHA (prevent injection)
259
+ if (!entry.stashRef || !/^[0-9a-f]{7,40}$/i.test(entry.stashRef))
260
+ return;
261
+ try {
262
+ // Restore files from the stash ref without dropping it
263
+ for (const file of entry.files) {
264
+ try {
265
+ // Use execFileSync to prevent command injection via filenames
266
+ execFileSync("git", ["checkout", entry.stashRef, "--", file], {
267
+ cwd: this.projectRoot,
268
+ stdio: "pipe",
269
+ timeout: 5000,
270
+ });
271
+ }
272
+ catch {
273
+ // File might not exist in the stash (e.g., new file that was deleted)
274
+ }
275
+ }
276
+ }
277
+ catch {
278
+ // Fallback: try applying the whole stash
279
+ try {
280
+ execFileSync("git", ["stash", "apply", entry.stashRef], {
281
+ cwd: this.projectRoot,
282
+ stdio: "pipe",
283
+ timeout: 10000,
284
+ });
285
+ }
286
+ catch {
287
+ // Best effort — stash may conflict
288
+ }
289
+ }
290
+ }
291
+ restoreCopyCheckpoint(entry) {
292
+ if (!entry.copyDir || !fs.existsSync(entry.copyDir))
293
+ return;
294
+ for (const relFile of entry.files) {
295
+ // Guard against path traversal
296
+ if (!isWithinRoot(this.projectRoot, relFile))
297
+ continue;
298
+ const srcPath = path.join(entry.copyDir, relFile);
299
+ const destPath = path.join(this.projectRoot, relFile);
300
+ if (!fs.existsSync(srcPath))
301
+ continue;
302
+ const destDir = path.dirname(destPath);
303
+ if (!fs.existsSync(destDir)) {
304
+ fs.mkdirSync(destDir, { recursive: true });
305
+ }
306
+ fs.copyFileSync(srcPath, destPath);
307
+ }
308
+ }
309
+ cleanupCopyDir(dir) {
310
+ try {
311
+ fs.rmSync(dir, { recursive: true, force: true });
312
+ }
313
+ catch {
314
+ // Best effort
315
+ }
316
+ }
317
+ /**
318
+ * Get the checkpoint history (most recent first).
319
+ */
320
+ getHistory() {
321
+ return [...this.stack].reverse();
322
+ }
323
+ /**
324
+ * Get the redo stack (most recent first).
325
+ */
326
+ getRedoHistory() {
327
+ return [...this.redoStack].reverse();
328
+ }
329
+ /**
330
+ * Number of checkpoints available for undo.
331
+ */
332
+ get undoCount() {
333
+ return this.stack.length;
334
+ }
335
+ /**
336
+ * Number of checkpoints available for redo.
337
+ */
338
+ get redoCount() {
339
+ return this.redoStack.length;
340
+ }
341
+ }
342
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/tools/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Core tool definitions for the agentic executor.
3
+ * Each tool has a JSON Schema input definition that models use
4
+ * to produce structured tool calls.
5
+ */
6
+ import type { ToolDefinition } from "../providers/base.js";
7
+ export declare const TOOL_READ_FILE: ToolDefinition;
8
+ export declare const TOOL_WRITE_FILE: ToolDefinition;
9
+ export declare const TOOL_EDIT_FILE: ToolDefinition;
10
+ export declare const TOOL_LIST_DIRECTORY: ToolDefinition;
11
+ export declare const TOOL_SEARCH_FILES: ToolDefinition;
12
+ export declare const TOOL_RUN_COMMAND: ToolDefinition;
13
+ export declare const ALL_TOOLS: ToolDefinition[];