brainclaw 0.19.5 → 0.19.7
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 +0 -0
- package/README.md +22 -20
- package/dist/cli.js +0 -0
- package/dist/commands/accept.js +102 -104
- package/dist/commands/adapter-openclaw-import.js +0 -0
- package/dist/commands/add-step.js +3 -5
- package/dist/commands/agent-board.js +0 -0
- package/dist/commands/audit.js +0 -0
- package/dist/commands/bootstrap.js +0 -0
- package/dist/commands/capability.js +3 -5
- package/dist/commands/changes.js +0 -0
- package/dist/commands/check-constraints.js +0 -0
- package/dist/commands/claim-resource.js +0 -0
- package/dist/commands/claim.js +14 -12
- package/dist/commands/complete-step.js +3 -5
- package/dist/commands/constraint.js +3 -5
- package/dist/commands/context-diff.js +0 -0
- package/dist/commands/context.js +0 -0
- package/dist/commands/decision.js +3 -6
- package/dist/commands/delete-plan.js +3 -5
- package/dist/commands/diff.js +0 -0
- package/dist/commands/doctor.js +0 -0
- package/dist/commands/enable-agent.js +0 -0
- package/dist/commands/env.js +0 -0
- package/dist/commands/estimation-report.js +0 -0
- package/dist/commands/explore.js +0 -0
- package/dist/commands/export.js +0 -0
- package/dist/commands/handoff.js +3 -5
- package/dist/commands/history.js +0 -0
- package/dist/commands/hooks.js +0 -0
- package/dist/commands/init.js +0 -0
- package/dist/commands/install-hooks.js +0 -0
- package/dist/commands/instruction.js +16 -9
- package/dist/commands/list-agents.js +0 -0
- package/dist/commands/list-claims.js +0 -0
- package/dist/commands/list-instructions.js +0 -0
- package/dist/commands/list-plans.js +0 -0
- package/dist/commands/mcp-worker.js +0 -0
- package/dist/commands/mcp.js +11 -21
- package/dist/commands/memory.js +4 -7
- package/dist/commands/metrics.js +0 -0
- package/dist/commands/plan-resource.js +0 -0
- package/dist/commands/plan.js +3 -5
- package/dist/commands/prune-candidates.js +0 -0
- package/dist/commands/prune.js +27 -25
- package/dist/commands/pull.js +0 -0
- package/dist/commands/push.js +0 -0
- package/dist/commands/rebuild.js +0 -0
- package/dist/commands/reflect-runtime-note.js +0 -0
- package/dist/commands/reflect.js +3 -5
- package/dist/commands/register-agent.js +0 -0
- package/dist/commands/reject.js +0 -0
- package/dist/commands/release-claim.js +23 -20
- package/dist/commands/release-claims.js +22 -21
- package/dist/commands/review.js +0 -0
- package/dist/commands/rollback.js +2 -2
- package/dist/commands/runtime-note.js +0 -0
- package/dist/commands/runtime-status.js +0 -0
- package/dist/commands/search.js +0 -0
- package/dist/commands/session-end.js +0 -0
- package/dist/commands/session-start.js +0 -0
- package/dist/commands/set-trust.js +0 -0
- package/dist/commands/setup.js +0 -0
- package/dist/commands/show-candidate.js +0 -0
- package/dist/commands/star-candidate.js +0 -0
- package/dist/commands/status.js +0 -0
- package/dist/commands/sync.js +0 -0
- package/dist/commands/tool.js +3 -5
- package/dist/commands/trap.js +3 -5
- package/dist/commands/update-handoff.js +3 -5
- package/dist/commands/update-plan.js +3 -5
- package/dist/commands/upgrade.js +2 -2
- package/dist/commands/use-candidate.js +0 -0
- package/dist/commands/version.js +0 -0
- package/dist/commands/watch.js +0 -0
- package/dist/commands/whoami.js +0 -0
- package/dist/core/agent-context.js +0 -0
- package/dist/core/agent-files.js +0 -0
- package/dist/core/agent-integrations.js +0 -0
- package/dist/core/agent-inventory.js +0 -0
- package/dist/core/agent-registry.js +0 -0
- package/dist/core/ai-agent-detection.js +0 -0
- package/dist/core/audit.js +25 -25
- package/dist/core/bootstrap.js +0 -0
- package/dist/core/brainclaw-version.js +0 -0
- package/dist/core/candidates.js +10 -6
- package/dist/core/circuit-breaker.js +0 -0
- package/dist/core/claims.js +10 -8
- package/dist/core/config.js +0 -0
- package/dist/core/context-diff.js +0 -0
- package/dist/core/context.js +0 -0
- package/dist/core/contradictions.js +0 -0
- package/dist/core/coordination.js +2 -2
- package/dist/core/cross-project.js +0 -0
- package/dist/core/duplicates.js +0 -0
- package/dist/core/event-log.js +0 -0
- package/dist/core/events.js +0 -0
- package/dist/core/execution-context.js +0 -0
- package/dist/core/freshness.js +0 -0
- package/dist/core/global-registry.js +0 -0
- package/dist/core/host.js +0 -0
- package/dist/core/identity.js +0 -0
- package/dist/core/ids.js +0 -0
- package/dist/core/input-validation.js +0 -0
- package/dist/core/instructions.js +4 -2
- package/dist/core/io.js +8 -0
- package/dist/core/json-store.js +0 -0
- package/dist/core/lifecycle.js +0 -0
- package/dist/core/lock.js +18 -2
- package/dist/core/logger.js +0 -0
- package/dist/core/machine-profile.js +0 -0
- package/dist/core/markdown.js +0 -0
- package/dist/core/memory-git.js +0 -0
- package/dist/core/migration.js +0 -0
- package/dist/core/project-registry.js +0 -0
- package/dist/core/reflection-safety.js +0 -0
- package/dist/core/repo-analysis.js +0 -0
- package/dist/core/reputation.js +0 -0
- package/dist/core/runtime.js +18 -14
- package/dist/core/schema.js +0 -0
- package/dist/core/search.js +0 -0
- package/dist/core/security.js +0 -0
- package/dist/core/setup-state.js +0 -0
- package/dist/core/state.js +21 -4
- package/dist/core/store-resolution.js +0 -0
- package/dist/core/sync-remote.js +0 -0
- package/dist/core/traps.js +0 -0
- package/docs/adapters/openclaw.md +43 -0
- package/docs/cli.md +1230 -0
- package/docs/concepts/coordination.md +52 -0
- package/docs/concepts/memory.md +87 -0
- package/docs/concepts/plans-and-claims.md +139 -0
- package/docs/concepts/runtime-notes.md +38 -0
- package/docs/concepts/workspace-bootstrapping.md +40 -0
- package/docs/context-format-changelog.md +35 -0
- package/docs/context-format.md +48 -0
- package/docs/integrations/agents.md +169 -0
- package/docs/integrations/claude-code.md +23 -0
- package/docs/integrations/codex.md +23 -0
- package/docs/integrations/copilot.md +21 -0
- package/docs/integrations/cursor.md +23 -0
- package/docs/integrations/mcp.md +51 -0
- package/docs/integrations/overview.md +61 -0
- package/docs/mcp-schema-changelog.md +108 -0
- package/docs/product/positioning.md +97 -0
- package/docs/quickstart.md +99 -0
- package/docs/reputation.md +52 -0
- package/docs/review.md +43 -0
- package/docs/security.md +53 -0
- package/docs/storage.md +81 -0
- package/package.json +7 -6
package/dist/commands/mcp.js
CHANGED
|
@@ -8,9 +8,8 @@ import { buildCoordinationSnapshot } from '../core/coordination.js';
|
|
|
8
8
|
import { buildContext, renderContextMarkdown, renderContextPromptTemplate } from '../core/context.js';
|
|
9
9
|
import { buildExecutionContext, renderExecutionContextSummary } from '../core/execution-context.js';
|
|
10
10
|
import { loadConfig } from '../core/config.js';
|
|
11
|
-
import { loadState,
|
|
12
|
-
import { memoryExists
|
|
13
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
11
|
+
import { loadState, persistState } from '../core/state.js';
|
|
12
|
+
import { memoryExists } from '../core/io.js';
|
|
14
13
|
import { generateCandidateIdWithLabel, listArchivedCandidates, listCandidates, saveCandidate } from '../core/candidates.js';
|
|
15
14
|
import { generateClaimId, listClaims, loadClaim, saveClaim } from '../core/claims.js';
|
|
16
15
|
import { createRuntimeNote } from './runtime-note.js';
|
|
@@ -1808,8 +1807,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
1808
1807
|
if (releasePlanStatus === 'done' && !releasePlan.completed_at)
|
|
1809
1808
|
releasePlan.completed_at = ts;
|
|
1810
1809
|
releasePlan.updated_at = ts;
|
|
1811
|
-
|
|
1812
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(releaseState, cwd));
|
|
1810
|
+
persistState(releaseState, cwd);
|
|
1813
1811
|
releasePlanUpdated = true;
|
|
1814
1812
|
}
|
|
1815
1813
|
}
|
|
@@ -1957,8 +1955,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
1957
1955
|
estimated_effort: estimatedEffort,
|
|
1958
1956
|
};
|
|
1959
1957
|
state.plan_items.push(entry);
|
|
1960
|
-
|
|
1961
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
1958
|
+
persistState(state, cwd);
|
|
1962
1959
|
appendAuditEntry({ actor: resolved.identity.agent_name, actor_id: resolved.identity.agent_id, action: 'create', item_id: id, item_type: 'plan' }, cwd);
|
|
1963
1960
|
return {
|
|
1964
1961
|
response: toolResponse({
|
|
@@ -1996,8 +1993,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
1996
1993
|
if (args.actualEffort)
|
|
1997
1994
|
plan.actual_effort = args.actualEffort;
|
|
1998
1995
|
plan.updated_at = timestamp;
|
|
1999
|
-
|
|
2000
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
1996
|
+
persistState(state, cwd);
|
|
2001
1997
|
appendAuditEntry({ actor: resolved.identity.agent_name, actor_id: resolved.identity.agent_id, action: 'update', item_id: plan.id, item_type: 'plan' }, cwd);
|
|
2002
1998
|
return {
|
|
2003
1999
|
response: toolResponse({
|
|
@@ -2032,8 +2028,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2032
2028
|
};
|
|
2033
2029
|
plan.steps = [...(plan.steps ?? []), step];
|
|
2034
2030
|
plan.updated_at = nowISO();
|
|
2035
|
-
|
|
2036
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
2031
|
+
persistState(state, cwd);
|
|
2037
2032
|
const total = plan.steps.length;
|
|
2038
2033
|
const done = plan.steps.filter((s) => s.status === 'done').length;
|
|
2039
2034
|
return {
|
|
@@ -2066,8 +2061,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2066
2061
|
step.status = 'done';
|
|
2067
2062
|
step.updated_at = nowISO();
|
|
2068
2063
|
plan.updated_at = nowISO();
|
|
2069
|
-
|
|
2070
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
2064
|
+
persistState(state, cwd);
|
|
2071
2065
|
const total = plan.steps.length;
|
|
2072
2066
|
const done = plan.steps.filter((s) => s.status === 'done').length;
|
|
2073
2067
|
return {
|
|
@@ -2124,8 +2118,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2124
2118
|
else if (itemType === 'trap') {
|
|
2125
2119
|
state.known_traps = state.known_traps.filter((t) => t.id !== itemId && t.short_label !== itemId);
|
|
2126
2120
|
}
|
|
2127
|
-
|
|
2128
|
-
writeFileAtomic(memoryPath('project.md', foundStore.cwd), generateMarkdown(state, foundStore.cwd));
|
|
2121
|
+
persistState(state, foundStore.cwd);
|
|
2129
2122
|
appendAuditEntry({ actor: resolved.identity.agent_name, actor_id: resolved.identity.agent_id, action: 'delete', item_id: itemId, item_type: itemType }, foundStore.cwd);
|
|
2130
2123
|
return {
|
|
2131
2124
|
response: toolResponse({
|
|
@@ -2211,8 +2204,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2211
2204
|
else if (itemType === 'trap') {
|
|
2212
2205
|
sourceState.known_traps = sourceState.known_traps.filter((t) => t.id !== itemId);
|
|
2213
2206
|
}
|
|
2214
|
-
|
|
2215
|
-
writeFileAtomic(memoryPath('project.md', sourceStore.cwd), generateMarkdown(sourceState, sourceStore.cwd));
|
|
2207
|
+
persistState(sourceState, sourceStore.cwd);
|
|
2216
2208
|
// Add to target store
|
|
2217
2209
|
const targetState = loadState(targetCwd);
|
|
2218
2210
|
if (itemType === 'constraint') {
|
|
@@ -2224,8 +2216,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2224
2216
|
else if (itemType === 'trap') {
|
|
2225
2217
|
targetState.known_traps.push(item);
|
|
2226
2218
|
}
|
|
2227
|
-
|
|
2228
|
-
writeFileAtomic(memoryPath('project.md', targetCwd), generateMarkdown(targetState, targetCwd));
|
|
2219
|
+
persistState(targetState, targetCwd);
|
|
2229
2220
|
}
|
|
2230
2221
|
else {
|
|
2231
2222
|
// Just update in place
|
|
@@ -2245,8 +2236,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
2245
2236
|
if (idx >= 0)
|
|
2246
2237
|
state.known_traps[idx] = item;
|
|
2247
2238
|
}
|
|
2248
|
-
|
|
2249
|
-
writeFileAtomic(memoryPath('project.md', sourceStore.cwd), generateMarkdown(state, sourceStore.cwd));
|
|
2239
|
+
persistState(state, sourceStore.cwd);
|
|
2250
2240
|
}
|
|
2251
2241
|
appendAuditEntry({ actor: resolved.identity.agent_name, actor_id: resolved.identity.agent_id, action: 'update', item_id: itemId, item_type: itemType }, sourceStore.cwd);
|
|
2252
2242
|
return {
|
package/dist/commands/memory.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from '../core/config.js';
|
|
2
|
-
import { memoryExists
|
|
3
|
-
import {
|
|
4
|
-
import { loadState, saveState } from '../core/state.js';
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
3
|
+
import { loadState, persistState } from '../core/state.js';
|
|
5
4
|
import { scanText } from '../core/security.js';
|
|
6
5
|
import { validateCliInput } from '../core/input-validation.js';
|
|
7
6
|
import { resolveTargetStore } from '../core/store-resolution.js';
|
|
@@ -222,8 +221,7 @@ function runMemoryUpdate(id, options) {
|
|
|
222
221
|
break;
|
|
223
222
|
}
|
|
224
223
|
}
|
|
225
|
-
|
|
226
|
-
writeFileAtomic(memoryPath('project.md', options.cwd), generateMarkdown(state, options.cwd));
|
|
224
|
+
persistState(state, options.cwd);
|
|
227
225
|
console.log(`✔ Memory item updated: [${resolved.item.id}] ${resolved.item.text}`);
|
|
228
226
|
}
|
|
229
227
|
function runMemoryDelete(id, cwd) {
|
|
@@ -250,8 +248,7 @@ function runMemoryDelete(id, cwd) {
|
|
|
250
248
|
console.error(`Error: Memory item '${id}' not found.`);
|
|
251
249
|
process.exit(1);
|
|
252
250
|
}
|
|
253
|
-
|
|
254
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
251
|
+
persistState(state, cwd);
|
|
255
252
|
console.log(`✔ Memory item deleted: [${deleted.id}] ${deleted.text}`);
|
|
256
253
|
}
|
|
257
254
|
function collectMemoryItems(state) {
|
package/dist/commands/metrics.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/commands/plan.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { loadState,
|
|
1
|
+
import { loadState, persistState } from '../core/state.js';
|
|
2
2
|
import { resolveCurrentAgentName } from '../core/agent-registry.js';
|
|
3
3
|
import { loadConfig } from '../core/config.js';
|
|
4
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
5
4
|
import { generateIdWithLabel, nowISO } from '../core/ids.js';
|
|
6
5
|
import { scanText } from '../core/security.js';
|
|
7
|
-
import { memoryExists
|
|
6
|
+
import { memoryExists } from '../core/io.js';
|
|
8
7
|
import { validateCliInput } from '../core/input-validation.js';
|
|
9
8
|
import { runListPlans } from './list-plans.js';
|
|
10
9
|
import { resolveTargetStore } from '../core/store-resolution.js';
|
|
@@ -68,8 +67,7 @@ export function runPlan(text, options = {}) {
|
|
|
68
67
|
estimated_effort: estimatedEffort,
|
|
69
68
|
};
|
|
70
69
|
state.plan_items.push(entry);
|
|
71
|
-
|
|
72
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
70
|
+
persistState(state, cwd);
|
|
73
71
|
const storeLabel = options.store && options.store !== 'local' ? ` [store:${options.store}]` : '';
|
|
74
72
|
console.log(`✔ Plan item added: [${id}] ${text}${storeLabel}`);
|
|
75
73
|
}
|
|
File without changes
|
package/dist/commands/prune.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { loadState, saveState } from '../core/state.js';
|
|
2
|
-
import { memoryExists } from '../core/io.js';
|
|
2
|
+
import { memoryExists, memoryPath, withStoreLock, writeFileAtomic } from '../core/io.js';
|
|
3
|
+
import { generateMarkdown } from '../core/markdown.js';
|
|
3
4
|
import { deleteRuntimeNote, listRuntimeNotes } from '../core/runtime.js';
|
|
4
5
|
import { expireStaleActiveClaims } from '../core/claims.js';
|
|
5
6
|
export function runPrune(options = {}) {
|
|
@@ -8,36 +9,37 @@ export function runPrune(options = {}) {
|
|
|
8
9
|
console.error('Project memory not initialized. Run `brainclaw init` first.');
|
|
9
10
|
process.exit(1);
|
|
10
11
|
}
|
|
11
|
-
const state = loadState(cwd);
|
|
12
12
|
const now = new Date().toISOString();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
for (const c of state.active_constraints) {
|
|
16
|
-
if (c.status === 'active' && c.expires_at && c.expires_at < now) {
|
|
17
|
-
c.status = 'expired';
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// Filter out constraints that have been expired for a while to keep memory clean
|
|
21
|
-
// For the MVP, we just remove them if they are expired
|
|
22
|
-
state.active_constraints = state.active_constraints.filter(c => c.status !== 'expired');
|
|
23
|
-
const prunedCount = originalLength - state.active_constraints.length;
|
|
24
|
-
saveState(state, cwd);
|
|
25
|
-
const expiredClaimsCount = expireStaleActiveClaims(cwd);
|
|
13
|
+
let prunedCount = 0;
|
|
14
|
+
let expiredClaimsCount = 0;
|
|
26
15
|
let expiredNotesCount = 0;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
for (const
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
16
|
+
withStoreLock(cwd, () => {
|
|
17
|
+
const state = loadState(cwd);
|
|
18
|
+
const originalLength = state.active_constraints.length;
|
|
19
|
+
for (const c of state.active_constraints) {
|
|
20
|
+
if (c.status === 'active' && c.expires_at && c.expires_at < now) {
|
|
21
|
+
c.status = 'expired';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
state.active_constraints = state.active_constraints.filter(c => c.status !== 'expired');
|
|
25
|
+
prunedCount = originalLength - state.active_constraints.length;
|
|
26
|
+
saveState(state, cwd);
|
|
27
|
+
expiredClaimsCount = expireStaleActiveClaims(cwd);
|
|
28
|
+
if (options.expired) {
|
|
29
|
+
const notes = listRuntimeNotes(undefined, cwd);
|
|
30
|
+
for (const note of notes) {
|
|
31
|
+
if (note.expires_at && note.expires_at < now) {
|
|
32
|
+
try {
|
|
33
|
+
if (deleteRuntimeNote(note, cwd)) {
|
|
34
|
+
expiredNotesCount++;
|
|
35
|
+
}
|
|
35
36
|
}
|
|
37
|
+
catch { /* ignore */ }
|
|
36
38
|
}
|
|
37
|
-
catch { /* ignore */ }
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(loadState(cwd), cwd));
|
|
42
|
+
});
|
|
41
43
|
if (options.expired) {
|
|
42
44
|
console.log(`✔ Pruned ${prunedCount} expired constraints, ${expiredNotesCount} expired runtime notes, ${expiredClaimsCount} expired claims.`);
|
|
43
45
|
}
|
package/dist/commands/pull.js
CHANGED
|
File without changes
|
package/dist/commands/push.js
CHANGED
|
File without changes
|
package/dist/commands/rebuild.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/commands/reflect.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { memoryExists
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
3
3
|
import { loadConfig } from '../core/config.js';
|
|
4
4
|
import { buildOperationalIdentity } from '../core/identity.js';
|
|
5
|
-
import { loadState,
|
|
6
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
5
|
+
import { loadState, persistState } from '../core/state.js';
|
|
7
6
|
import { scanText } from '../core/security.js';
|
|
8
7
|
import { nowISO, generateIdWithLabel } from '../core/ids.js';
|
|
9
8
|
import { saveCandidate, generateCandidateIdWithLabel, listCandidates } from '../core/candidates.js';
|
|
@@ -265,8 +264,7 @@ function promoteCandidateToState(candidate, cwd) {
|
|
|
265
264
|
break;
|
|
266
265
|
}
|
|
267
266
|
}
|
|
268
|
-
|
|
269
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state));
|
|
267
|
+
persistState(state, cwd);
|
|
270
268
|
return promotedItemId;
|
|
271
269
|
}
|
|
272
270
|
export function mapEventTypeToCandidateType(eventType) {
|
|
File without changes
|
package/dist/commands/reject.js
CHANGED
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { memoryExists } from '../core/io.js';
|
|
2
|
-
import { memoryPath, writeFileAtomic } from '../core/io.js';
|
|
2
|
+
import { memoryPath, withStoreLock, writeFileAtomic } from '../core/io.js';
|
|
3
3
|
import { loadClaim, listClaims, releaseClaim } from '../core/claims.js';
|
|
4
4
|
import { generateMarkdown } from '../core/markdown.js';
|
|
5
5
|
import { loadState, saveState } from '../core/state.js';
|
|
@@ -9,27 +9,30 @@ export function runReleaseClaim(id, options = {}) {
|
|
|
9
9
|
process.exit(1);
|
|
10
10
|
}
|
|
11
11
|
try {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
|
|
12
|
+
let claim = loadClaim(id, options.cwd);
|
|
13
|
+
withStoreLock(options.cwd, () => {
|
|
14
|
+
const existing = loadClaim(id, options.cwd);
|
|
15
|
+
claim = releaseClaim(id, options.cwd);
|
|
16
|
+
let state = loadState(options.cwd);
|
|
17
|
+
if (existing.plan_id) {
|
|
18
|
+
const plan = state.plan_items.find((item) => item.id === existing.plan_id);
|
|
19
|
+
if (plan) {
|
|
20
|
+
const otherActiveClaims = listClaims(options.cwd).filter((item) => item.status === 'active' && item.plan_id === existing.plan_id);
|
|
21
|
+
if (options.planStatus) {
|
|
22
|
+
plan.status = options.planStatus;
|
|
23
|
+
}
|
|
24
|
+
else if (otherActiveClaims.length === 0 && plan.status === 'in_progress') {
|
|
25
|
+
plan.status = 'todo';
|
|
26
|
+
}
|
|
27
|
+
if (otherActiveClaims.length === 0 && plan.assignee === existing.agent) {
|
|
28
|
+
plan.assignee = undefined;
|
|
29
|
+
}
|
|
30
|
+
plan.updated_at = new Date().toISOString();
|
|
31
|
+
saveState(state, options.cwd);
|
|
21
32
|
}
|
|
22
|
-
else if (otherActiveClaims.length === 0 && plan.status === 'in_progress') {
|
|
23
|
-
plan.status = 'todo';
|
|
24
|
-
}
|
|
25
|
-
if (otherActiveClaims.length === 0 && plan.assignee === existing.agent) {
|
|
26
|
-
plan.assignee = undefined;
|
|
27
|
-
}
|
|
28
|
-
plan.updated_at = new Date().toISOString();
|
|
29
|
-
saveState(state, options.cwd);
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
writeFileAtomic(memoryPath('project.md', options.cwd), generateMarkdown(state, options.cwd));
|
|
35
|
+
});
|
|
33
36
|
console.log(`✔ Claim [${id}] released (was: ${claim.agent} → ${claim.scope})`);
|
|
34
37
|
}
|
|
35
38
|
catch (e) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { memoryExists, memoryPath, writeFileAtomic } from '../core/io.js';
|
|
2
|
+
import { memoryExists, memoryPath, withStoreLock, writeFileAtomic } from '../core/io.js';
|
|
3
3
|
import { listClaims, releaseClaim } from '../core/claims.js';
|
|
4
4
|
import { generateMarkdown } from '../core/markdown.js';
|
|
5
5
|
import { loadState, saveState } from '../core/state.js';
|
|
@@ -35,31 +35,32 @@ export function runReleaseClaims(options = {}) {
|
|
|
35
35
|
const toRelease = claims.filter((c) => changedFiles.some((f) => scopeMatchesFile(c.scope, f)));
|
|
36
36
|
if (toRelease.length === 0)
|
|
37
37
|
process.exit(0);
|
|
38
|
-
let state = loadState(options.cwd);
|
|
39
38
|
let released = 0;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
plan.status
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
withStoreLock(options.cwd, () => {
|
|
40
|
+
let state = loadState(options.cwd);
|
|
41
|
+
for (const claim of toRelease) {
|
|
42
|
+
try {
|
|
43
|
+
releaseClaim(claim.id, options.cwd);
|
|
44
|
+
released++;
|
|
45
|
+
if (claim.plan_id) {
|
|
46
|
+
state = loadState(options.cwd);
|
|
47
|
+
const plan = state.plan_items.find((p) => p.id === claim.plan_id);
|
|
48
|
+
if (plan) {
|
|
49
|
+
const remaining = listClaims(options.cwd).filter((c) => c.status === 'active' && c.plan_id === claim.plan_id);
|
|
50
|
+
if (remaining.length === 0 && plan.status === 'in_progress') {
|
|
51
|
+
plan.status = 'todo';
|
|
52
|
+
plan.updated_at = new Date().toISOString();
|
|
53
|
+
saveState(state, options.cwd);
|
|
54
|
+
}
|
|
54
55
|
}
|
|
55
56
|
}
|
|
57
|
+
console.log(`✔ Auto-released claim [${claim.id}]: ${claim.scope}`);
|
|
56
58
|
}
|
|
57
|
-
|
|
59
|
+
catch { /* skip individual failures */ }
|
|
58
60
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
writeFileAtomic(memoryPath('project.md', options.cwd), generateMarkdown(state, options.cwd));
|
|
61
|
+
state = loadState(options.cwd);
|
|
62
|
+
writeFileAtomic(memoryPath('project.md', options.cwd), generateMarkdown(state, options.cwd));
|
|
63
|
+
});
|
|
63
64
|
if (released > 0) {
|
|
64
65
|
console.log(`brainclaw: ${released} claim(s) auto-released after merge.`);
|
|
65
66
|
}
|
package/dist/commands/review.js
CHANGED
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memoryExists } from '../core/io.js';
|
|
2
2
|
import { readAuditLog } from '../core/audit.js';
|
|
3
|
-
import { loadState,
|
|
3
|
+
import { loadState, persistState } from '../core/state.js';
|
|
4
4
|
import { loadCandidate, saveCandidate } from '../core/candidates.js';
|
|
5
5
|
import { appendAuditEntry } from '../core/audit.js';
|
|
6
6
|
import { buildOperationalIdentity } from '../core/identity.js';
|
|
@@ -128,7 +128,7 @@ function applyRollback(entry, actorName, options) {
|
|
|
128
128
|
state.known_traps.push(before);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
persistState(state);
|
|
132
132
|
}
|
|
133
133
|
else {
|
|
134
134
|
return { ok: false, message: `Rollback not supported for item_type '${item_type}'.` };
|
|
File without changes
|
|
File without changes
|
package/dist/commands/search.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/commands/setup.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/commands/status.js
CHANGED
|
File without changes
|
package/dist/commands/sync.js
CHANGED
|
File without changes
|
package/dist/commands/tool.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { loadState,
|
|
1
|
+
import { loadState, persistState } from '../core/state.js';
|
|
2
2
|
import { resolveCurrentAgentName } from '../core/agent-registry.js';
|
|
3
|
-
import { memoryExists
|
|
4
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
3
|
+
import { memoryExists } from '../core/io.js';
|
|
5
4
|
import { generateIdWithLabel, nowISO } from '../core/ids.js';
|
|
6
5
|
import { loadConfig } from '../core/config.js';
|
|
7
6
|
import { scanText } from '../core/security.js';
|
|
@@ -89,8 +88,7 @@ function runToolAdd(name, description, options, cwd) {
|
|
|
89
88
|
// For now, store as decision to avoid schema migration
|
|
90
89
|
// Will migrate to separate tool storage in v0.16
|
|
91
90
|
state.recent_decisions.push(entry);
|
|
92
|
-
|
|
93
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state));
|
|
91
|
+
persistState(state, cwd);
|
|
94
92
|
console.log(`✔ Tool added: [${id}] ${name}`);
|
|
95
93
|
console.log(' (Stored in decisions for now; will move to dedicated registry in v0.16)');
|
|
96
94
|
}
|
package/dist/commands/trap.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { loadState,
|
|
1
|
+
import { loadState, persistState } from '../core/state.js';
|
|
2
2
|
import { resolveCurrentAgentName } from '../core/agent-registry.js';
|
|
3
3
|
import { resolveCurrentHostId } from '../core/host.js';
|
|
4
4
|
import { loadConfig } from '../core/config.js';
|
|
5
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
6
5
|
import { nowISO } from '../core/ids.js';
|
|
7
6
|
import { scanText } from '../core/security.js';
|
|
8
|
-
import { memoryExists
|
|
7
|
+
import { memoryExists } from '../core/io.js';
|
|
9
8
|
import { generateTrapIdWithLabel, saveOperationalTrap } from '../core/traps.js';
|
|
10
9
|
import { validateCliInput, validateCliTtl } from '../core/input-validation.js';
|
|
11
10
|
import { resolveTargetStore } from '../core/store-resolution.js';
|
|
@@ -49,8 +48,7 @@ export function runTrap(text, options = {}) {
|
|
|
49
48
|
};
|
|
50
49
|
if (visibility === 'shared') {
|
|
51
50
|
state.known_traps.push(entry);
|
|
52
|
-
|
|
53
|
-
writeFileAtomic(memoryPath('project.md', cwd), generateMarkdown(state, cwd));
|
|
51
|
+
persistState(state, cwd);
|
|
54
52
|
}
|
|
55
53
|
else {
|
|
56
54
|
saveOperationalTrap(entry, cwd);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { loadState,
|
|
2
|
-
import { memoryExists
|
|
3
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
1
|
+
import { loadState, persistState } from '../core/state.js';
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
4
3
|
export function runUpdateHandoff(id, options = {}) {
|
|
5
4
|
if (!memoryExists()) {
|
|
6
5
|
console.error('Error: .brainclaw/ not found. Run `brainclaw init` first.');
|
|
@@ -16,8 +15,7 @@ export function runUpdateHandoff(id, options = {}) {
|
|
|
16
15
|
handoff.status = options.status;
|
|
17
16
|
if (options.to !== undefined)
|
|
18
17
|
handoff.to = options.to;
|
|
19
|
-
|
|
20
|
-
writeFileAtomic(memoryPath('project.md'), generateMarkdown(state));
|
|
18
|
+
persistState(state);
|
|
21
19
|
console.log(`✔ Handoff updated: [${handoff.id}] ${handoff.from} → ${handoff.to} (${handoff.status})`);
|
|
22
20
|
}
|
|
23
21
|
//# sourceMappingURL=update-handoff.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { loadState,
|
|
2
|
-
import { memoryExists
|
|
3
|
-
import { generateMarkdown } from '../core/markdown.js';
|
|
1
|
+
import { loadState, persistState } from '../core/state.js';
|
|
2
|
+
import { memoryExists } from '../core/io.js';
|
|
4
3
|
import { nowISO } from '../core/ids.js';
|
|
5
4
|
export function runUpdatePlan(id, options = {}) {
|
|
6
5
|
if (!memoryExists(options.cwd)) {
|
|
@@ -30,8 +29,7 @@ export function runUpdatePlan(id, options = {}) {
|
|
|
30
29
|
if (options.actualEffort)
|
|
31
30
|
plan.actual_effort = options.actualEffort;
|
|
32
31
|
plan.updated_at = timestamp;
|
|
33
|
-
|
|
34
|
-
writeFileAtomic(memoryPath('project.md', options.cwd), generateMarkdown(state, options.cwd));
|
|
32
|
+
persistState(state, options.cwd);
|
|
35
33
|
console.log(`✔ Plan item updated: [${plan.id}] ${plan.text}`);
|
|
36
34
|
}
|
|
37
35
|
//# sourceMappingURL=update-plan.js.map
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { ensureMemoryDir, memoryDir, memoryExists } from '../core/io.js';
|
|
4
|
-
import { loadState,
|
|
4
|
+
import { loadState, persistState } from '../core/state.js';
|
|
5
5
|
import { scanMigrationStatus } from '../core/migration.js';
|
|
6
6
|
import { commitMemoryChange, initMemoryRepo } from '../core/memory-git.js';
|
|
7
7
|
import { BRAINCLAW_SECTION_END, BRAINCLAW_SECTION_START, buildBrainclawSection, buildClaudeCodeCommandText, ensureClaudeCodeCommand, hasBrainclawSection, } from '../core/agent-files.js';
|
|
@@ -114,7 +114,7 @@ export function runUpgrade(options = {}) {
|
|
|
114
114
|
// Execute schema migrations by re-saving state (loadState auto-migrates via Zod parse)
|
|
115
115
|
if (outdated.length > 0) {
|
|
116
116
|
const state = loadState(cwd);
|
|
117
|
-
|
|
117
|
+
persistState(state, cwd);
|
|
118
118
|
}
|
|
119
119
|
const refreshedAgentFiles = refreshManagedWorkspaceAgentFiles(cwd);
|
|
120
120
|
// Clean up empty legacy directories (recursively removes empty subdirs first)
|
|
File without changes
|
package/dist/commands/version.js
CHANGED
|
File without changes
|
package/dist/commands/watch.js
CHANGED
|
File without changes
|
package/dist/commands/whoami.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/core/agent-files.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/core/audit.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { memoryDir } from './io.js';
|
|
3
|
+
import { memoryDir, withStoreLock } from './io.js';
|
|
4
4
|
import { nowISO } from './ids.js';
|
|
5
5
|
import { logger } from './logger.js';
|
|
6
6
|
import { appendEvent } from './event-log.js';
|
|
@@ -23,31 +23,31 @@ function auditLogPath(cwd) {
|
|
|
23
23
|
}
|
|
24
24
|
export function appendAuditEntry(entry, cwd) {
|
|
25
25
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
item_type: entry.item_type,
|
|
32
|
-
before: entry.before,
|
|
33
|
-
after: entry.after,
|
|
34
|
-
actor_id: entry.actor_id,
|
|
35
|
-
reason: entry.reason,
|
|
36
|
-
};
|
|
37
|
-
// Remove undefined fields for compactness
|
|
38
|
-
const line = JSON.stringify(Object.fromEntries(Object.entries(full).filter(([, v]) => v !== undefined)));
|
|
39
|
-
fs.appendFileSync(auditLogPath(cwd), line + '\n', 'utf-8');
|
|
40
|
-
// Mirror to structured event log
|
|
41
|
-
const eventAction = AUDIT_TO_EVENT_ACTION[entry.action];
|
|
42
|
-
if (eventAction) {
|
|
43
|
-
appendEvent({
|
|
44
|
-
action: eventAction,
|
|
45
|
-
item_type: entry.item_type ?? 'state',
|
|
26
|
+
withStoreLock(cwd, () => {
|
|
27
|
+
const full = {
|
|
28
|
+
timestamp: nowISO(),
|
|
29
|
+
actor: entry.actor,
|
|
30
|
+
action: entry.action,
|
|
46
31
|
item_id: entry.item_id,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
32
|
+
item_type: entry.item_type,
|
|
33
|
+
before: entry.before,
|
|
34
|
+
after: entry.after,
|
|
35
|
+
actor_id: entry.actor_id,
|
|
36
|
+
reason: entry.reason,
|
|
37
|
+
};
|
|
38
|
+
const line = JSON.stringify(Object.fromEntries(Object.entries(full).filter(([, v]) => v !== undefined)));
|
|
39
|
+
fs.appendFileSync(auditLogPath(cwd), line + '\n', 'utf-8');
|
|
40
|
+
const eventAction = AUDIT_TO_EVENT_ACTION[entry.action];
|
|
41
|
+
if (eventAction) {
|
|
42
|
+
appendEvent({
|
|
43
|
+
action: eventAction,
|
|
44
|
+
item_type: entry.item_type ?? 'state',
|
|
45
|
+
item_id: entry.item_id,
|
|
46
|
+
agent: entry.actor,
|
|
47
|
+
agent_id: entry.actor_id,
|
|
48
|
+
}, cwd);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
51
|
}
|
|
52
52
|
catch (err) {
|
|
53
53
|
logger.debug('Failed to write audit log entry:', err);
|
package/dist/core/bootstrap.js
CHANGED
|
File without changes
|