@phuetz/code-buddy 0.1.25 → 0.1.26
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 +1049 -741
- package/dist/agent/codebuddy-agent.d.ts +5 -0
- package/dist/agent/codebuddy-agent.js +46 -1
- package/dist/agent/codebuddy-agent.js.map +1 -1
- package/dist/agent/execution/agent-executor.d.ts +12 -0
- package/dist/agent/execution/agent-executor.js +147 -6
- package/dist/agent/execution/agent-executor.js.map +1 -1
- package/dist/agent/lessons-tracker.d.ts +50 -0
- package/dist/agent/lessons-tracker.js +234 -0
- package/dist/agent/lessons-tracker.js.map +1 -0
- package/dist/agent/message-queue.d.ts +39 -2
- package/dist/agent/message-queue.js +67 -2
- package/dist/agent/message-queue.js.map +1 -1
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/index.js.map +1 -1
- package/dist/agent/middleware/workflow-guard.d.ts +21 -0
- package/dist/agent/middleware/workflow-guard.js +94 -0
- package/dist/agent/middleware/workflow-guard.js.map +1 -0
- package/dist/agent/repo-profiler.d.ts +61 -0
- package/dist/agent/repo-profiler.js +295 -0
- package/dist/agent/repo-profiler.js.map +1 -0
- package/dist/agent/response-constraint.d.ts +61 -0
- package/dist/agent/response-constraint.js +91 -0
- package/dist/agent/response-constraint.js.map +1 -0
- package/dist/agent/todo-tracker.d.ts +67 -0
- package/dist/agent/todo-tracker.js +245 -0
- package/dist/agent/todo-tracker.js.map +1 -0
- package/dist/agent/tool-handler.d.ts +11 -0
- package/dist/agent/tool-handler.js +79 -1
- package/dist/agent/tool-handler.js.map +1 -1
- package/dist/agent/types.d.ts +20 -2
- package/dist/agent/wide-research.d.ts +93 -0
- package/dist/agent/wide-research.js +232 -0
- package/dist/agent/wide-research.js.map +1 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +2 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/pro/callback-router.d.ts +54 -0
- package/dist/channels/pro/callback-router.js +178 -0
- package/dist/channels/pro/callback-router.js.map +1 -0
- package/dist/channels/pro/ci-watcher.d.ts +86 -0
- package/dist/channels/pro/ci-watcher.js +343 -0
- package/dist/channels/pro/ci-watcher.js.map +1 -0
- package/dist/channels/pro/diff-first.d.ts +63 -0
- package/dist/channels/pro/diff-first.js +187 -0
- package/dist/channels/pro/diff-first.js.map +1 -0
- package/dist/channels/pro/enhanced-commands.d.ts +83 -0
- package/dist/channels/pro/enhanced-commands.js +218 -0
- package/dist/channels/pro/enhanced-commands.js.map +1 -0
- package/dist/channels/pro/index.d.ts +19 -0
- package/dist/channels/pro/index.js +21 -0
- package/dist/channels/pro/index.js.map +1 -0
- package/dist/channels/pro/pro-features.d.ts +79 -0
- package/dist/channels/pro/pro-features.js +203 -0
- package/dist/channels/pro/pro-features.js.map +1 -0
- package/dist/channels/pro/run-commands.d.ts +59 -0
- package/dist/channels/pro/run-commands.js +122 -0
- package/dist/channels/pro/run-commands.js.map +1 -0
- package/dist/channels/pro/run-tracker.d.ts +74 -0
- package/dist/channels/pro/run-tracker.js +252 -0
- package/dist/channels/pro/run-tracker.js.map +1 -0
- package/dist/channels/pro/scoped-auth.d.ts +97 -0
- package/dist/channels/pro/scoped-auth.js +340 -0
- package/dist/channels/pro/scoped-auth.js.map +1 -0
- package/dist/channels/pro/text-formatter.d.ts +27 -0
- package/dist/channels/pro/text-formatter.js +269 -0
- package/dist/channels/pro/text-formatter.js.map +1 -0
- package/dist/channels/pro/types.d.ts +242 -0
- package/dist/channels/pro/types.js +14 -0
- package/dist/channels/pro/types.js.map +1 -0
- package/dist/channels/streaming-policy.d.ts +66 -0
- package/dist/channels/streaming-policy.js +266 -0
- package/dist/channels/streaming-policy.js.map +1 -0
- package/dist/channels/telegram/ci-watcher.d.ts +5 -0
- package/dist/channels/telegram/ci-watcher.js +5 -0
- package/dist/channels/telegram/ci-watcher.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +28 -0
- package/dist/channels/telegram/client.js +147 -1
- package/dist/channels/telegram/client.js.map +1 -1
- package/dist/channels/telegram/diff-first.d.ts +5 -0
- package/dist/channels/telegram/diff-first.js +5 -0
- package/dist/channels/telegram/diff-first.js.map +1 -0
- package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
- package/dist/channels/telegram/enhanced-commands.js +6 -0
- package/dist/channels/telegram/enhanced-commands.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +6 -0
- package/dist/channels/telegram/index.js +6 -0
- package/dist/channels/telegram/index.js.map +1 -1
- package/dist/channels/telegram/pro-formatter.d.ts +30 -0
- package/dist/channels/telegram/pro-formatter.js +276 -0
- package/dist/channels/telegram/pro-formatter.js.map +1 -0
- package/dist/channels/telegram/run-commands.d.ts +5 -0
- package/dist/channels/telegram/run-commands.js +6 -0
- package/dist/channels/telegram/run-commands.js.map +1 -0
- package/dist/channels/telegram/run-tracker.d.ts +5 -0
- package/dist/channels/telegram/run-tracker.js +5 -0
- package/dist/channels/telegram/run-tracker.js.map +1 -0
- package/dist/channels/telegram/scoped-auth.d.ts +6 -0
- package/dist/channels/telegram/scoped-auth.js +5 -0
- package/dist/channels/telegram/scoped-auth.js.map +1 -0
- package/dist/channels/telegram/types.d.ts +34 -0
- package/dist/codebuddy/client.js +14 -1
- package/dist/codebuddy/client.js.map +1 -1
- package/dist/commands/dev/index.d.ts +12 -0
- package/dist/commands/dev/index.js +231 -0
- package/dist/commands/dev/index.js.map +1 -0
- package/dist/commands/dev/workflows.d.ts +31 -0
- package/dist/commands/dev/workflows.js +214 -0
- package/dist/commands/dev/workflows.js.map +1 -0
- package/dist/commands/execpolicy.d.ts +17 -0
- package/dist/commands/execpolicy.js +155 -0
- package/dist/commands/execpolicy.js.map +1 -0
- package/dist/commands/knowledge.d.ts +13 -0
- package/dist/commands/knowledge.js +142 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/lessons.d.ts +11 -0
- package/dist/commands/lessons.js +129 -0
- package/dist/commands/lessons.js.map +1 -0
- package/dist/commands/pairing.d.ts +14 -0
- package/dist/commands/pairing.js +132 -0
- package/dist/commands/pairing.js.map +1 -0
- package/dist/commands/research/index.d.ts +13 -0
- package/dist/commands/research/index.js +91 -0
- package/dist/commands/research/index.js.map +1 -0
- package/dist/commands/run-cli/index.d.ts +11 -0
- package/dist/commands/run-cli/index.js +49 -0
- package/dist/commands/run-cli/index.js.map +1 -0
- package/dist/commands/todos.d.ts +9 -0
- package/dist/commands/todos.js +119 -0
- package/dist/commands/todos.js.map +1 -0
- package/dist/config/toml-config.d.ts +21 -0
- package/dist/config/toml-config.js +15 -0
- package/dist/config/toml-config.js.map +1 -1
- package/dist/context/enhanced-compression.js +12 -1
- package/dist/context/enhanced-compression.js.map +1 -1
- package/dist/context/observation-variator.d.ts +44 -0
- package/dist/context/observation-variator.js +83 -0
- package/dist/context/observation-variator.js.map +1 -0
- package/dist/context/precompaction-flush.d.ts +40 -0
- package/dist/context/precompaction-flush.js +134 -0
- package/dist/context/precompaction-flush.js.map +1 -0
- package/dist/context/restorable-compression.d.ts +80 -0
- package/dist/context/restorable-compression.js +228 -0
- package/dist/context/restorable-compression.js.map +1 -0
- package/dist/daemon/daily-reset.d.ts +77 -0
- package/dist/daemon/daily-reset.js +175 -0
- package/dist/daemon/daily-reset.js.map +1 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +1 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge/knowledge-manager.d.ts +77 -0
- package/dist/knowledge/knowledge-manager.js +244 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/observability/run-store.d.ts +133 -0
- package/dist/observability/run-store.js +419 -0
- package/dist/observability/run-store.js.map +1 -0
- package/dist/observability/run-viewer.d.ts +33 -0
- package/dist/observability/run-viewer.js +254 -0
- package/dist/observability/run-viewer.js.map +1 -0
- package/dist/optimization/cache-breakpoints.d.ts +52 -0
- package/dist/optimization/cache-breakpoints.js +97 -0
- package/dist/optimization/cache-breakpoints.js.map +1 -0
- package/dist/persistence/session-store.d.ts +3 -1
- package/dist/persistence/session-store.js +1 -1
- package/dist/persistence/session-store.js.map +1 -1
- package/dist/prompts/system-base.js +51 -7
- package/dist/prompts/system-base.js.map +1 -1
- package/dist/prompts/variation-injector.d.ts +55 -0
- package/dist/prompts/variation-injector.js +171 -0
- package/dist/prompts/variation-injector.js.map +1 -0
- package/dist/prompts/workflow-rules.d.ts +10 -0
- package/dist/prompts/workflow-rules.js +79 -0
- package/dist/prompts/workflow-rules.js.map +1 -0
- package/dist/sandbox/execpolicy.d.ts +45 -0
- package/dist/sandbox/execpolicy.js +80 -0
- package/dist/sandbox/execpolicy.js.map +1 -1
- package/dist/sandbox/os-sandbox.d.ts +25 -0
- package/dist/sandbox/os-sandbox.js +73 -0
- package/dist/sandbox/os-sandbox.js.map +1 -1
- package/dist/security/security-audit.d.ts +10 -0
- package/dist/security/security-audit.js +116 -0
- package/dist/security/security-audit.js.map +1 -1
- package/dist/security/shell-env-policy.d.ts +45 -0
- package/dist/security/shell-env-policy.js +141 -0
- package/dist/security/shell-env-policy.js.map +1 -0
- package/dist/security/ssrf-guard.d.ts +61 -0
- package/dist/security/ssrf-guard.js +382 -0
- package/dist/security/ssrf-guard.js.map +1 -0
- package/dist/security/write-policy.d.ts +57 -0
- package/dist/security/write-policy.js +117 -0
- package/dist/security/write-policy.js.map +1 -0
- package/dist/services/prompt-builder.js +37 -0
- package/dist/services/prompt-builder.js.map +1 -1
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/ask-human-tool.d.ts +62 -0
- package/dist/tools/ask-human-tool.js +112 -0
- package/dist/tools/ask-human-tool.js.map +1 -0
- package/dist/tools/bash/bash-tool.d.ts +15 -0
- package/dist/tools/bash/bash-tool.js +62 -0
- package/dist/tools/bash/bash-tool.js.map +1 -1
- package/dist/tools/bash/command-validator.d.ts +1 -0
- package/dist/tools/bash/command-validator.js +5 -0
- package/dist/tools/bash/command-validator.js.map +1 -1
- package/dist/tools/create-skill-tool.d.ts +87 -0
- package/dist/tools/create-skill-tool.js +142 -0
- package/dist/tools/create-skill-tool.js.map +1 -0
- package/dist/tools/fetch-tool.js +5 -3
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-tool.d.ts +22 -0
- package/dist/tools/plan-tool.js +128 -0
- package/dist/tools/plan-tool.js.map +1 -0
- package/dist/tools/registry/attention-tools.d.ts +32 -0
- package/dist/tools/registry/attention-tools.js +225 -0
- package/dist/tools/registry/attention-tools.js.map +1 -0
- package/dist/tools/registry/index.d.ts +9 -1
- package/dist/tools/registry/index.js +30 -2
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/registry/knowledge-tools.d.ts +46 -0
- package/dist/tools/registry/knowledge-tools.js +293 -0
- package/dist/tools/registry/knowledge-tools.js.map +1 -0
- package/dist/tools/registry/lessons-tools.d.ts +48 -0
- package/dist/tools/registry/lessons-tools.js +359 -0
- package/dist/tools/registry/lessons-tools.js.map +1 -0
- package/dist/tools/registry/plan-tools.d.ts +2 -0
- package/dist/tools/registry/plan-tools.js +7 -0
- package/dist/tools/registry/plan-tools.js.map +1 -0
- package/dist/tools/registry/script-tools.d.ts +2 -0
- package/dist/tools/registry/script-tools.js +7 -0
- package/dist/tools/registry/script-tools.js.map +1 -0
- package/dist/tools/registry/tool-aliases.d.ts +44 -0
- package/dist/tools/registry/tool-aliases.js +130 -0
- package/dist/tools/registry/tool-aliases.js.map +1 -0
- package/dist/tools/run-script-tool.d.ts +13 -0
- package/dist/tools/run-script-tool.js +146 -0
- package/dist/tools/run-script-tool.js.map +1 -0
- package/dist/tools/web-search.d.ts +25 -0
- package/dist/tools/web-search.js +68 -6
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/debug-logger.d.ts +1 -1
- package/dist/utils/stable-json.d.ts +27 -0
- package/dist/utils/stable-json.js +50 -0
- package/dist/utils/stable-json.js.map +1 -0
- package/dist/webhooks/webhook-manager.d.ts +7 -0
- package/dist/webhooks/webhook-manager.js +29 -0
- package/dist/webhooks/webhook-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev Workflows — 4 golden-path workflows for buddy dev.
|
|
3
|
+
*
|
|
4
|
+
* Each workflow:
|
|
5
|
+
* 1. Injects repoProfile.contextPack into the agent system prompt
|
|
6
|
+
* 2. Forces plan-first (shows plan, waits for confirmation in interactive mode)
|
|
7
|
+
* 3. Activates WritePolicy.strict → all modifications go through ApplyPatch
|
|
8
|
+
* 4. Records every tool call in RunStore
|
|
9
|
+
* 5. Runs tests/lint after modifications
|
|
10
|
+
* 6. Generates summary.md artefact
|
|
11
|
+
*/
|
|
12
|
+
import readline from 'readline';
|
|
13
|
+
import { RunStore } from '../../observability/run-store.js';
|
|
14
|
+
import { WritePolicy } from '../../security/write-policy.js';
|
|
15
|
+
import { getRepoProfiler } from '../../agent/repo-profiler.js';
|
|
16
|
+
// ──────────────────────────────────────────────────────────────────
|
|
17
|
+
// Workflow system prompts
|
|
18
|
+
// ──────────────────────────────────────────────────────────────────
|
|
19
|
+
const WORKFLOW_PROMPTS = {
|
|
20
|
+
'add-feature': `You are implementing a new feature. Follow this strict sequence:
|
|
21
|
+
1. PLAN: Output a numbered plan listing each file to create/modify and why.
|
|
22
|
+
2. Wait for confirmation before proceeding.
|
|
23
|
+
3. IMPLEMENT: Apply changes as unified diffs via apply_patch tool.
|
|
24
|
+
4. TEST: Run the test suite and report results.
|
|
25
|
+
5. SUMMARIZE: Output a brief summary of what was done and any next steps.
|
|
26
|
+
Always use apply_patch for file modifications. Never write files directly.`,
|
|
27
|
+
'fix-tests': `You are fixing failing tests. Follow this strict sequence:
|
|
28
|
+
1. DIAGNOSE: Run the test suite, identify failing tests and root causes.
|
|
29
|
+
2. PLAN: List the fixes needed (files + what to change).
|
|
30
|
+
3. Wait for confirmation before proceeding.
|
|
31
|
+
4. FIX: Apply changes as unified diffs via apply_patch tool.
|
|
32
|
+
5. VERIFY: Re-run tests to confirm they pass.
|
|
33
|
+
6. SUMMARIZE: Report which tests now pass and any remaining issues.
|
|
34
|
+
Always use apply_patch for file modifications. Never write files directly.`,
|
|
35
|
+
'refactor': `You are refactoring existing code. Follow this strict sequence:
|
|
36
|
+
1. ANALYZE: Identify the code to refactor and what improvements to make.
|
|
37
|
+
2. PLAN: List every file/function to change and the refactoring steps.
|
|
38
|
+
3. Wait for confirmation before proceeding.
|
|
39
|
+
4. REFACTOR: Apply changes as unified diffs via apply_patch tool.
|
|
40
|
+
5. TEST: Run tests to confirm no regressions.
|
|
41
|
+
6. SUMMARIZE: Describe what was improved and any follow-up work.
|
|
42
|
+
Always use apply_patch for file modifications. Never write files directly.`,
|
|
43
|
+
'security-audit': `You are performing a security audit. Follow this strict sequence:
|
|
44
|
+
1. SCAN: Review code for security vulnerabilities (injection, XSS, auth, secrets).
|
|
45
|
+
2. REPORT: List all findings with severity (Critical/High/Medium/Low) and file locations.
|
|
46
|
+
3. PLAN: Prioritize fixes starting with Critical issues.
|
|
47
|
+
4. Wait for confirmation before proceeding.
|
|
48
|
+
5. FIX: Apply patches for Critical/High issues via apply_patch tool.
|
|
49
|
+
6. VERIFY: Re-scan patched files to confirm issues are resolved.
|
|
50
|
+
7. SUMMARIZE: Full audit report with findings, fixes applied, and remaining risks.
|
|
51
|
+
Always use apply_patch for file modifications. Never write files directly.`,
|
|
52
|
+
};
|
|
53
|
+
// ──────────────────────────────────────────────────────────────────
|
|
54
|
+
// Plan-first confirmation
|
|
55
|
+
// ──────────────────────────────────────────────────────────────────
|
|
56
|
+
async function waitForConfirmation(prompt, nonInteractive) {
|
|
57
|
+
if (nonInteractive)
|
|
58
|
+
return true;
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
const rl = readline.createInterface({
|
|
61
|
+
input: process.stdin,
|
|
62
|
+
output: process.stdout,
|
|
63
|
+
});
|
|
64
|
+
rl.question(`${prompt} [y/N] `, (answer) => {
|
|
65
|
+
rl.close();
|
|
66
|
+
resolve(answer.trim().toLowerCase() === 'y');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// ──────────────────────────────────────────────────────────────────
|
|
71
|
+
// Test runner helper
|
|
72
|
+
// ──────────────────────────────────────────────────────────────────
|
|
73
|
+
async function runTests(profile) {
|
|
74
|
+
const testCmd = profile.commands.test;
|
|
75
|
+
if (!testCmd)
|
|
76
|
+
return 'No test command configured.';
|
|
77
|
+
const { execSync } = await import('child_process');
|
|
78
|
+
try {
|
|
79
|
+
const output = execSync(testCmd, {
|
|
80
|
+
encoding: 'utf-8',
|
|
81
|
+
stdio: 'pipe',
|
|
82
|
+
timeout: 120_000,
|
|
83
|
+
});
|
|
84
|
+
return `Tests passed.\n${output.slice(0, 2000)}`;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const e = err;
|
|
88
|
+
const out = (e.stdout || '') + (e.stderr || '');
|
|
89
|
+
return `Tests failed.\n${out.slice(0, 2000)}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// ──────────────────────────────────────────────────────────────────
|
|
93
|
+
// Main workflow runner
|
|
94
|
+
// ──────────────────────────────────────────────────────────────────
|
|
95
|
+
/**
|
|
96
|
+
* Run a golden-path workflow with plan-first, diff-first, and full observability.
|
|
97
|
+
*/
|
|
98
|
+
export async function runWorkflow(type, objective, agent, options = {}) {
|
|
99
|
+
const { nonInteractive = false, writePolicyMode = 'strict', tags = [] } = options;
|
|
100
|
+
// ── Setup ─────────────────────────────────────────────────────
|
|
101
|
+
const runStore = RunStore.getInstance();
|
|
102
|
+
const profiler = getRepoProfiler();
|
|
103
|
+
const profile = await profiler.getProfile();
|
|
104
|
+
// Start a run for observability
|
|
105
|
+
const runId = runStore.startRun(objective, {
|
|
106
|
+
tags: [type, ...tags],
|
|
107
|
+
});
|
|
108
|
+
// Enable WritePolicy (strict by default in workflows)
|
|
109
|
+
const writePolicy = WritePolicy.getInstance();
|
|
110
|
+
const previousMode = writePolicy.getMode();
|
|
111
|
+
writePolicy.setMode(writePolicyMode);
|
|
112
|
+
// Link agent tool calls to this run
|
|
113
|
+
agent.setRunId(runId);
|
|
114
|
+
const artifactPaths = [];
|
|
115
|
+
try {
|
|
116
|
+
// ── Step 1: Plan ────────────────────────────────────────────
|
|
117
|
+
runStore.emit(runId, { type: 'step_start', data: { step: 'plan', objective } });
|
|
118
|
+
const workflowPrompt = WORKFLOW_PROMPTS[type];
|
|
119
|
+
const planPrompt = `${workflowPrompt}
|
|
120
|
+
|
|
121
|
+
Repo context: ${profile.contextPack}
|
|
122
|
+
|
|
123
|
+
Objective: ${objective}
|
|
124
|
+
|
|
125
|
+
Start with PLAN only. List exactly what you will do.`;
|
|
126
|
+
console.log(`\n[${type}] Planning: ${objective}`);
|
|
127
|
+
console.log('─'.repeat(60));
|
|
128
|
+
let planOutput = '';
|
|
129
|
+
for await (const chunk of agent.processUserMessageStream(planPrompt)) {
|
|
130
|
+
if (chunk.type === 'content' && chunk.content) {
|
|
131
|
+
process.stdout.write(chunk.content);
|
|
132
|
+
planOutput += chunk.content;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
runStore.emit(runId, { type: 'step_end', data: { step: 'plan', outputLength: planOutput.length } });
|
|
136
|
+
// Save plan artifact
|
|
137
|
+
const planPath = runStore.saveArtifact(runId, 'plan.md', `# Plan\n\nObjective: ${objective}\n\n${planOutput}`);
|
|
138
|
+
artifactPaths.push(planPath);
|
|
139
|
+
// ── Step 2: Confirmation ─────────────────────────────────────
|
|
140
|
+
console.log('\n' + '─'.repeat(60));
|
|
141
|
+
const confirmed = await waitForConfirmation('\nProceed with implementation?', nonInteractive);
|
|
142
|
+
if (!confirmed) {
|
|
143
|
+
runStore.emit(runId, { type: 'decision', data: { description: 'User cancelled at plan review' } });
|
|
144
|
+
runStore.endRun(runId, 'cancelled');
|
|
145
|
+
writePolicy.setMode(previousMode);
|
|
146
|
+
agent.setRunId(undefined);
|
|
147
|
+
return { runId, status: 'cancelled', artifactPaths };
|
|
148
|
+
}
|
|
149
|
+
runStore.emit(runId, { type: 'decision', data: { description: 'Plan confirmed, proceeding with implementation' } });
|
|
150
|
+
// ── Step 3: Implement ────────────────────────────────────────
|
|
151
|
+
runStore.emit(runId, { type: 'step_start', data: { step: 'implement' } });
|
|
152
|
+
console.log('\n[Implementing…]');
|
|
153
|
+
const implementPrompt = `Now proceed with the implementation. Apply all changes using apply_patch with unified diffs.`;
|
|
154
|
+
let patchOutput = '';
|
|
155
|
+
for await (const chunk of agent.processUserMessageStream(implementPrompt)) {
|
|
156
|
+
if (chunk.type === 'content' && chunk.content) {
|
|
157
|
+
process.stdout.write(chunk.content);
|
|
158
|
+
patchOutput += chunk.content;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
runStore.emit(runId, { type: 'step_end', data: { step: 'implement' } });
|
|
162
|
+
// Extract and save patch artifact if any diff markers found
|
|
163
|
+
if (patchOutput.includes('---') && patchOutput.includes('+++')) {
|
|
164
|
+
const diffMatch = patchOutput.match(/^(---.*?\+\+\+.*?^@@.*?)(?=\n---|\Z)/ms);
|
|
165
|
+
const diffContent = diffMatch ? diffMatch[0] : patchOutput;
|
|
166
|
+
const patchPath = runStore.saveArtifact(runId, 'patch.diff', diffContent);
|
|
167
|
+
artifactPaths.push(patchPath);
|
|
168
|
+
}
|
|
169
|
+
// ── Step 4: Test ─────────────────────────────────────────────
|
|
170
|
+
runStore.emit(runId, { type: 'step_start', data: { step: 'test' } });
|
|
171
|
+
console.log('\n[Running tests…]');
|
|
172
|
+
const testResults = await runTests(profile);
|
|
173
|
+
console.log(testResults.slice(0, 500));
|
|
174
|
+
const testLogPath = runStore.saveArtifact(runId, 'test-results.log', testResults);
|
|
175
|
+
artifactPaths.push(testLogPath);
|
|
176
|
+
runStore.emit(runId, { type: 'step_end', data: { step: 'test', passed: testResults.startsWith('Tests passed') } });
|
|
177
|
+
// ── Step 5: Summary ──────────────────────────────────────────
|
|
178
|
+
runStore.emit(runId, { type: 'step_start', data: { step: 'summary' } });
|
|
179
|
+
const summaryPrompt = `Generate a brief summary of what was accomplished:
|
|
180
|
+
- What changed (files modified/created)
|
|
181
|
+
- Test results
|
|
182
|
+
- Any next steps or known issues
|
|
183
|
+
Keep it under 300 words.`;
|
|
184
|
+
let summaryOutput = '';
|
|
185
|
+
for await (const chunk of agent.processUserMessageStream(summaryPrompt)) {
|
|
186
|
+
if (chunk.type === 'content' && chunk.content) {
|
|
187
|
+
process.stdout.write(chunk.content);
|
|
188
|
+
summaryOutput += chunk.content;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const summaryContent = `# Summary\n\nObjective: ${objective}\nWorkflow: ${type}\nRun: ${runId}\n\n## Test Results\n\n${testResults.slice(0, 500)}\n\n## Changes\n\n${summaryOutput}`;
|
|
192
|
+
const summaryPath = runStore.saveArtifact(runId, 'summary.md', summaryContent);
|
|
193
|
+
artifactPaths.push(summaryPath);
|
|
194
|
+
runStore.emit(runId, { type: 'step_end', data: { step: 'summary' } });
|
|
195
|
+
runStore.endRun(runId, 'completed');
|
|
196
|
+
writePolicy.setMode(previousMode);
|
|
197
|
+
agent.setRunId(undefined);
|
|
198
|
+
return {
|
|
199
|
+
runId,
|
|
200
|
+
status: 'completed',
|
|
201
|
+
artifactPaths,
|
|
202
|
+
summary: summaryOutput,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
207
|
+
runStore.emit(runId, { type: 'error', data: { message } });
|
|
208
|
+
runStore.endRun(runId, 'failed');
|
|
209
|
+
writePolicy.setMode(previousMode);
|
|
210
|
+
agent.setRunId(undefined);
|
|
211
|
+
return { runId, status: 'failed', artifactPaths };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=workflows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../src/commands/dev/workflows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy execpolicy — CLI for the ExecPolicy command authorization system.
|
|
3
|
+
*
|
|
4
|
+
* Codex-inspired command execution policy management with token-array prefix
|
|
5
|
+
* rules and glob/regex pattern rules.
|
|
6
|
+
*
|
|
7
|
+
* Subcommands:
|
|
8
|
+
* check <command> Evaluate a command against all active rules
|
|
9
|
+
* check-argv <cmd> [args…] Evaluate a parsed argv token array (prefix rules first)
|
|
10
|
+
* list List all active rules
|
|
11
|
+
* list-prefix List prefix rules
|
|
12
|
+
* add-prefix <tokens…> Add a prefix rule
|
|
13
|
+
* show-dangerous <command> Check if a command matches dangerous patterns
|
|
14
|
+
* dashboard Show full policy dashboard
|
|
15
|
+
*/
|
|
16
|
+
import { Command } from 'commander';
|
|
17
|
+
export declare function createExecPolicyCommand(): Command;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy execpolicy — CLI for the ExecPolicy command authorization system.
|
|
3
|
+
*
|
|
4
|
+
* Codex-inspired command execution policy management with token-array prefix
|
|
5
|
+
* rules and glob/regex pattern rules.
|
|
6
|
+
*
|
|
7
|
+
* Subcommands:
|
|
8
|
+
* check <command> Evaluate a command against all active rules
|
|
9
|
+
* check-argv <cmd> [args…] Evaluate a parsed argv token array (prefix rules first)
|
|
10
|
+
* list List all active rules
|
|
11
|
+
* list-prefix List prefix rules
|
|
12
|
+
* add-prefix <tokens…> Add a prefix rule
|
|
13
|
+
* show-dangerous <command> Check if a command matches dangerous patterns
|
|
14
|
+
* dashboard Show full policy dashboard
|
|
15
|
+
*/
|
|
16
|
+
import { Command } from 'commander';
|
|
17
|
+
import { initializeExecPolicy } from '../sandbox/execpolicy.js';
|
|
18
|
+
export function createExecPolicyCommand() {
|
|
19
|
+
const cmd = new Command('execpolicy').description('Manage execution policy rules — allow/deny/ask/sandbox for shell commands (Codex-inspired)');
|
|
20
|
+
// ── check ──────────────────────────────────────────────────────────────────
|
|
21
|
+
cmd
|
|
22
|
+
.command('check <command>')
|
|
23
|
+
.description('Evaluate a shell command string against all active rules')
|
|
24
|
+
.option('-d, --cwd <dir>', 'Working directory context', process.cwd())
|
|
25
|
+
.action(async (command, opts) => {
|
|
26
|
+
const policy = await initializeExecPolicy();
|
|
27
|
+
const result = policy.evaluate(command, [], opts.cwd);
|
|
28
|
+
const icon = result.action === 'allow' ? '✓' :
|
|
29
|
+
result.action === 'deny' ? '✗' :
|
|
30
|
+
result.action === 'sandbox' ? '📦' : '?';
|
|
31
|
+
console.log(`${icon} Action: ${result.action.toUpperCase()}`);
|
|
32
|
+
console.log(` Reason: ${result.reason}`);
|
|
33
|
+
if (result.matchedRule) {
|
|
34
|
+
console.log(` Rule: [${result.matchedRule.id}] ${result.matchedRule.name}`);
|
|
35
|
+
}
|
|
36
|
+
if (result.constraints && Object.keys(result.constraints).length > 0) {
|
|
37
|
+
console.log(` Constraints:`, JSON.stringify(result.constraints, null, 2));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// ── check-argv ─────────────────────────────────────────────────────────────
|
|
41
|
+
cmd
|
|
42
|
+
.command('check-argv <cmd> [args...]')
|
|
43
|
+
.description('Evaluate a parsed argv token array (prefix rules take priority over regex/glob)')
|
|
44
|
+
.option('-d, --cwd <dir>', 'Working directory context', process.cwd())
|
|
45
|
+
.action(async (cmd2, args, opts) => {
|
|
46
|
+
const policy = await initializeExecPolicy();
|
|
47
|
+
const argv = [cmd2, ...args];
|
|
48
|
+
const result = policy.evaluateArgv(argv, opts.cwd);
|
|
49
|
+
const icon = result.action === 'allow' ? '✓' :
|
|
50
|
+
result.action === 'deny' ? '✗' :
|
|
51
|
+
result.action === 'sandbox' ? '📦' : '?';
|
|
52
|
+
console.log(`Argv: ${argv.join(' ')}`);
|
|
53
|
+
console.log(`${icon} Action: ${result.action.toUpperCase()}`);
|
|
54
|
+
console.log(` Reason: ${result.reason}`);
|
|
55
|
+
});
|
|
56
|
+
// ── list ───────────────────────────────────────────────────────────────────
|
|
57
|
+
cmd
|
|
58
|
+
.command('list')
|
|
59
|
+
.description('List all active policy rules')
|
|
60
|
+
.option('--no-builtin', 'Hide built-in rules')
|
|
61
|
+
.action(async (opts) => {
|
|
62
|
+
const policy = await initializeExecPolicy();
|
|
63
|
+
const rules = policy.getRules(opts.builtin !== false);
|
|
64
|
+
if (rules.length === 0) {
|
|
65
|
+
console.log('No rules found.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log(`\n${'ID'.padEnd(36)} ${'ACTION'.padEnd(8)} ${'PRI'.padEnd(4)} NAME`);
|
|
69
|
+
console.log('─'.repeat(80));
|
|
70
|
+
for (const r of rules) {
|
|
71
|
+
const status = r.enabled ? '' : ' [disabled]';
|
|
72
|
+
console.log(`${r.id.padEnd(36)} ${r.action.padEnd(8)} ${String(r.priority).padEnd(4)} ${r.name}${status}`);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// ── list-prefix ────────────────────────────────────────────────────────────
|
|
76
|
+
cmd
|
|
77
|
+
.command('list-prefix')
|
|
78
|
+
.description('List token-array prefix rules')
|
|
79
|
+
.action(async () => {
|
|
80
|
+
const policy = await initializeExecPolicy();
|
|
81
|
+
const rules = policy.getPrefixRules();
|
|
82
|
+
if (rules.length === 0) {
|
|
83
|
+
console.log('No prefix rules defined.');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.log(`\n${'PREFIX TOKENS'.padEnd(40)} ${'ACTION'.padEnd(8)} ID`);
|
|
87
|
+
console.log('─'.repeat(80));
|
|
88
|
+
for (const r of rules) {
|
|
89
|
+
const tokens = r.prefix.join(' ').padEnd(40);
|
|
90
|
+
const desc = r.description ? ` # ${r.description}` : '';
|
|
91
|
+
console.log(`${tokens} ${r.action.padEnd(8)} ${r.id}${desc}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// ── add-prefix ─────────────────────────────────────────────────────────────
|
|
95
|
+
cmd
|
|
96
|
+
.command('add-prefix <tokens...>')
|
|
97
|
+
.description('Add a token-array prefix rule (e.g. "add-prefix git push --action deny")')
|
|
98
|
+
.option('-a, --action <action>', 'Action: allow|deny|ask|sandbox', 'ask')
|
|
99
|
+
.option('--desc <description>', 'Human-readable description')
|
|
100
|
+
.option('--disable', 'Create rule in disabled state')
|
|
101
|
+
.action(async (tokens, opts) => {
|
|
102
|
+
const validActions = ['allow', 'deny', 'ask', 'sandbox'];
|
|
103
|
+
if (!validActions.includes(opts.action)) {
|
|
104
|
+
console.error(`Invalid action "${opts.action}". Must be one of: ${validActions.join(', ')}`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
const policy = await initializeExecPolicy();
|
|
108
|
+
const rule = {
|
|
109
|
+
prefix: tokens,
|
|
110
|
+
action: opts.action,
|
|
111
|
+
description: opts.desc,
|
|
112
|
+
enabled: !opts.disable,
|
|
113
|
+
};
|
|
114
|
+
const created = policy.addPrefixRule(rule);
|
|
115
|
+
console.log(`✓ Added prefix rule [${created.id}]: ${tokens.join(' ')} → ${opts.action}`);
|
|
116
|
+
await policy.saveRules();
|
|
117
|
+
});
|
|
118
|
+
// ── show-dangerous ─────────────────────────────────────────────────────────
|
|
119
|
+
cmd
|
|
120
|
+
.command('show-dangerous <command>')
|
|
121
|
+
.description('Check if a command matches known dangerous patterns')
|
|
122
|
+
.action(async (command) => {
|
|
123
|
+
// Access dangerous pattern detection via evaluate
|
|
124
|
+
const policy = await initializeExecPolicy();
|
|
125
|
+
const result = policy.evaluate(command);
|
|
126
|
+
if (result.action === 'deny' && result.matchedRule === null) {
|
|
127
|
+
// Dangerous pattern match (no rule matched, directly denied)
|
|
128
|
+
console.log(`⚠️ DANGEROUS: ${result.reason}`);
|
|
129
|
+
}
|
|
130
|
+
else if (result.action === 'deny') {
|
|
131
|
+
console.log(`✗ DENIED by rule: ${result.matchedRule?.name ?? result.reason}`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log(`✓ No dangerous pattern detected. Action: ${result.action}`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
// ── dashboard ──────────────────────────────────────────────────────────────
|
|
138
|
+
cmd
|
|
139
|
+
.command('dashboard')
|
|
140
|
+
.description('Show full execution policy dashboard')
|
|
141
|
+
.action(async () => {
|
|
142
|
+
const policy = await initializeExecPolicy();
|
|
143
|
+
console.log(policy.formatDashboard());
|
|
144
|
+
const prefixRules = policy.getPrefixRules();
|
|
145
|
+
if (prefixRules.length > 0) {
|
|
146
|
+
console.log(`\n🔑 Prefix Rules (${prefixRules.length})`);
|
|
147
|
+
for (const r of prefixRules) {
|
|
148
|
+
const status = r.enabled ? '' : ' [disabled]';
|
|
149
|
+
console.log(` ${r.prefix.join(' ')} → ${r.action}${status}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return cmd;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=execpolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execpolicy.js","sourceRoot":"","sources":["../../src/commands/execpolicy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy knowledge – Knowledge base CLI commands
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy knowledge list – list all loaded knowledge entries
|
|
6
|
+
* buddy knowledge show <title> – display a knowledge entry
|
|
7
|
+
* buddy knowledge add – interactive: add a new entry
|
|
8
|
+
* buddy knowledge remove <title> – remove a knowledge entry
|
|
9
|
+
* buddy knowledge search <query> – search knowledge base
|
|
10
|
+
* buddy knowledge context – show the full context block the agent would see
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
export declare function createKnowledgeCommand(): Command;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy knowledge – Knowledge base CLI commands
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy knowledge list – list all loaded knowledge entries
|
|
6
|
+
* buddy knowledge show <title> – display a knowledge entry
|
|
7
|
+
* buddy knowledge add – interactive: add a new entry
|
|
8
|
+
* buddy knowledge remove <title> – remove a knowledge entry
|
|
9
|
+
* buddy knowledge search <query> – search knowledge base
|
|
10
|
+
* buddy knowledge context – show the full context block the agent would see
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
import { getKnowledgeManager } from '../knowledge/knowledge-manager.js';
|
|
14
|
+
export function createKnowledgeCommand() {
|
|
15
|
+
const cmd = new Command('knowledge')
|
|
16
|
+
.description('Manage agent knowledge bases (Knowledge.md files injected as agent context)');
|
|
17
|
+
cmd
|
|
18
|
+
.command('list')
|
|
19
|
+
.description('List all loaded knowledge entries')
|
|
20
|
+
.action(async () => {
|
|
21
|
+
const km = getKnowledgeManager();
|
|
22
|
+
await km.load();
|
|
23
|
+
const entries = km.list();
|
|
24
|
+
if (entries.length === 0) {
|
|
25
|
+
console.log('No knowledge entries found.');
|
|
26
|
+
console.log('');
|
|
27
|
+
console.log('Add knowledge files to:');
|
|
28
|
+
console.log(' ~/.codebuddy/knowledge/*.md (global)');
|
|
29
|
+
console.log(' .codebuddy/knowledge/*.md (project)');
|
|
30
|
+
console.log(' Knowledge.md (local quick-add)');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log(`\nKnowledge entries (${entries.length}):`);
|
|
34
|
+
console.log('─'.repeat(60));
|
|
35
|
+
for (const e of entries) {
|
|
36
|
+
const tags = e.tags.length > 0 ? ` [${e.tags.join(', ')}]` : '';
|
|
37
|
+
const scope = e.scope.length > 0 ? ` scope: ${e.scope.join(', ')}` : '';
|
|
38
|
+
console.log(` ${e.title}${tags}${scope} (${e.source})`);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
cmd
|
|
42
|
+
.command('show <title>')
|
|
43
|
+
.description('Display a knowledge entry by title')
|
|
44
|
+
.action(async (title) => {
|
|
45
|
+
const km = getKnowledgeManager();
|
|
46
|
+
await km.load();
|
|
47
|
+
const entry = km.list().find(e => e.title.toLowerCase() === title.toLowerCase());
|
|
48
|
+
if (!entry) {
|
|
49
|
+
console.error(`❌ No knowledge entry found: "${title}"`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
console.log(`\n# ${entry.title}`);
|
|
53
|
+
console.log(`Source: ${entry.source} | Path: ${entry.path}`);
|
|
54
|
+
if (entry.tags.length > 0)
|
|
55
|
+
console.log(`Tags: ${entry.tags.join(', ')}`);
|
|
56
|
+
if (entry.scope.length > 0)
|
|
57
|
+
console.log(`Scope: ${entry.scope.join(', ')}`);
|
|
58
|
+
console.log('\n' + entry.content);
|
|
59
|
+
});
|
|
60
|
+
cmd
|
|
61
|
+
.command('search <query>')
|
|
62
|
+
.description('Search knowledge base with keyword query')
|
|
63
|
+
.option('-n, --limit <n>', 'Max results', '5')
|
|
64
|
+
.action(async (query, opts) => {
|
|
65
|
+
const km = getKnowledgeManager();
|
|
66
|
+
await km.load();
|
|
67
|
+
const results = km.search(query, parseInt(opts.limit, 10));
|
|
68
|
+
if (results.length === 0) {
|
|
69
|
+
console.log(`No matches for "${query}".`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
console.log(`\nSearch results for "${query}" (${results.length}):`);
|
|
73
|
+
console.log('─'.repeat(60));
|
|
74
|
+
for (const { entry, score, excerpt } of results) {
|
|
75
|
+
console.log(`\n[${score.toFixed(2)}] ${entry.title} (${entry.source})`);
|
|
76
|
+
console.log(excerpt.slice(0, 300));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
cmd
|
|
80
|
+
.command('add')
|
|
81
|
+
.description('Add a new knowledge entry (interactive)')
|
|
82
|
+
.option('-t, --title <title>', 'Entry title')
|
|
83
|
+
.option('-f, --file <file>', 'Read content from a file')
|
|
84
|
+
.option('--tags <tags>', 'Comma-separated tags')
|
|
85
|
+
.option('--scope <scope>', 'Comma-separated scope modes')
|
|
86
|
+
.action(async (opts) => {
|
|
87
|
+
const { createInterface } = await import('readline');
|
|
88
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
89
|
+
const ask = (q) => new Promise(resolve => rl.question(q, resolve));
|
|
90
|
+
const title = opts.title || await ask('Title: ');
|
|
91
|
+
const tags = opts.tags ? opts.tags.split(',').map((t) => t.trim()) : [];
|
|
92
|
+
const scope = opts.scope ? opts.scope.split(',').map((s) => s.trim()) : [];
|
|
93
|
+
let content;
|
|
94
|
+
if (opts.file) {
|
|
95
|
+
const { readFileSync } = await import('fs');
|
|
96
|
+
content = readFileSync(opts.file, 'utf-8');
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.log('Content (end with a line containing only "---"):');
|
|
100
|
+
const lines = [];
|
|
101
|
+
for await (const line of rl) {
|
|
102
|
+
if (line === '---')
|
|
103
|
+
break;
|
|
104
|
+
lines.push(line);
|
|
105
|
+
}
|
|
106
|
+
content = lines.join('\n');
|
|
107
|
+
}
|
|
108
|
+
rl.close();
|
|
109
|
+
const km = getKnowledgeManager();
|
|
110
|
+
const filePath = await km.add(title, content, tags, scope);
|
|
111
|
+
console.log(`✅ Knowledge entry saved: ${filePath}`);
|
|
112
|
+
});
|
|
113
|
+
cmd
|
|
114
|
+
.command('remove <title>')
|
|
115
|
+
.description('Remove a knowledge entry by title')
|
|
116
|
+
.action(async (title) => {
|
|
117
|
+
const km = getKnowledgeManager();
|
|
118
|
+
await km.load();
|
|
119
|
+
const ok = await km.remove(title);
|
|
120
|
+
if (!ok) {
|
|
121
|
+
console.error(`❌ Could not remove "${title}" – not found or not removable.`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
console.log(`✅ Removed knowledge entry: "${title}"`);
|
|
125
|
+
});
|
|
126
|
+
cmd
|
|
127
|
+
.command('context')
|
|
128
|
+
.description('Show the full knowledge context block the agent would receive')
|
|
129
|
+
.option('-s, --scope <scope>', 'Filter by agent mode scope')
|
|
130
|
+
.action(async (opts) => {
|
|
131
|
+
const km = getKnowledgeManager();
|
|
132
|
+
await km.load();
|
|
133
|
+
const block = km.buildContextBlock({ scope: opts.scope });
|
|
134
|
+
if (!block) {
|
|
135
|
+
console.log('(no knowledge entries loaded)');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
console.log(block);
|
|
139
|
+
});
|
|
140
|
+
return cmd;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/commands/knowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `buddy lessons` CLI command
|
|
3
|
+
*
|
|
4
|
+
* Manages the persistent lessons.md self-improvement loop.
|
|
5
|
+
* Lessons are automatically injected before every LLM turn (before the
|
|
6
|
+
* todo suffix) so the agent internalises learned patterns across sessions.
|
|
7
|
+
*
|
|
8
|
+
* Subcommands: list, add, search, clear
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
export declare function createLessonsCommand(): Command;
|