@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,129 @@
|
|
|
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
|
+
import { getLessonsTracker } from '../agent/lessons-tracker.js';
|
|
12
|
+
const VALID_CATEGORIES = ['PATTERN', 'RULE', 'CONTEXT', 'INSIGHT'];
|
|
13
|
+
export function createLessonsCommand() {
|
|
14
|
+
const cmd = new Command('lessons');
|
|
15
|
+
cmd.description('Manage lessons learned (self-improvement loop) — injected into every agent turn');
|
|
16
|
+
// ---- list ----------------------------------------------------------------
|
|
17
|
+
cmd
|
|
18
|
+
.command('list')
|
|
19
|
+
.alias('ls')
|
|
20
|
+
.description('List all lessons, optionally filtered by category')
|
|
21
|
+
.option('-c, --category <cat>', `Filter by category: ${VALID_CATEGORIES.join('|')}`)
|
|
22
|
+
.action((opts) => {
|
|
23
|
+
const cat = opts.category?.toUpperCase();
|
|
24
|
+
if (cat && !VALID_CATEGORIES.includes(cat)) {
|
|
25
|
+
console.error(`Invalid category: ${cat}. Must be one of: ${VALID_CATEGORIES.join(', ')}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const tracker = getLessonsTracker(process.cwd());
|
|
29
|
+
const items = tracker.list(cat);
|
|
30
|
+
if (items.length === 0) {
|
|
31
|
+
console.log('No lessons recorded yet.');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Group by category for readability
|
|
35
|
+
const grouped = new Map();
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
const arr = grouped.get(item.category) ?? [];
|
|
38
|
+
arr.push(item);
|
|
39
|
+
grouped.set(item.category, arr);
|
|
40
|
+
}
|
|
41
|
+
for (const category of VALID_CATEGORIES) {
|
|
42
|
+
const catItems = grouped.get(category);
|
|
43
|
+
if (!catItems || catItems.length === 0)
|
|
44
|
+
continue;
|
|
45
|
+
console.log(`\n## ${category}`);
|
|
46
|
+
for (const item of catItems) {
|
|
47
|
+
const ctx = item.context ? ` (${item.context})` : '';
|
|
48
|
+
const date = new Date(item.createdAt).toISOString().slice(0, 10);
|
|
49
|
+
console.log(` [${item.id}]${ctx} ${item.content} — ${date} ${item.source}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// ---- add -----------------------------------------------------------------
|
|
54
|
+
cmd
|
|
55
|
+
.command('add <content>')
|
|
56
|
+
.description('Add a new lesson')
|
|
57
|
+
.option('-c, --category <cat>', `Category: ${VALID_CATEGORIES.join('|')}`, 'INSIGHT')
|
|
58
|
+
.option('--context <ctx>', 'Optional domain context (e.g. TypeScript, React)')
|
|
59
|
+
.action((content, opts) => {
|
|
60
|
+
const cat = opts.category.toUpperCase();
|
|
61
|
+
if (!VALID_CATEGORIES.includes(cat)) {
|
|
62
|
+
console.error(`Invalid category: ${cat}. Must be one of: ${VALID_CATEGORIES.join(', ')}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const tracker = getLessonsTracker(process.cwd());
|
|
66
|
+
const item = tracker.add(cat, content, 'manual', opts.context);
|
|
67
|
+
console.log(`Added [${item.id}] (${item.category}): ${item.content}`);
|
|
68
|
+
});
|
|
69
|
+
// ---- search --------------------------------------------------------------
|
|
70
|
+
cmd
|
|
71
|
+
.command('search <query>')
|
|
72
|
+
.description('Search lessons by keyword')
|
|
73
|
+
.option('-c, --category <cat>', `Filter by category: ${VALID_CATEGORIES.join('|')}`)
|
|
74
|
+
.option('-n, --limit <n>', 'Max results', '10')
|
|
75
|
+
.action((query, opts) => {
|
|
76
|
+
const cat = opts.category?.toUpperCase();
|
|
77
|
+
if (cat && !VALID_CATEGORIES.includes(cat)) {
|
|
78
|
+
console.error(`Invalid category: ${cat}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const limit = parseInt(opts.limit, 10) || 10;
|
|
82
|
+
const tracker = getLessonsTracker(process.cwd());
|
|
83
|
+
const results = tracker.search(query, cat).slice(0, limit);
|
|
84
|
+
if (results.length === 0) {
|
|
85
|
+
console.log(`No lessons found matching "${query}".`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log(`Found ${results.length} lesson(s) matching "${query}":\n`);
|
|
89
|
+
for (const item of results) {
|
|
90
|
+
const ctx = item.context ? ` (${item.context})` : '';
|
|
91
|
+
console.log(` [${item.id}] ${item.category}${ctx}: ${item.content}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// ---- clear ---------------------------------------------------------------
|
|
95
|
+
cmd
|
|
96
|
+
.command('clear')
|
|
97
|
+
.description('Remove lessons (all or by category)')
|
|
98
|
+
.option('-c, --category <cat>', `Remove only this category: ${VALID_CATEGORIES.join('|')}`)
|
|
99
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
100
|
+
.action((opts) => {
|
|
101
|
+
const cat = opts.category?.toUpperCase();
|
|
102
|
+
if (cat && !VALID_CATEGORIES.includes(cat)) {
|
|
103
|
+
console.error(`Invalid category: ${cat}`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
if (!opts.yes) {
|
|
107
|
+
const target = cat ? `category ${cat}` : 'ALL lessons';
|
|
108
|
+
console.log(`This will remove ${target}. Pass --yes to confirm.`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const tracker = getLessonsTracker(process.cwd());
|
|
112
|
+
const n = tracker.clearByCategory(cat);
|
|
113
|
+
console.log(`Cleared ${n} lesson(s)${cat ? ` in category ${cat}` : ''}.`);
|
|
114
|
+
});
|
|
115
|
+
// ---- context (preview) ---------------------------------------------------
|
|
116
|
+
cmd
|
|
117
|
+
.command('context')
|
|
118
|
+
.description('Preview the lessons context block injected into each agent turn')
|
|
119
|
+
.action(() => {
|
|
120
|
+
const tracker = getLessonsTracker(process.cwd());
|
|
121
|
+
const block = tracker.buildContextBlock();
|
|
122
|
+
if (!block)
|
|
123
|
+
console.log('No lessons — nothing to inject.');
|
|
124
|
+
else
|
|
125
|
+
console.log(block);
|
|
126
|
+
});
|
|
127
|
+
return cmd;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=lessons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lessons.js","sourceRoot":"","sources":["../../src/commands/lessons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy pairing – DM Pairing CLI commands
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy pairing status – show pairing mode status
|
|
6
|
+
* buddy pairing list – list approved senders
|
|
7
|
+
* buddy pairing pending – list pending pairing requests
|
|
8
|
+
* buddy pairing approve <code> – approve a pending request by code
|
|
9
|
+
* buddy pairing revoke <id> – revoke an approved sender
|
|
10
|
+
* buddy pairing enable – enable pairing mode
|
|
11
|
+
* buddy pairing disable – disable pairing mode
|
|
12
|
+
*/
|
|
13
|
+
import { Command } from 'commander';
|
|
14
|
+
export declare function createPairingCommand(): Command;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy pairing – DM Pairing CLI commands
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy pairing status – show pairing mode status
|
|
6
|
+
* buddy pairing list – list approved senders
|
|
7
|
+
* buddy pairing pending – list pending pairing requests
|
|
8
|
+
* buddy pairing approve <code> – approve a pending request by code
|
|
9
|
+
* buddy pairing revoke <id> – revoke an approved sender
|
|
10
|
+
* buddy pairing enable – enable pairing mode
|
|
11
|
+
* buddy pairing disable – disable pairing mode
|
|
12
|
+
*/
|
|
13
|
+
import { Command } from 'commander';
|
|
14
|
+
import { getDMPairing } from '../channels/dm-pairing.js';
|
|
15
|
+
export function createPairingCommand() {
|
|
16
|
+
const cmd = new Command('pairing')
|
|
17
|
+
.description('Manage DM pairing security (allowlist unknown senders on messaging channels)');
|
|
18
|
+
cmd
|
|
19
|
+
.command('status')
|
|
20
|
+
.description('Show pairing mode configuration and statistics')
|
|
21
|
+
.action(() => {
|
|
22
|
+
const pairing = getDMPairing();
|
|
23
|
+
const stats = pairing.getStats();
|
|
24
|
+
console.log('\nDM Pairing Status');
|
|
25
|
+
console.log('─'.repeat(40));
|
|
26
|
+
console.log(`Enabled: ${stats.enabled ? '✅ yes' : '❌ no'}`);
|
|
27
|
+
console.log(`Approved senders: ${stats.totalApproved}`);
|
|
28
|
+
console.log(`Pending requests: ${stats.totalPending}`);
|
|
29
|
+
console.log(`Blocked senders: ${stats.totalBlocked}`);
|
|
30
|
+
if (Object.keys(stats.approvedByChannel).length > 0) {
|
|
31
|
+
console.log('\nApproved by channel:');
|
|
32
|
+
for (const [ch, count] of Object.entries(stats.approvedByChannel)) {
|
|
33
|
+
console.log(` ${ch}: ${count}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
cmd
|
|
38
|
+
.command('list')
|
|
39
|
+
.description('List approved senders')
|
|
40
|
+
.option('-c, --channel <channel>', 'Filter by channel type')
|
|
41
|
+
.action(async (opts) => {
|
|
42
|
+
const pairing = getDMPairing();
|
|
43
|
+
await pairing.loadAllowlist();
|
|
44
|
+
const senders = opts.channel
|
|
45
|
+
? pairing.listApprovedForChannel(opts.channel)
|
|
46
|
+
: pairing.listApproved();
|
|
47
|
+
if (senders.length === 0) {
|
|
48
|
+
console.log('No approved senders.');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(`\nApproved senders (${senders.length}):`);
|
|
52
|
+
console.log('─'.repeat(60));
|
|
53
|
+
for (const s of senders) {
|
|
54
|
+
const when = new Date(s.approvedAt).toLocaleDateString();
|
|
55
|
+
const name = s.displayName ? ` (${s.displayName})` : '';
|
|
56
|
+
console.log(` [${s.channelType}] ${s.senderId}${name} — approved ${when} by ${s.approvedBy}`);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
cmd
|
|
60
|
+
.command('pending')
|
|
61
|
+
.description('List pending pairing requests')
|
|
62
|
+
.action(() => {
|
|
63
|
+
const pairing = getDMPairing();
|
|
64
|
+
const requests = pairing.listPending();
|
|
65
|
+
if (requests.length === 0) {
|
|
66
|
+
console.log('No pending pairing requests.');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log(`\nPending pairing requests (${requests.length}):`);
|
|
70
|
+
console.log('─'.repeat(60));
|
|
71
|
+
for (const r of requests) {
|
|
72
|
+
const exp = new Date(r.expiresAt).toLocaleTimeString();
|
|
73
|
+
const name = r.displayName ? ` (${r.displayName})` : '';
|
|
74
|
+
console.log(` [${r.channelType}] ${r.senderId}${name}`);
|
|
75
|
+
console.log(` Code: ${r.code} Attempts: ${r.attempts} Expires: ${exp}`);
|
|
76
|
+
if (r.messageExcerpt) {
|
|
77
|
+
console.log(` Message: "${r.messageExcerpt}"`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
cmd
|
|
82
|
+
.command('approve <code>')
|
|
83
|
+
.description('Approve a pending pairing request by code')
|
|
84
|
+
.requiredOption('-c, --channel <channel>', 'Channel type (telegram, discord, slack, etc.)')
|
|
85
|
+
.action((code, opts) => {
|
|
86
|
+
const pairing = getDMPairing();
|
|
87
|
+
const sender = pairing.approve(opts.channel, code.toUpperCase());
|
|
88
|
+
if (!sender) {
|
|
89
|
+
console.error(`❌ No pending request found for code "${code}" on channel "${opts.channel}".`);
|
|
90
|
+
console.error(' The code may have expired. Ask the user to send a new message to generate a fresh code.');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
const name = sender.displayName ? ` (${sender.displayName})` : '';
|
|
94
|
+
console.log(`✅ Approved: [${sender.channelType}] ${sender.senderId}${name}`);
|
|
95
|
+
});
|
|
96
|
+
cmd
|
|
97
|
+
.command('add <senderId>')
|
|
98
|
+
.description('Directly approve a sender without a pairing code')
|
|
99
|
+
.requiredOption('-c, --channel <channel>', 'Channel type')
|
|
100
|
+
.option('-n, --name <name>', 'Display name for this sender')
|
|
101
|
+
.action(async (senderId, opts) => {
|
|
102
|
+
const pairing = getDMPairing();
|
|
103
|
+
const sender = pairing.approveDirectly(opts.channel, senderId, 'owner-cli', opts.name);
|
|
104
|
+
console.log(`✅ Added: [${sender.channelType}] ${sender.senderId}`);
|
|
105
|
+
await pairing.persistAllowlist();
|
|
106
|
+
});
|
|
107
|
+
cmd
|
|
108
|
+
.command('revoke <senderId>')
|
|
109
|
+
.description('Revoke approval for a sender')
|
|
110
|
+
.requiredOption('-c, --channel <channel>', 'Channel type')
|
|
111
|
+
.action(async (senderId, opts) => {
|
|
112
|
+
const pairing = getDMPairing();
|
|
113
|
+
await pairing.loadAllowlist();
|
|
114
|
+
const ok = pairing.revoke(opts.channel, senderId);
|
|
115
|
+
if (!ok) {
|
|
116
|
+
console.error(`❌ Sender "${senderId}" not found in allowlist for channel "${opts.channel}".`);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
console.log(`✅ Revoked: [${opts.channel}] ${senderId}`);
|
|
120
|
+
});
|
|
121
|
+
cmd
|
|
122
|
+
.command('enable')
|
|
123
|
+
.description('Enable DM pairing mode (requires restart of channel adapters)')
|
|
124
|
+
.action(() => {
|
|
125
|
+
console.log('⚠️ Pairing mode must be enabled via config or environment:');
|
|
126
|
+
console.log(' Set DM_PAIRING_ENABLED=true in your .env, then restart.');
|
|
127
|
+
console.log('');
|
|
128
|
+
console.log(' Or in code: getDMPairing({ enabled: true })');
|
|
129
|
+
});
|
|
130
|
+
return cmd;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/commands/pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy research – Wide Research CLI command
|
|
3
|
+
*
|
|
4
|
+
* Spawns N parallel agent workers to research independent subtopics,
|
|
5
|
+
* then synthesizes a comprehensive report.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* buddy research "quantum computing breakthroughs in 2025"
|
|
9
|
+
* buddy research "best practices for TypeScript monorepos" --workers 8
|
|
10
|
+
* buddy research "competitor analysis for Manus AI" --workers 5 --output report.md
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
export declare function createResearchCommand(): Command;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy research – Wide Research CLI command
|
|
3
|
+
*
|
|
4
|
+
* Spawns N parallel agent workers to research independent subtopics,
|
|
5
|
+
* then synthesizes a comprehensive report.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* buddy research "quantum computing breakthroughs in 2025"
|
|
9
|
+
* buddy research "best practices for TypeScript monorepos" --workers 8
|
|
10
|
+
* buddy research "competitor analysis for Manus AI" --workers 5 --output report.md
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
import { WideResearchOrchestrator } from '../../agent/wide-research.js';
|
|
14
|
+
import * as fs from 'fs/promises';
|
|
15
|
+
export function createResearchCommand() {
|
|
16
|
+
const cmd = new Command('research')
|
|
17
|
+
.description('Wide Research: spawn parallel agent workers to research a topic comprehensively')
|
|
18
|
+
.argument('<topic>', 'The topic to research')
|
|
19
|
+
.option('-w, --workers <n>', 'Number of parallel research workers (default: 5, max: 20)', '5')
|
|
20
|
+
.option('-r, --rounds <n>', 'Max tool rounds per worker (default: 15)', '15')
|
|
21
|
+
.option('-o, --output <file>', 'Save the report to a Markdown file')
|
|
22
|
+
.option('--context <text>', 'Additional context injected into each worker')
|
|
23
|
+
.action(async (topic, opts) => {
|
|
24
|
+
const apiKey = process.env.GROK_API_KEY || process.env.ANTHROPIC_API_KEY || '';
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
console.error('❌ No API key found. Set GROK_API_KEY or ANTHROPIC_API_KEY.');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const workers = Math.min(parseInt(opts.workers, 10) || 5, 20);
|
|
30
|
+
const maxRoundsPerWorker = parseInt(opts.rounds, 10) || 15;
|
|
31
|
+
console.log(`\n🔬 Wide Research: "${topic}"`);
|
|
32
|
+
console.log(` Workers: ${workers} | Max rounds per worker: ${maxRoundsPerWorker}`);
|
|
33
|
+
console.log('─'.repeat(60));
|
|
34
|
+
const orchestrator = new WideResearchOrchestrator({
|
|
35
|
+
workers,
|
|
36
|
+
maxRoundsPerWorker,
|
|
37
|
+
context: opts.context,
|
|
38
|
+
});
|
|
39
|
+
// Stream progress events
|
|
40
|
+
orchestrator.on('progress', (event) => {
|
|
41
|
+
switch (event.type) {
|
|
42
|
+
case 'decomposed':
|
|
43
|
+
console.log(`\n📋 Subtopics (${event.subtopics?.length}):`);
|
|
44
|
+
event.subtopics?.forEach((s, i) => console.log(` ${i + 1}. ${s}`));
|
|
45
|
+
console.log('');
|
|
46
|
+
break;
|
|
47
|
+
case 'worker_start':
|
|
48
|
+
console.log(` ▶ [${event.workerIndex + 1}] Starting: ${event.subtopic}`);
|
|
49
|
+
break;
|
|
50
|
+
case 'worker_done':
|
|
51
|
+
const icon = event.success ? '✅' : '❌';
|
|
52
|
+
console.log(` ${icon} [${event.workerIndex + 1}] Done: ${event.subtopic}`);
|
|
53
|
+
break;
|
|
54
|
+
case 'aggregating':
|
|
55
|
+
console.log('\n🔗 Aggregating results into final report...');
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const result = await orchestrator.research(topic, apiKey);
|
|
61
|
+
console.log('\n' + '─'.repeat(60));
|
|
62
|
+
console.log(`✅ Research complete!`);
|
|
63
|
+
console.log(` Workers succeeded: ${result.successCount}/${result.subtopics.length}`);
|
|
64
|
+
console.log(` Duration: ${(result.durationMs / 1000).toFixed(1)}s`);
|
|
65
|
+
if (opts.output) {
|
|
66
|
+
const reportContent = [
|
|
67
|
+
`# Research Report: ${topic}`,
|
|
68
|
+
``,
|
|
69
|
+
`Generated: ${new Date().toISOString()}`,
|
|
70
|
+
`Workers: ${result.successCount}/${result.subtopics.length} succeeded`,
|
|
71
|
+
`Duration: ${(result.durationMs / 1000).toFixed(1)}s`,
|
|
72
|
+
``,
|
|
73
|
+
`---`,
|
|
74
|
+
``,
|
|
75
|
+
result.report,
|
|
76
|
+
].join('\n');
|
|
77
|
+
await fs.writeFile(opts.output, reportContent, 'utf-8');
|
|
78
|
+
console.log(`\n📄 Report saved: ${opts.output}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log('\n' + result.report);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.error(`\n❌ Research failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return cmd;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/research/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAElC,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,iFAAiF,CAAC;SAC9F,QAAQ,CAAC,SAAS,EAAE,uBAAuB,CAAC;SAC5C,MAAM,CAAC,mBAAmB,EAAE,2DAA2D,EAAE,GAAG,CAAC;SAC7F,MAAM,CAAC,kBAAkB,EAAE,0CAA0C,EAAE,IAAI,CAAC;SAC5E,MAAM,CAAC,qBAAqB,EAAE,oCAAoC,CAAC;SACnE,MAAM,CAAC,kBAAkB,EAAE,8CAA8C,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;QAE/E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QAE3D,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,+BAA+B,kBAAkB,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,MAAM,YAAY,GAAG,IAAI,wBAAwB,CAAC;YAChD,OAAO;YACP,kBAAkB;YAClB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QAEH,yBAAyB;QACzB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAyG,EAAE,EAAE;YACxI,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,YAAY;oBACf,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC;oBAC5D,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;oBACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChB,MAAM;gBACR,KAAK,cAAc;oBACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,WAAY,GAAG,CAAC,eAAe,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC3E,MAAM;gBACR,KAAK,aAAa;oBAChB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBACvC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,WAAY,GAAG,CAAC,WAAW,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC7E,MAAM;gBACR,KAAK,aAAa;oBAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;oBAC7D,MAAM;YACV,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAE1D,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAEtE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,aAAa,GAAG;oBACpB,sBAAsB,KAAK,EAAE;oBAC7B,EAAE;oBACF,cAAc,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;oBACxC,YAAY,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,YAAY;oBACtE,aAAa,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;oBACrD,EAAE;oBACF,KAAK;oBACL,EAAE;oBACF,MAAM,CAAC,MAAM;iBACd,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEb,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;gBACxD,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy run — observability commands for RunStore runs
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy run list [--limit N] → list recent runs
|
|
6
|
+
* buddy run show <runId> → full timeline + metrics + artifacts
|
|
7
|
+
* buddy run tail <runId> → live-stream events (follow mode)
|
|
8
|
+
* buddy run replay <runId> → show timeline + re-execute test steps
|
|
9
|
+
*/
|
|
10
|
+
import type { Command } from 'commander';
|
|
11
|
+
export declare function registerRunCommands(program: Command): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy run — observability commands for RunStore runs
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* buddy run list [--limit N] → list recent runs
|
|
6
|
+
* buddy run show <runId> → full timeline + metrics + artifacts
|
|
7
|
+
* buddy run tail <runId> → live-stream events (follow mode)
|
|
8
|
+
* buddy run replay <runId> → show timeline + re-execute test steps
|
|
9
|
+
*/
|
|
10
|
+
export function registerRunCommands(program) {
|
|
11
|
+
const run = program
|
|
12
|
+
.command('run')
|
|
13
|
+
.description('Inspect and replay agent runs (observability)');
|
|
14
|
+
// ── buddy run list ─────────────────────────────────────────────
|
|
15
|
+
run
|
|
16
|
+
.command('list')
|
|
17
|
+
.description('List recent runs')
|
|
18
|
+
.option('-n, --limit <n>', 'number of runs to show', '20')
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
const { listRuns } = await import('../../observability/run-viewer.js');
|
|
21
|
+
listRuns(parseInt(opts.limit, 10));
|
|
22
|
+
});
|
|
23
|
+
// ── buddy run show ─────────────────────────────────────────────
|
|
24
|
+
run
|
|
25
|
+
.command('show <runId>')
|
|
26
|
+
.description('Show complete timeline, metrics, and artifacts for a run')
|
|
27
|
+
.action(async (runId) => {
|
|
28
|
+
const { showRun } = await import('../../observability/run-viewer.js');
|
|
29
|
+
await showRun(runId);
|
|
30
|
+
});
|
|
31
|
+
// ── buddy run tail ─────────────────────────────────────────────
|
|
32
|
+
run
|
|
33
|
+
.command('tail <runId>')
|
|
34
|
+
.description('Stream run events in real-time (follow mode)')
|
|
35
|
+
.action(async (runId) => {
|
|
36
|
+
const { tailRun } = await import('../../observability/run-viewer.js');
|
|
37
|
+
await tailRun(runId);
|
|
38
|
+
});
|
|
39
|
+
// ── buddy run replay ───────────────────────────────────────────
|
|
40
|
+
run
|
|
41
|
+
.command('replay <runId>')
|
|
42
|
+
.description('Show timeline and re-execute test steps')
|
|
43
|
+
.option('--no-rerun', 'only show timeline, do not re-run tests')
|
|
44
|
+
.action(async (runId, opts) => {
|
|
45
|
+
const { replayRun } = await import('../../observability/run-viewer.js');
|
|
46
|
+
await replayRun(runId, opts.rerun !== false);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/run-cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,GAAG,GAAG,OAAO;SAChB,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,+CAA+C,CAAC,CAAC;IAEhE,kEAAkE;IAClE,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,kBAAkB,CAAC;SAC/B,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,IAAI,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,IAAuB,EAAE,EAAE;QACxC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC;QACvE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEL,kEAAkE;IAClE,GAAG;SACA,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,0DAA0D,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;QAC9B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC;QACtE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,kEAAkE;IAClE,GAAG;SACA,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;QAC9B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC;QACtE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,kEAAkE;IAClE,GAAG;SACA,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,YAAY,EAAE,yCAAyC,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAwB,EAAE,EAAE;QACxD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAC;QACxE,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `buddy todo` CLI command
|
|
3
|
+
*
|
|
4
|
+
* Manages the persistent todo.md task list (Manus AI attention bias pattern).
|
|
5
|
+
* The same list is automatically injected at the end of every LLM context
|
|
6
|
+
* turn to keep objectives in focus across long sessions.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function createTodosCommand(): Command;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `buddy todo` CLI command
|
|
3
|
+
*
|
|
4
|
+
* Manages the persistent todo.md task list (Manus AI attention bias pattern).
|
|
5
|
+
* The same list is automatically injected at the end of every LLM context
|
|
6
|
+
* turn to keep objectives in focus across long sessions.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
import { getTodoTracker } from '../agent/todo-tracker.js';
|
|
10
|
+
export function createTodosCommand() {
|
|
11
|
+
const cmd = new Command('todo');
|
|
12
|
+
cmd.description('Manage the persistent task list (todo.md) — injected into every agent turn');
|
|
13
|
+
// list
|
|
14
|
+
cmd
|
|
15
|
+
.command('list')
|
|
16
|
+
.alias('ls')
|
|
17
|
+
.description('List all todo items')
|
|
18
|
+
.option('--pending', 'Show only pending items')
|
|
19
|
+
.action((opts) => {
|
|
20
|
+
const tracker = getTodoTracker(process.cwd());
|
|
21
|
+
tracker.load();
|
|
22
|
+
const items = opts.pending ? tracker.getPending() : tracker.getAll();
|
|
23
|
+
if (items.length === 0) {
|
|
24
|
+
console.log('No items.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const statusIcon = {
|
|
28
|
+
pending: '⬜',
|
|
29
|
+
in_progress: '🔄',
|
|
30
|
+
done: '✅',
|
|
31
|
+
blocked: '🚫',
|
|
32
|
+
};
|
|
33
|
+
for (const item of items) {
|
|
34
|
+
const icon = statusIcon[item.status];
|
|
35
|
+
const prio = item.priority !== 'medium' ? ` [${item.priority}]` : '';
|
|
36
|
+
console.log(`${icon} [${item.id}]${prio} ${item.text}`);
|
|
37
|
+
for (const sub of item.subtasks) {
|
|
38
|
+
console.log(` ${statusIcon[sub.status]} ${sub.text}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
// add
|
|
43
|
+
cmd
|
|
44
|
+
.command('add <text>')
|
|
45
|
+
.description('Add a new todo item')
|
|
46
|
+
.option('-p, --priority <priority>', 'Priority: high|medium|low', 'medium')
|
|
47
|
+
.action((text, opts) => {
|
|
48
|
+
const tracker = getTodoTracker(process.cwd());
|
|
49
|
+
const item = tracker.add(text, opts.priority);
|
|
50
|
+
console.log(`Added [${item.id}]: ${item.text}`);
|
|
51
|
+
});
|
|
52
|
+
// done
|
|
53
|
+
cmd
|
|
54
|
+
.command('done <id>')
|
|
55
|
+
.description('Mark an item as completed')
|
|
56
|
+
.action((id) => {
|
|
57
|
+
const tracker = getTodoTracker(process.cwd());
|
|
58
|
+
const ok = tracker.complete(id);
|
|
59
|
+
if (ok)
|
|
60
|
+
console.log(`Marked done: ${id}`);
|
|
61
|
+
else
|
|
62
|
+
console.error(`Item not found: ${id}`);
|
|
63
|
+
});
|
|
64
|
+
// update
|
|
65
|
+
cmd
|
|
66
|
+
.command('update <id>')
|
|
67
|
+
.description('Update an item')
|
|
68
|
+
.option('-t, --text <text>', 'New text')
|
|
69
|
+
.option('-s, --status <status>', 'New status: pending|in_progress|done|blocked')
|
|
70
|
+
.option('-p, --priority <priority>', 'New priority: high|medium|low')
|
|
71
|
+
.action((id, opts) => {
|
|
72
|
+
const tracker = getTodoTracker(process.cwd());
|
|
73
|
+
const ok = tracker.update(id, {
|
|
74
|
+
text: opts.text,
|
|
75
|
+
status: opts.status,
|
|
76
|
+
priority: opts.priority,
|
|
77
|
+
});
|
|
78
|
+
if (ok)
|
|
79
|
+
console.log(`Updated: ${id}`);
|
|
80
|
+
else
|
|
81
|
+
console.error(`Item not found: ${id}`);
|
|
82
|
+
});
|
|
83
|
+
// remove
|
|
84
|
+
cmd
|
|
85
|
+
.command('remove <id>')
|
|
86
|
+
.alias('rm')
|
|
87
|
+
.description('Remove an item')
|
|
88
|
+
.action((id) => {
|
|
89
|
+
const tracker = getTodoTracker(process.cwd());
|
|
90
|
+
const ok = tracker.remove(id);
|
|
91
|
+
if (ok)
|
|
92
|
+
console.log(`Removed: ${id}`);
|
|
93
|
+
else
|
|
94
|
+
console.error(`Item not found: ${id}`);
|
|
95
|
+
});
|
|
96
|
+
// clear-done
|
|
97
|
+
cmd
|
|
98
|
+
.command('clear-done')
|
|
99
|
+
.description('Remove all completed items')
|
|
100
|
+
.action(() => {
|
|
101
|
+
const tracker = getTodoTracker(process.cwd());
|
|
102
|
+
const n = tracker.clearDone();
|
|
103
|
+
console.log(`Cleared ${n} completed items.`);
|
|
104
|
+
});
|
|
105
|
+
// context
|
|
106
|
+
cmd
|
|
107
|
+
.command('context')
|
|
108
|
+
.description('Preview the todo context block injected into each agent turn')
|
|
109
|
+
.action(() => {
|
|
110
|
+
const tracker = getTodoTracker(process.cwd());
|
|
111
|
+
const block = tracker.buildContextSuffix();
|
|
112
|
+
if (!block)
|
|
113
|
+
console.log('No pending items — nothing to inject.');
|
|
114
|
+
else
|
|
115
|
+
console.log(block);
|
|
116
|
+
});
|
|
117
|
+
return cmd;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=todos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todos.js","sourceRoot":"","sources":["../../src/commands/todos.ts"],"names":[],"mappings":"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"}
|