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
|
File without changes
|
package/dist/core/candidates.js
CHANGED
|
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { CandidateSchema } from './schema.js';
|
|
5
|
-
import { resolveEntityDir } from './io.js';
|
|
5
|
+
import { resolveEntityDir, withStoreLock } from './io.js';
|
|
6
6
|
import { nowISO, getNextShortLabel } from './ids.js';
|
|
7
7
|
import { JsonStore } from './json-store.js';
|
|
8
8
|
function inboxDir(cwd, mode = 'read') {
|
|
@@ -35,8 +35,10 @@ function candidateStore(dest = 'pending', cwd) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
export function saveCandidate(candidate, cwd) {
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
withStoreLock(cwd, () => {
|
|
39
|
+
ensureInboxDirs(cwd);
|
|
40
|
+
candidateStore('pending', cwd).save(CandidateSchema.parse(candidate));
|
|
41
|
+
});
|
|
40
42
|
}
|
|
41
43
|
export function loadCandidate(id, cwd) {
|
|
42
44
|
return candidateStore('pending', cwd).load(id);
|
|
@@ -49,9 +51,11 @@ export function listCandidates(status, cwd) {
|
|
|
49
51
|
return status ? candidates.filter((candidate) => candidate.status === status) : candidates;
|
|
50
52
|
}
|
|
51
53
|
export function archiveCandidate(candidate, dest, cwd) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
withStoreLock(cwd, () => {
|
|
55
|
+
ensureInboxDirs(cwd);
|
|
56
|
+
candidateStore(dest, cwd).save(CandidateSchema.parse(candidate));
|
|
57
|
+
candidateStore('pending', cwd).delete(candidate.id);
|
|
58
|
+
});
|
|
55
59
|
}
|
|
56
60
|
export function listArchivedCandidates(dest, cwd) {
|
|
57
61
|
return candidateStore(dest, cwd).list();
|
|
File without changes
|
package/dist/core/claims.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import { ClaimSchema } from './schema.js';
|
|
4
|
-
import { resolveEntityDir } from './io.js';
|
|
4
|
+
import { resolveEntityDir, withStoreLock } from './io.js';
|
|
5
5
|
import { nowISO } from './ids.js';
|
|
6
6
|
import { JsonStore } from './json-store.js';
|
|
7
7
|
function claimsDir(cwd, mode = 'read') {
|
|
@@ -22,14 +22,16 @@ function claimStore(cwd) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
export function saveClaim(claim, cwd) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
withStoreLock(cwd, () => {
|
|
26
|
+
ensureClaimsDir(cwd);
|
|
27
|
+
const writeStore = new JsonStore({
|
|
28
|
+
dirPath: claimsDir(cwd, 'write'),
|
|
29
|
+
documentType: 'claim',
|
|
30
|
+
getId: (c) => c.id,
|
|
31
|
+
sort: (a, b) => a.created_at.localeCompare(b.created_at),
|
|
32
|
+
});
|
|
33
|
+
writeStore.save(ClaimSchema.parse(claim));
|
|
31
34
|
});
|
|
32
|
-
writeStore.save(ClaimSchema.parse(claim));
|
|
33
35
|
}
|
|
34
36
|
export function loadClaim(id, cwd) {
|
|
35
37
|
return claimStore(cwd).load(id);
|
package/dist/core/config.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/core/context.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -5,7 +5,7 @@ import { listClaims } from './claims.js';
|
|
|
5
5
|
import { inferProjectFromTarget, loadInstructions, resolveInstructions } from './instructions.js';
|
|
6
6
|
import { buildReputationSummary, findAgentReputationSummary } from './reputation.js';
|
|
7
7
|
import { listRuntimeNotes } from './runtime.js';
|
|
8
|
-
import { loadState,
|
|
8
|
+
import { loadState, persistState } from './state.js';
|
|
9
9
|
export function buildCoordinationSnapshot(options = {}) {
|
|
10
10
|
const config = loadConfig(options.cwd);
|
|
11
11
|
const state = loadState(options.cwd);
|
|
@@ -58,7 +58,7 @@ export function buildCoordinationSnapshot(options = {}) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
if (changed)
|
|
61
|
-
|
|
61
|
+
persistState(state, options.cwd);
|
|
62
62
|
}
|
|
63
63
|
return {
|
|
64
64
|
project_id: config.project_id,
|
|
File without changes
|
package/dist/core/duplicates.js
CHANGED
|
File without changes
|
package/dist/core/event-log.js
CHANGED
|
File without changes
|
package/dist/core/events.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/core/freshness.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/core/host.js
CHANGED
|
File without changes
|
package/dist/core/identity.js
CHANGED
|
File without changes
|
package/dist/core/ids.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { resolveEntityDir } from './io.js';
|
|
2
|
+
import { resolveEntityDir, withStoreLock } from './io.js';
|
|
3
3
|
import { generateId } from './ids.js';
|
|
4
4
|
import { InstructionEntrySchema } from './schema.js';
|
|
5
5
|
import { JsonStore } from './json-store.js';
|
|
@@ -19,7 +19,9 @@ export function loadInstructions(cwd) {
|
|
|
19
19
|
return instructionStore(cwd).list();
|
|
20
20
|
}
|
|
21
21
|
export function saveInstruction(entry, cwd) {
|
|
22
|
-
|
|
22
|
+
withStoreLock(cwd, () => {
|
|
23
|
+
instructionStore(cwd, 'write').save(InstructionEntrySchema.parse(entry));
|
|
24
|
+
});
|
|
23
25
|
}
|
|
24
26
|
export function createInstruction(text, options, cwd) {
|
|
25
27
|
const entries = loadInstructions(cwd);
|
package/dist/core/io.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { withLock, cleanStaleLocks } from './lock.js';
|
|
4
4
|
export const MEMORY_DIR = '.brainclaw';
|
|
5
|
+
const STORE_LOCK_BASENAME = '.store-mutation';
|
|
5
6
|
const RETRYABLE_RENAME_ERROR_CODES = new Set(['EPERM', 'EBUSY', 'EACCES']);
|
|
6
7
|
const DEFAULT_RENAME_RETRY_ATTEMPTS = 6;
|
|
7
8
|
const DEFAULT_RENAME_RETRY_DELAY_MS = 25;
|
|
@@ -72,6 +73,9 @@ export function memoryDir(cwd = process.cwd(), preferredDirName) {
|
|
|
72
73
|
export function memoryPath(filename, cwd, preferredDirName) {
|
|
73
74
|
return path.join(memoryDir(cwd, preferredDirName), filename);
|
|
74
75
|
}
|
|
76
|
+
export function storeLockPath(cwd, preferredDirName) {
|
|
77
|
+
return memoryPath(STORE_LOCK_BASENAME, cwd, preferredDirName);
|
|
78
|
+
}
|
|
75
79
|
export function memoryExists(cwd, preferredDirName) {
|
|
76
80
|
return fs.existsSync(memoryDir(cwd, preferredDirName));
|
|
77
81
|
}
|
|
@@ -95,6 +99,10 @@ export function ensureMemoryDir(cwd, preferredDirName) {
|
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
}
|
|
102
|
+
export function withStoreLock(cwd = process.cwd(), fn, preferredDirName) {
|
|
103
|
+
ensureMemoryDir(cwd, preferredDirName);
|
|
104
|
+
return withLock(storeLockPath(cwd, preferredDirName), fn);
|
|
105
|
+
}
|
|
98
106
|
/** Check if a path is a file, or a directory with at least one entry. */
|
|
99
107
|
function hasContent(p) {
|
|
100
108
|
try {
|
package/dist/core/json-store.js
CHANGED
|
File without changes
|
package/dist/core/lifecycle.js
CHANGED
|
File without changes
|
package/dist/core/lock.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 2000;
|
|
4
4
|
const LOCK_RETRY_INTERVAL_MS = 50;
|
|
5
5
|
const LOCK_EXPIRY_MS = 5000;
|
|
6
|
+
const heldLocks = new Map();
|
|
6
7
|
function lockFilePath(targetPath) {
|
|
7
8
|
return targetPath + '.lock';
|
|
8
9
|
}
|
|
@@ -59,22 +60,37 @@ function tryBreakLock(lockPath) {
|
|
|
59
60
|
}
|
|
60
61
|
export function acquireLock(targetPath, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
61
62
|
const lockPath = lockFilePath(targetPath);
|
|
63
|
+
const heldCount = heldLocks.get(lockPath);
|
|
64
|
+
if (heldCount) {
|
|
65
|
+
heldLocks.set(lockPath, heldCount + 1);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
62
68
|
const deadline = Date.now() + timeoutMs;
|
|
63
69
|
const dir = path.dirname(lockPath);
|
|
64
70
|
if (!fs.existsSync(dir)) {
|
|
65
71
|
fs.mkdirSync(dir, { recursive: true });
|
|
66
72
|
}
|
|
67
73
|
while (Date.now() < deadline) {
|
|
68
|
-
if (tryCreateLock(lockPath))
|
|
74
|
+
if (tryCreateLock(lockPath)) {
|
|
75
|
+
heldLocks.set(lockPath, 1);
|
|
69
76
|
return true;
|
|
70
|
-
|
|
77
|
+
}
|
|
78
|
+
if (tryBreakLock(lockPath)) {
|
|
79
|
+
heldLocks.set(lockPath, 1);
|
|
71
80
|
return true;
|
|
81
|
+
}
|
|
72
82
|
syncSleep(Math.min(LOCK_RETRY_INTERVAL_MS, deadline - Date.now()));
|
|
73
83
|
}
|
|
74
84
|
return false;
|
|
75
85
|
}
|
|
76
86
|
export function releaseLock(targetPath) {
|
|
77
87
|
const lockPath = lockFilePath(targetPath);
|
|
88
|
+
const heldCount = heldLocks.get(lockPath);
|
|
89
|
+
if (heldCount && heldCount > 1) {
|
|
90
|
+
heldLocks.set(lockPath, heldCount - 1);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
heldLocks.delete(lockPath);
|
|
78
94
|
try {
|
|
79
95
|
if (fs.existsSync(lockPath)) {
|
|
80
96
|
fs.unlinkSync(lockPath);
|
package/dist/core/logger.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/core/markdown.js
CHANGED
|
File without changes
|
package/dist/core/memory-git.js
CHANGED
|
File without changes
|
package/dist/core/migration.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/core/reputation.js
CHANGED
|
File without changes
|
package/dist/core/runtime.js
CHANGED
|
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { resolveCurrentHostId, sanitizeHostId } from './host.js';
|
|
5
|
-
import { resolveEntityDir } from './io.js';
|
|
5
|
+
import { resolveEntityDir, withStoreLock } from './io.js';
|
|
6
6
|
import { loadVersionedJsonFile, saveVersionedJsonFile } from './migration.js';
|
|
7
7
|
import { RuntimeNoteSchema } from './schema.js';
|
|
8
8
|
import { commitMemoryChange } from './memory-git.js';
|
|
@@ -40,13 +40,15 @@ export function saveRuntimeNote(note, cwd) {
|
|
|
40
40
|
const persistedNote = visibility === 'shared'
|
|
41
41
|
? { ...note, visibility, host_id: hostId }
|
|
42
42
|
: { ...note, visibility, host_id: hostId };
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
withStoreLock(cwd, () => {
|
|
44
|
+
ensureRuntimeDir(note.agent, cwd, visibility, hostId);
|
|
45
|
+
const filepath = visibility === 'shared'
|
|
46
|
+
? path.join(sharedAgentDir(note.agent, cwd, 'write'), `${note.id}.json`)
|
|
47
|
+
: path.join(hostAgentDir(visibility, hostId, note.agent, cwd, 'write'), `${note.id}.json`);
|
|
48
|
+
saveVersionedJsonFile('runtime_note', filepath, RuntimeNoteSchema.parse(persistedNote));
|
|
49
|
+
appendEvent({ action: 'create', item_type: 'runtime_note', item_id: note.id, agent: note.agent, agent_id: note.agent_id }, cwd);
|
|
50
|
+
commitMemoryChange(`runtime note: ${note.note_type ?? 'note'} (${note.agent})`, cwd);
|
|
51
|
+
});
|
|
50
52
|
}
|
|
51
53
|
export function runtimeNotePath(note, cwd) {
|
|
52
54
|
const visibility = note.visibility ?? 'shared';
|
|
@@ -56,12 +58,14 @@ export function runtimeNotePath(note, cwd) {
|
|
|
56
58
|
: path.join(hostAgentDir(visibility, hostId, note.agent, cwd), `${note.id}.json`);
|
|
57
59
|
}
|
|
58
60
|
export function deleteRuntimeNote(note, cwd) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
return withStoreLock(cwd, () => {
|
|
62
|
+
const filepath = runtimeNotePath(note, cwd);
|
|
63
|
+
if (!fs.existsSync(filepath)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
fs.unlinkSync(filepath);
|
|
67
|
+
return true;
|
|
68
|
+
});
|
|
65
69
|
}
|
|
66
70
|
function readAgentNotes(dir, agent) {
|
|
67
71
|
if (!fs.existsSync(dir))
|
package/dist/core/schema.js
CHANGED
|
File without changes
|
package/dist/core/search.js
CHANGED
|
File without changes
|
package/dist/core/security.js
CHANGED
|
File without changes
|
package/dist/core/setup-state.js
CHANGED
|
File without changes
|
package/dist/core/state.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { ConstraintSchema, DecisionSchema, TrapSchema, HandoffSchema, PlanItemSchema } from './schema.js';
|
|
4
|
-
import { ensureMemoryDir, resolveEntityDir } from './io.js';
|
|
4
|
+
import { ensureMemoryDir, memoryPath, resolveEntityDir, withStoreLock, writeFileAtomic } from './io.js';
|
|
5
5
|
import { commitMemoryChange } from './memory-git.js';
|
|
6
6
|
import { appendEvent } from './event-log.js';
|
|
7
7
|
import { loadVersionedJsonFile, saveVersionedJsonFile } from './migration.js';
|
|
8
|
+
import { generateMarkdown } from './markdown.js';
|
|
8
9
|
export function emptyState() {
|
|
9
10
|
return {
|
|
10
11
|
version: 1,
|
|
@@ -69,15 +70,31 @@ function syncDirectory(dirPath, items, documentType) {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
export function saveState(state, cwd) {
|
|
73
|
+
persistState(state, cwd, { writeProjectMarkdown: false });
|
|
74
|
+
}
|
|
75
|
+
function writeStateDirectories(state, cwd) {
|
|
72
76
|
ensureMemoryDir(cwd);
|
|
73
77
|
const effectiveCwd = cwd ?? process.cwd();
|
|
74
|
-
// Write to entity-aligned directories
|
|
75
78
|
syncDirectory(resolveEntityDir('constraints', effectiveCwd, 'write'), state.active_constraints, 'constraint');
|
|
76
79
|
syncDirectory(resolveEntityDir('decisions', effectiveCwd, 'write'), state.recent_decisions, 'decision');
|
|
77
80
|
syncDirectory(resolveEntityDir('traps', effectiveCwd, 'write'), state.known_traps, 'trap');
|
|
78
81
|
syncDirectory(resolveEntityDir('handoffs', effectiveCwd, 'write'), state.open_handoffs, 'handoff');
|
|
79
82
|
syncDirectory(resolveEntityDir('plans', effectiveCwd, 'write'), state.plan_items, 'plan');
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
}
|
|
84
|
+
export function persistState(state, cwd, options = {}) {
|
|
85
|
+
const effectiveCwd = cwd ?? process.cwd();
|
|
86
|
+
withStoreLock(effectiveCwd, () => {
|
|
87
|
+
writeStateDirectories(state, effectiveCwd);
|
|
88
|
+
if (options.writeProjectMarkdown ?? true) {
|
|
89
|
+
writeFileAtomic(memoryPath('project.md', effectiveCwd), generateMarkdown(state, effectiveCwd));
|
|
90
|
+
}
|
|
91
|
+
appendEvent({
|
|
92
|
+
action: options.eventAction ?? 'update',
|
|
93
|
+
item_type: 'state',
|
|
94
|
+
agent: 'system',
|
|
95
|
+
summary: options.eventSummary,
|
|
96
|
+
}, effectiveCwd);
|
|
97
|
+
commitMemoryChange(options.commitMessage ?? 'state update', effectiveCwd);
|
|
98
|
+
});
|
|
82
99
|
}
|
|
83
100
|
//# sourceMappingURL=state.js.map
|
|
File without changes
|
package/dist/core/sync-remote.js
CHANGED
|
File without changes
|
package/dist/core/traps.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# OpenClaw Adapter Guide
|
|
2
|
+
|
|
3
|
+
This adapter helps convert OpenClaw runtime traces into brainclaw candidates.
|
|
4
|
+
|
|
5
|
+
## Supported Inputs
|
|
6
|
+
|
|
7
|
+
- Runtime event file: JSON array of events.
|
|
8
|
+
- Runtime session import: events filtered by `metadata.session` from `.brainclaw/runtime/`.
|
|
9
|
+
|
|
10
|
+
## Basic Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
brainclaw adapter-openclaw-import ./openclaw-events.json
|
|
14
|
+
brainclaw adapter-openclaw-import --session sess_42
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Dry-Run Workflow
|
|
18
|
+
|
|
19
|
+
Use `--dry-run` to preview what would be ingested without writing any files:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
brainclaw adapter-openclaw-import ./openclaw-events.json --dry-run
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Dry-run is useful for CI checks and for validating mapping quality before modifying `.brainclaw/inbox/`.
|
|
26
|
+
|
|
27
|
+
## Event Mapping
|
|
28
|
+
|
|
29
|
+
Current mapping converts events into reflective candidate types:
|
|
30
|
+
|
|
31
|
+
- `risk_detected` -> `trap`
|
|
32
|
+
- `handoff_requested` -> `handoff`
|
|
33
|
+
- `observation` -> `decision`
|
|
34
|
+
- `constraint_detected` -> `constraint`
|
|
35
|
+
|
|
36
|
+
If an event type is unknown, it defaults to `decision`.
|
|
37
|
+
|
|
38
|
+
## Recommended Team Flow
|
|
39
|
+
|
|
40
|
+
1. Import events from file or session.
|
|
41
|
+
2. Run `brainclaw review --prioritized`.
|
|
42
|
+
3. Curators process with `brainclaw accept` or `brainclaw reject`.
|
|
43
|
+
4. Use `brainclaw doctor` or `brainclaw doctor --json` to monitor quality.
|