monomind 1.11.12 → 1.11.13
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/.claude/commands/mastermind/idea.md +1 -1
- package/.claude/commands/mastermind/master.md +1 -1
- package/.claude/skills/mastermind/_protocol.md +4 -4
- package/.claude/skills/mastermind/build.md +3 -3
- package/.claude/skills/mastermind/content.md +3 -3
- package/.claude/skills/mastermind/createorg.md +2 -2
- package/.claude/skills/mastermind/finance.md +3 -3
- package/.claude/skills/mastermind/marketing.md +3 -3
- package/.claude/skills/mastermind/ops.md +3 -3
- package/.claude/skills/mastermind/release.md +3 -3
- package/.claude/skills/mastermind/research.md +3 -3
- package/.claude/skills/mastermind/review.md +3 -3
- package/.claude/skills/mastermind/sales.md +3 -3
- package/package.json +1 -1
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -3
- package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/update/checker.js +24 -7
- package/packages/@monomind/cli/dist/src/update/index.js +3 -6
- package/packages/@monomind/cli/package.json +1 -1
- package/packages/@monomind/cli/dist/src/agents/halt-signal.d.ts +0 -25
- package/packages/@monomind/cli/dist/src/agents/halt-signal.js +0 -76
- package/packages/@monomind/cli/dist/src/agents/index.d.ts +0 -18
- package/packages/@monomind/cli/dist/src/agents/index.js +0 -13
- package/packages/@monomind/cli/dist/src/agents/managed-agent.d.ts +0 -41
- package/packages/@monomind/cli/dist/src/agents/managed-agent.js +0 -69
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +0 -23
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +0 -49
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +0 -22
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +0 -80
- package/packages/@monomind/cli/dist/src/agents/registry-query.d.ts +0 -71
- package/packages/@monomind/cli/dist/src/agents/registry-query.js +0 -125
- package/packages/@monomind/cli/dist/src/agents/score-decay.d.ts +0 -19
- package/packages/@monomind/cli/dist/src/agents/score-decay.js +0 -22
- package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.d.ts +0 -13
- package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.js +0 -40
- package/packages/@monomind/cli/dist/src/agents/specialization-scorer.d.ts +0 -54
- package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +0 -212
- package/packages/@monomind/cli/dist/src/agents/termination-watcher.d.ts +0 -30
- package/packages/@monomind/cli/dist/src/agents/termination-watcher.js +0 -84
- package/packages/@monomind/cli/dist/src/agents/trigger-index.d.ts +0 -20
- package/packages/@monomind/cli/dist/src/agents/trigger-index.js +0 -38
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +0 -64
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +0 -308
- package/packages/@monomind/cli/dist/src/agents/version-diff.d.ts +0 -18
- package/packages/@monomind/cli/dist/src/agents/version-diff.js +0 -64
- package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +0 -60
- package/packages/@monomind/cli/dist/src/agents/version-store.js +0 -235
- package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.d.ts +0 -45
- package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.js +0 -404
- package/packages/@monomind/cli/dist/src/commands/agent-wasm.d.ts +0 -14
- package/packages/@monomind/cli/dist/src/commands/agent-wasm.js +0 -333
- package/packages/@monomind/cli/dist/src/commands/ui.js +0 -68
- package/packages/@monomind/cli/dist/src/consensus/index.d.ts +0 -7
- package/packages/@monomind/cli/dist/src/consensus/index.js +0 -6
- package/packages/@monomind/cli/dist/src/context/context-provider.d.ts +0 -44
- package/packages/@monomind/cli/dist/src/context/context-provider.js +0 -25
- package/packages/@monomind/cli/dist/src/context/git-state-provider.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/context/git-state-provider.js +0 -34
- package/packages/@monomind/cli/dist/src/context/index.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/context/index.js +0 -12
- package/packages/@monomind/cli/dist/src/context/project-conventions-provider.d.ts +0 -15
- package/packages/@monomind/cli/dist/src/context/project-conventions-provider.js +0 -19
- package/packages/@monomind/cli/dist/src/context/prompt-assembler.d.ts +0 -26
- package/packages/@monomind/cli/dist/src/context/prompt-assembler.js +0 -93
- package/packages/@monomind/cli/dist/src/context/task-history-provider.d.ts +0 -24
- package/packages/@monomind/cli/dist/src/context/task-history-provider.js +0 -32
- package/packages/@monomind/cli/dist/src/context/user-preferences-provider.d.ts +0 -14
- package/packages/@monomind/cli/dist/src/context/user-preferences-provider.js +0 -27
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +0 -31
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +0 -81
- package/packages/@monomind/cli/dist/src/dlq/dlq-writer.d.ts +0 -24
- package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +0 -65
- package/packages/@monomind/cli/dist/src/dlq/index.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/dlq/index.js +0 -7
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +0 -33
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +0 -107
- package/packages/@monomind/cli/dist/src/eval/dataset-runner.d.ts +0 -23
- package/packages/@monomind/cli/dist/src/eval/dataset-runner.js +0 -59
- package/packages/@monomind/cli/dist/src/eval/index.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/eval/index.js +0 -7
- package/packages/@monomind/cli/dist/src/eval/trace-collector.d.ts +0 -40
- package/packages/@monomind/cli/dist/src/eval/trace-collector.js +0 -102
- package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.d.ts +0 -68
- package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.js +0 -264
- package/packages/@monomind/cli/dist/src/interactive/interrupt.d.ts +0 -22
- package/packages/@monomind/cli/dist/src/interactive/interrupt.js +0 -71
- package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.d.ts +0 -25
- package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.js +0 -48
- package/packages/@monomind/cli/dist/src/mcp/tool-registry.d.ts +0 -61
- package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +0 -246
- package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.d.ts +0 -9
- package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.js +0 -230
- package/packages/@monomind/cli/dist/src/model/complexity-scorer.d.ts +0 -21
- package/packages/@monomind/cli/dist/src/model/complexity-scorer.js +0 -106
- package/packages/@monomind/cli/dist/src/model/index.d.ts +0 -4
- package/packages/@monomind/cli/dist/src/model/index.js +0 -4
- package/packages/@monomind/cli/dist/src/model/model-settings.d.ts +0 -22
- package/packages/@monomind/cli/dist/src/model/model-settings.js +0 -33
- package/packages/@monomind/cli/dist/src/model/model-tier-resolver.d.ts +0 -24
- package/packages/@monomind/cli/dist/src/model/model-tier-resolver.js +0 -65
- package/packages/@monomind/cli/dist/src/monovector/capabilities.d.ts +0 -34
- package/packages/@monomind/cli/dist/src/monovector/capabilities.js +0 -37
- package/packages/@monomind/cli/dist/src/orchestration/index.d.ts +0 -7
- package/packages/@monomind/cli/dist/src/orchestration/index.js +0 -6
- package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.js +0 -31
- package/packages/@monomind/cli/dist/src/orchestration/routing-modes.d.ts +0 -68
- package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +0 -180
- package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.d.ts +0 -7
- package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.js +0 -126
- package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.js +0 -188
- package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.d.ts +0 -7
- package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.js +0 -206
- package/packages/@monomind/cli/dist/src/runtime/headless.d.ts +0 -60
- package/packages/@monomind/cli/dist/src/runtime/headless.js +0 -284
- package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.d.ts +0 -50
- package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.js +0 -95
- package/packages/@monomind/cli/dist/src/services/container-worker-pool.d.ts +0 -197
- package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +0 -623
- package/packages/@monomind/cli/dist/src/services/index.d.ts +0 -13
- package/packages/@monomind/cli/dist/src/services/index.js +0 -11
- package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +0 -201
- package/packages/@monomind/cli/dist/src/services/worker-queue.js +0 -594
- package/packages/@monomind/cli/dist/src/swarm/communication-graph.d.ts +0 -25
- package/packages/@monomind/cli/dist/src/swarm/communication-graph.js +0 -77
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +0 -31
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +0 -61
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +0 -19
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +0 -68
- package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.d.ts +0 -13
- package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.js +0 -205
- package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.js +0 -190
- package/packages/@monomind/cli/dist/src/transfer/test-seraphine.d.ts +0 -6
- package/packages/@monomind/cli/dist/src/transfer/test-seraphine.js +0 -105
- package/packages/@monomind/cli/dist/src/transfer/tests/test-store.d.ts +0 -7
- package/packages/@monomind/cli/dist/src/transfer/tests/test-store.js +0 -214
- package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +0 -82
- package/packages/@monomind/cli/dist/src/workflow/context-resolver.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/workflow/context-resolver.js +0 -23
- package/packages/@monomind/cli/dist/src/workflow/dag-builder.d.ts +0 -17
- package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +0 -129
- package/packages/@monomind/cli/dist/src/workflow/dag-executor.d.ts +0 -9
- package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +0 -116
- package/packages/@monomind/cli/dist/src/workflow/dag-types.d.ts +0 -41
- package/packages/@monomind/cli/dist/src/workflow/dag-types.js +0 -8
- package/packages/@monomind/cli/dist/src/workflow/dsl-parser.d.ts +0 -12
- package/packages/@monomind/cli/dist/src/workflow/dsl-parser.js +0 -20
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +0 -165
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +0 -82
- package/packages/@monomind/cli/dist/src/workflow/index.d.ts +0 -13
- package/packages/@monomind/cli/dist/src/workflow/index.js +0 -11
- package/packages/@monomind/cli/dist/src/workflow/template-engine.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/workflow/template-engine.js +0 -40
- package/packages/@monomind/cli/dist/src/workflow/workflow-executor.d.ts +0 -29
- package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +0 -227
- package/packages/@monomind/guidance/dist/adversarial.d.ts +0 -284
- package/packages/@monomind/guidance/dist/adversarial.js +0 -572
- package/packages/@monomind/guidance/dist/analyzer.d.ts +0 -530
- package/packages/@monomind/guidance/dist/analyzer.js +0 -2518
- package/packages/@monomind/guidance/dist/artifacts.d.ts +0 -283
- package/packages/@monomind/guidance/dist/artifacts.js +0 -356
- package/packages/@monomind/guidance/dist/authority.d.ts +0 -290
- package/packages/@monomind/guidance/dist/authority.js +0 -558
- package/packages/@monomind/guidance/dist/capabilities.d.ts +0 -209
- package/packages/@monomind/guidance/dist/capabilities.js +0 -485
- package/packages/@monomind/guidance/dist/coherence.d.ts +0 -233
- package/packages/@monomind/guidance/dist/coherence.js +0 -372
- package/packages/@monomind/guidance/dist/compiler.d.ts +0 -87
- package/packages/@monomind/guidance/dist/compiler.js +0 -419
- package/packages/@monomind/guidance/dist/conformance-kit.d.ts +0 -225
- package/packages/@monomind/guidance/dist/conformance-kit.js +0 -629
- package/packages/@monomind/guidance/dist/continue-gate.d.ts +0 -214
- package/packages/@monomind/guidance/dist/continue-gate.js +0 -353
- package/packages/@monomind/guidance/dist/crypto-utils.d.ts +0 -17
- package/packages/@monomind/guidance/dist/crypto-utils.js +0 -24
- package/packages/@monomind/guidance/dist/evolution.d.ts +0 -282
- package/packages/@monomind/guidance/dist/evolution.js +0 -500
- package/packages/@monomind/guidance/dist/gates.d.ts +0 -79
- package/packages/@monomind/guidance/dist/gates.js +0 -302
- package/packages/@monomind/guidance/dist/gateway.d.ts +0 -206
- package/packages/@monomind/guidance/dist/gateway.js +0 -452
- package/packages/@monomind/guidance/dist/generators.d.ts +0 -153
- package/packages/@monomind/guidance/dist/generators.js +0 -682
- package/packages/@monomind/guidance/dist/headless.d.ts +0 -177
- package/packages/@monomind/guidance/dist/headless.js +0 -342
- package/packages/@monomind/guidance/dist/hooks.d.ts +0 -109
- package/packages/@monomind/guidance/dist/hooks.js +0 -347
- package/packages/@monomind/guidance/dist/index.d.ts +0 -205
- package/packages/@monomind/guidance/dist/index.js +0 -321
- package/packages/@monomind/guidance/dist/ledger.d.ts +0 -162
- package/packages/@monomind/guidance/dist/ledger.js +0 -375
- package/packages/@monomind/guidance/dist/manifest-validator.d.ts +0 -289
- package/packages/@monomind/guidance/dist/manifest-validator.js +0 -838
- package/packages/@monomind/guidance/dist/memory-gate.d.ts +0 -222
- package/packages/@monomind/guidance/dist/memory-gate.js +0 -382
- package/packages/@monomind/guidance/dist/meta-governance.d.ts +0 -265
- package/packages/@monomind/guidance/dist/meta-governance.js +0 -348
- package/packages/@monomind/guidance/dist/optimizer.d.ts +0 -104
- package/packages/@monomind/guidance/dist/optimizer.js +0 -329
- package/packages/@monomind/guidance/dist/persistence.d.ts +0 -189
- package/packages/@monomind/guidance/dist/persistence.js +0 -464
- package/packages/@monomind/guidance/dist/proof.d.ts +0 -185
- package/packages/@monomind/guidance/dist/proof.js +0 -238
- package/packages/@monomind/guidance/dist/retriever.d.ts +0 -116
- package/packages/@monomind/guidance/dist/retriever.js +0 -394
- package/packages/@monomind/guidance/dist/ruvbot-integration.d.ts +0 -370
- package/packages/@monomind/guidance/dist/ruvbot-integration.js +0 -738
- package/packages/@monomind/guidance/dist/temporal.d.ts +0 -426
- package/packages/@monomind/guidance/dist/temporal.js +0 -658
- package/packages/@monomind/guidance/dist/trust.d.ts +0 -283
- package/packages/@monomind/guidance/dist/trust.js +0 -473
- package/packages/@monomind/guidance/dist/truth-anchors.d.ts +0 -276
- package/packages/@monomind/guidance/dist/truth-anchors.js +0 -488
- package/packages/@monomind/guidance/dist/types.d.ts +0 -378
- package/packages/@monomind/guidance/dist/types.js +0 -10
- package/packages/@monomind/guidance/dist/uncertainty.d.ts +0 -372
- package/packages/@monomind/guidance/dist/uncertainty.js +0 -619
- package/packages/@monomind/guidance/dist/wasm-kernel.d.ts +0 -48
- package/packages/@monomind/guidance/dist/wasm-kernel.js +0 -158
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Trigger Scanner (Task 32)
|
|
3
|
-
*
|
|
4
|
-
* Scans task descriptions against compiled trigger patterns
|
|
5
|
-
* from agent frontmatter and returns matches.
|
|
6
|
-
*
|
|
7
|
-
* - Patterns are tested in descending priority order.
|
|
8
|
-
* - A `takeover` match short-circuits: only that agent is returned.
|
|
9
|
-
* - `inject` matches accumulate as additional candidates.
|
|
10
|
-
* - Invalid regex patterns are silently skipped.
|
|
11
|
-
*/
|
|
12
|
-
import { readFileSync, readdirSync, lstatSync, statSync, realpathSync } from 'fs';
|
|
13
|
-
import { join, extname, resolve, sep } from 'path';
|
|
14
|
-
export class TriggerScanner {
|
|
15
|
-
compiled = [];
|
|
16
|
-
patterns = [];
|
|
17
|
-
totalAgentsScanned = 0;
|
|
18
|
-
buildingIndex = false;
|
|
19
|
-
constructor(patterns = []) {
|
|
20
|
-
for (const p of patterns) {
|
|
21
|
-
this.compileAndAdd(p);
|
|
22
|
-
}
|
|
23
|
-
this.sortByPriority();
|
|
24
|
-
}
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Public API
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
/**
|
|
29
|
-
* Test all patterns against `taskDescription` and return matches.
|
|
30
|
-
*
|
|
31
|
-
* Patterns are tested in descending priority order.
|
|
32
|
-
* If a `takeover` pattern matches, scanning stops immediately
|
|
33
|
-
* and only that agent is returned.
|
|
34
|
-
*/
|
|
35
|
-
scan(taskDescription) {
|
|
36
|
-
const matches = [];
|
|
37
|
-
for (const { source, regex } of this.compiled) {
|
|
38
|
-
// Reset lastIndex in case the regex has the global flag
|
|
39
|
-
regex.lastIndex = 0;
|
|
40
|
-
const m = regex.exec(taskDescription);
|
|
41
|
-
if (!m)
|
|
42
|
-
continue;
|
|
43
|
-
const match = {
|
|
44
|
-
agentSlug: source.agentSlug,
|
|
45
|
-
pattern: source.pattern,
|
|
46
|
-
mode: source.mode,
|
|
47
|
-
matchedText: m[0],
|
|
48
|
-
};
|
|
49
|
-
if (source.mode === 'takeover') {
|
|
50
|
-
// Short-circuit: return only this agent
|
|
51
|
-
return [match];
|
|
52
|
-
}
|
|
53
|
-
matches.push(match);
|
|
54
|
-
}
|
|
55
|
-
return matches;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Build an index by scanning agent markdown files under `agentDir`.
|
|
59
|
-
*
|
|
60
|
-
* Reads each `.md` file, extracts YAML frontmatter, and looks for
|
|
61
|
-
* `triggers:` entries with `pattern`, `mode`, and optional `priority`.
|
|
62
|
-
*/
|
|
63
|
-
buildIndex(agentDir, allowedRoot) {
|
|
64
|
-
if (this.buildingIndex) {
|
|
65
|
-
throw new Error('buildIndex is already running; concurrent invocations are not safe');
|
|
66
|
-
}
|
|
67
|
-
this.buildingIndex = true;
|
|
68
|
-
try {
|
|
69
|
-
return this._buildIndex(agentDir, allowedRoot);
|
|
70
|
-
}
|
|
71
|
-
finally {
|
|
72
|
-
this.buildingIndex = false;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
_buildIndex(agentDir, allowedRoot) {
|
|
76
|
-
if (allowedRoot) {
|
|
77
|
-
let resolvedDir;
|
|
78
|
-
let resolvedRoot;
|
|
79
|
-
try {
|
|
80
|
-
resolvedDir = realpathSync(resolve(agentDir));
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
resolvedDir = resolve(agentDir);
|
|
84
|
-
}
|
|
85
|
-
try {
|
|
86
|
-
resolvedRoot = realpathSync(resolve(allowedRoot));
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
resolvedRoot = resolve(allowedRoot);
|
|
90
|
-
}
|
|
91
|
-
if (!resolvedDir.startsWith(resolvedRoot + sep) && resolvedDir !== resolvedRoot) {
|
|
92
|
-
throw new Error(`Agent directory escapes workspace: ${resolvedDir}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const mdFiles = this.collectMdFiles(agentDir);
|
|
96
|
-
this.patterns = [];
|
|
97
|
-
this.compiled = [];
|
|
98
|
-
this.totalAgentsScanned = mdFiles.length;
|
|
99
|
-
const MAX_AGENT_FILE_BYTES = 1 * 1024 * 1024;
|
|
100
|
-
for (const filePath of mdFiles) {
|
|
101
|
-
let content;
|
|
102
|
-
try {
|
|
103
|
-
if (statSync(filePath).size > MAX_AGENT_FILE_BYTES)
|
|
104
|
-
continue;
|
|
105
|
-
content = readFileSync(filePath, 'utf-8');
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
const slug = this.slugFromPath(filePath);
|
|
111
|
-
const triggers = this.extractTriggers(content, slug);
|
|
112
|
-
for (const t of triggers) {
|
|
113
|
-
this.compileAndAdd(t);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
this.sortByPriority();
|
|
117
|
-
return {
|
|
118
|
-
patterns: [...this.patterns],
|
|
119
|
-
builtAt: new Date().toISOString(),
|
|
120
|
-
totalAgentsScanned: this.totalAgentsScanned,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
/** Add a pattern to the index at runtime. */
|
|
124
|
-
addPattern(pattern) {
|
|
125
|
-
this.compileAndAdd(pattern);
|
|
126
|
-
this.sortByPriority();
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Remove a specific pattern for an agent.
|
|
130
|
-
* Returns `true` if the pattern was found and removed.
|
|
131
|
-
*/
|
|
132
|
-
removePattern(agentSlug, pattern) {
|
|
133
|
-
const idx = this.patterns.findIndex((p) => p.agentSlug === agentSlug && p.pattern === pattern);
|
|
134
|
-
if (idx === -1)
|
|
135
|
-
return false;
|
|
136
|
-
this.patterns.splice(idx, 1);
|
|
137
|
-
this.compiled.splice(idx, 1);
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
/** Return a snapshot of the current index. */
|
|
141
|
-
getIndex() {
|
|
142
|
-
return {
|
|
143
|
-
patterns: [...this.patterns],
|
|
144
|
-
builtAt: new Date().toISOString(),
|
|
145
|
-
totalAgentsScanned: this.totalAgentsScanned,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
/** Number of compiled patterns. */
|
|
149
|
-
get size() {
|
|
150
|
-
return this.compiled.length;
|
|
151
|
-
}
|
|
152
|
-
// ---------------------------------------------------------------------------
|
|
153
|
-
// Internal helpers
|
|
154
|
-
// ---------------------------------------------------------------------------
|
|
155
|
-
compileAndAdd(pattern) {
|
|
156
|
-
if (pattern.pattern.length > 200)
|
|
157
|
-
return;
|
|
158
|
-
// Reject patterns with nested/repeated quantifiers (ReDoS vectors)
|
|
159
|
-
// Covers: (a+)+, (a|b+)+, (a?){n}, ((a)+)+, [a-z]+{n}
|
|
160
|
-
if (/(\(.*[+*?].*\)|[+*?]){2,}|\{[0-9,]+\}.*[+*?]|(\[[^\]]*\]|\.)[+*?][+*?]/.test(pattern.pattern))
|
|
161
|
-
return;
|
|
162
|
-
if (/\([^)]*([+*][^)]*){2,}\)/.test(pattern.pattern))
|
|
163
|
-
return;
|
|
164
|
-
try {
|
|
165
|
-
const regex = new RegExp(pattern.pattern, 'i');
|
|
166
|
-
this.patterns.push(pattern);
|
|
167
|
-
this.compiled.push({ source: pattern, regex });
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
// Invalid regex — skip silently
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
sortByPriority() {
|
|
174
|
-
// Sort both arrays in-sync by descending priority
|
|
175
|
-
const indexed = this.patterns.map((p, i) => ({ p, c: this.compiled[i], priority: p.priority }));
|
|
176
|
-
indexed.sort((a, b) => b.priority - a.priority);
|
|
177
|
-
this.patterns = indexed.map((x) => x.p);
|
|
178
|
-
this.compiled = indexed.map((x) => x.c);
|
|
179
|
-
}
|
|
180
|
-
/** Recursively collect `.md` files (symlinks skipped, visited inodes tracked). */
|
|
181
|
-
collectMdFiles(dir, visited = new Set()) {
|
|
182
|
-
const results = [];
|
|
183
|
-
let entries;
|
|
184
|
-
try {
|
|
185
|
-
entries = readdirSync(dir);
|
|
186
|
-
}
|
|
187
|
-
catch {
|
|
188
|
-
return results;
|
|
189
|
-
}
|
|
190
|
-
for (const entry of entries) {
|
|
191
|
-
const full = join(dir, entry);
|
|
192
|
-
let lstat;
|
|
193
|
-
try {
|
|
194
|
-
lstat = lstatSync(full);
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
if (lstat.isSymbolicLink())
|
|
200
|
-
continue;
|
|
201
|
-
if (lstat.isDirectory()) {
|
|
202
|
-
if (visited.has(lstat.ino))
|
|
203
|
-
continue;
|
|
204
|
-
visited.add(lstat.ino);
|
|
205
|
-
results.push(...this.collectMdFiles(full, visited));
|
|
206
|
-
}
|
|
207
|
-
else if (lstat.isFile() && extname(entry) === '.md') {
|
|
208
|
-
results.push(full);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return results;
|
|
212
|
-
}
|
|
213
|
-
/** Derive slug from filename. */
|
|
214
|
-
slugFromPath(filePath) {
|
|
215
|
-
const base = filePath.split('/').pop() ?? '';
|
|
216
|
-
return base
|
|
217
|
-
.replace(/\.md$/i, '')
|
|
218
|
-
.toLowerCase()
|
|
219
|
-
.replace(/\s+/g, '-')
|
|
220
|
-
.replace(/[^a-z0-9-]/g, '');
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Extract trigger definitions from markdown frontmatter.
|
|
224
|
-
*
|
|
225
|
-
* Looks for a YAML block between `---` markers, then finds lines like:
|
|
226
|
-
* - pattern: "\\b(auth|jwt)\\b"
|
|
227
|
-
* mode: "inject"
|
|
228
|
-
* priority: 10
|
|
229
|
-
*/
|
|
230
|
-
extractTriggers(content, agentSlug) {
|
|
231
|
-
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
232
|
-
if (!fmMatch)
|
|
233
|
-
return [];
|
|
234
|
-
const block = fmMatch[1];
|
|
235
|
-
const triggers = [];
|
|
236
|
-
// Find trigger blocks: lines starting with "- pattern:" under a triggers: section
|
|
237
|
-
const lines = block.split('\n');
|
|
238
|
-
let inTriggers = false;
|
|
239
|
-
let currentTrigger = null;
|
|
240
|
-
for (const line of lines) {
|
|
241
|
-
const trimmed = line.trim();
|
|
242
|
-
// Measure leading whitespace to distinguish top-level keys from nested props
|
|
243
|
-
const indent = line.length - line.trimStart().length;
|
|
244
|
-
if (trimmed === 'triggers:' || trimmed.startsWith('triggers:')) {
|
|
245
|
-
inTriggers = true;
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
// Exit triggers section when we hit a non-indented top-level key (indent 0)
|
|
249
|
-
if (inTriggers && indent === 0 && /^[a-zA-Z]/.test(trimmed)) {
|
|
250
|
-
inTriggers = false;
|
|
251
|
-
if (currentTrigger?.pattern) {
|
|
252
|
-
triggers.push(this.finalizeTrigger(currentTrigger, agentSlug));
|
|
253
|
-
}
|
|
254
|
-
currentTrigger = null;
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
if (!inTriggers)
|
|
258
|
-
continue;
|
|
259
|
-
// New list item
|
|
260
|
-
if (trimmed.startsWith('- pattern:')) {
|
|
261
|
-
if (currentTrigger?.pattern) {
|
|
262
|
-
triggers.push(this.finalizeTrigger(currentTrigger, agentSlug));
|
|
263
|
-
}
|
|
264
|
-
currentTrigger = {
|
|
265
|
-
pattern: this.extractYamlValue(trimmed.replace(/^- pattern:\s*/, '')),
|
|
266
|
-
agentSlug,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
else if (currentTrigger && trimmed.startsWith('mode:')) {
|
|
270
|
-
const val = this.extractYamlValue(trimmed.replace(/^mode:\s*/, ''));
|
|
271
|
-
if (val === 'inject' || val === 'takeover') {
|
|
272
|
-
currentTrigger.mode = val;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
else if (currentTrigger && trimmed.startsWith('priority:')) {
|
|
276
|
-
const val = parseInt(trimmed.replace(/^priority:\s*/, ''), 10);
|
|
277
|
-
if (!isNaN(val)) {
|
|
278
|
-
currentTrigger.priority = val;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// Flush last trigger
|
|
283
|
-
if (currentTrigger?.pattern) {
|
|
284
|
-
triggers.push(this.finalizeTrigger(currentTrigger, agentSlug));
|
|
285
|
-
}
|
|
286
|
-
return triggers;
|
|
287
|
-
}
|
|
288
|
-
finalizeTrigger(partial, agentSlug) {
|
|
289
|
-
return {
|
|
290
|
-
pattern: partial.pattern,
|
|
291
|
-
mode: partial.mode ?? 'inject',
|
|
292
|
-
priority: partial.priority ?? 0,
|
|
293
|
-
agentSlug,
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
extractYamlValue(raw) {
|
|
297
|
-
let v = raw.trim();
|
|
298
|
-
if (v.startsWith('"') && v.endsWith('"')) {
|
|
299
|
-
// YAML double-quoted: unescape \\ → \ so "\\b" becomes \b (word boundary)
|
|
300
|
-
v = v.slice(1, -1).replace(/\\\\/g, '\\');
|
|
301
|
-
}
|
|
302
|
-
else if (v.startsWith("'") && v.endsWith("'")) {
|
|
303
|
-
v = v.slice(1, -1);
|
|
304
|
-
}
|
|
305
|
-
return v;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
//# sourceMappingURL=trigger-scanner.js.map
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Version Diff Utility (Task 29)
|
|
3
|
-
*
|
|
4
|
-
* Computes a simple unified-style diff between two content strings.
|
|
5
|
-
*/
|
|
6
|
-
export interface LineDiffResult {
|
|
7
|
-
additions: number;
|
|
8
|
-
deletions: number;
|
|
9
|
-
hunks: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Compute a unified diff between two content strings.
|
|
13
|
-
*
|
|
14
|
-
* Uses a simple line-by-line LCS-based approach to produce
|
|
15
|
-
* addition/deletion counts and a unified-style hunk string.
|
|
16
|
-
*/
|
|
17
|
-
export declare function computeUnifiedDiff(oldContent: string, newContent: string): LineDiffResult;
|
|
18
|
-
//# sourceMappingURL=version-diff.d.ts.map
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Version Diff Utility (Task 29)
|
|
3
|
-
*
|
|
4
|
-
* Computes a simple unified-style diff between two content strings.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Compute a unified diff between two content strings.
|
|
8
|
-
*
|
|
9
|
-
* Uses a simple line-by-line LCS-based approach to produce
|
|
10
|
-
* addition/deletion counts and a unified-style hunk string.
|
|
11
|
-
*/
|
|
12
|
-
export function computeUnifiedDiff(oldContent, newContent) {
|
|
13
|
-
const oldLines = oldContent.split('\n');
|
|
14
|
-
const newLines = newContent.split('\n');
|
|
15
|
-
// Simple LCS to find common subsequence
|
|
16
|
-
const m = oldLines.length;
|
|
17
|
-
const n = newLines.length;
|
|
18
|
-
// Build LCS table
|
|
19
|
-
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
20
|
-
for (let i = 1; i <= m; i++) {
|
|
21
|
-
for (let j = 1; j <= n; j++) {
|
|
22
|
-
if (oldLines[i - 1] === newLines[j - 1]) {
|
|
23
|
-
dp[i][j] = dp[i - 1][j - 1] + 1;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// Backtrack to produce diff lines
|
|
31
|
-
const diffLines = [];
|
|
32
|
-
let additions = 0;
|
|
33
|
-
let deletions = 0;
|
|
34
|
-
let i = m;
|
|
35
|
-
let j = n;
|
|
36
|
-
const result = [];
|
|
37
|
-
while (i > 0 || j > 0) {
|
|
38
|
-
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
39
|
-
result.push({ type: ' ', line: oldLines[i - 1] });
|
|
40
|
-
i--;
|
|
41
|
-
j--;
|
|
42
|
-
}
|
|
43
|
-
else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
44
|
-
result.push({ type: '+', line: newLines[j - 1] });
|
|
45
|
-
additions++;
|
|
46
|
-
j--;
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
result.push({ type: '-', line: oldLines[i - 1] });
|
|
50
|
-
deletions++;
|
|
51
|
-
i--;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
result.reverse();
|
|
55
|
-
for (const entry of result) {
|
|
56
|
-
diffLines.push(`${entry.type} ${entry.line}`);
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
additions,
|
|
60
|
-
deletions,
|
|
61
|
-
hunks: diffLines.join('\n'),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=version-diff.js.map
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Version Store (Task 29)
|
|
3
|
-
*
|
|
4
|
-
* JSONL-based append-only storage for agent definition versions.
|
|
5
|
-
* Supports save, list, get, rollback, and diff operations.
|
|
6
|
-
*/
|
|
7
|
-
import type { AgentVersionRecord, DiffResult } from '../../../shared/src/types/agent-version.js';
|
|
8
|
-
/**
|
|
9
|
-
* JSONL-based agent version store.
|
|
10
|
-
*
|
|
11
|
-
* Each slug's versions are stored in `<dirPath>/versions.jsonl`, one JSON
|
|
12
|
-
* object per line. Rollback rewrites the file to update `isCurrent` flags.
|
|
13
|
-
*/
|
|
14
|
-
export declare class AgentVersionStore {
|
|
15
|
-
private readonly dirPath;
|
|
16
|
-
private readonly filePath;
|
|
17
|
-
constructor(dirPath: string);
|
|
18
|
-
private readAll;
|
|
19
|
-
private writeAll;
|
|
20
|
-
/**
|
|
21
|
-
* Save a new version for the given agent slug.
|
|
22
|
-
*
|
|
23
|
-
* Computes a SHA-256 hash of the content, marks all previous versions for
|
|
24
|
-
* the same slug as non-current, and appends the new record.
|
|
25
|
-
*/
|
|
26
|
-
saveVersion(slug: string, content: string, version: string, changelog: string, opts?: {
|
|
27
|
-
deprecated?: boolean;
|
|
28
|
-
deprecatedBy?: string;
|
|
29
|
-
capturedBy?: string;
|
|
30
|
-
}): AgentVersionRecord;
|
|
31
|
-
/**
|
|
32
|
-
* List all versions for a slug, sorted by capturedAt DESC (newest first).
|
|
33
|
-
* Uses insertion order (line index) as a stable tiebreaker.
|
|
34
|
-
*/
|
|
35
|
-
listVersions(slug: string): AgentVersionRecord[];
|
|
36
|
-
/**
|
|
37
|
-
* Get the current active version for a slug, or null.
|
|
38
|
-
*/
|
|
39
|
-
getCurrent(slug: string): AgentVersionRecord | null;
|
|
40
|
-
/**
|
|
41
|
-
* Get a specific version by slug and semver string, or null.
|
|
42
|
-
*/
|
|
43
|
-
getVersion(slug: string, version: string): AgentVersionRecord | null;
|
|
44
|
-
/**
|
|
45
|
-
* Roll back to a specific version.
|
|
46
|
-
*
|
|
47
|
-
* Marks the target version as current and all others for that slug as
|
|
48
|
-
* non-current. Rewrites the JSONL file.
|
|
49
|
-
*
|
|
50
|
-
* @throws Error if the target version does not exist.
|
|
51
|
-
*/
|
|
52
|
-
rollback(slug: string, toVersion: string): AgentVersionRecord;
|
|
53
|
-
/**
|
|
54
|
-
* Compute a line-level diff between two versions of the same agent.
|
|
55
|
-
*
|
|
56
|
-
* @throws Error if either version does not exist.
|
|
57
|
-
*/
|
|
58
|
-
diff(slug: string, fromVersion: string, toVersion: string): DiffResult;
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=version-store.d.ts.map
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Version Store (Task 29)
|
|
3
|
-
*
|
|
4
|
-
* JSONL-based append-only storage for agent definition versions.
|
|
5
|
-
* Supports save, list, get, rollback, and diff operations.
|
|
6
|
-
*/
|
|
7
|
-
import { createHash, randomUUID, randomBytes } from 'crypto';
|
|
8
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs';
|
|
9
|
-
import { join } from 'path';
|
|
10
|
-
import { computeUnifiedDiff } from './version-diff.js';
|
|
11
|
-
import { parseJsonl } from '../utils/parse-jsonl.js';
|
|
12
|
-
function toStored(r) {
|
|
13
|
-
return {
|
|
14
|
-
id: r.id,
|
|
15
|
-
slug: r.slug,
|
|
16
|
-
version: r.version,
|
|
17
|
-
changelog: r.changelog,
|
|
18
|
-
deprecated: r.deprecated,
|
|
19
|
-
deprecatedBy: r.deprecatedBy,
|
|
20
|
-
content: r.content,
|
|
21
|
-
contentHash: r.contentHash,
|
|
22
|
-
capturedAt: r.capturedAt instanceof Date
|
|
23
|
-
? r.capturedAt.toISOString()
|
|
24
|
-
: String(r.capturedAt),
|
|
25
|
-
capturedBy: r.capturedBy,
|
|
26
|
-
isCurrent: r.isCurrent,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function fromStored(s) {
|
|
30
|
-
return {
|
|
31
|
-
id: s.id,
|
|
32
|
-
slug: s.slug,
|
|
33
|
-
version: s.version,
|
|
34
|
-
changelog: s.changelog,
|
|
35
|
-
deprecated: s.deprecated,
|
|
36
|
-
deprecatedBy: s.deprecatedBy,
|
|
37
|
-
content: s.content,
|
|
38
|
-
contentHash: s.contentHash,
|
|
39
|
-
capturedAt: new Date(s.capturedAt),
|
|
40
|
-
capturedBy: s.capturedBy,
|
|
41
|
-
isCurrent: s.isCurrent,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* JSONL-based agent version store.
|
|
46
|
-
*
|
|
47
|
-
* Each slug's versions are stored in `<dirPath>/versions.jsonl`, one JSON
|
|
48
|
-
* object per line. Rollback rewrites the file to update `isCurrent` flags.
|
|
49
|
-
*/
|
|
50
|
-
export class AgentVersionStore {
|
|
51
|
-
dirPath;
|
|
52
|
-
filePath;
|
|
53
|
-
constructor(dirPath) {
|
|
54
|
-
this.dirPath = dirPath;
|
|
55
|
-
if (!existsSync(dirPath)) {
|
|
56
|
-
mkdirSync(dirPath, { recursive: true });
|
|
57
|
-
}
|
|
58
|
-
this.filePath = join(dirPath, 'versions.jsonl');
|
|
59
|
-
}
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
// Persistence helpers
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
readAll() {
|
|
64
|
-
if (!existsSync(this.filePath)) {
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
const stat = statSync(this.filePath);
|
|
68
|
-
if (stat.size > 10 * 1024 * 1024) {
|
|
69
|
-
throw new Error('Version store exceeds size limit; run compaction');
|
|
70
|
-
}
|
|
71
|
-
const raw = readFileSync(this.filePath, 'utf-8');
|
|
72
|
-
// Drop any record whose stored contentHash does not match the SHA-256 of
|
|
73
|
-
// its content. saveVersion advertises tamper-evidence by computing the
|
|
74
|
-
// hash; without this verification step, an attacker who can write the
|
|
75
|
-
// JSONL file can swap `content` with a poisoned agent prompt while
|
|
76
|
-
// leaving `contentHash` unchanged, and the next getCurrent() returns
|
|
77
|
-
// the tampered prompt verbatim into the LLM context.
|
|
78
|
-
const records = parseJsonl(raw);
|
|
79
|
-
const verified = [];
|
|
80
|
-
for (const r of records) {
|
|
81
|
-
if (typeof r?.content !== 'string' ||
|
|
82
|
-
typeof r?.contentHash !== 'string' ||
|
|
83
|
-
typeof r?.id !== 'string' ||
|
|
84
|
-
typeof r?.slug !== 'string' ||
|
|
85
|
-
typeof r?.version !== 'string' ||
|
|
86
|
-
typeof r?.changelog !== 'string' ||
|
|
87
|
-
typeof r?.capturedBy !== 'string' ||
|
|
88
|
-
typeof r?.capturedAt !== 'string')
|
|
89
|
-
continue;
|
|
90
|
-
const actual = createHash('sha256').update(r.content).digest('hex');
|
|
91
|
-
if (actual !== r.contentHash)
|
|
92
|
-
continue; // silently drop tampered record
|
|
93
|
-
verified.push(r);
|
|
94
|
-
}
|
|
95
|
-
return verified.map(fromStored);
|
|
96
|
-
}
|
|
97
|
-
writeAll(records) {
|
|
98
|
-
const lines = records.map((r) => JSON.stringify(toStored(r)));
|
|
99
|
-
const tmp = `${this.filePath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
100
|
-
writeFileSync(tmp, lines.join('\n') + '\n', 'utf-8');
|
|
101
|
-
renameSync(tmp, this.filePath);
|
|
102
|
-
}
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
|
-
// Public API
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
/**
|
|
107
|
-
* Save a new version for the given agent slug.
|
|
108
|
-
*
|
|
109
|
-
* Computes a SHA-256 hash of the content, marks all previous versions for
|
|
110
|
-
* the same slug as non-current, and appends the new record.
|
|
111
|
-
*/
|
|
112
|
-
saveVersion(slug, content, version, changelog, opts = {}) {
|
|
113
|
-
const MAX_CONTENT_BYTES = 512 * 1024;
|
|
114
|
-
if (Buffer.byteLength(content, 'utf-8') > MAX_CONTENT_BYTES) {
|
|
115
|
-
throw new Error(`content exceeds maximum allowed size (${MAX_CONTENT_BYTES} bytes)`);
|
|
116
|
-
}
|
|
117
|
-
const contentHash = createHash('sha256').update(content).digest('hex');
|
|
118
|
-
// SINGLE-WRITER CONTRACT: version-store is written only by the daemon process.
|
|
119
|
-
// Concurrent saveVersion() calls from multiple processes would race on readAll/writeAll.
|
|
120
|
-
// If multi-writer access is needed in future, introduce an advisory lock here.
|
|
121
|
-
const existing = this.readAll();
|
|
122
|
-
for (const rec of existing) {
|
|
123
|
-
if (rec.slug === slug && rec.isCurrent) {
|
|
124
|
-
rec.isCurrent = false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const record = {
|
|
128
|
-
id: randomUUID(),
|
|
129
|
-
slug,
|
|
130
|
-
version,
|
|
131
|
-
changelog,
|
|
132
|
-
deprecated: opts.deprecated ?? false,
|
|
133
|
-
deprecatedBy: opts.deprecatedBy,
|
|
134
|
-
content,
|
|
135
|
-
contentHash,
|
|
136
|
-
capturedAt: new Date(),
|
|
137
|
-
capturedBy: opts.capturedBy ?? 'system',
|
|
138
|
-
isCurrent: true,
|
|
139
|
-
};
|
|
140
|
-
existing.push(record);
|
|
141
|
-
this.writeAll(existing);
|
|
142
|
-
return record;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* List all versions for a slug, sorted by capturedAt DESC (newest first).
|
|
146
|
-
* Uses insertion order (line index) as a stable tiebreaker.
|
|
147
|
-
*/
|
|
148
|
-
listVersions(slug) {
|
|
149
|
-
const all = this.readAll();
|
|
150
|
-
const indexed = all.map((r, i) => ({ r, i }));
|
|
151
|
-
return indexed
|
|
152
|
-
.filter(({ r }) => r.slug === slug)
|
|
153
|
-
.sort((a, b) => {
|
|
154
|
-
const timeDiff = new Date(b.r.capturedAt).getTime() -
|
|
155
|
-
new Date(a.r.capturedAt).getTime();
|
|
156
|
-
return timeDiff !== 0 ? timeDiff : b.i - a.i;
|
|
157
|
-
})
|
|
158
|
-
.map(({ r }) => r);
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Get the current active version for a slug, or null.
|
|
162
|
-
*/
|
|
163
|
-
getCurrent(slug) {
|
|
164
|
-
const all = this.readAll();
|
|
165
|
-
const indexed = all.map((r, i) => ({ r, i }));
|
|
166
|
-
const matching = indexed.filter(({ r }) => r.slug === slug && r.isCurrent);
|
|
167
|
-
if (matching.length === 0)
|
|
168
|
-
return null;
|
|
169
|
-
// Return the most recent current record (insertion order as tiebreaker)
|
|
170
|
-
return matching.sort((a, b) => {
|
|
171
|
-
const timeDiff = new Date(b.r.capturedAt).getTime() -
|
|
172
|
-
new Date(a.r.capturedAt).getTime();
|
|
173
|
-
return timeDiff !== 0 ? timeDiff : b.i - a.i;
|
|
174
|
-
})[0].r;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Get a specific version by slug and semver string, or null.
|
|
178
|
-
*/
|
|
179
|
-
getVersion(slug, version) {
|
|
180
|
-
return (this.readAll().find((r) => r.slug === slug && r.version === version) ?? null);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Roll back to a specific version.
|
|
184
|
-
*
|
|
185
|
-
* Marks the target version as current and all others for that slug as
|
|
186
|
-
* non-current. Rewrites the JSONL file.
|
|
187
|
-
*
|
|
188
|
-
* @throws Error if the target version does not exist.
|
|
189
|
-
*/
|
|
190
|
-
rollback(slug, toVersion) {
|
|
191
|
-
const all = this.readAll();
|
|
192
|
-
let target;
|
|
193
|
-
for (const rec of all) {
|
|
194
|
-
if (rec.slug === slug) {
|
|
195
|
-
if (rec.version === toVersion) {
|
|
196
|
-
rec.isCurrent = true;
|
|
197
|
-
target = rec;
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
rec.isCurrent = false;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (!target) {
|
|
205
|
-
throw new Error(`Version "${toVersion}" not found for agent "${slug}"`);
|
|
206
|
-
}
|
|
207
|
-
this.writeAll(all);
|
|
208
|
-
return target;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Compute a line-level diff between two versions of the same agent.
|
|
212
|
-
*
|
|
213
|
-
* @throws Error if either version does not exist.
|
|
214
|
-
*/
|
|
215
|
-
diff(slug, fromVersion, toVersion) {
|
|
216
|
-
const from = this.getVersion(slug, fromVersion);
|
|
217
|
-
if (!from) {
|
|
218
|
-
throw new Error(`Version "${fromVersion}" not found for agent "${slug}"`);
|
|
219
|
-
}
|
|
220
|
-
const to = this.getVersion(slug, toVersion);
|
|
221
|
-
if (!to) {
|
|
222
|
-
throw new Error(`Version "${toVersion}" not found for agent "${slug}"`);
|
|
223
|
-
}
|
|
224
|
-
const { additions, deletions, hunks } = computeUnifiedDiff(from.content, to.content);
|
|
225
|
-
return {
|
|
226
|
-
slug,
|
|
227
|
-
fromVersion,
|
|
228
|
-
toVersion,
|
|
229
|
-
additions,
|
|
230
|
-
deletions,
|
|
231
|
-
hunks,
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
//# sourceMappingURL=version-store.js.map
|