@stackmemoryai/stackmemory 1.10.5 → 1.14.0
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 +131 -64
- package/README.md +107 -24
- package/bin/claude-sm +16 -1
- package/bin/claude-smd +16 -1
- package/bin/codex-smd +16 -1
- package/bin/gemini-sm +16 -1
- package/bin/hermes-sm +21 -0
- package/bin/hermes-smd +21 -0
- package/bin/opencode-sm +16 -1
- package/dist/src/cli/claude-sm.js +266 -84
- package/dist/src/cli/codex-sm.js +225 -33
- package/dist/src/cli/commands/bench.js +209 -2
- package/dist/src/cli/commands/brain.js +206 -0
- package/dist/src/cli/commands/cache.js +126 -0
- package/dist/src/cli/commands/company-os.js +184 -0
- package/dist/src/cli/commands/context.js +5 -0
- package/dist/src/cli/commands/daemon.js +41 -0
- package/dist/src/cli/commands/handoff.js +40 -9
- package/dist/src/cli/commands/onboard.js +70 -3
- package/dist/src/cli/commands/operator.js +127 -0
- package/dist/src/cli/commands/optimize.js +117 -0
- package/dist/src/cli/commands/orchestrate.js +232 -5
- package/dist/src/cli/commands/orchestrator.js +315 -26
- package/dist/src/cli/commands/pack.js +322 -0
- package/dist/src/cli/commands/patterns.js +254 -0
- package/dist/src/cli/commands/portal.js +161 -0
- package/dist/src/cli/commands/scaffold.js +92 -0
- package/dist/src/cli/commands/search.js +40 -1
- package/dist/src/cli/commands/setup.js +178 -11
- package/dist/src/cli/commands/skills.js +10 -1
- package/dist/src/cli/commands/state.js +265 -0
- package/dist/src/cli/commands/sync.js +253 -0
- package/dist/src/cli/commands/tasks.js +130 -1
- package/dist/src/cli/commands/vision.js +221 -0
- package/dist/src/cli/gemini-sm.js +19 -29
- package/dist/src/cli/hermes-sm.js +224 -0
- package/dist/src/cli/index.js +105 -39
- package/dist/src/cli/opencode-sm.js +38 -21
- package/dist/src/cli/utils/determinism-watcher.js +66 -0
- package/dist/src/cli/utils/real-cli-bin.js +116 -0
- package/dist/src/core/brain/brain-store.js +187 -0
- package/dist/src/core/brain/brain-sync.js +193 -0
- package/dist/src/core/brain/index.js +78 -0
- package/dist/src/core/brain/types.js +10 -0
- package/dist/src/core/cache/content-cache.js +238 -0
- package/dist/src/{integrations/diffmem → core/cache}/index.js +5 -5
- package/dist/src/core/cache/token-estimator.js +39 -0
- package/dist/src/core/config/feature-flags.js +2 -6
- package/dist/src/core/context/frame-database.js +79 -27
- package/dist/src/core/context/recursive-context-manager.js +1 -1
- package/dist/src/core/context/rehydration.js +2 -1
- package/dist/src/core/cross-search/cross-project-search.js +269 -0
- package/dist/src/core/cross-search/index.js +10 -0
- package/dist/src/core/database/sqlite-adapter.js +14 -84
- package/dist/src/core/extensions/provider-adapter.js +5 -0
- package/dist/src/core/models/model-router.js +54 -2
- package/dist/src/core/models/provider-pricing.js +58 -4
- package/dist/src/core/monitoring/logger.js +2 -1
- package/dist/src/core/optimization/trace-optimizer.js +413 -0
- package/dist/src/core/patterns/index.js +22 -0
- package/dist/src/core/patterns/pattern-applier.js +39 -0
- package/dist/src/core/patterns/pattern-observer.js +157 -0
- package/dist/src/core/patterns/pattern-store.js +259 -0
- package/dist/src/core/patterns/types.js +19 -0
- package/dist/src/core/provenance/confidence-scorer.js +128 -0
- package/dist/src/core/provenance/index.js +40 -0
- package/dist/src/core/provenance/provenance-store.js +194 -0
- package/dist/src/core/provenance/types.js +82 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
- package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
- package/dist/src/core/session/project-handoff.js +64 -0
- package/dist/src/core/session/session-manager.js +28 -0
- package/dist/src/core/shared-state/canonical-store.js +564 -0
- package/dist/src/core/skill-packs/index.js +18 -0
- package/dist/src/core/skill-packs/parser.js +42 -0
- package/dist/src/core/skill-packs/registry.js +224 -0
- package/dist/src/core/skill-packs/types.js +79 -0
- package/dist/src/core/storage/cloud-sync-manager.js +116 -0
- package/dist/src/core/storage/cloud-sync.js +574 -0
- package/dist/src/core/storage/two-tier-storage.js +5 -1
- package/dist/src/core/tasks/master-tasks-template.js +43 -0
- package/dist/src/core/tasks/md-task-parser.js +138 -0
- package/dist/src/core/trace/trace-event-store.js +282 -0
- package/dist/src/core/vision/index.js +27 -0
- package/dist/src/core/vision/signals.js +79 -0
- package/dist/src/core/vision/types.js +22 -0
- package/dist/src/core/vision/vision-file.js +146 -0
- package/dist/src/core/vision/vision-loop.js +220 -0
- package/dist/src/core/wiki/wiki-compiler.js +103 -1
- package/dist/src/daemon/daemon-config.js +52 -0
- package/dist/src/daemon/services/desire-path-service.js +566 -0
- package/dist/src/daemon/services/github-service.js +126 -0
- package/dist/src/daemon/services/research-stream-service.js +320 -0
- package/dist/src/daemon/services/telemetry-service.js +192 -0
- package/dist/src/daemon/unified-daemon.js +58 -1
- package/dist/src/features/browser/cli-browser-agent.js +417 -0
- package/dist/src/features/browser/stagehand-workflows.js +578 -0
- package/dist/src/features/operator/adapter-factory.js +62 -0
- package/dist/src/features/operator/browser-adapter.js +109 -0
- package/dist/src/features/operator/desktop-adapter.js +125 -0
- package/dist/src/features/operator/index.js +39 -0
- package/dist/src/features/operator/llm-decision.js +137 -0
- package/dist/src/features/operator/operator-logger.js +92 -0
- package/dist/src/features/operator/overnight-runner.js +327 -0
- package/dist/src/features/operator/screen-adapter.js +91 -0
- package/dist/src/features/operator/session-manager.js +127 -0
- package/dist/src/features/operator/state-machine.js +227 -0
- package/dist/src/features/operator/task-queue.js +81 -0
- package/dist/src/features/portal/index.js +26 -0
- package/dist/src/features/portal/server.js +240 -0
- package/dist/src/features/portal/types.js +14 -0
- package/dist/src/features/portal/ui.js +195 -0
- package/dist/src/features/sweep/pty-wrapper.js +13 -5
- package/dist/src/features/tasks/task-aware-context.js +2 -1
- package/dist/src/features/tui/simple-monitor.js +0 -23
- package/dist/src/features/tui/swarm-monitor.js +8 -66
- package/dist/src/features/web/client/hooks/use-socket.js +12 -0
- package/dist/src/{core/merge/index.js → features/web/client/lib/utils.js} +8 -4
- package/dist/src/features/web/client/next-env.d.js +4 -0
- package/dist/src/features/web/client/stores/session-store.js +12 -0
- package/dist/src/features/web/server/gcp-billing.js +76 -0
- package/dist/src/features/web/server/index.js +10 -0
- package/dist/src/features/web/server/spend-calculator.js +228 -0
- package/dist/src/hooks/schemas.js +6 -1
- package/dist/src/integrations/anthropic/client.js +3 -2
- package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
- package/dist/src/integrations/claude-code/subagent-client.js +307 -11
- package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
- package/dist/src/integrations/github/pr-state.js +158 -0
- package/dist/src/integrations/linear/client.js +4 -1
- package/dist/src/integrations/linear/webhook-retry.js +196 -0
- package/dist/src/integrations/linear/webhook-server.js +18 -22
- package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
- package/dist/src/integrations/mcp/handlers/index.js +40 -84
- package/dist/src/integrations/mcp/server.js +542 -641
- package/dist/src/integrations/mcp/tool-alias-registry.js +297 -0
- package/dist/src/integrations/mcp/tool-definitions.js +152 -682
- package/dist/src/mcp/stackmemory-mcp-server.js +571 -231
- package/dist/src/orchestrators/multimodal/determinism.js +244 -0
- package/dist/src/orchestrators/multimodal/harness.js +149 -78
- package/dist/src/orchestrators/multimodal/providers.js +44 -3
- package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
- package/dist/src/utils/hook-installer.js +0 -8
- package/dist/src/utils/process-cleanup.js +1 -7
- package/docs/README.md +42 -0
- package/docs/guides/README_INSTALL.md +208 -0
- package/package.json +27 -9
- package/packs/coding/python-fastapi/instructions.md +60 -0
- package/packs/coding/python-fastapi/pack.yaml +28 -0
- package/packs/coding/typescript-react/instructions.md +47 -0
- package/packs/coding/typescript-react/pack.yaml +28 -0
- package/packs/core/commands/capture.md +32 -0
- package/packs/core/commands/learn.md +73 -0
- package/packs/core/commands/next.md +36 -0
- package/packs/core/commands/restart.md +58 -0
- package/packs/core/commands/restore.md +29 -0
- package/packs/core/commands/start.md +57 -0
- package/packs/core/commands/stop.md +65 -0
- package/packs/core/commands/summary.md +40 -0
- package/packs/core/manifest.json +24 -0
- package/packs/ops/decision-recovery/instructions.md +65 -0
- package/packs/ops/decision-recovery/pack.yaml +89 -0
- package/scripts/claude-code-wrapper.sh +11 -0
- package/scripts/claude-sm-setup.sh +12 -1
- package/scripts/codex-wrapper.sh +11 -0
- package/scripts/git-hooks/branch-context-manager.sh +11 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
- package/scripts/hooks/cleanup-shell.sh +12 -1
- package/scripts/hooks/task-complete.sh +12 -1
- package/scripts/install-code-execution-hooks.sh +12 -1
- package/scripts/install-sweep-hook.sh +12 -0
- package/scripts/install.sh +11 -0
- package/scripts/opencode-wrapper.sh +11 -0
- package/scripts/portal/cloud-init.yaml +69 -0
- package/scripts/portal/setup.sh +69 -0
- package/scripts/portal/stackmemory-portal.service +34 -0
- package/scripts/setup-claude-integration.sh +12 -1
- package/scripts/smoke-init-db.sh +23 -0
- package/scripts/stackmemory-daemon.sh +11 -0
- package/scripts/verify-dist.cjs +11 -4
- package/dist/src/cli/commands/ralph.js +0 -1053
- package/dist/src/cli/commands/team.js +0 -168
- package/dist/src/core/context/shared-context-layer.js +0 -620
- package/dist/src/core/context/stack-merge-resolver.js +0 -748
- package/dist/src/core/merge/conflict-detector.js +0 -430
- package/dist/src/core/merge/resolution-engine.js +0 -557
- package/dist/src/core/merge/stack-diff.js +0 -531
- package/dist/src/core/merge/unified-merge-resolver.js +0 -302
- package/dist/src/hooks/diffmem-hooks.js +0 -376
- package/dist/src/integrations/diffmem/client.js +0 -208
- package/dist/src/integrations/diffmem/config.js +0 -14
- package/dist/src/integrations/greptile/client.js +0 -101
- package/dist/src/integrations/greptile/config.js +0 -14
- package/dist/src/integrations/greptile/index.js +0 -11
- package/dist/src/integrations/mcp/handlers/cord-handlers.js +0 -397
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
- package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
- package/dist/src/integrations/mcp/handlers/team-handlers.js +0 -211
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
- package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -391
- package/dist/src/integrations/ralph/index.js +0 -17
- package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -435
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/src/integrations/ralph/loopmax.js +0 -488
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
- package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1007
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
- package/scripts/ralph-loop-implementation.js +0 -404
- /package/dist/src/core/{merge → cache}/types.js +0 -0
- /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
- /package/dist/src/{integrations/greptile/types.js → core/trace/trace-event.js} +0 -0
- /package/dist/src/{integrations/ralph → features/operator}/types.js +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
+
import { dirname as __pathDirname } from 'path';
|
|
3
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { createHash } from "crypto";
|
|
6
|
+
import { estimateTokens } from "../../core/cache/token-estimator.js";
|
|
7
|
+
import {
|
|
8
|
+
appendFileSync,
|
|
9
|
+
existsSync,
|
|
10
|
+
mkdirSync,
|
|
11
|
+
readFileSync,
|
|
12
|
+
writeFileSync
|
|
13
|
+
} from "fs";
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { compactPlan } from "./utils.js";
|
|
16
|
+
import { runSpike } from "./harness.js";
|
|
17
|
+
const DETERMINISM_WATCH_PATTERNS = [
|
|
18
|
+
"src/orchestrators/multimodal",
|
|
19
|
+
"src/cli/commands/bench.ts",
|
|
20
|
+
"src/cli/index.ts",
|
|
21
|
+
"src/core/monitoring/logger.ts"
|
|
22
|
+
];
|
|
23
|
+
const DETERMINISM_WATCH_IGNORE = [
|
|
24
|
+
".git/**",
|
|
25
|
+
"node_modules/**",
|
|
26
|
+
"dist/**",
|
|
27
|
+
"build/**",
|
|
28
|
+
".next/**",
|
|
29
|
+
".turbo/**",
|
|
30
|
+
"coverage/**",
|
|
31
|
+
".stackmemory/**"
|
|
32
|
+
];
|
|
33
|
+
function stableStringify(value) {
|
|
34
|
+
return JSON.stringify(canonicalize(value));
|
|
35
|
+
}
|
|
36
|
+
function canonicalize(value) {
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.map((item) => canonicalize(item));
|
|
39
|
+
}
|
|
40
|
+
if (value && typeof value === "object") {
|
|
41
|
+
const entries = Object.entries(value).sort(
|
|
42
|
+
([a], [b]) => a.localeCompare(b)
|
|
43
|
+
);
|
|
44
|
+
return Object.fromEntries(
|
|
45
|
+
entries.map(([key, entryValue]) => [key, canonicalize(entryValue)])
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function hashValue(value) {
|
|
51
|
+
return createHash("sha256").update(stableStringify(value)).digest("hex");
|
|
52
|
+
}
|
|
53
|
+
function modeAgreement(values) {
|
|
54
|
+
if (values.length === 0) return 1;
|
|
55
|
+
const counts = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const value of values) {
|
|
57
|
+
counts.set(value, (counts.get(value) || 0) + 1);
|
|
58
|
+
}
|
|
59
|
+
const maxCount = Math.max(...counts.values());
|
|
60
|
+
return maxCount / values.length;
|
|
61
|
+
}
|
|
62
|
+
function normalizeResult(result) {
|
|
63
|
+
return {
|
|
64
|
+
plan: compactPlan(result.plan),
|
|
65
|
+
critique: canonicalize(result.critique),
|
|
66
|
+
implementation: {
|
|
67
|
+
success: result.implementation.success,
|
|
68
|
+
summary: result.implementation.summary,
|
|
69
|
+
commands: [...result.implementation.commands || []]
|
|
70
|
+
},
|
|
71
|
+
iterations: (result.iterations || []).map((iteration) => ({
|
|
72
|
+
command: iteration.command,
|
|
73
|
+
ok: iteration.ok,
|
|
74
|
+
critique: canonicalize(iteration.critique),
|
|
75
|
+
outputPreviewHash: hashValue(iteration.outputPreview)
|
|
76
|
+
}))
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function estimateContextTokens(result) {
|
|
80
|
+
const normalized = normalizeResult(result);
|
|
81
|
+
return estimateTokens(stableStringify(normalized));
|
|
82
|
+
}
|
|
83
|
+
function toSnapshot(result, index) {
|
|
84
|
+
const normalized = normalizeResult(result);
|
|
85
|
+
return {
|
|
86
|
+
index,
|
|
87
|
+
approved: result.critique.approved,
|
|
88
|
+
iterations: (result.iterations || []).length,
|
|
89
|
+
planHash: hashValue(compactPlan(result.plan)),
|
|
90
|
+
critiqueHash: hashValue(canonicalize(result.critique)),
|
|
91
|
+
commandsHash: hashValue(result.implementation.commands || []),
|
|
92
|
+
resultHash: hashValue(normalized),
|
|
93
|
+
contextTokens: estimateContextTokens(result)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function computeNumericStability(values) {
|
|
97
|
+
if (values.length <= 1) return 1;
|
|
98
|
+
const min = Math.min(...values);
|
|
99
|
+
const max = Math.max(...values);
|
|
100
|
+
if (max === min) return 1;
|
|
101
|
+
return Math.max(0, 1 - (max - min) / Math.max(max, 1));
|
|
102
|
+
}
|
|
103
|
+
function scoreReport(snapshots) {
|
|
104
|
+
const dimensions = [
|
|
105
|
+
{
|
|
106
|
+
name: "result",
|
|
107
|
+
weight: 40,
|
|
108
|
+
score: modeAgreement(snapshots.map((item) => item.resultHash)) * 100,
|
|
109
|
+
details: "Full normalized result hash agreement"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "plan",
|
|
113
|
+
weight: 20,
|
|
114
|
+
score: modeAgreement(snapshots.map((item) => item.planHash)) * 100,
|
|
115
|
+
details: "Plan structure hash agreement"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: "critique",
|
|
119
|
+
weight: 15,
|
|
120
|
+
score: modeAgreement(snapshots.map((item) => item.critiqueHash)) * 100,
|
|
121
|
+
details: "Critique hash agreement"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "commands",
|
|
125
|
+
weight: 10,
|
|
126
|
+
score: modeAgreement(snapshots.map((item) => item.commandsHash)) * 100,
|
|
127
|
+
details: "Implementer command sequence agreement"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "iterations",
|
|
131
|
+
weight: 10,
|
|
132
|
+
score: modeAgreement(snapshots.map((item) => item.iterations)) * 100,
|
|
133
|
+
details: "Retry-count agreement"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "context_tokens",
|
|
137
|
+
weight: 5,
|
|
138
|
+
score: computeNumericStability(snapshots.map((item) => item.contextTokens)) * 100,
|
|
139
|
+
details: "Token-footprint stability"
|
|
140
|
+
}
|
|
141
|
+
];
|
|
142
|
+
const weightedScore = dimensions.reduce((sum, dimension) => {
|
|
143
|
+
return sum + dimension.score * dimension.weight;
|
|
144
|
+
}, 0);
|
|
145
|
+
const totalWeight = dimensions.reduce(
|
|
146
|
+
(sum, dimension) => sum + dimension.weight,
|
|
147
|
+
0
|
|
148
|
+
);
|
|
149
|
+
const score = totalWeight > 0 ? weightedScore / totalWeight : 0;
|
|
150
|
+
const recommendations = [];
|
|
151
|
+
if (dimensions[0].score < 100) {
|
|
152
|
+
recommendations.push(
|
|
153
|
+
"Pin planner/critic outputs behind deterministic fixtures or replay traces."
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (dimensions[1].score < 100) {
|
|
157
|
+
recommendations.push(
|
|
158
|
+
"Canonicalize plan generation further and remove any model-dependent fields from smoke checks."
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
if (dimensions[4].score < 100) {
|
|
162
|
+
recommendations.push(
|
|
163
|
+
"Tighten retry rules so the same failure mode produces the same iteration count."
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (dimensions[5].score < 100) {
|
|
167
|
+
recommendations.push(
|
|
168
|
+
"Reduce context assembly drift by sorting symbols and fixing token accounting."
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
runs: snapshots.length,
|
|
173
|
+
score: Math.round(score * 100) / 100,
|
|
174
|
+
snapshots,
|
|
175
|
+
dimensions,
|
|
176
|
+
recommendations
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
async function runDeterminismSmoke(input, options = {}) {
|
|
180
|
+
const runs = Math.max(1, options.runs ?? 5);
|
|
181
|
+
const snapshots = [];
|
|
182
|
+
for (let index = 0; index < runs; index++) {
|
|
183
|
+
const result = await runSpike(input, {
|
|
184
|
+
...options,
|
|
185
|
+
dryRun: options.dryRun ?? true,
|
|
186
|
+
deterministicFixture: options.deterministicFixture ?? true,
|
|
187
|
+
persistAudit: false,
|
|
188
|
+
record: false,
|
|
189
|
+
recordFrame: false
|
|
190
|
+
});
|
|
191
|
+
snapshots.push(toSnapshot(result, index + 1));
|
|
192
|
+
}
|
|
193
|
+
return scoreReport(snapshots);
|
|
194
|
+
}
|
|
195
|
+
function getDeterminismWatchTargets(repoPath) {
|
|
196
|
+
const existingTargets = DETERMINISM_WATCH_PATTERNS.filter(
|
|
197
|
+
(target) => existsSync(join(repoPath, target))
|
|
198
|
+
);
|
|
199
|
+
if (existingTargets.length > 0) {
|
|
200
|
+
return existingTargets;
|
|
201
|
+
}
|
|
202
|
+
return ["."];
|
|
203
|
+
}
|
|
204
|
+
function getDeterminismDir(repoPath) {
|
|
205
|
+
return join(repoPath, ".stackmemory", "determinism");
|
|
206
|
+
}
|
|
207
|
+
function persistDeterminismReport(repoPath, report, meta) {
|
|
208
|
+
const dir = getDeterminismDir(repoPath);
|
|
209
|
+
mkdirSync(dir, { recursive: true });
|
|
210
|
+
const stored = {
|
|
211
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
212
|
+
task: meta.task,
|
|
213
|
+
trigger: meta.trigger,
|
|
214
|
+
changedPaths: meta.changedPaths || [],
|
|
215
|
+
report
|
|
216
|
+
};
|
|
217
|
+
writeFileSync(
|
|
218
|
+
join(dir, "latest.json"),
|
|
219
|
+
JSON.stringify(stored, null, 2) + "\n"
|
|
220
|
+
);
|
|
221
|
+
appendFileSync(join(dir, "history.jsonl"), JSON.stringify(stored) + "\n");
|
|
222
|
+
return stored;
|
|
223
|
+
}
|
|
224
|
+
function readLatestDeterminismReport(repoPath) {
|
|
225
|
+
const latestPath = join(getDeterminismDir(repoPath), "latest.json");
|
|
226
|
+
if (!existsSync(latestPath)) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
return JSON.parse(
|
|
231
|
+
readFileSync(latestPath, "utf8")
|
|
232
|
+
);
|
|
233
|
+
} catch {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
export {
|
|
238
|
+
DETERMINISM_WATCH_IGNORE,
|
|
239
|
+
DETERMINISM_WATCH_PATTERNS,
|
|
240
|
+
getDeterminismWatchTargets,
|
|
241
|
+
persistDeterminismReport,
|
|
242
|
+
readLatestDeterminismReport,
|
|
243
|
+
runDeterminismSmoke
|
|
244
|
+
};
|
|
@@ -2,6 +2,7 @@ import { fileURLToPath as __fileURLToPath } from 'url';
|
|
|
2
2
|
import { dirname as __pathDirname } from 'path';
|
|
3
3
|
const __filename = __fileURLToPath(import.meta.url);
|
|
4
4
|
const __dirname = __pathDirname(__filename);
|
|
5
|
+
import { estimateTokens } from "../../core/cache/token-estimator.js";
|
|
5
6
|
import {
|
|
6
7
|
callClaude,
|
|
7
8
|
callCodexCLI,
|
|
@@ -51,6 +52,45 @@ function heuristicPlan(input) {
|
|
|
51
52
|
]
|
|
52
53
|
};
|
|
53
54
|
}
|
|
55
|
+
function deterministicCritique(args) {
|
|
56
|
+
const issues = [];
|
|
57
|
+
const suggestions = [];
|
|
58
|
+
if (!args.ok) {
|
|
59
|
+
issues.push("Implementer command failed");
|
|
60
|
+
suggestions.push("Fix the command invocation before retrying");
|
|
61
|
+
}
|
|
62
|
+
if (args.diff.includes("<<<<<<<") || args.diff.includes(">>>>>>>")) {
|
|
63
|
+
issues.push("Merge conflict markers detected in diff");
|
|
64
|
+
suggestions.push("Resolve conflict markers before approval");
|
|
65
|
+
}
|
|
66
|
+
if (args.checks && !args.checks.lintOk) {
|
|
67
|
+
issues.push("Lint checks failed");
|
|
68
|
+
suggestions.push("Address lint failures before approval");
|
|
69
|
+
}
|
|
70
|
+
if (args.checks && !args.checks.testsOk) {
|
|
71
|
+
issues.push("Tests failed");
|
|
72
|
+
suggestions.push("Fix failing tests before approval");
|
|
73
|
+
}
|
|
74
|
+
const failedVerifications = args.checks?.verifications.filter((verification) => !verification.ok) || [];
|
|
75
|
+
if (failedVerifications.length > 0) {
|
|
76
|
+
issues.push(
|
|
77
|
+
`Verification command failed: ${failedVerifications[0]?.command}`
|
|
78
|
+
);
|
|
79
|
+
suggestions.push(
|
|
80
|
+
"Use the verification output as the primary repro signal and fix the root cause"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (!args.diff || args.diff.startsWith("(no changes detected)")) {
|
|
84
|
+
suggestions.push(
|
|
85
|
+
"No code changes detected; verify the task can be satisfied without edits"
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
approved: issues.length === 0,
|
|
90
|
+
issues,
|
|
91
|
+
suggestions
|
|
92
|
+
};
|
|
93
|
+
}
|
|
54
94
|
async function runSpike(input, options = {}) {
|
|
55
95
|
const plannerSystem = `You write concise, actionable implementation plans. Output raw JSON only (no markdown code fences). Schema: { "summary": "string", "steps": [{ "id": "step-1", "title": "string", "rationale": "string", "acceptanceCriteria": ["string"] }], "risks": ["string"] }`;
|
|
56
96
|
const contextSummary = getLocalContextSummary(input.repoPath);
|
|
@@ -61,23 +101,28 @@ ${contextSummary}
|
|
|
61
101
|
Constraints: Keep the plan minimal and implementable in a single PR.`;
|
|
62
102
|
const t0 = Date.now();
|
|
63
103
|
let plan;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
system: plannerSystem
|
|
68
|
-
});
|
|
104
|
+
if (options.deterministicFixture) {
|
|
105
|
+
plan = heuristicPlan(input);
|
|
106
|
+
} else {
|
|
69
107
|
try {
|
|
70
|
-
const
|
|
71
|
-
|
|
108
|
+
const raw = await callClaude(plannerPrompt, {
|
|
109
|
+
model: options.plannerModel,
|
|
110
|
+
system: plannerSystem
|
|
111
|
+
});
|
|
112
|
+
try {
|
|
113
|
+
const cleaned = raw.replace(/^```(?:json)?\s*\n?/i, "").replace(/\n?```\s*$/i, "").trim();
|
|
114
|
+
plan = JSON.parse(cleaned);
|
|
115
|
+
} catch {
|
|
116
|
+
plan = heuristicPlan(input);
|
|
117
|
+
}
|
|
72
118
|
} catch {
|
|
73
119
|
plan = heuristicPlan(input);
|
|
74
120
|
}
|
|
75
|
-
} catch {
|
|
76
|
-
plan = heuristicPlan(input);
|
|
77
121
|
}
|
|
78
122
|
const planLatencyMs = Date.now() - t0;
|
|
79
123
|
const implementer = options.implementer || "codex";
|
|
80
124
|
const maxIters = Math.max(1, options.maxIters ?? 2);
|
|
125
|
+
const verificationCommands = options.verificationCommands || [];
|
|
81
126
|
const iterations = [];
|
|
82
127
|
let approved = false;
|
|
83
128
|
let lastCommand = "";
|
|
@@ -89,10 +134,14 @@ Constraints: Keep the plan minimal and implementable in a single PR.`;
|
|
|
89
134
|
};
|
|
90
135
|
for (let i = 0; i < maxIters; i++) {
|
|
91
136
|
const stepsList = plan.steps.map((s, idx) => `${idx + 1}. ${s.title}`).join("\n");
|
|
137
|
+
const verificationPrompt = verificationCommands.length > 0 ? `
|
|
138
|
+
|
|
139
|
+
Verification commands that must pass:
|
|
140
|
+
${verificationCommands.map((command) => `- ${command}`).join("\n")}` : "\n\nIf this task fixes uncertain behavior, first create or identify a deterministic repro/test/trace that fails for the current behavior, then use it to guide the fix.";
|
|
92
141
|
const basePrompt = `Implement the following plan:
|
|
93
142
|
${stepsList}
|
|
94
143
|
|
|
95
|
-
Keep changes minimal and focused. Avoid unrelated edits
|
|
144
|
+
Keep changes minimal and focused. Avoid unrelated edits.${verificationPrompt}`;
|
|
96
145
|
const refine = i === 0 ? "" : `
|
|
97
146
|
Incorporate reviewer suggestions: ${lastCritique.suggestions.join("; ")}`;
|
|
98
147
|
const implPrompt = basePrompt + refine;
|
|
@@ -116,14 +165,20 @@ Incorporate reviewer suggestions: ${lastCritique.suggestions.join("; ")}`;
|
|
|
116
165
|
_lastOutput = impl.output;
|
|
117
166
|
}
|
|
118
167
|
const diff = options.dryRun !== false ? "(dry run \u2014 no diff)" : captureGitDiff(input.repoPath);
|
|
119
|
-
const checks = options.dryRun !== false ? null : runPostImplChecks(input.repoPath);
|
|
168
|
+
const checks = options.dryRun !== false ? null : runPostImplChecks(input.repoPath, verificationCommands);
|
|
169
|
+
const verificationSection = checks && checks.verifications.length > 0 ? `
|
|
170
|
+
Custom verification:
|
|
171
|
+
${checks.verifications.map(
|
|
172
|
+
(verification) => ` - ${verification.ok ? "PASS" : "FAIL"} ${verification.command}
|
|
173
|
+
${verification.output}`
|
|
174
|
+
).join("\n")}` : "";
|
|
120
175
|
const checksSection = checks ? `
|
|
121
176
|
|
|
122
177
|
Post-implementation checks:
|
|
123
178
|
Lint: ${checks.lintOk ? "PASS" : "FAIL"}
|
|
124
179
|
${checks.lintOutput}
|
|
125
180
|
Tests: ${checks.testsOk ? "PASS" : "FAIL"}
|
|
126
|
-
${checks.testOutput}` : "";
|
|
181
|
+
${checks.testOutput}${verificationSection}` : "";
|
|
127
182
|
const criticSystem = `You are a strict code reviewer. Review the git diff against the plan. Check for: correctness, missing steps, unrelated changes, bugs, security issues. Also review lint and test results if provided. Return raw JSON only (no markdown fences): { "approved": boolean, "issues": ["string"], "suggestions": ["string"] }`;
|
|
128
183
|
const criticPrompt = `Plan: ${plan.summary}
|
|
129
184
|
Acceptance criteria:
|
|
@@ -134,25 +189,35 @@ Implementer exit: ${ok ? "success" : "failed"}
|
|
|
134
189
|
|
|
135
190
|
Git diff:
|
|
136
191
|
${diff}${checksSection}`;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
192
|
+
if (options.deterministicFixture) {
|
|
193
|
+
lastCritique = deterministicCritique({
|
|
194
|
+
plan,
|
|
195
|
+
ok,
|
|
196
|
+
diff,
|
|
197
|
+
checks
|
|
141
198
|
});
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
199
|
+
} else {
|
|
200
|
+
try {
|
|
201
|
+
const raw = await callClaude(criticPrompt, {
|
|
202
|
+
model: options.reviewerModel,
|
|
203
|
+
system: criticSystem
|
|
204
|
+
});
|
|
205
|
+
const cleaned = raw.replace(/^```(?:json)?\s*\n?/i, "").replace(/\n?```\s*$/i, "").trim();
|
|
206
|
+
lastCritique = JSON.parse(cleaned);
|
|
207
|
+
} catch {
|
|
208
|
+
lastCritique = {
|
|
209
|
+
approved: ok,
|
|
210
|
+
issues: ok ? [] : ["Critique failed"],
|
|
211
|
+
suggestions: []
|
|
212
|
+
};
|
|
213
|
+
}
|
|
150
214
|
}
|
|
151
215
|
iterations.push({
|
|
152
216
|
command: lastCommand,
|
|
153
217
|
ok,
|
|
154
218
|
outputPreview: diff.slice(0, 2e3),
|
|
155
|
-
critique: lastCritique
|
|
219
|
+
critique: lastCritique,
|
|
220
|
+
checks
|
|
156
221
|
});
|
|
157
222
|
if (lastCritique.approved) {
|
|
158
223
|
approved = true;
|
|
@@ -175,64 +240,66 @@ ${diff}${checksSection}`;
|
|
|
175
240
|
editAttempts: editMetrics.editAttempts,
|
|
176
241
|
editSuccesses: editMetrics.editSuccesses,
|
|
177
242
|
editFuzzyFallbacks: editMetrics.editFuzzyFallbacks,
|
|
178
|
-
contextTokens:
|
|
243
|
+
contextTokens: estimateTokens(finalDiff)
|
|
179
244
|
};
|
|
180
|
-
|
|
181
|
-
const dir = options.auditDir || path.join(input.repoPath, ".stackmemory", "build");
|
|
182
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
183
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
184
|
-
const file = path.join(dir, `spike-${stamp}.json`);
|
|
185
|
-
fs.writeFileSync(
|
|
186
|
-
file,
|
|
187
|
-
JSON.stringify(
|
|
188
|
-
{
|
|
189
|
-
input,
|
|
190
|
-
options: { ...options, auditDir: void 0 },
|
|
191
|
-
plan,
|
|
192
|
-
iterations,
|
|
193
|
-
metrics: runMetrics
|
|
194
|
-
},
|
|
195
|
-
null,
|
|
196
|
-
2
|
|
197
|
-
)
|
|
198
|
-
);
|
|
199
|
-
const metricsFile = path.join(dir, "harness-metrics.jsonl");
|
|
200
|
-
fs.appendFileSync(metricsFile, JSON.stringify(runMetrics) + "\n");
|
|
245
|
+
if (options.persistAudit !== false) {
|
|
201
246
|
try {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
247
|
+
const dir = options.auditDir || path.join(input.repoPath, ".stackmemory", "build");
|
|
248
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
249
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
250
|
+
const file = path.join(dir, `spike-${stamp}.json`);
|
|
251
|
+
fs.writeFileSync(
|
|
252
|
+
file,
|
|
253
|
+
JSON.stringify(
|
|
254
|
+
{
|
|
255
|
+
input,
|
|
256
|
+
options: { ...options, auditDir: void 0 },
|
|
257
|
+
plan,
|
|
258
|
+
iterations,
|
|
259
|
+
metrics: runMetrics
|
|
260
|
+
},
|
|
261
|
+
null,
|
|
262
|
+
2
|
|
263
|
+
)
|
|
264
|
+
);
|
|
265
|
+
const metricsFile = path.join(dir, "harness-metrics.jsonl");
|
|
266
|
+
fs.appendFileSync(metricsFile, JSON.stringify(runMetrics) + "\n");
|
|
267
|
+
try {
|
|
268
|
+
const lines = fs.readFileSync(metricsFile, "utf-8").split("\n").filter((l) => l.trim());
|
|
269
|
+
const recent = lines.slice(-10).map((l) => JSON.parse(l));
|
|
270
|
+
if (recent.length >= 3) {
|
|
271
|
+
const summary = summarizeRuns(recent);
|
|
272
|
+
if (summary.approvalRate < HARNESS_TARGETS.firstPassApprovalRate) {
|
|
273
|
+
feedbackLoops.fire(
|
|
274
|
+
"harnessRegression",
|
|
275
|
+
"metrics_append",
|
|
276
|
+
{
|
|
277
|
+
metric: "approvalRate",
|
|
278
|
+
current: summary.approvalRate,
|
|
279
|
+
target: HARNESS_TARGETS.firstPassApprovalRate,
|
|
280
|
+
window: recent.length
|
|
281
|
+
},
|
|
282
|
+
"regression_alert"
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
if (summary.p95TotalLatencyMs > HARNESS_TARGETS.totalLatencyP95Ms) {
|
|
286
|
+
feedbackLoops.fire(
|
|
287
|
+
"harnessRegression",
|
|
288
|
+
"metrics_append",
|
|
289
|
+
{
|
|
290
|
+
metric: "totalLatencyP95",
|
|
291
|
+
current: summary.p95TotalLatencyMs,
|
|
292
|
+
target: HARNESS_TARGETS.totalLatencyP95Ms,
|
|
293
|
+
window: recent.length
|
|
294
|
+
},
|
|
295
|
+
"regression_alert"
|
|
296
|
+
);
|
|
297
|
+
}
|
|
231
298
|
}
|
|
299
|
+
} catch {
|
|
232
300
|
}
|
|
233
301
|
} catch {
|
|
234
302
|
}
|
|
235
|
-
} catch {
|
|
236
303
|
}
|
|
237
304
|
if (options.record) {
|
|
238
305
|
void recordContext(
|
|
@@ -265,7 +332,8 @@ ${diff}${checksSection}`;
|
|
|
265
332
|
commands: iterations.map((it) => it.command)
|
|
266
333
|
},
|
|
267
334
|
critique: lastCritique,
|
|
268
|
-
iterations
|
|
335
|
+
iterations,
|
|
336
|
+
verification: iterations.at(-1)?.checks || null
|
|
269
337
|
};
|
|
270
338
|
}
|
|
271
339
|
const runPlanAndCode = runSpike;
|
|
@@ -341,6 +409,9 @@ Repo: ${input.repoPath}
|
|
|
341
409
|
Notes: ${input.contextNotes || "(none)"}
|
|
342
410
|
${contextSummary}
|
|
343
411
|
Constraints: Keep the plan minimal and implementable in a single PR.`;
|
|
412
|
+
if (options.deterministicFixture) {
|
|
413
|
+
return heuristicPlan(input);
|
|
414
|
+
}
|
|
344
415
|
try {
|
|
345
416
|
const raw = await callClaude(plannerPrompt, {
|
|
346
417
|
model: options.plannerModel,
|
|
@@ -115,7 +115,7 @@ ${newFiles.join("\n")}`;
|
|
|
115
115
|
return "(git diff failed)";
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
-
function runPostImplChecks(cwd) {
|
|
118
|
+
function runPostImplChecks(cwd, verificationCommands = []) {
|
|
119
119
|
const maxOutput = 2e3;
|
|
120
120
|
function truncate(s) {
|
|
121
121
|
if (s.length <= maxOutput) return s;
|
|
@@ -152,7 +152,47 @@ function runPostImplChecks(cwd) {
|
|
|
152
152
|
} catch (e) {
|
|
153
153
|
testOutput = truncate(e instanceof Error ? e.message : String(e));
|
|
154
154
|
}
|
|
155
|
-
return {
|
|
155
|
+
return {
|
|
156
|
+
lintOk,
|
|
157
|
+
lintOutput,
|
|
158
|
+
testsOk,
|
|
159
|
+
testOutput,
|
|
160
|
+
verifications: runVerificationCommands(cwd, verificationCommands)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function runVerificationCommands(cwd, commands, options = {}) {
|
|
164
|
+
const timeout = options.timeoutMs ?? 12e4;
|
|
165
|
+
const maxOutput = options.maxOutput ?? 4e3;
|
|
166
|
+
const truncate = (value) => {
|
|
167
|
+
if (value.length <= maxOutput) return value;
|
|
168
|
+
return value.slice(0, maxOutput) + `
|
|
169
|
+
... (truncated, ${value.length} total chars)`;
|
|
170
|
+
};
|
|
171
|
+
return commands.map((command) => command.trim()).filter(Boolean).map((command) => {
|
|
172
|
+
try {
|
|
173
|
+
const result = spawnSync(command, {
|
|
174
|
+
cwd,
|
|
175
|
+
encoding: "utf8",
|
|
176
|
+
shell: true,
|
|
177
|
+
timeout,
|
|
178
|
+
maxBuffer: Math.max(maxOutput * 4, 1024 * 1024)
|
|
179
|
+
});
|
|
180
|
+
const output = truncate((result.stdout || "") + (result.stderr || ""));
|
|
181
|
+
return {
|
|
182
|
+
command,
|
|
183
|
+
ok: result.status === 0,
|
|
184
|
+
output: output || (result.status === 0 ? "(command completed with no output)" : `(command failed with exit ${result.status ?? "unknown"})`)
|
|
185
|
+
};
|
|
186
|
+
} catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
command,
|
|
189
|
+
ok: false,
|
|
190
|
+
output: truncate(
|
|
191
|
+
error instanceof Error ? error.message : String(error)
|
|
192
|
+
)
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
});
|
|
156
196
|
}
|
|
157
197
|
function parseEditMetrics(diff) {
|
|
158
198
|
if (!diff || diff.startsWith("(")) {
|
|
@@ -204,5 +244,6 @@ export {
|
|
|
204
244
|
captureGitDiff,
|
|
205
245
|
implementWithClaude,
|
|
206
246
|
parseEditMetrics,
|
|
207
|
-
runPostImplChecks
|
|
247
|
+
runPostImplChecks,
|
|
248
|
+
runVerificationCommands
|
|
208
249
|
};
|
|
@@ -5,6 +5,7 @@ const __dirname = __pathDirname(__filename);
|
|
|
5
5
|
import * as fs from "fs";
|
|
6
6
|
import * as path from "path";
|
|
7
7
|
import { logger } from "../core/monitoring/logger.js";
|
|
8
|
+
import { estimateTokens } from "../core/cache/token-estimator.js";
|
|
8
9
|
import { ParallelExecutor } from "../core/execution/parallel-executor.js";
|
|
9
10
|
import { RecursiveContextManager } from "../core/context/recursive-context-manager.js";
|
|
10
11
|
import { ClaudeCodeSubagentClient } from "../integrations/claude-code/subagent-client.js";
|
|
@@ -345,7 +346,7 @@ Rules:
|
|
|
345
346
|
context: agentContext
|
|
346
347
|
});
|
|
347
348
|
node.result = response.result;
|
|
348
|
-
node.tokens = response.tokens ||
|
|
349
|
+
node.tokens = response.tokens || estimateTokens(JSON.stringify(response));
|
|
349
350
|
node.cost = this.calculateNodeCost(node.tokens, agentConfig.model);
|
|
350
351
|
if (options.shareContextRealtime) {
|
|
351
352
|
await this.shareAgentResults(node);
|
|
@@ -527,9 +528,6 @@ ${sections.join("\n\n")}` : "";
|
|
|
527
528
|
`- Output structured JSON when possible`
|
|
528
529
|
].join("\n");
|
|
529
530
|
}
|
|
530
|
-
estimateTokens(text) {
|
|
531
|
-
return Math.ceil(text.length / 4);
|
|
532
|
-
}
|
|
533
531
|
async shareAgentResults(_node) {
|
|
534
532
|
logger.debug("Sharing agent results", { nodeId: _node.id });
|
|
535
533
|
}
|
|
@@ -32,14 +32,6 @@ const CANONICAL_HOOKS = [
|
|
|
32
32
|
commandPrefix: "node",
|
|
33
33
|
required: true
|
|
34
34
|
},
|
|
35
|
-
{
|
|
36
|
-
scriptName: "cord-trace.js",
|
|
37
|
-
eventType: "PostToolUse",
|
|
38
|
-
matcher: "mcp__.*__cord_(spawn|fork|complete|ask|tree)",
|
|
39
|
-
timeout: 2,
|
|
40
|
-
commandPrefix: "node",
|
|
41
|
-
required: true
|
|
42
|
-
},
|
|
43
35
|
{
|
|
44
36
|
scriptName: "theory-capture.js",
|
|
45
37
|
eventType: "PostToolUse",
|
|
@@ -15,13 +15,7 @@ function isProcessAlive(pid) {
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
const STACKMEMORY_PROCESS_PATTERNS = [
|
|
19
|
-
"stackmemory",
|
|
20
|
-
"ralph orchestrate",
|
|
21
|
-
"ralph swarm",
|
|
22
|
-
"ralph loop",
|
|
23
|
-
"hooks start"
|
|
24
|
-
];
|
|
18
|
+
const STACKMEMORY_PROCESS_PATTERNS = ["stackmemory", "hooks start"];
|
|
25
19
|
function getStackmemoryProcesses() {
|
|
26
20
|
const processes = [];
|
|
27
21
|
try {
|