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,580 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// --- Helpers ---
|
|
3
|
+
/** Coerce legacy effort strings ("30min", "2h", "1d") to integer minutes for migration.
|
|
4
|
+
* Already-numeric values pass through unchanged. Unparseable strings → undefined. */
|
|
5
|
+
function coerceEffortToMinutes(val) {
|
|
6
|
+
if (typeof val === 'number')
|
|
7
|
+
return val;
|
|
8
|
+
if (typeof val === 'string') {
|
|
9
|
+
const s = val.trim().toLowerCase();
|
|
10
|
+
let total = 0, matched = false;
|
|
11
|
+
const d = s.match(/(\d+(?:\.\d+)?)\s*d/);
|
|
12
|
+
if (d) {
|
|
13
|
+
total += parseFloat(d[1]) * 8 * 60;
|
|
14
|
+
matched = true;
|
|
15
|
+
}
|
|
16
|
+
const h = s.match(/(\d+(?:\.\d+)?)\s*h/);
|
|
17
|
+
if (h) {
|
|
18
|
+
total += parseFloat(h[1]) * 60;
|
|
19
|
+
matched = true;
|
|
20
|
+
}
|
|
21
|
+
const m = s.match(/(\d+(?:\.\d+)?)\s*m(?:in)?/);
|
|
22
|
+
if (m) {
|
|
23
|
+
total += parseFloat(m[1]);
|
|
24
|
+
matched = true;
|
|
25
|
+
}
|
|
26
|
+
if (!matched) {
|
|
27
|
+
const bare = parseFloat(s);
|
|
28
|
+
if (!isNaN(bare) && bare > 0 && /^\d+(\.\d+)?$/.test(s))
|
|
29
|
+
return Math.round(bare);
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return total > 0 ? Math.round(total) : undefined;
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
// --- Entry schemas ---
|
|
37
|
+
export const ConstraintStatusSchema = z.enum(['active', 'resolved', 'expired']);
|
|
38
|
+
export const ConstraintCategorySchema = z.enum(['architecture', 'performance', 'security', 'reliability', 'compatibility', 'process', 'other']);
|
|
39
|
+
export const SeveritySchema = z.enum(['low', 'medium', 'high']);
|
|
40
|
+
export const TrapStatusSchema = z.enum(['active', 'resolved', 'expired']);
|
|
41
|
+
export const PrioritySchema = z.enum(['low', 'medium', 'high']);
|
|
42
|
+
export const MemoryVisibilitySchema = z.enum(['shared', 'machine', 'private']);
|
|
43
|
+
export const HandoffStatusSchema = z.enum(['open', 'accepted', 'closed']);
|
|
44
|
+
export const DecisionOutcomeSchema = z.enum(['approved', 'rejected', 'deferred', 'pending']);
|
|
45
|
+
export const ConstraintSchema = z.object({
|
|
46
|
+
schema_version: z.number().int().positive().optional(),
|
|
47
|
+
id: z.string(),
|
|
48
|
+
short_label: z.string().optional(),
|
|
49
|
+
text: z.string(),
|
|
50
|
+
created_at: z.string(),
|
|
51
|
+
author: z.string(),
|
|
52
|
+
author_id: z.string().optional(),
|
|
53
|
+
model: z.string().optional(),
|
|
54
|
+
project_id: z.string().optional(),
|
|
55
|
+
host_id: z.string().optional(),
|
|
56
|
+
session_id: z.string().optional(),
|
|
57
|
+
status: ConstraintStatusSchema,
|
|
58
|
+
category: ConstraintCategorySchema.optional(),
|
|
59
|
+
tags: z.array(z.string()),
|
|
60
|
+
related_paths: z.array(z.string()).optional(),
|
|
61
|
+
expires_at: z.string().optional(),
|
|
62
|
+
});
|
|
63
|
+
export const DecisionSchema = z.object({
|
|
64
|
+
schema_version: z.number().int().positive().optional(),
|
|
65
|
+
id: z.string(),
|
|
66
|
+
short_label: z.string().optional(),
|
|
67
|
+
text: z.string(),
|
|
68
|
+
created_at: z.string(),
|
|
69
|
+
author: z.string(),
|
|
70
|
+
author_id: z.string().optional(),
|
|
71
|
+
model: z.string().optional(),
|
|
72
|
+
project_id: z.string().optional(),
|
|
73
|
+
host_id: z.string().optional(),
|
|
74
|
+
session_id: z.string().optional(),
|
|
75
|
+
outcome: DecisionOutcomeSchema.optional(),
|
|
76
|
+
related_paths: z.array(z.string()).optional(),
|
|
77
|
+
plan_id: z.string().optional(),
|
|
78
|
+
tags: z.array(z.string()),
|
|
79
|
+
});
|
|
80
|
+
export const TrapSchema = z.object({
|
|
81
|
+
schema_version: z.number().int().positive().optional(),
|
|
82
|
+
id: z.string(),
|
|
83
|
+
short_label: z.string().optional(),
|
|
84
|
+
text: z.string(),
|
|
85
|
+
created_at: z.string(),
|
|
86
|
+
author: z.string(),
|
|
87
|
+
author_id: z.string().optional(),
|
|
88
|
+
model: z.string().optional(),
|
|
89
|
+
project_id: z.string().optional(),
|
|
90
|
+
session_id: z.string().optional(),
|
|
91
|
+
status: TrapStatusSchema.default('active'),
|
|
92
|
+
severity: SeveritySchema,
|
|
93
|
+
tags: z.array(z.string()),
|
|
94
|
+
related_paths: z.array(z.string()).optional(),
|
|
95
|
+
plan_id: z.string().optional(),
|
|
96
|
+
visibility: MemoryVisibilitySchema.default('shared'),
|
|
97
|
+
host_id: z.string().optional(),
|
|
98
|
+
expires_at: z.string().optional(),
|
|
99
|
+
});
|
|
100
|
+
export const HandoffSchema = z.object({
|
|
101
|
+
schema_version: z.number().int().positive().optional(),
|
|
102
|
+
id: z.string(),
|
|
103
|
+
short_label: z.string().optional(),
|
|
104
|
+
from: z.string(),
|
|
105
|
+
to: z.string(),
|
|
106
|
+
text: z.string(),
|
|
107
|
+
created_at: z.string(),
|
|
108
|
+
author: z.string(),
|
|
109
|
+
author_id: z.string().optional(),
|
|
110
|
+
model: z.string().optional(),
|
|
111
|
+
project_id: z.string().optional(),
|
|
112
|
+
host_id: z.string().optional(),
|
|
113
|
+
session_id: z.string().optional(),
|
|
114
|
+
status: HandoffStatusSchema,
|
|
115
|
+
project: z.string().optional(),
|
|
116
|
+
plan_id: z.string().optional(),
|
|
117
|
+
tags: z.array(z.string()),
|
|
118
|
+
related_paths: z.array(z.string()).optional(),
|
|
119
|
+
snapshot: z.object({
|
|
120
|
+
diff: z.string().optional(),
|
|
121
|
+
}).optional(),
|
|
122
|
+
});
|
|
123
|
+
export const PlanStatusSchema = z.enum(['todo', 'in_progress', 'blocked', 'done', 'dropped']);
|
|
124
|
+
export const PlanStepSchema = z.object({
|
|
125
|
+
id: z.string(),
|
|
126
|
+
text: z.string(),
|
|
127
|
+
status: z.enum(['todo', 'done']),
|
|
128
|
+
assignee: z.string().optional(),
|
|
129
|
+
created_at: z.string(),
|
|
130
|
+
updated_at: z.string(),
|
|
131
|
+
});
|
|
132
|
+
export const PlanTypeSchema = z.enum(['feat', 'fix', 'chore', 'spike', 'doc']).default('feat');
|
|
133
|
+
export const PlanItemSchema = z.object({
|
|
134
|
+
schema_version: z.number().int().positive().optional(),
|
|
135
|
+
id: z.string(),
|
|
136
|
+
short_label: z.string().optional(),
|
|
137
|
+
text: z.string(),
|
|
138
|
+
type: PlanTypeSchema.optional(),
|
|
139
|
+
created_at: z.string(),
|
|
140
|
+
updated_at: z.string(),
|
|
141
|
+
author: z.string(),
|
|
142
|
+
model: z.string().optional(),
|
|
143
|
+
status: PlanStatusSchema,
|
|
144
|
+
priority: PrioritySchema,
|
|
145
|
+
assignee: z.string().optional(),
|
|
146
|
+
project: z.string().optional(),
|
|
147
|
+
tags: z.array(z.string()),
|
|
148
|
+
related_paths: z.array(z.string()).optional(),
|
|
149
|
+
depends_on: z.array(z.string()).default([]),
|
|
150
|
+
steps: z.array(PlanStepSchema).optional(),
|
|
151
|
+
estimated_effort: z.preprocess(coerceEffortToMinutes, z.number().int().positive().optional()),
|
|
152
|
+
actual_effort: z.string().optional(),
|
|
153
|
+
started_at: z.string().optional(),
|
|
154
|
+
completed_at: z.string().optional(),
|
|
155
|
+
});
|
|
156
|
+
export const InstructionLayerSchema = z.enum(['global', 'project', 'agent']);
|
|
157
|
+
export const InstructionEntrySchema = z.object({
|
|
158
|
+
schema_version: z.number().int().positive().optional(),
|
|
159
|
+
id: z.string(),
|
|
160
|
+
layer: InstructionLayerSchema,
|
|
161
|
+
scope: z.string().optional(),
|
|
162
|
+
text: z.string(),
|
|
163
|
+
created_at: z.string(),
|
|
164
|
+
updated_at: z.string(),
|
|
165
|
+
author: z.string(),
|
|
166
|
+
tags: z.array(z.string()).default([]),
|
|
167
|
+
active: z.boolean().default(true),
|
|
168
|
+
supersedes: z.string().optional(),
|
|
169
|
+
});
|
|
170
|
+
export const CapabilityStatusSchema = z.enum(['stable', 'experimental', 'deprecated']);
|
|
171
|
+
export const ProjectCapabilitySchema = z.object({
|
|
172
|
+
schema_version: z.number().int().positive().optional(),
|
|
173
|
+
id: z.string(),
|
|
174
|
+
name: z.string(),
|
|
175
|
+
description: z.string(),
|
|
176
|
+
category: z.string(), // e.g. "auth", "api", "storage", "testing"
|
|
177
|
+
provided_by: z.string().optional(), // path to implementation
|
|
178
|
+
requires: z.array(z.string()).optional(), // capability IDs this depends on
|
|
179
|
+
tags: z.array(z.string()),
|
|
180
|
+
example_usage: z.string().optional(),
|
|
181
|
+
status: CapabilityStatusSchema.default('stable'),
|
|
182
|
+
related_paths: z.array(z.string()).optional(),
|
|
183
|
+
created_at: z.string(),
|
|
184
|
+
author: z.string(),
|
|
185
|
+
author_id: z.string().optional(),
|
|
186
|
+
});
|
|
187
|
+
export const ToolTypeSchema = z.enum(['workflow', 'validator', 'generator', 'utility', 'explorer']);
|
|
188
|
+
export const ProjectToolSchema = z.object({
|
|
189
|
+
schema_version: z.number().int().positive().optional(),
|
|
190
|
+
id: z.string(),
|
|
191
|
+
name: z.string(),
|
|
192
|
+
description: z.string(),
|
|
193
|
+
type: ToolTypeSchema,
|
|
194
|
+
implementation: z.string(), // path or command
|
|
195
|
+
mcp_name: z.string().optional(), // if exposed as MCP tool
|
|
196
|
+
cli_command: z.string().optional(), // if exposed as CLI command
|
|
197
|
+
requires: z.array(z.string()).optional(), // tool IDs this depends on
|
|
198
|
+
suggests_for: z.array(z.string()).optional(), // agent types or domains
|
|
199
|
+
invocation_example: z.string().optional(),
|
|
200
|
+
tags: z.array(z.string()),
|
|
201
|
+
status: CapabilityStatusSchema.default('stable'),
|
|
202
|
+
related_paths: z.array(z.string()).optional(),
|
|
203
|
+
created_at: z.string(),
|
|
204
|
+
author: z.string(),
|
|
205
|
+
author_id: z.string().optional(),
|
|
206
|
+
});
|
|
207
|
+
// --- State schema ---
|
|
208
|
+
export const StateSchema = z.object({
|
|
209
|
+
version: z.literal(1),
|
|
210
|
+
write_version: z.number().default(1),
|
|
211
|
+
active_constraints: z.array(ConstraintSchema),
|
|
212
|
+
recent_decisions: z.array(DecisionSchema),
|
|
213
|
+
known_traps: z.array(TrapSchema),
|
|
214
|
+
open_handoffs: z.array(HandoffSchema),
|
|
215
|
+
plan_items: z.array(PlanItemSchema).default([]),
|
|
216
|
+
});
|
|
217
|
+
// --- Config schema ---
|
|
218
|
+
export const RedactionConfigSchema = z.object({
|
|
219
|
+
enabled: z.boolean(),
|
|
220
|
+
patterns: z.array(z.string()),
|
|
221
|
+
});
|
|
222
|
+
export const SecurityConfigSchema = z.object({
|
|
223
|
+
mode: z.enum(['warn', 'strict']).default('warn'),
|
|
224
|
+
strict_redaction: z.boolean().default(false),
|
|
225
|
+
block_sensitive_paths: z.boolean().default(true),
|
|
226
|
+
});
|
|
227
|
+
export const MarkdownConfigSchema = z.object({
|
|
228
|
+
max_items_per_section: z.number().default(20),
|
|
229
|
+
compact_mode: z.boolean().default(false),
|
|
230
|
+
});
|
|
231
|
+
// --- Reflective memory schemas ---
|
|
232
|
+
export const CandidateTypeSchema = z.enum([
|
|
233
|
+
'constraint', 'decision', 'trap', 'handoff',
|
|
234
|
+
]);
|
|
235
|
+
export const CandidateStatusSchema = z.enum(['pending', 'accepted', 'rejected']);
|
|
236
|
+
export const CandidateUseSchema = z.object({
|
|
237
|
+
by: z.string(),
|
|
238
|
+
context: z.string(),
|
|
239
|
+
created_at: z.string(),
|
|
240
|
+
});
|
|
241
|
+
export const ContradictionSeveritySchema = z.enum(['low', 'medium', 'high']);
|
|
242
|
+
export const CandidateContradictionSchema = z.object({
|
|
243
|
+
item_id: z.string(),
|
|
244
|
+
conflicts_with: z.string(),
|
|
245
|
+
reason: z.string(),
|
|
246
|
+
section: z.string(),
|
|
247
|
+
severity: ContradictionSeveritySchema,
|
|
248
|
+
score: z.number(),
|
|
249
|
+
kind: z.string(),
|
|
250
|
+
});
|
|
251
|
+
export const CandidateSchema = z.object({
|
|
252
|
+
schema_version: z.number().int().positive().optional(),
|
|
253
|
+
id: z.string(),
|
|
254
|
+
short_label: z.string().optional(),
|
|
255
|
+
type: CandidateTypeSchema,
|
|
256
|
+
text: z.string(),
|
|
257
|
+
created_at: z.string(),
|
|
258
|
+
author: z.string(),
|
|
259
|
+
author_id: z.string().optional(),
|
|
260
|
+
project_id: z.string().optional(),
|
|
261
|
+
host_id: z.string().optional(),
|
|
262
|
+
session_id: z.string().optional(),
|
|
263
|
+
source: z.string().optional(),
|
|
264
|
+
tags: z.array(z.string()),
|
|
265
|
+
status: CandidateStatusSchema,
|
|
266
|
+
// type-specific optional fields
|
|
267
|
+
severity: SeveritySchema.optional(),
|
|
268
|
+
from: z.string().optional(),
|
|
269
|
+
to: z.string().optional(),
|
|
270
|
+
related_paths: z.array(z.string()).optional(),
|
|
271
|
+
star_count: z.number().default(0),
|
|
272
|
+
starred_by: z.array(z.string()).default([]),
|
|
273
|
+
last_starred_at: z.string().optional(),
|
|
274
|
+
usage_count: z.number().default(0),
|
|
275
|
+
usage_events: z.array(CandidateUseSchema).default([]),
|
|
276
|
+
last_used_at: z.string().optional(),
|
|
277
|
+
plan_id: z.string().optional(),
|
|
278
|
+
contradictions_detected: z.array(CandidateContradictionSchema).optional(),
|
|
279
|
+
contradiction_summary: z.string().optional(),
|
|
280
|
+
promotion_blocked_reason: z.string().optional(),
|
|
281
|
+
resolved_at: z.string().optional(),
|
|
282
|
+
resolved_by: z.string().optional(),
|
|
283
|
+
resolution_reason: z.string().optional(),
|
|
284
|
+
});
|
|
285
|
+
export const ReflectiveMemoryConfigSchema = z.object({
|
|
286
|
+
enabled: z.boolean().default(true),
|
|
287
|
+
auto_accept: z.boolean().default(false),
|
|
288
|
+
max_pending: z.number().default(50),
|
|
289
|
+
promotion_stars_threshold: z.number().default(3),
|
|
290
|
+
promotion_uses_threshold: z.number().default(2),
|
|
291
|
+
prune_rejected_after_days: z.number().default(30),
|
|
292
|
+
auto_promote_trusted: z.boolean().default(false),
|
|
293
|
+
auto_promote_score_threshold: z.number().default(5),
|
|
294
|
+
circuit_breaker_threshold: z.number().int().positive().default(5),
|
|
295
|
+
circuit_breaker_window_days: z.number().int().positive().default(7),
|
|
296
|
+
});
|
|
297
|
+
export const GovernanceConfigSchema = z.object({
|
|
298
|
+
approval_policy: z.enum(['none', 'review', 'strict']).default('review'),
|
|
299
|
+
curators: z.array(z.string()).default([]),
|
|
300
|
+
review_sla_hours: z.number().default(24),
|
|
301
|
+
});
|
|
302
|
+
export const ReputationConfigSchema = z.object({
|
|
303
|
+
enabled: z.boolean().default(false),
|
|
304
|
+
visibility: z.enum(['internal-only', 'summary', 'full']).default('internal-only'),
|
|
305
|
+
decay_days: z.number().default(30),
|
|
306
|
+
ranking_weight: z.number().default(0.15),
|
|
307
|
+
resume_weight: z.number().default(0.35),
|
|
308
|
+
mcp_exposure: z.boolean().default(false),
|
|
309
|
+
});
|
|
310
|
+
// --- Work claims schemas ---
|
|
311
|
+
export const ClaimStatusSchema = z.enum(['active', 'released', 'stale']);
|
|
312
|
+
export const ClaimSchema = z.object({
|
|
313
|
+
schema_version: z.number().int().positive().optional(),
|
|
314
|
+
id: z.string(),
|
|
315
|
+
agent: z.string(),
|
|
316
|
+
agent_id: z.string().optional(),
|
|
317
|
+
project_id: z.string().optional(),
|
|
318
|
+
host_id: z.string().optional(),
|
|
319
|
+
session_id: z.string().optional(),
|
|
320
|
+
scope: z.string(),
|
|
321
|
+
description: z.string(),
|
|
322
|
+
created_at: z.string(),
|
|
323
|
+
project: z.string().optional(),
|
|
324
|
+
plan_id: z.string().optional(),
|
|
325
|
+
status: ClaimStatusSchema,
|
|
326
|
+
released_at: z.string().optional(),
|
|
327
|
+
expires_at: z.string().optional(),
|
|
328
|
+
});
|
|
329
|
+
// --- Runtime notes schemas ---
|
|
330
|
+
export const RuntimeNoteSchema = z.object({
|
|
331
|
+
schema_version: z.number().int().positive().optional(),
|
|
332
|
+
id: z.string(),
|
|
333
|
+
agent: z.string(),
|
|
334
|
+
agent_id: z.string().optional(),
|
|
335
|
+
project_id: z.string().optional(),
|
|
336
|
+
session_id: z.string().optional(),
|
|
337
|
+
text: z.string(),
|
|
338
|
+
created_at: z.string(),
|
|
339
|
+
project: z.string().optional(),
|
|
340
|
+
plan_id: z.string().optional(),
|
|
341
|
+
tags: z.array(z.string()),
|
|
342
|
+
visibility: MemoryVisibilitySchema.default('shared'),
|
|
343
|
+
host_id: z.string().optional(),
|
|
344
|
+
expires_at: z.string().optional(),
|
|
345
|
+
note_type: z.enum(['observation', 'session_start', 'session_end']).default('observation'),
|
|
346
|
+
});
|
|
347
|
+
// --- Runtime event schemas ---
|
|
348
|
+
export const RuntimeEventTypeSchema = z.enum([
|
|
349
|
+
'task_started',
|
|
350
|
+
'observation',
|
|
351
|
+
'risk_detected',
|
|
352
|
+
'handoff_requested',
|
|
353
|
+
'task_finished',
|
|
354
|
+
'session_start',
|
|
355
|
+
'session_end',
|
|
356
|
+
]);
|
|
357
|
+
export const RuntimeEventSchema = z.object({
|
|
358
|
+
id: z.string(),
|
|
359
|
+
agent: z.string(),
|
|
360
|
+
agent_id: z.string().optional(),
|
|
361
|
+
project_id: z.string().optional(),
|
|
362
|
+
host_id: z.string().optional(),
|
|
363
|
+
session_id: z.string().optional(),
|
|
364
|
+
event_type: RuntimeEventTypeSchema,
|
|
365
|
+
created_at: z.string(),
|
|
366
|
+
text: z.string(),
|
|
367
|
+
tags: z.array(z.string()).default([]),
|
|
368
|
+
// Optional routing and type hints for candidate generation
|
|
369
|
+
candidate_type: CandidateTypeSchema.optional(),
|
|
370
|
+
severity: SeveritySchema.optional(),
|
|
371
|
+
from: z.string().optional(),
|
|
372
|
+
to: z.string().optional(),
|
|
373
|
+
related_paths: z.array(z.string()).optional(),
|
|
374
|
+
metadata: z.record(z.unknown()).optional(),
|
|
375
|
+
});
|
|
376
|
+
// --- Profile schema ---
|
|
377
|
+
export const ProfileSchema = z.enum(['dev', 'openclaw', 'ops', 'research']);
|
|
378
|
+
export const ProjectModeSchema = z.enum(['single-project', 'multi-project', 'auto']);
|
|
379
|
+
export const ProjectStrategySchema = z.enum(['manual', 'folder']);
|
|
380
|
+
export const TopologyModeSchema = z.enum(['embedded', 'sidecar', 'local-only']);
|
|
381
|
+
export const IgnoreStrategySchema = z.enum(['project-gitignore', 'none']);
|
|
382
|
+
export const AgentKindSchema = z.enum(['agent', 'human', 'unknown']);
|
|
383
|
+
export const AgentTrustLevelSchema = z.enum(['observer', 'contributor', 'trusted', 'curator']);
|
|
384
|
+
export const AgentIdentityKeySchema = z.object({
|
|
385
|
+
algorithm: z.literal('ed25519'),
|
|
386
|
+
public_key: z.string(),
|
|
387
|
+
fingerprint: z.string(),
|
|
388
|
+
created_at: z.string(),
|
|
389
|
+
});
|
|
390
|
+
export const ProjectIdentityDocumentSchema = z.object({
|
|
391
|
+
schema_version: z.number().int().positive().optional(),
|
|
392
|
+
version: z.literal(1),
|
|
393
|
+
project_id: z.string(),
|
|
394
|
+
project_name: z.string(),
|
|
395
|
+
created_at: z.string(),
|
|
396
|
+
storage_dir: z.string(),
|
|
397
|
+
topology: TopologyModeSchema,
|
|
398
|
+
});
|
|
399
|
+
export const AgentIdentityDocumentSchema = z.object({
|
|
400
|
+
schema_version: z.number().int().positive().optional(),
|
|
401
|
+
version: z.literal(1),
|
|
402
|
+
agent_id: z.string(),
|
|
403
|
+
agent_name: z.string(),
|
|
404
|
+
created_at: z.string(),
|
|
405
|
+
kind: AgentKindSchema.default('unknown'),
|
|
406
|
+
trust_level: AgentTrustLevelSchema.default('contributor'),
|
|
407
|
+
capabilities: z.array(z.string()).default([]),
|
|
408
|
+
identity_key: AgentIdentityKeySchema.optional(),
|
|
409
|
+
model: z.string().optional(),
|
|
410
|
+
});
|
|
411
|
+
export const ProjectsConfigSchema = z.object({
|
|
412
|
+
strategy: ProjectStrategySchema.default('manual'),
|
|
413
|
+
known: z.array(z.string()).default([]),
|
|
414
|
+
});
|
|
415
|
+
export const RemoteSyncSchema = z.object({
|
|
416
|
+
url: z.string(),
|
|
417
|
+
provider: z.enum(['github', 'gitlab', 'bitbucket', 'other']).optional(),
|
|
418
|
+
ssh_key_path: z.string().optional(),
|
|
419
|
+
sync_strategy: z.enum(['pull-only', 'push-pull', 'pr-based']).default('push-pull'),
|
|
420
|
+
});
|
|
421
|
+
export const SessionSnapshotSchema = z.object({
|
|
422
|
+
schema_version: z.number().int().positive().optional(),
|
|
423
|
+
session_id: z.string(),
|
|
424
|
+
agent: z.string(),
|
|
425
|
+
agent_id: z.string().optional(),
|
|
426
|
+
model: z.string().optional(),
|
|
427
|
+
started_at: z.string(),
|
|
428
|
+
context_target: z.string().optional(),
|
|
429
|
+
initial_context_hash: z.string().optional(),
|
|
430
|
+
git_sha: z.string().optional(),
|
|
431
|
+
});
|
|
432
|
+
export const CurrentSessionStateSchema = z.object({
|
|
433
|
+
schema_version: z.number().int().positive().optional(),
|
|
434
|
+
session_id: z.string(),
|
|
435
|
+
started_at: z.string(),
|
|
436
|
+
last_seen_at: z.string(),
|
|
437
|
+
agent: z.string(),
|
|
438
|
+
agent_id: z.string(),
|
|
439
|
+
host_id: z.string(),
|
|
440
|
+
});
|
|
441
|
+
export const MemorySeedKindSchema = z.enum([
|
|
442
|
+
'command',
|
|
443
|
+
'convention',
|
|
444
|
+
'entrypoint',
|
|
445
|
+
'hotspot',
|
|
446
|
+
'agent_rule',
|
|
447
|
+
'warning',
|
|
448
|
+
'environment',
|
|
449
|
+
'tooling',
|
|
450
|
+
]);
|
|
451
|
+
export const MemorySeedSourceKindSchema = z.enum([
|
|
452
|
+
'readme',
|
|
453
|
+
'agents_md',
|
|
454
|
+
'manifest',
|
|
455
|
+
'repo_analysis',
|
|
456
|
+
'git',
|
|
457
|
+
'inference',
|
|
458
|
+
'machine',
|
|
459
|
+
'skill',
|
|
460
|
+
'mcp',
|
|
461
|
+
]);
|
|
462
|
+
export const MemorySeedConfidenceSchema = z.enum(['low', 'medium', 'high']);
|
|
463
|
+
export const MemorySeedDocumentSchema = z.object({
|
|
464
|
+
schema_version: z.number().int().positive().optional(),
|
|
465
|
+
id: z.string(),
|
|
466
|
+
derived_at: z.string(),
|
|
467
|
+
text: z.string(),
|
|
468
|
+
seed_kind: MemorySeedKindSchema,
|
|
469
|
+
source_kind: MemorySeedSourceKindSchema,
|
|
470
|
+
source_ref: z.string(),
|
|
471
|
+
confidence: MemorySeedConfidenceSchema,
|
|
472
|
+
related_paths: z.array(z.string()).optional(),
|
|
473
|
+
tags: z.array(z.string()).default([]),
|
|
474
|
+
promotion_hint: z.enum(['constraint', 'decision', 'trap']).optional(),
|
|
475
|
+
});
|
|
476
|
+
export const BootstrapProfileDocumentSchema = z.object({
|
|
477
|
+
schema_version: z.number().int().positive().optional(),
|
|
478
|
+
derived_at: z.string(),
|
|
479
|
+
repo_fingerprint: z.string().optional(),
|
|
480
|
+
summary: z.string(),
|
|
481
|
+
sources_scanned: z.array(z.string()).default([]),
|
|
482
|
+
git_available: z.boolean().default(false),
|
|
483
|
+
agents_md_present: z.boolean().default(false),
|
|
484
|
+
seed_count: z.number().int().nonnegative(),
|
|
485
|
+
target: z.string().optional(),
|
|
486
|
+
});
|
|
487
|
+
export const AgentIntegrationNameSchema = z.enum([
|
|
488
|
+
'github-copilot',
|
|
489
|
+
'claude-code',
|
|
490
|
+
'cursor',
|
|
491
|
+
'windsurf',
|
|
492
|
+
'cline',
|
|
493
|
+
'codex',
|
|
494
|
+
'opencode',
|
|
495
|
+
'antigravity',
|
|
496
|
+
'continue',
|
|
497
|
+
'roo',
|
|
498
|
+
]);
|
|
499
|
+
export const AgentIntegrationSurfaceKindSchema = z.enum(['instructions', 'mcp', 'skill', 'rule', 'hook']);
|
|
500
|
+
export const AgentIntegrationLocationSchema = z.enum(['workspace', 'machine']);
|
|
501
|
+
export const AgentIntegrationDeclarationSourceSchema = z.enum(['manual', 'detected']);
|
|
502
|
+
export const AgentIntegrationSurfaceSchema = z.object({
|
|
503
|
+
kind: AgentIntegrationSurfaceKindSchema,
|
|
504
|
+
location: AgentIntegrationLocationSchema,
|
|
505
|
+
path: z.string().optional(),
|
|
506
|
+
});
|
|
507
|
+
export const AgentIntegrationDeclarationSchema = z.object({
|
|
508
|
+
agent_name: AgentIntegrationNameSchema,
|
|
509
|
+
declaration_source: AgentIntegrationDeclarationSourceSchema.default('manual'),
|
|
510
|
+
surfaces: z.array(AgentIntegrationSurfaceSchema).default([]),
|
|
511
|
+
notes: z.string().optional(),
|
|
512
|
+
});
|
|
513
|
+
export const AgentIntegrationsConfigSchema = z.object({
|
|
514
|
+
declarations: z.array(AgentIntegrationDeclarationSchema).default([]),
|
|
515
|
+
});
|
|
516
|
+
export const CrossProjectLinkSchema = z.object({
|
|
517
|
+
path: z.string(),
|
|
518
|
+
name: z.string().optional(),
|
|
519
|
+
role: z.enum(['subscriber', 'publisher']).default('subscriber'),
|
|
520
|
+
});
|
|
521
|
+
export const BrainclawUpdateSourceLocalPackSchema = z.object({
|
|
522
|
+
type: z.literal('local-pack'),
|
|
523
|
+
manifest_path: z.string(),
|
|
524
|
+
});
|
|
525
|
+
export const BrainclawUpdateSourceNpmSchema = z.object({
|
|
526
|
+
type: z.literal('npm'),
|
|
527
|
+
package_name: z.string().default('brainclaw'),
|
|
528
|
+
dist_tag: z.string().default('latest'),
|
|
529
|
+
});
|
|
530
|
+
export const BrainclawUpdateSourceSchema = z.discriminatedUnion('type', [
|
|
531
|
+
BrainclawUpdateSourceLocalPackSchema,
|
|
532
|
+
BrainclawUpdateSourceNpmSchema,
|
|
533
|
+
]);
|
|
534
|
+
export const BrainclawLocalReleaseManifestSchema = z.object({
|
|
535
|
+
schema_version: z.number().int().positive().optional(),
|
|
536
|
+
version: z.literal(1),
|
|
537
|
+
channel: z.literal('local-pack').default('local-pack'),
|
|
538
|
+
package_name: z.string().default('brainclaw'),
|
|
539
|
+
latest_installable_version: z.string(),
|
|
540
|
+
published_at: z.string().optional(),
|
|
541
|
+
artifact_path: z.string().optional(),
|
|
542
|
+
install_command: z.string().optional(),
|
|
543
|
+
release_notes: z.string().optional(),
|
|
544
|
+
});
|
|
545
|
+
export const ConfigSchema = z.object({
|
|
546
|
+
schema_version: z.number().int().positive().optional(),
|
|
547
|
+
version: z.literal(1),
|
|
548
|
+
project_name: z.string(),
|
|
549
|
+
project_id: z.string().optional(),
|
|
550
|
+
minimum_brainclaw_version: z.string().optional(),
|
|
551
|
+
recommended_brainclaw_version: z.string().optional(),
|
|
552
|
+
brainclaw_upgrade_message: z.string().optional(),
|
|
553
|
+
brainclaw_upgrade_command: z.string().optional(),
|
|
554
|
+
brainclaw_update_source: BrainclawUpdateSourceSchema.optional(),
|
|
555
|
+
current_agent: z.string().optional(),
|
|
556
|
+
current_agent_id: z.string().optional(),
|
|
557
|
+
storage_dir: z.string().default('.brainclaw'),
|
|
558
|
+
topology: TopologyModeSchema.default('embedded'),
|
|
559
|
+
ignore_strategy: IgnoreStrategySchema.default('none'),
|
|
560
|
+
project_mode: ProjectModeSchema.default('auto'),
|
|
561
|
+
projects: ProjectsConfigSchema.default({ strategy: 'manual', known: [] }),
|
|
562
|
+
profile: ProfileSchema.optional(),
|
|
563
|
+
target_audience: z.enum(['human', 'agent']).optional().default('human'),
|
|
564
|
+
openclaw_bridge: z.boolean().optional().default(false),
|
|
565
|
+
remote_sync: RemoteSyncSchema.optional(),
|
|
566
|
+
telemetry: z.literal(false),
|
|
567
|
+
allow_network: z.literal(false),
|
|
568
|
+
redaction: RedactionConfigSchema,
|
|
569
|
+
sensitive_paths: z.array(z.string()),
|
|
570
|
+
security: SecurityConfigSchema.optional(),
|
|
571
|
+
markdown: MarkdownConfigSchema.optional(),
|
|
572
|
+
reflective_memory: ReflectiveMemoryConfigSchema.optional(),
|
|
573
|
+
governance: GovernanceConfigSchema.optional(),
|
|
574
|
+
reputation: ReputationConfigSchema.optional(),
|
|
575
|
+
agent_integrations: AgentIntegrationsConfigSchema.default({ declarations: [] }),
|
|
576
|
+
cross_project_links: z.array(CrossProjectLinkSchema).optional().default([]),
|
|
577
|
+
implicit_session_ttl: z.string().default('4h'),
|
|
578
|
+
auto_reflect_notes: z.boolean().default(false),
|
|
579
|
+
});
|
|
580
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { loadState } from './state.js';
|
|
2
|
+
import { listCandidates } from './candidates.js';
|
|
3
|
+
const K1 = 1.5;
|
|
4
|
+
const B = 0.75;
|
|
5
|
+
function tokenize(text) {
|
|
6
|
+
return text
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.replace(/[^a-z0-9_/-]/g, ' ')
|
|
9
|
+
.split(/\s+/)
|
|
10
|
+
.filter(t => t.length > 1);
|
|
11
|
+
}
|
|
12
|
+
function buildCorpus(state, includePending) {
|
|
13
|
+
const docs = [];
|
|
14
|
+
const add = (section, item) => {
|
|
15
|
+
const textParts = [item.text, item.author ?? '', ...(item.tags ?? []), ...(item.related_paths ?? [])];
|
|
16
|
+
docs.push({ ...item, section, terms: tokenize(textParts.join(' ')) });
|
|
17
|
+
};
|
|
18
|
+
for (const c of state.active_constraints)
|
|
19
|
+
add('constraints', c);
|
|
20
|
+
for (const d of state.recent_decisions)
|
|
21
|
+
add('decisions', d);
|
|
22
|
+
for (const t of state.known_traps)
|
|
23
|
+
add('traps', { ...t, text: t.text });
|
|
24
|
+
for (const h of state.open_handoffs)
|
|
25
|
+
add('handoffs', { ...h, text: `${h.from} -> ${h.to}: ${h.text}` });
|
|
26
|
+
for (const p of state.plan_items)
|
|
27
|
+
add('plans', p);
|
|
28
|
+
if (includePending) {
|
|
29
|
+
const candidates = listCandidates('pending');
|
|
30
|
+
for (const c of candidates)
|
|
31
|
+
add('candidates', { ...c, author: c.author });
|
|
32
|
+
}
|
|
33
|
+
return docs;
|
|
34
|
+
}
|
|
35
|
+
function bm25Score(queryTerms, doc, avgDocLen, idf) {
|
|
36
|
+
const docLen = doc.terms.length;
|
|
37
|
+
let score = 0;
|
|
38
|
+
const docTermFreq = new Map();
|
|
39
|
+
for (const t of doc.terms) {
|
|
40
|
+
docTermFreq.set(t, (docTermFreq.get(t) ?? 0) + 1);
|
|
41
|
+
}
|
|
42
|
+
for (const term of queryTerms) {
|
|
43
|
+
const tf = docTermFreq.get(term) ?? 0;
|
|
44
|
+
if (tf === 0)
|
|
45
|
+
continue;
|
|
46
|
+
const idfVal = idf.get(term) ?? 0;
|
|
47
|
+
const tfNorm = (tf * (K1 + 1)) / (tf + K1 * (1 - B + B * (docLen / avgDocLen)));
|
|
48
|
+
score += idfVal * tfNorm;
|
|
49
|
+
}
|
|
50
|
+
return score;
|
|
51
|
+
}
|
|
52
|
+
export function searchCorpus(documents, options) {
|
|
53
|
+
const corpus = documents.map((document) => {
|
|
54
|
+
const textParts = [document.text, document.author ?? '', ...(document.tags ?? []), ...(document.related_paths ?? [])];
|
|
55
|
+
return {
|
|
56
|
+
...document,
|
|
57
|
+
terms: tokenize(textParts.join(' ')),
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
// Section filter
|
|
61
|
+
const candidates = options.section
|
|
62
|
+
? corpus.filter(d => d.section === options.section)
|
|
63
|
+
: corpus;
|
|
64
|
+
// Tag filter
|
|
65
|
+
const tagFiltered = options.tags && options.tags.length > 0
|
|
66
|
+
? candidates.filter(d => options.tags.some(t => d.tags.includes(t)))
|
|
67
|
+
: candidates;
|
|
68
|
+
// Date filter
|
|
69
|
+
const dateFiltered = options.since
|
|
70
|
+
? tagFiltered.filter(d => d.created_at >= options.since)
|
|
71
|
+
: tagFiltered;
|
|
72
|
+
if (dateFiltered.length === 0)
|
|
73
|
+
return [];
|
|
74
|
+
const queryTerms = tokenize(options.query);
|
|
75
|
+
if (queryTerms.length === 0) {
|
|
76
|
+
// No query — return all sorted by date
|
|
77
|
+
return dateFiltered
|
|
78
|
+
.sort((a, b) => b.created_at.localeCompare(a.created_at))
|
|
79
|
+
.slice(0, options.maxResults ?? 20)
|
|
80
|
+
.map(d => ({ id: d.id, section: d.section, text: d.text, author: d.author, created_at: d.created_at, tags: d.tags, related_paths: d.related_paths, score: 0 }));
|
|
81
|
+
}
|
|
82
|
+
// Compute IDF
|
|
83
|
+
const N = dateFiltered.length;
|
|
84
|
+
const docFreq = new Map();
|
|
85
|
+
for (const term of queryTerms) {
|
|
86
|
+
const df = dateFiltered.filter(d => d.terms.includes(term)).length;
|
|
87
|
+
docFreq.set(term, df);
|
|
88
|
+
}
|
|
89
|
+
const idf = new Map();
|
|
90
|
+
for (const [term, df] of docFreq) {
|
|
91
|
+
idf.set(term, Math.log((N - df + 0.5) / (df + 0.5) + 1));
|
|
92
|
+
}
|
|
93
|
+
const avgDocLen = dateFiltered.reduce((sum, d) => sum + d.terms.length, 0) / N;
|
|
94
|
+
const scored = dateFiltered
|
|
95
|
+
.map(d => ({ doc: d, score: bm25Score(queryTerms, d, avgDocLen, idf) }))
|
|
96
|
+
.filter(r => r.score > 0)
|
|
97
|
+
.sort((a, b) => b.score - a.score)
|
|
98
|
+
.slice(0, options.maxResults ?? 20);
|
|
99
|
+
return scored.map(r => ({
|
|
100
|
+
id: r.doc.id,
|
|
101
|
+
section: r.doc.section,
|
|
102
|
+
text: r.doc.text,
|
|
103
|
+
author: r.doc.author,
|
|
104
|
+
created_at: r.doc.created_at,
|
|
105
|
+
tags: r.doc.tags,
|
|
106
|
+
related_paths: r.doc.related_paths,
|
|
107
|
+
score: Math.round(r.score * 100) / 100,
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
export function search(options) {
|
|
111
|
+
const state = loadState(options.cwd);
|
|
112
|
+
const corpus = buildCorpus(state, options.includePending ?? false);
|
|
113
|
+
return searchCorpus(corpus, options);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=search.js.map
|