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.
- package/.env.example +36 -0
- package/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/ast/context.d.ts +16 -0
- package/dist/ast/context.js +37 -0
- package/dist/ast/context.js.map +1 -0
- package/dist/ast/diff.d.ts +27 -0
- package/dist/ast/diff.js +44 -0
- package/dist/ast/diff.js.map +1 -0
- package/dist/ast/locks.d.ts +47 -0
- package/dist/ast/locks.js +88 -0
- package/dist/ast/locks.js.map +1 -0
- package/dist/ast/merge.d.ts +22 -0
- package/dist/ast/merge.js +120 -0
- package/dist/ast/merge.js.map +1 -0
- package/dist/ast/ownership.d.ts +31 -0
- package/dist/ast/ownership.js +111 -0
- package/dist/ast/ownership.js.map +1 -0
- package/dist/ast/parser.d.ts +44 -0
- package/dist/ast/parser.js +134 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +423 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.js +63 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/duo.d.ts +9 -0
- package/dist/commands/duo.js +285 -0
- package/dist/commands/duo.js.map +1 -0
- package/dist/commands/github.d.ts +2 -0
- package/dist/commands/github.js +85 -0
- package/dist/commands/github.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +33 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/negotiation.d.ts +2 -0
- package/dist/commands/negotiation.js +160 -0
- package/dist/commands/negotiation.js.map +1 -0
- package/dist/commands/repl_commands.d.ts +26 -0
- package/dist/commands/repl_commands.js +226 -0
- package/dist/commands/repl_commands.js.map +1 -0
- package/dist/commands/shell.d.ts +1 -0
- package/dist/commands/shell.js +110 -0
- package/dist/commands/shell.js.map +1 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.js +231 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/task.d.ts +2 -0
- package/dist/commands/task.js +215 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/config/loader.d.ts +193 -0
- package/dist/config/loader.js +106 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/context/project_context.d.ts +79 -0
- package/dist/context/project_context.js +292 -0
- package/dist/context/project_context.js.map +1 -0
- package/dist/context/token_budget.d.ts +35 -0
- package/dist/context/token_budget.js +81 -0
- package/dist/context/token_budget.js.map +1 -0
- package/dist/db/queries.d.ts +121 -0
- package/dist/db/queries.js +109 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +110 -0
- package/dist/db/schema.js +346 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/duo/duo_orchestrator.d.ts +50 -0
- package/dist/duo/duo_orchestrator.js +510 -0
- package/dist/duo/duo_orchestrator.js.map +1 -0
- package/dist/duo/duo_session.d.ts +47 -0
- package/dist/duo/duo_session.js +127 -0
- package/dist/duo/duo_session.js.map +1 -0
- package/dist/duo/duo_types.d.ts +168 -0
- package/dist/duo/duo_types.js +53 -0
- package/dist/duo/duo_types.js.map +1 -0
- package/dist/duo/session_store.d.ts +71 -0
- package/dist/duo/session_store.js +177 -0
- package/dist/duo/session_store.js.map +1 -0
- package/dist/git/worktree.d.ts +21 -0
- package/dist/git/worktree.js +86 -0
- package/dist/git/worktree.js.map +1 -0
- package/dist/github/cache.d.ts +23 -0
- package/dist/github/cache.js +67 -0
- package/dist/github/cache.js.map +1 -0
- package/dist/github/issues.d.ts +17 -0
- package/dist/github/issues.js +93 -0
- package/dist/github/issues.js.map +1 -0
- package/dist/github/mcp_client.d.ts +57 -0
- package/dist/github/mcp_client.js +214 -0
- package/dist/github/mcp_client.js.map +1 -0
- package/dist/github/sync.d.ts +11 -0
- package/dist/github/sync.js +65 -0
- package/dist/github/sync.js.map +1 -0
- package/dist/github/webhook.d.ts +25 -0
- package/dist/github/webhook.js +197 -0
- package/dist/github/webhook.js.map +1 -0
- package/dist/negotiation/index.d.ts +1 -0
- package/dist/negotiation/index.js +2 -0
- package/dist/negotiation/index.js.map +1 -0
- package/dist/negotiation/protocol.d.ts +62 -0
- package/dist/negotiation/protocol.js +188 -0
- package/dist/negotiation/protocol.js.map +1 -0
- package/dist/orchestrator/complexity_scorer.d.ts +2 -0
- package/dist/orchestrator/complexity_scorer.js +79 -0
- package/dist/orchestrator/complexity_scorer.js.map +1 -0
- package/dist/orchestrator/dependency_graph.d.ts +7 -0
- package/dist/orchestrator/dependency_graph.js +73 -0
- package/dist/orchestrator/dependency_graph.js.map +1 -0
- package/dist/orchestrator/intent_parser.d.ts +11 -0
- package/dist/orchestrator/intent_parser.js +116 -0
- package/dist/orchestrator/intent_parser.js.map +1 -0
- package/dist/orchestrator/task_runner.d.ts +56 -0
- package/dist/orchestrator/task_runner.js +181 -0
- package/dist/orchestrator/task_runner.js.map +1 -0
- package/dist/orchestrator/types.d.ts +44 -0
- package/dist/orchestrator/types.js +21 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +12 -0
- package/dist/providers/anthropic.js +258 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/auction.d.ts +42 -0
- package/dist/providers/auction.js +190 -0
- package/dist/providers/auction.js.map +1 -0
- package/dist/providers/base.d.ts +103 -0
- package/dist/providers/base.js +2 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/cost_tracker.d.ts +45 -0
- package/dist/providers/cost_tracker.js +111 -0
- package/dist/providers/cost_tracker.js.map +1 -0
- package/dist/providers/duo_pair_router.d.ts +11 -0
- package/dist/providers/duo_pair_router.js +67 -0
- package/dist/providers/duo_pair_router.js.map +1 -0
- package/dist/providers/factory.d.ts +7 -0
- package/dist/providers/factory.js +130 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/grading_rubric.d.ts +37 -0
- package/dist/providers/grading_rubric.js +238 -0
- package/dist/providers/grading_rubric.js.map +1 -0
- package/dist/providers/openai.d.ts +12 -0
- package/dist/providers/openai.js +229 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openrouter.d.ts +14 -0
- package/dist/providers/openrouter.js +178 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/performance_tracker.d.ts +21 -0
- package/dist/providers/performance_tracker.js +63 -0
- package/dist/providers/performance_tracker.js.map +1 -0
- package/dist/providers/registry_loader.d.ts +6 -0
- package/dist/providers/registry_loader.js +54 -0
- package/dist/providers/registry_loader.js.map +1 -0
- package/dist/providers/retry.d.ts +66 -0
- package/dist/providers/retry.js +203 -0
- package/dist/providers/retry.js.map +1 -0
- package/dist/providers/role_scorer.d.ts +16 -0
- package/dist/providers/role_scorer.js +16 -0
- package/dist/providers/role_scorer.js.map +1 -0
- package/dist/providers/router.d.ts +84 -0
- package/dist/providers/router.js +542 -0
- package/dist/providers/router.js.map +1 -0
- package/dist/security/credentials.d.ts +6 -0
- package/dist/security/credentials.js +16 -0
- package/dist/security/credentials.js.map +1 -0
- package/dist/setup/browser.d.ts +1 -0
- package/dist/setup/browser.js +12 -0
- package/dist/setup/browser.js.map +1 -0
- package/dist/setup/global_config.d.ts +14 -0
- package/dist/setup/global_config.js +54 -0
- package/dist/setup/global_config.js.map +1 -0
- package/dist/setup/wizard.d.ts +2 -0
- package/dist/setup/wizard.js +206 -0
- package/dist/setup/wizard.js.map +1 -0
- package/dist/tools/agent_loop.d.ts +38 -0
- package/dist/tools/agent_loop.js +72 -0
- package/dist/tools/agent_loop.js.map +1 -0
- package/dist/tools/approval.d.ts +64 -0
- package/dist/tools/approval.js +172 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/checkpoint.d.ts +65 -0
- package/dist/tools/checkpoint.js +342 -0
- package/dist/tools/checkpoint.js.map +1 -0
- package/dist/tools/definitions.d.ts +13 -0
- package/dist/tools/definitions.js +103 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/diff_display.d.ts +46 -0
- package/dist/tools/diff_display.js +298 -0
- package/dist/tools/diff_display.js.map +1 -0
- package/dist/tools/executor.d.ts +12 -0
- package/dist/tools/executor.js +340 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/permissions.d.ts +17 -0
- package/dist/tools/permissions.js +139 -0
- package/dist/tools/permissions.js.map +1 -0
- package/dist/tools/tool_types.d.ts +48 -0
- package/dist/tools/tool_types.js +7 -0
- package/dist/tools/tool_types.js.map +1 -0
- package/dist/ui/banner.d.ts +4 -0
- package/dist/ui/banner.js +104 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/callbacks.d.ts +30 -0
- package/dist/ui/callbacks.js +132 -0
- package/dist/ui/callbacks.js.map +1 -0
- package/dist/ui/colors.d.ts +14 -0
- package/dist/ui/colors.js +28 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/dashboard.d.ts +51 -0
- package/dist/ui/dashboard.js +181 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/leaderboard.d.ts +16 -0
- package/dist/ui/leaderboard.js +43 -0
- package/dist/ui/leaderboard.js.map +1 -0
- package/dist/ui/logger.d.ts +28 -0
- package/dist/ui/logger.js +117 -0
- package/dist/ui/logger.js.map +1 -0
- package/dist/ui/progress.d.ts +16 -0
- package/dist/ui/progress.js +62 -0
- package/dist/ui/progress.js.map +1 -0
- package/dist/ui/tokenizer.d.ts +5 -0
- package/dist/ui/tokenizer.js +54 -0
- package/dist/ui/tokenizer.js.map +1 -0
- 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":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAkB5D,mEAAmE;AAEnE,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,QAAQ,CAAC,qCAAqC,EAAE;YAC9C,GAAG;YACH,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,+DAA+D,EAAE;YACpF,GAAG;YACH,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,0CAA0C,EAAE;YAC/D,GAAG;YACH,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,SAAS,YAAY,CAAC,IAAY,EAAE,QAAgB;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC;AACnE,CAAC;AAED,kEAAkE;AAElE,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,MAAM,OAAO,iBAAiB;IACX,WAAW,CAAS;IACpB,aAAa,CAAS;IAC/B,KAAK,GAAsB,EAAE,CAAC;IAC9B,SAAS,GAAsB,EAAE,CAAC;IAClC,MAAM,GAAG,CAAC,CAAC;IACX,YAAY,GAAmB,IAAI,CAAC;IAE5C,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IACzE,CAAC;IAEO,SAAS;QACf,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAa;QAClB,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAEO,mBAAmB,CAAC,KAAa;QACvC,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,MAAM,cAAc,GAAG,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,cAAc,CAAC,CAAC;QAEtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,wBAAwB;QAEhE,8DAA8D;QAC9D,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,8DAA8D;gBAC9D,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,cAAc,CAAC,EAAE;oBACjE,GAAG,EAAE,IAAI,CAAC,WAAW;oBACrB,KAAK,EAAE,MAAM;oBACb,OAAO,EAAE,IAAI;iBACd,CAAC,CAAC;gBACH,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,4CAA4C;YAC9C,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,wEAAwE;YACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,kBAAkB,EAAE;gBACvC,GAAG,EAAE,IAAI,CAAC,WAAW;gBACrB,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE,KAAK;aACf,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YAErB,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;YAE7C,MAAM,KAAK,GAAoB;gBAC7B,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;gBACjB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,GAAG;gBACb,KAAK,EAAE,QAAQ;gBACf,KAAK;aACN,CAAC;YAEF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;YAC1B,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;gBAAS,CAAC;YACT,6CAA6C;YAC7C,IAAI,cAAc,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,YAAY,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,EAAE;wBACxD,GAAG,EAAE,IAAI,CAAC,WAAW;wBACrB,KAAK,EAAE,MAAM;wBACb,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,cAAc;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,KAAa;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAEjE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACvC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,oDAAoD;QACpD,IAAI,KAAe,CAAC;QACpB,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACrB,KAAK,GAAG,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,iEAAiE;YACjE,oDAAoD;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,+BAA+B;YAC/B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;gBAAE,SAAS;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,KAAK,GAAoB;YAC7B,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;YACjB,SAAS;YACT,QAAQ,EAAE,MAAM;YAChB,OAAO;YACP,KAAK;YACL,KAAK;SACN,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,gBAAgB;QACtB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC/C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAEO,cAAc,CAAC,KAAsB;QAC3C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,mEAAmE;QACnE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,mBAAmB;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,OAAO,EAAE,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpD,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAK,GAAG,CAAC;QACZ,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,QAAQ,GAA2B,IAAI,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK;gBAAE,MAAM;YAClB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,QAAQ,GAAG,KAAK,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7C,2DAA2D;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAG,CAAC;QAEpC,qDAAqD;QACrD,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACxB,8DAA8D;QAC9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,iBAAiB,CAAC,KAAsB;QAC9C,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC/C,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACtD,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,KAAsB;QACjD,sDAAsD;QACtD,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,OAAO;QAEzE,IAAI,CAAC;YACH,uDAAuD;YACvD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,8DAA8D;oBAC9D,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;wBAC5D,GAAG,EAAE,IAAI,CAAC,WAAW;wBACrB,KAAK,EAAE,MAAM;wBACb,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,sEAAsE;gBACxE,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;YACzC,IAAI,CAAC;gBACH,YAAY,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;oBACtD,GAAG,EAAE,IAAI,CAAC,WAAW;oBACrB,KAAK,EAAE,MAAM;oBACb,OAAO,EAAE,KAAK;iBACf,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAEO,qBAAqB,CAAC,KAAsB;QAClD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO;QAE5D,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAClC,+BAA+B;YAC/B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;gBAAE,SAAS;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,GAAW;QAChC,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -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[];
|