brainclaw 0.19.2
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/LICENSE +74 -0
- package/README.md +226 -0
- package/dist/cli.js +1037 -0
- package/dist/commands/accept.js +149 -0
- package/dist/commands/adapter-openclaw-import.js +75 -0
- package/dist/commands/add-step.js +35 -0
- package/dist/commands/agent-board.js +106 -0
- package/dist/commands/audit.js +35 -0
- package/dist/commands/bootstrap.js +34 -0
- package/dist/commands/capability.js +104 -0
- package/dist/commands/changes.js +112 -0
- package/dist/commands/check-constraints.js +63 -0
- package/dist/commands/claim-resource.js +54 -0
- package/dist/commands/claim.js +92 -0
- package/dist/commands/complete-step.js +34 -0
- package/dist/commands/constraint.js +44 -0
- package/dist/commands/context-diff.js +32 -0
- package/dist/commands/context.js +63 -0
- package/dist/commands/decision.js +45 -0
- package/dist/commands/delete-plan.js +20 -0
- package/dist/commands/diff.js +99 -0
- package/dist/commands/doctor.js +1275 -0
- package/dist/commands/enable-agent.js +63 -0
- package/dist/commands/env.js +46 -0
- package/dist/commands/estimation-report.js +167 -0
- package/dist/commands/explore.js +47 -0
- package/dist/commands/export.js +381 -0
- package/dist/commands/handoff.js +63 -0
- package/dist/commands/history.js +22 -0
- package/dist/commands/hooks.js +123 -0
- package/dist/commands/init.js +356 -0
- package/dist/commands/install-hooks.js +115 -0
- package/dist/commands/instruction.js +56 -0
- package/dist/commands/list-agents.js +44 -0
- package/dist/commands/list-claims.js +45 -0
- package/dist/commands/list-instructions.js +50 -0
- package/dist/commands/list-plans.js +48 -0
- package/dist/commands/mcp-worker.js +12 -0
- package/dist/commands/mcp.js +2272 -0
- package/dist/commands/memory.js +283 -0
- package/dist/commands/metrics.js +175 -0
- package/dist/commands/plan-resource.js +62 -0
- package/dist/commands/plan.js +76 -0
- package/dist/commands/prune-candidates.js +36 -0
- package/dist/commands/prune.js +48 -0
- package/dist/commands/pull.js +25 -0
- package/dist/commands/push.js +28 -0
- package/dist/commands/rebuild.js +14 -0
- package/dist/commands/reflect-runtime-note.js +74 -0
- package/dist/commands/reflect.js +286 -0
- package/dist/commands/register-agent.js +29 -0
- package/dist/commands/reject.js +52 -0
- package/dist/commands/release-claim.js +41 -0
- package/dist/commands/release-claims.js +67 -0
- package/dist/commands/review.js +242 -0
- package/dist/commands/rollback.js +156 -0
- package/dist/commands/runtime-note.js +144 -0
- package/dist/commands/runtime-status.js +49 -0
- package/dist/commands/search.js +36 -0
- package/dist/commands/session-end.js +187 -0
- package/dist/commands/session-start.js +147 -0
- package/dist/commands/set-trust.js +92 -0
- package/dist/commands/setup.js +446 -0
- package/dist/commands/show-candidate.js +31 -0
- package/dist/commands/star-candidate.js +28 -0
- package/dist/commands/status.js +133 -0
- package/dist/commands/sync.js +159 -0
- package/dist/commands/tool.js +126 -0
- package/dist/commands/trap.js +74 -0
- package/dist/commands/update-handoff.js +23 -0
- package/dist/commands/update-plan.js +37 -0
- package/dist/commands/upgrade.js +382 -0
- package/dist/commands/use-candidate.js +35 -0
- package/dist/commands/version.js +96 -0
- package/dist/commands/watch.js +215 -0
- package/dist/commands/whoami.js +104 -0
- package/dist/core/agent-context.js +340 -0
- package/dist/core/agent-files.js +874 -0
- package/dist/core/agent-integrations.js +135 -0
- package/dist/core/agent-inventory.js +401 -0
- package/dist/core/agent-registry.js +420 -0
- package/dist/core/ai-agent-detection.js +140 -0
- package/dist/core/audit.js +85 -0
- package/dist/core/bootstrap.js +658 -0
- package/dist/core/brainclaw-version.js +433 -0
- package/dist/core/candidates.js +137 -0
- package/dist/core/circuit-breaker.js +118 -0
- package/dist/core/claims.js +72 -0
- package/dist/core/config.js +86 -0
- package/dist/core/context-diff.js +122 -0
- package/dist/core/context.js +1212 -0
- package/dist/core/contradictions.js +270 -0
- package/dist/core/coordination.js +86 -0
- package/dist/core/cross-project.js +99 -0
- package/dist/core/duplicates.js +72 -0
- package/dist/core/event-log.js +152 -0
- package/dist/core/events.js +56 -0
- package/dist/core/execution-context.js +204 -0
- package/dist/core/freshness.js +87 -0
- package/dist/core/global-registry.js +182 -0
- package/dist/core/host.js +10 -0
- package/dist/core/identity.js +151 -0
- package/dist/core/ids.js +56 -0
- package/dist/core/input-validation.js +81 -0
- package/dist/core/instructions.js +117 -0
- package/dist/core/io.js +191 -0
- package/dist/core/json-store.js +63 -0
- package/dist/core/lifecycle.js +45 -0
- package/dist/core/lock.js +129 -0
- package/dist/core/logger.js +49 -0
- package/dist/core/machine-profile.js +332 -0
- package/dist/core/markdown.js +120 -0
- package/dist/core/memory-git.js +133 -0
- package/dist/core/migration.js +247 -0
- package/dist/core/project-registry.js +64 -0
- package/dist/core/reflection-safety.js +21 -0
- package/dist/core/repo-analysis.js +133 -0
- package/dist/core/reputation.js +409 -0
- package/dist/core/runtime.js +134 -0
- package/dist/core/schema.js +580 -0
- package/dist/core/search.js +115 -0
- package/dist/core/security.js +66 -0
- package/dist/core/setup-state.js +50 -0
- package/dist/core/state.js +83 -0
- package/dist/core/store-resolution.js +119 -0
- package/dist/core/sync-remote.js +83 -0
- package/dist/core/traps.js +86 -0
- package/package.json +60 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { registerAgentIdentity, setCurrentAgentIdentity } from '../core/agent-registry.js';
|
|
2
|
+
import { loadConfig, saveConfig } from '../core/config.js';
|
|
3
|
+
import { describeAutoConfigWrite, writeDetectedAgentAutoConfig } from '../core/agent-files.js';
|
|
4
|
+
import { isAgentIntegrationName, upsertAgentIntegrationDeclaration } from '../core/agent-integrations.js';
|
|
5
|
+
import { memoryExists } from '../core/io.js';
|
|
6
|
+
import { writeAgentExportForAgent } from './export.js';
|
|
7
|
+
import { writeDetectedAgentHooks } from './hooks.js';
|
|
8
|
+
export function runEnableAgent(agentName, options = {}) {
|
|
9
|
+
const cwd = options.cwd ?? process.cwd();
|
|
10
|
+
if (!memoryExists(cwd)) {
|
|
11
|
+
console.error('Error: .brainclaw/ not found. Run `brainclaw init` first.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
if (!isAgentIntegrationName(agentName)) {
|
|
15
|
+
console.error(`Error: unsupported agent '${agentName}'. Use \`brainclaw register-agent\` for identity-only registration.`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const agent = registerAgentIdentity({
|
|
19
|
+
agentName,
|
|
20
|
+
kind: options.kind ?? 'agent',
|
|
21
|
+
capabilities: options.capability,
|
|
22
|
+
replaceCapabilities: options.replaceCapabilities,
|
|
23
|
+
generateFingerprint: options.generateFingerprint,
|
|
24
|
+
cwd,
|
|
25
|
+
});
|
|
26
|
+
if (options.setCurrent) {
|
|
27
|
+
setCurrentAgentIdentity(agent, cwd);
|
|
28
|
+
}
|
|
29
|
+
const config = loadConfig(cwd);
|
|
30
|
+
upsertAgentIntegrationDeclaration(config, agentName, 'manual');
|
|
31
|
+
saveConfig(config, cwd);
|
|
32
|
+
const exportResult = writeAgentExportForAgent(agentName, cwd);
|
|
33
|
+
// Windsurf uses .windsurfrules for both native rules and session hooks.
|
|
34
|
+
// Avoid clobbering the exported rules file during activation.
|
|
35
|
+
const hookResults = agentName === 'windsurf'
|
|
36
|
+
? []
|
|
37
|
+
: writeDetectedAgentHooks(agentName, config.project_name, cwd)
|
|
38
|
+
.filter((hook) => hook.relativePath !== exportResult?.relativePath);
|
|
39
|
+
const autoConfigResults = writeDetectedAgentAutoConfig(agentName, cwd);
|
|
40
|
+
const messages = autoConfigResults.map(describeAutoConfigWrite).filter((message) => Boolean(message));
|
|
41
|
+
if (options.json) {
|
|
42
|
+
console.log(JSON.stringify({
|
|
43
|
+
agent,
|
|
44
|
+
current: options.setCurrent ?? false,
|
|
45
|
+
declaration_added: true,
|
|
46
|
+
export: exportResult,
|
|
47
|
+
hooks: hookResults,
|
|
48
|
+
auto_config: autoConfigResults,
|
|
49
|
+
}, null, 2));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log(`✔ Agent enabled: ${agent.agent_name} (${agent.agent_id})${options.setCurrent ? ' [current]' : ''}`);
|
|
53
|
+
if (exportResult) {
|
|
54
|
+
console.log(`✔ Agent instructions written to ${exportResult.relativePath} (${exportResult.created ? 'created' : 'updated'})`);
|
|
55
|
+
}
|
|
56
|
+
for (const hook of hookResults) {
|
|
57
|
+
console.log(`✔ Session hook written to ${hook.relativePath} (${hook.created ? 'created' : 'updated'})`);
|
|
58
|
+
}
|
|
59
|
+
for (const message of messages) {
|
|
60
|
+
console.log(message);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=enable-agent.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { memoryExists } from '../core/io.js';
|
|
2
|
+
import { loadConfig } from '../core/config.js';
|
|
3
|
+
import { assessAgentIntegrationReadiness } from '../core/agent-integrations.js';
|
|
4
|
+
import { assessBrainclawVersion } from '../core/brainclaw-version.js';
|
|
5
|
+
import { buildExecutionContext, compactExecutionContext, renderExecutionContextSummary } from '../core/execution-context.js';
|
|
6
|
+
import { buildAgentToolingContext, renderAgentToolingSummary } from '../core/agent-context.js';
|
|
7
|
+
export function runEnv(options = {}) {
|
|
8
|
+
const cwd = options.cwd ?? process.cwd();
|
|
9
|
+
if (!memoryExists(cwd)) {
|
|
10
|
+
console.error('Error: .brainclaw/ not found. Run `brainclaw init` first.');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const executionContext = buildExecutionContext({ cwd });
|
|
14
|
+
const config = loadConfig(cwd);
|
|
15
|
+
const integrationReadiness = assessAgentIntegrationReadiness(config, cwd);
|
|
16
|
+
const brainclawVersion = assessBrainclawVersion(config);
|
|
17
|
+
const agentTooling = options.agentTooling ? buildAgentToolingContext({ cwd }) : undefined;
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(JSON.stringify({
|
|
20
|
+
execution_context: executionContext,
|
|
21
|
+
brainclaw_version: brainclawVersion,
|
|
22
|
+
declared_agent_integrations: config.agent_integrations,
|
|
23
|
+
integration_readiness: integrationReadiness,
|
|
24
|
+
...(agentTooling ? { agent_tooling: agentTooling } : {}),
|
|
25
|
+
}, null, 2));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.log(renderExecutionContextSummary(compactExecutionContext(executionContext), false));
|
|
29
|
+
console.log(`Brainclaw CLI: ${brainclawVersion.cli_version}`);
|
|
30
|
+
if (brainclawVersion.status !== 'ok') {
|
|
31
|
+
console.log(brainclawVersion.message);
|
|
32
|
+
if (brainclawVersion.upgrade_message) {
|
|
33
|
+
console.log(`Upgrade benefits: ${brainclawVersion.upgrade_message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
console.log(`Declared agent integrations: ${config.agent_integrations.declarations.length}`);
|
|
37
|
+
const missingDeclarations = integrationReadiness.filter((entry) => !entry.ready);
|
|
38
|
+
if (missingDeclarations.length > 0) {
|
|
39
|
+
console.log(`Integrations missing activation: ${missingDeclarations.length}`);
|
|
40
|
+
}
|
|
41
|
+
if (agentTooling) {
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(renderAgentToolingSummary(agentTooling));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { loadState } from '../core/state.js';
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
3
|
+
/** Parse legacy actual_effort strings ("30min", "2h", "1h30m", "1d", "45m") → minutes.
|
|
4
|
+
* Still needed for actual_effort which remains a free string. */
|
|
5
|
+
export function parseEffortMinutes(effort) {
|
|
6
|
+
const s = effort.trim().toLowerCase();
|
|
7
|
+
let total = 0;
|
|
8
|
+
let matched = false;
|
|
9
|
+
const days = s.match(/(\d+(?:\.\d+)?)\s*d/);
|
|
10
|
+
if (days) {
|
|
11
|
+
total += parseFloat(days[1]) * 8 * 60;
|
|
12
|
+
matched = true;
|
|
13
|
+
}
|
|
14
|
+
const hours = s.match(/(\d+(?:\.\d+)?)\s*h/);
|
|
15
|
+
if (hours) {
|
|
16
|
+
total += parseFloat(hours[1]) * 60;
|
|
17
|
+
matched = true;
|
|
18
|
+
}
|
|
19
|
+
const mins = s.match(/(\d+(?:\.\d+)?)\s*m(?:in)?/);
|
|
20
|
+
if (mins) {
|
|
21
|
+
total += parseFloat(mins[1]);
|
|
22
|
+
matched = true;
|
|
23
|
+
}
|
|
24
|
+
if (!matched) {
|
|
25
|
+
const bare = parseFloat(s);
|
|
26
|
+
if (!isNaN(bare))
|
|
27
|
+
return bare;
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return total > 0 ? total : undefined;
|
|
31
|
+
}
|
|
32
|
+
function median(values) {
|
|
33
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
34
|
+
const mid = Math.floor(sorted.length / 2);
|
|
35
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
36
|
+
}
|
|
37
|
+
function mean(values) {
|
|
38
|
+
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
39
|
+
}
|
|
40
|
+
export function buildCalibrationHint(medianRatio) {
|
|
41
|
+
if (medianRatio < 0.5)
|
|
42
|
+
return `You tend to underestimate by ~${(1 / medianRatio).toFixed(1)}x — pad estimates up`;
|
|
43
|
+
if (medianRatio < 0.8)
|
|
44
|
+
return `You slightly underestimate — add ~${Math.round((1 - medianRatio) * 100)}% to estimates`;
|
|
45
|
+
if (medianRatio <= 1.25)
|
|
46
|
+
return 'Estimates are well-calibrated';
|
|
47
|
+
if (medianRatio <= 2.0)
|
|
48
|
+
return `You tend to overestimate by ~${medianRatio.toFixed(1)}x — cut estimates by ~${Math.round((1 - 1 / medianRatio) * 100)}%`;
|
|
49
|
+
return `You significantly overestimate by ~${medianRatio.toFixed(1)}x — estimates should be ~${medianRatio.toFixed(1)}x smaller`;
|
|
50
|
+
}
|
|
51
|
+
/** Render a ratio bar (40 chars wide, 1.0x at the midpoint). */
|
|
52
|
+
export function renderRatioBar(ratio, width = 40) {
|
|
53
|
+
const pivot = Math.floor(width / 2); // position of 1.0x
|
|
54
|
+
const filled = Math.min(Math.round(ratio * pivot), width);
|
|
55
|
+
const bar = Array.from({ length: width }, (_, i) => {
|
|
56
|
+
if (i < filled)
|
|
57
|
+
return '█';
|
|
58
|
+
if (i === pivot && filled < pivot)
|
|
59
|
+
return '│';
|
|
60
|
+
return '░';
|
|
61
|
+
}).join('');
|
|
62
|
+
return bar;
|
|
63
|
+
}
|
|
64
|
+
export function buildEstimationReport(options = {}) {
|
|
65
|
+
const state = loadState(options.cwd);
|
|
66
|
+
const done = state.plan_items.filter((p) => p.status === 'done' && (!options.agent || p.author === options.agent));
|
|
67
|
+
const entries = done.map((p) => {
|
|
68
|
+
const entry = {
|
|
69
|
+
id: p.id,
|
|
70
|
+
text: p.text,
|
|
71
|
+
author: p.author,
|
|
72
|
+
estimated_minutes: p.estimated_effort, // already a number after schema coercion
|
|
73
|
+
actual_effort: p.actual_effort,
|
|
74
|
+
completed_at: p.completed_at,
|
|
75
|
+
};
|
|
76
|
+
// Compute elapsed from wall-clock timestamps
|
|
77
|
+
const endTime = p.completed_at ?? p.updated_at;
|
|
78
|
+
const startTime = p.started_at ?? p.created_at;
|
|
79
|
+
if (endTime && startTime) {
|
|
80
|
+
const elapsed = (new Date(endTime).getTime() - new Date(startTime).getTime()) / 60000;
|
|
81
|
+
if (elapsed > 0)
|
|
82
|
+
entry.elapsed_minutes = Math.round(elapsed);
|
|
83
|
+
}
|
|
84
|
+
// Resolve actual minutes: explicit actual_effort string > elapsed wall-clock
|
|
85
|
+
const actualMinutes = p.actual_effort
|
|
86
|
+
? parseEffortMinutes(p.actual_effort)
|
|
87
|
+
: entry.elapsed_minutes;
|
|
88
|
+
if (actualMinutes !== undefined)
|
|
89
|
+
entry.elapsed_minutes = Math.round(actualMinutes);
|
|
90
|
+
if (entry.estimated_minutes !== undefined && actualMinutes !== undefined && actualMinutes > 0) {
|
|
91
|
+
entry.ratio = parseFloat((entry.estimated_minutes / actualMinutes).toFixed(2));
|
|
92
|
+
}
|
|
93
|
+
return entry;
|
|
94
|
+
});
|
|
95
|
+
const withBoth = entries.filter((e) => e.ratio !== undefined);
|
|
96
|
+
const ratios = withBoth.map((e) => e.ratio);
|
|
97
|
+
const medianRatio = ratios.length > 0 ? parseFloat(median(ratios).toFixed(2)) : undefined;
|
|
98
|
+
const meanRatio = ratios.length > 0 ? parseFloat(mean(ratios).toFixed(2)) : undefined;
|
|
99
|
+
return {
|
|
100
|
+
entries,
|
|
101
|
+
summary: {
|
|
102
|
+
total: entries.length,
|
|
103
|
+
with_estimate: entries.filter((e) => e.estimated_minutes !== undefined).length,
|
|
104
|
+
with_both: withBoth.length,
|
|
105
|
+
median_ratio: medianRatio,
|
|
106
|
+
mean_ratio: meanRatio,
|
|
107
|
+
calibration_hint: medianRatio !== undefined ? buildCalibrationHint(medianRatio) : undefined,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function runEstimationReport(options = {}) {
|
|
112
|
+
if (!memoryExists(options.cwd)) {
|
|
113
|
+
console.error('Error: .brainclaw/ not found. Run `brainclaw init` first.');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
const report = buildEstimationReport(options);
|
|
117
|
+
if (options.json) {
|
|
118
|
+
console.log(JSON.stringify(report, null, 2));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { summary, entries } = report;
|
|
122
|
+
if (summary.total === 0) {
|
|
123
|
+
console.log('No completed plans found.');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log(`\nEstimation Report — ${summary.total} completed plan(s)`);
|
|
127
|
+
console.log(`With estimates: ${summary.with_estimate} · With both: ${summary.with_both}`);
|
|
128
|
+
if (summary.median_ratio !== undefined) {
|
|
129
|
+
console.log(`\nMedian ratio (estimated÷actual): ${summary.median_ratio}x · Mean: ${summary.mean_ratio}x`);
|
|
130
|
+
console.log(`→ ${summary.calibration_hint}`);
|
|
131
|
+
}
|
|
132
|
+
// Chart — only plans with ratio data
|
|
133
|
+
const chartable = entries.filter((e) => e.ratio !== undefined);
|
|
134
|
+
if (chartable.length > 0) {
|
|
135
|
+
console.log('\n— Accuracy chart (ratio = estimated ÷ actual) —');
|
|
136
|
+
console.log(' < 1.0 = went over estimate │ > 1.0 = finished early\n');
|
|
137
|
+
// Header scale
|
|
138
|
+
const W = 40;
|
|
139
|
+
const pivot = W / 2;
|
|
140
|
+
const scaleTop = ' ' + '0.0x' + ' '.repeat(pivot - 4) + '1.0x' + ' '.repeat(W - pivot - 4) + '2.0x+';
|
|
141
|
+
const scaleLine = ' ├' + '─'.repeat(pivot - 1) + '┼' + '─'.repeat(W - pivot - 1) + '┤';
|
|
142
|
+
console.log(scaleTop);
|
|
143
|
+
console.log(scaleLine);
|
|
144
|
+
for (const e of chartable) {
|
|
145
|
+
const label = (e.text.length > 35 ? e.text.slice(0, 32) + '…' : e.text).padEnd(35);
|
|
146
|
+
const bar = renderRatioBar(e.ratio);
|
|
147
|
+
const pct = e.ratio >= 1
|
|
148
|
+
? ` EARLY -${Math.round((1 - 1 / e.ratio) * 100)}%`
|
|
149
|
+
: ` OVER +${Math.round((1 / e.ratio - 1) * 100)}%`;
|
|
150
|
+
const est = e.estimated_minutes !== undefined ? `${e.estimated_minutes}min` : '?';
|
|
151
|
+
const act = e.elapsed_minutes !== undefined ? `${e.elapsed_minutes}min` : '?';
|
|
152
|
+
console.log(` ${label} ${bar} ${e.ratio}x ${est}→${act}${pct}`);
|
|
153
|
+
}
|
|
154
|
+
console.log('');
|
|
155
|
+
}
|
|
156
|
+
// Detail table for plans with estimate but no actual
|
|
157
|
+
const estimateOnly = entries.filter((e) => e.estimated_minutes !== undefined && e.ratio === undefined);
|
|
158
|
+
if (estimateOnly.length > 0) {
|
|
159
|
+
console.log('— Estimated but no elapsed time —');
|
|
160
|
+
for (const e of estimateOnly) {
|
|
161
|
+
const short = e.text.length > 60 ? e.text.slice(0, 57) + '…' : e.text;
|
|
162
|
+
console.log(` [${e.id.slice(-8)}] ${short} — est:${e.estimated_minutes}min`);
|
|
163
|
+
}
|
|
164
|
+
console.log('');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=estimation-report.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { loadState } from '../core/state.js';
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
3
|
+
export function runExplore(options = {}) {
|
|
4
|
+
const cwd = options.cwd ?? process.cwd();
|
|
5
|
+
if (!memoryExists(cwd)) {
|
|
6
|
+
console.error('Error: .brainclaw/ not found. Run `brainclaw init` first.');
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
const state = loadState(cwd);
|
|
10
|
+
const capabilities = state.recent_decisions.filter((d) => d.tags.includes('capability'));
|
|
11
|
+
const tools = state.recent_decisions.filter((d) => d.tags.includes('tool'));
|
|
12
|
+
console.log('\n╔════════════════════════════════════════════════════════╗');
|
|
13
|
+
console.log('║ Project Capabilities & Tools ║');
|
|
14
|
+
console.log('╚════════════════════════════════════════════════════════╝\n');
|
|
15
|
+
console.log(`📦 Capabilities (${capabilities.length}):\n`);
|
|
16
|
+
if (capabilities.length === 0) {
|
|
17
|
+
console.log(' No capabilities registered yet.\n');
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
capabilities.forEach((cap) => {
|
|
21
|
+
const category = cap.tags.find((t) => t !== 'capability') || 'general';
|
|
22
|
+
console.log(` [${cap.id}] ${cap.text.split('\n')[0]}`);
|
|
23
|
+
console.log(` Category: ${category}\n`);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
console.log(`🔧 Tools (${tools.length}):\n`);
|
|
27
|
+
if (tools.length === 0) {
|
|
28
|
+
console.log(' No tools registered yet.\n');
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
tools.forEach((tool) => {
|
|
32
|
+
const type = tool.tags.find((t) => t !== 'tool') || 'utility';
|
|
33
|
+
console.log(` [${tool.id}] ${tool.text.split('\n')[0]}`);
|
|
34
|
+
console.log(` Type: ${type}\n`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (capabilities.length === 0 && tools.length === 0) {
|
|
38
|
+
console.log('💡 Tip: Register your first capability or tool with:');
|
|
39
|
+
console.log(' brainclaw capability add <name> <description>');
|
|
40
|
+
console.log(' brainclaw tool add <name> <description>\n');
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.log('💡 Tip: Use `brainclaw capability describe <id>` or `brainclaw tool describe <id>` for details');
|
|
44
|
+
console.log(' Use `brainclaw tool search <query>` to find tools\n');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=explore.js.map
|