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.
Files changed (128) hide show
  1. package/LICENSE +74 -0
  2. package/README.md +226 -0
  3. package/dist/cli.js +1037 -0
  4. package/dist/commands/accept.js +149 -0
  5. package/dist/commands/adapter-openclaw-import.js +75 -0
  6. package/dist/commands/add-step.js +35 -0
  7. package/dist/commands/agent-board.js +106 -0
  8. package/dist/commands/audit.js +35 -0
  9. package/dist/commands/bootstrap.js +34 -0
  10. package/dist/commands/capability.js +104 -0
  11. package/dist/commands/changes.js +112 -0
  12. package/dist/commands/check-constraints.js +63 -0
  13. package/dist/commands/claim-resource.js +54 -0
  14. package/dist/commands/claim.js +92 -0
  15. package/dist/commands/complete-step.js +34 -0
  16. package/dist/commands/constraint.js +44 -0
  17. package/dist/commands/context-diff.js +32 -0
  18. package/dist/commands/context.js +63 -0
  19. package/dist/commands/decision.js +45 -0
  20. package/dist/commands/delete-plan.js +20 -0
  21. package/dist/commands/diff.js +99 -0
  22. package/dist/commands/doctor.js +1275 -0
  23. package/dist/commands/enable-agent.js +63 -0
  24. package/dist/commands/env.js +46 -0
  25. package/dist/commands/estimation-report.js +167 -0
  26. package/dist/commands/explore.js +47 -0
  27. package/dist/commands/export.js +381 -0
  28. package/dist/commands/handoff.js +63 -0
  29. package/dist/commands/history.js +22 -0
  30. package/dist/commands/hooks.js +123 -0
  31. package/dist/commands/init.js +356 -0
  32. package/dist/commands/install-hooks.js +115 -0
  33. package/dist/commands/instruction.js +56 -0
  34. package/dist/commands/list-agents.js +44 -0
  35. package/dist/commands/list-claims.js +45 -0
  36. package/dist/commands/list-instructions.js +50 -0
  37. package/dist/commands/list-plans.js +48 -0
  38. package/dist/commands/mcp-worker.js +12 -0
  39. package/dist/commands/mcp.js +2272 -0
  40. package/dist/commands/memory.js +283 -0
  41. package/dist/commands/metrics.js +175 -0
  42. package/dist/commands/plan-resource.js +62 -0
  43. package/dist/commands/plan.js +76 -0
  44. package/dist/commands/prune-candidates.js +36 -0
  45. package/dist/commands/prune.js +48 -0
  46. package/dist/commands/pull.js +25 -0
  47. package/dist/commands/push.js +28 -0
  48. package/dist/commands/rebuild.js +14 -0
  49. package/dist/commands/reflect-runtime-note.js +74 -0
  50. package/dist/commands/reflect.js +286 -0
  51. package/dist/commands/register-agent.js +29 -0
  52. package/dist/commands/reject.js +52 -0
  53. package/dist/commands/release-claim.js +41 -0
  54. package/dist/commands/release-claims.js +67 -0
  55. package/dist/commands/review.js +242 -0
  56. package/dist/commands/rollback.js +156 -0
  57. package/dist/commands/runtime-note.js +144 -0
  58. package/dist/commands/runtime-status.js +49 -0
  59. package/dist/commands/search.js +36 -0
  60. package/dist/commands/session-end.js +187 -0
  61. package/dist/commands/session-start.js +147 -0
  62. package/dist/commands/set-trust.js +92 -0
  63. package/dist/commands/setup.js +446 -0
  64. package/dist/commands/show-candidate.js +31 -0
  65. package/dist/commands/star-candidate.js +28 -0
  66. package/dist/commands/status.js +133 -0
  67. package/dist/commands/sync.js +159 -0
  68. package/dist/commands/tool.js +126 -0
  69. package/dist/commands/trap.js +74 -0
  70. package/dist/commands/update-handoff.js +23 -0
  71. package/dist/commands/update-plan.js +37 -0
  72. package/dist/commands/upgrade.js +382 -0
  73. package/dist/commands/use-candidate.js +35 -0
  74. package/dist/commands/version.js +96 -0
  75. package/dist/commands/watch.js +215 -0
  76. package/dist/commands/whoami.js +104 -0
  77. package/dist/core/agent-context.js +340 -0
  78. package/dist/core/agent-files.js +874 -0
  79. package/dist/core/agent-integrations.js +135 -0
  80. package/dist/core/agent-inventory.js +401 -0
  81. package/dist/core/agent-registry.js +420 -0
  82. package/dist/core/ai-agent-detection.js +140 -0
  83. package/dist/core/audit.js +85 -0
  84. package/dist/core/bootstrap.js +658 -0
  85. package/dist/core/brainclaw-version.js +433 -0
  86. package/dist/core/candidates.js +137 -0
  87. package/dist/core/circuit-breaker.js +118 -0
  88. package/dist/core/claims.js +72 -0
  89. package/dist/core/config.js +86 -0
  90. package/dist/core/context-diff.js +122 -0
  91. package/dist/core/context.js +1212 -0
  92. package/dist/core/contradictions.js +270 -0
  93. package/dist/core/coordination.js +86 -0
  94. package/dist/core/cross-project.js +99 -0
  95. package/dist/core/duplicates.js +72 -0
  96. package/dist/core/event-log.js +152 -0
  97. package/dist/core/events.js +56 -0
  98. package/dist/core/execution-context.js +204 -0
  99. package/dist/core/freshness.js +87 -0
  100. package/dist/core/global-registry.js +182 -0
  101. package/dist/core/host.js +10 -0
  102. package/dist/core/identity.js +151 -0
  103. package/dist/core/ids.js +56 -0
  104. package/dist/core/input-validation.js +81 -0
  105. package/dist/core/instructions.js +117 -0
  106. package/dist/core/io.js +191 -0
  107. package/dist/core/json-store.js +63 -0
  108. package/dist/core/lifecycle.js +45 -0
  109. package/dist/core/lock.js +129 -0
  110. package/dist/core/logger.js +49 -0
  111. package/dist/core/machine-profile.js +332 -0
  112. package/dist/core/markdown.js +120 -0
  113. package/dist/core/memory-git.js +133 -0
  114. package/dist/core/migration.js +247 -0
  115. package/dist/core/project-registry.js +64 -0
  116. package/dist/core/reflection-safety.js +21 -0
  117. package/dist/core/repo-analysis.js +133 -0
  118. package/dist/core/reputation.js +409 -0
  119. package/dist/core/runtime.js +134 -0
  120. package/dist/core/schema.js +580 -0
  121. package/dist/core/search.js +115 -0
  122. package/dist/core/security.js +66 -0
  123. package/dist/core/setup-state.js +50 -0
  124. package/dist/core/state.js +83 -0
  125. package/dist/core/store-resolution.js +119 -0
  126. package/dist/core/sync-remote.js +83 -0
  127. package/dist/core/traps.js +86 -0
  128. 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