@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
package/dist/src/cli/index.js
CHANGED
|
@@ -4,6 +4,9 @@ import { dirname as __pathDirname } from 'path';
|
|
|
4
4
|
const __filename = __fileURLToPath(import.meta.url);
|
|
5
5
|
const __dirname = __pathDirname(__filename);
|
|
6
6
|
process.env["STACKMEMORY_CLI"] = "true";
|
|
7
|
+
if (!process.env["STACKMEMORY_LOG_LEVEL"] && process.argv.includes("--json")) {
|
|
8
|
+
process.env["STACKMEMORY_LOG_LEVEL"] = "ERROR";
|
|
9
|
+
}
|
|
7
10
|
import { config as loadDotenv } from "dotenv";
|
|
8
11
|
loadDotenv({ quiet: true });
|
|
9
12
|
import { initializeTracing, trace } from "../core/trace/index.js";
|
|
@@ -12,7 +15,6 @@ import { program } from "commander";
|
|
|
12
15
|
import { logger } from "../core/monitoring/logger.js";
|
|
13
16
|
import { FrameManager } from "../core/context/index.js";
|
|
14
17
|
import { sessionManager, FrameQueryMode } from "../core/session/index.js";
|
|
15
|
-
import { sharedContextLayer } from "../core/context/shared-context-layer.js";
|
|
16
18
|
import { UpdateChecker } from "../core/utils/update-checker.js";
|
|
17
19
|
import { ProgressTracker } from "../core/monitoring/progress-tracker.js";
|
|
18
20
|
import { registerProjectCommands } from "./commands/projects.js";
|
|
@@ -36,12 +38,14 @@ import {
|
|
|
36
38
|
} from "./commands/decision.js";
|
|
37
39
|
import clearCommand from "./commands/clear.js";
|
|
38
40
|
import serviceCommand from "./commands/service.js";
|
|
39
|
-
import { registerLoginCommand } from "./commands/login.js";
|
|
40
41
|
import { registerSignupCommand } from "./commands/signup.js";
|
|
42
|
+
import { createSyncCommand, createLoginCommand } from "./commands/sync.js";
|
|
41
43
|
import { registerLogoutCommand, registerDbCommands } from "./commands/db.js";
|
|
42
44
|
import { createHooksCommand } from "./commands/hooks.js";
|
|
43
45
|
import { createDaemonCommand } from "./commands/daemon.js";
|
|
44
46
|
import { createSweepCommand } from "./commands/sweep.js";
|
|
47
|
+
import { createPortalCommand } from "./commands/portal.js";
|
|
48
|
+
import { createBrainCommand } from "./commands/brain.js";
|
|
45
49
|
import { createShellCommand } from "./commands/shell.js";
|
|
46
50
|
import { createAPICommand } from "./commands/api.js";
|
|
47
51
|
import { createCleanupProcessesCommand } from "./commands/cleanup-processes.js";
|
|
@@ -54,21 +58,33 @@ import { createPingCommand } from "./commands/ping.js";
|
|
|
54
58
|
import { createAuditCommand } from "./commands/audit.js";
|
|
55
59
|
import { createStatsCommand } from "./commands/stats.js";
|
|
56
60
|
import { createBenchCommand } from "./commands/bench.js";
|
|
61
|
+
import { createOptimizeCommand } from "./commands/optimize.js";
|
|
62
|
+
import { createStateCommand } from "./commands/state.js";
|
|
57
63
|
import { createDigestCommands } from "./commands/digest.js";
|
|
58
|
-
import { createTeamCommands } from "./commands/team.js";
|
|
59
64
|
import { createDesiresCommands } from "./commands/desires.js";
|
|
60
65
|
import { createConductorCommands } from "./commands/orchestrate.js";
|
|
66
|
+
import { createOperatorCommands } from "./commands/operator.js";
|
|
67
|
+
import { createPatternsCommand } from "./commands/patterns.js";
|
|
61
68
|
import { createPreflightCommand } from "./commands/preflight.js";
|
|
62
69
|
import { createRulesCommand } from "./commands/rules.js";
|
|
63
70
|
import { createSnapshotCommand } from "./commands/snapshot.js";
|
|
64
71
|
import { createWikiCommand } from "./commands/wiki.js";
|
|
65
72
|
import { createLoopCommand } from "./commands/loop.js";
|
|
66
73
|
import { createSkillCommand } from "./commands/skill.js";
|
|
74
|
+
import { createPackCommand } from "./commands/pack.js";
|
|
75
|
+
import { createCacheCommand } from "./commands/cache.js";
|
|
76
|
+
import { createScaffoldCommand } from "./commands/scaffold.js";
|
|
77
|
+
import { createCompanyOsCommand } from "./commands/company-os.js";
|
|
67
78
|
import chalk from "chalk";
|
|
68
79
|
import * as fs from "fs";
|
|
69
80
|
import * as path from "path";
|
|
70
81
|
import { filterPending } from "../integrations/mcp/pending-utils.js";
|
|
82
|
+
import {
|
|
83
|
+
getCurrentRepoGitHubInfo,
|
|
84
|
+
refreshCurrentRepoPullRequestState
|
|
85
|
+
} from "../integrations/github/pr-state.js";
|
|
71
86
|
import { ProjectManager } from "../core/projects/project-manager.js";
|
|
87
|
+
import { canonicalStateStore } from "../core/shared-state/canonical-store.js";
|
|
72
88
|
import { join } from "path";
|
|
73
89
|
import { existsSync, mkdirSync } from "fs";
|
|
74
90
|
import { createRequire } from "module";
|
|
@@ -105,10 +121,13 @@ async function openDatabase(dbPath) {
|
|
|
105
121
|
function isTestEnv() {
|
|
106
122
|
return process.env["VITEST"] === "true" || process.env["NODE_ENV"] === "test" || process.env["STACKMEMORY_TEST_SKIP_DB"] === "1";
|
|
107
123
|
}
|
|
124
|
+
function collectRepeatedOption(value, previous = []) {
|
|
125
|
+
return [...previous, value];
|
|
126
|
+
}
|
|
108
127
|
UpdateChecker.checkForUpdates(VERSION, true).catch(() => {
|
|
109
128
|
});
|
|
110
129
|
program.name("stackmemory").description(
|
|
111
|
-
"Lossless memory runtime for AI coding tools - organizes context as a call stack instead of linear chat logs, with
|
|
130
|
+
"Lossless memory runtime for AI coding tools - organizes context as a call stack instead of linear chat logs, with infinite retention"
|
|
112
131
|
).version(VERSION);
|
|
113
132
|
program.command("init").description(
|
|
114
133
|
"Initialize StackMemory in current project (zero-config by default)"
|
|
@@ -198,33 +217,24 @@ program.command("status").description("Show current StackMemory status").option(
|
|
|
198
217
|
}
|
|
199
218
|
await UpdateChecker.checkForUpdates(VERSION);
|
|
200
219
|
await sessionManager.initialize();
|
|
201
|
-
await sharedContextLayer.initialize();
|
|
202
220
|
const { initObsidianVault } = await import("../core/storage/obsidian-vault-adapter.js");
|
|
203
221
|
await initObsidianVault();
|
|
204
222
|
const session = await sessionManager.getOrCreateSession({
|
|
205
223
|
projectPath: projectRoot,
|
|
206
224
|
sessionId: options.session
|
|
207
225
|
});
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
if (contextDiscovery.lastDecisions.length > 0) {
|
|
224
|
-
console.log(
|
|
225
|
-
` Last decision: ${contextDiscovery.lastDecisions[0].decision.slice(0, 60)}`
|
|
226
|
-
);
|
|
227
|
-
}
|
|
226
|
+
const sharedProjectState = await canonicalStateStore.getProjectSummary({
|
|
227
|
+
projectId: session.projectId,
|
|
228
|
+
projectPath: projectRoot,
|
|
229
|
+
eventLimit: 5
|
|
230
|
+
});
|
|
231
|
+
const githubInfo = getCurrentRepoGitHubInfo(projectRoot);
|
|
232
|
+
let githubProjection = githubInfo && await canonicalStateStore.getGitHubPullRequest({
|
|
233
|
+
repo: githubInfo.repo,
|
|
234
|
+
branch: githubInfo.branch
|
|
235
|
+
});
|
|
236
|
+
if (githubInfo && (!githubProjection || Date.now() - githubProjection.lastSyncedAt > 2 * 60 * 1e3)) {
|
|
237
|
+
githubProjection = await refreshCurrentRepoPullRequestState(projectRoot) || githubProjection;
|
|
228
238
|
}
|
|
229
239
|
const db = await openDatabase(dbPath);
|
|
230
240
|
const frameManager = new FrameManager(db, session.projectId);
|
|
@@ -276,6 +286,23 @@ program.command("status").description("Show current StackMemory status").option(
|
|
|
276
286
|
console.log(
|
|
277
287
|
` Cached contexts: ${contextCount.count || 0} (global)`
|
|
278
288
|
);
|
|
289
|
+
console.log(
|
|
290
|
+
` Shared sessions: ${sharedProjectState.activeSessions.length}`
|
|
291
|
+
);
|
|
292
|
+
console.log(
|
|
293
|
+
` Shared instances: ${sharedProjectState.activeInstances.length}`
|
|
294
|
+
);
|
|
295
|
+
console.log(
|
|
296
|
+
` Shared claims: ${sharedProjectState.activeClaims.length}`
|
|
297
|
+
);
|
|
298
|
+
const branchClaim = sharedProjectState.activeClaims.find(
|
|
299
|
+
(claim) => claim.branch && claim.branch === session.branch
|
|
300
|
+
);
|
|
301
|
+
if (branchClaim) {
|
|
302
|
+
console.log(
|
|
303
|
+
` Branch owner: ${branchClaim.tool} ${branchClaim.instanceId || branchClaim.sessionId || branchClaim.claimId.slice(0, 8)}`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
279
306
|
const recentFrames = db.prepare(
|
|
280
307
|
`
|
|
281
308
|
SELECT name, type, state, datetime(created_at, 'unixepoch') as created
|
|
@@ -295,6 +322,22 @@ program.command("status").description("Show current StackMemory status").option(
|
|
|
295
322
|
);
|
|
296
323
|
});
|
|
297
324
|
}
|
|
325
|
+
if (githubProjection) {
|
|
326
|
+
console.log(`
|
|
327
|
+
GitHub PR:`);
|
|
328
|
+
console.log(
|
|
329
|
+
` #${githubProjection.prNumber} ${githubProjection.state} ${githubProjection.title}`
|
|
330
|
+
);
|
|
331
|
+
console.log(
|
|
332
|
+
` ${githubProjection.headRefName} -> ${githubProjection.baseRefName}`
|
|
333
|
+
);
|
|
334
|
+
if (githubProjection.reviewDecision) {
|
|
335
|
+
console.log(` Review: ${githubProjection.reviewDecision}`);
|
|
336
|
+
}
|
|
337
|
+
if (githubProjection.statusCheckRollup) {
|
|
338
|
+
console.log(` Checks: ${githubProjection.statusCheckRollup}`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
298
341
|
console.log(`
|
|
299
342
|
Current Session:`);
|
|
300
343
|
console.log(` Stack depth: ${stackDepth}`);
|
|
@@ -460,7 +503,7 @@ program.command("context:test").description("Test context persistence by creatin
|
|
|
460
503
|
});
|
|
461
504
|
registerOnboardingCommand(program);
|
|
462
505
|
registerSignupCommand(program);
|
|
463
|
-
|
|
506
|
+
program.addCommand(createLoginCommand());
|
|
464
507
|
registerLogoutCommand(program);
|
|
465
508
|
registerDbCommands(program);
|
|
466
509
|
registerProjectCommands(program);
|
|
@@ -478,6 +521,7 @@ program.addCommand(createConfigCommand());
|
|
|
478
521
|
program.addCommand(createCaptureCommand());
|
|
479
522
|
program.addCommand(createRestoreCommand());
|
|
480
523
|
program.addCommand(createAutoCaptureCommand());
|
|
524
|
+
program.addCommand(createSyncCommand());
|
|
481
525
|
program.addCommand(createDecisionCommand());
|
|
482
526
|
program.addCommand(createMemoryCommand());
|
|
483
527
|
program.addCommand(clearCommand);
|
|
@@ -550,16 +594,10 @@ if (isFeatureEnabled("skills")) {
|
|
|
550
594
|
})
|
|
551
595
|
);
|
|
552
596
|
}
|
|
553
|
-
if (isFeatureEnabled("ralph")) {
|
|
554
|
-
lazyCommands.push(
|
|
555
|
-
import("./commands/ralph.js").then(
|
|
556
|
-
({ default: createRalphCommand }) => program.addCommand(createRalphCommand())
|
|
557
|
-
).catch(() => {
|
|
558
|
-
})
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
597
|
program.addCommand(createDaemonCommand());
|
|
562
598
|
program.addCommand(createSweepCommand());
|
|
599
|
+
program.addCommand(createPortalCommand());
|
|
600
|
+
program.addCommand(createBrainCommand());
|
|
563
601
|
program.addCommand(createShellCommand());
|
|
564
602
|
program.addCommand(createAPICommand());
|
|
565
603
|
program.addCommand(createCleanupProcessesCommand());
|
|
@@ -571,16 +609,23 @@ program.addCommand(createModelCommand());
|
|
|
571
609
|
program.addCommand(createAuditCommand());
|
|
572
610
|
program.addCommand(createStatsCommand());
|
|
573
611
|
program.addCommand(createBenchCommand());
|
|
612
|
+
program.addCommand(createOptimizeCommand());
|
|
613
|
+
program.addCommand(createStateCommand());
|
|
574
614
|
program.addCommand(createDigestCommands());
|
|
575
|
-
program.addCommand(createTeamCommands());
|
|
576
615
|
program.addCommand(createDesiresCommands());
|
|
577
616
|
program.addCommand(createConductorCommands());
|
|
617
|
+
program.addCommand(createOperatorCommands());
|
|
618
|
+
program.addCommand(createPatternsCommand());
|
|
578
619
|
program.addCommand(createPreflightCommand());
|
|
579
620
|
program.addCommand(createSnapshotCommand());
|
|
580
621
|
program.addCommand(createWikiCommand());
|
|
581
622
|
program.addCommand(createLoopCommand());
|
|
582
623
|
program.addCommand(createRulesCommand());
|
|
583
624
|
program.addCommand(createSkillCommand());
|
|
625
|
+
program.addCommand(createPackCommand());
|
|
626
|
+
program.addCommand(createCacheCommand());
|
|
627
|
+
program.addCommand(createScaffoldCommand());
|
|
628
|
+
program.addCommand(createCompanyOsCommand());
|
|
584
629
|
registerSetupCommands(program);
|
|
585
630
|
program.command("mm-spike").description(
|
|
586
631
|
"Run multi-agent planning/implementation spike (planner/implementer/critic)"
|
|
@@ -600,7 +645,16 @@ program.command("mm-spike").description(
|
|
|
600
645
|
"--execute",
|
|
601
646
|
"Execute implementer (codex-sm) instead of dry-run",
|
|
602
647
|
false
|
|
603
|
-
).option("--implementer <name>", "codex|claude", "codex").option("--max-iters <n>", "Retry loop iterations", "2").option("--audit-dir <path>", "Persist spike results to directory").option(
|
|
648
|
+
).option("--implementer <name>", "codex|claude", "codex").option("--max-iters <n>", "Retry loop iterations", "2").option("--audit-dir <path>", "Persist spike results to directory").option(
|
|
649
|
+
"--verify <cmd>",
|
|
650
|
+
"Verification command to run after each implementation attempt; repeatable",
|
|
651
|
+
collectRepeatedOption,
|
|
652
|
+
[]
|
|
653
|
+
).option("--record-frame", "Record as real frame with anchors", false).option("--record", "Record plan & critique into StackMemory context", false).option(
|
|
654
|
+
"--deterministic-fixture",
|
|
655
|
+
"Use deterministic fixture planner/critic for replayable smoke runs",
|
|
656
|
+
false
|
|
657
|
+
).option("--json", "Emit single JSON result (UI-friendly)", false).option("--quiet", "Minimal output (default)", true).option("--verbose", "Verbose sectioned output", false).option(
|
|
604
658
|
"--log",
|
|
605
659
|
"Pretty print interaction log (planner/implementer/critic)",
|
|
606
660
|
false
|
|
@@ -619,8 +673,10 @@ program.command("mm-spike").description(
|
|
|
619
673
|
maxIters: parseInt(opts.maxIters),
|
|
620
674
|
dryRun: !opts.execute,
|
|
621
675
|
auditDir: opts.auditDir,
|
|
676
|
+
verificationCommands: opts.verify,
|
|
622
677
|
recordFrame: Boolean(opts.recordFrame),
|
|
623
|
-
record: Boolean(opts.record)
|
|
678
|
+
record: Boolean(opts.record),
|
|
679
|
+
deterministicFixture: Boolean(opts.deterministicFixture)
|
|
624
680
|
}
|
|
625
681
|
);
|
|
626
682
|
if (opts.log) {
|
|
@@ -677,7 +733,15 @@ program.command("build").description(
|
|
|
677
733
|
"--reviewer-model <name>",
|
|
678
734
|
"Claude model for review",
|
|
679
735
|
"claude-sonnet-4-20250514"
|
|
680
|
-
).option("--execute", "Execute implementer (default: true)", true).option("--dry-run", "Skip execution, show commands only").option("--implementer <name>", "codex|claude", "codex").option("--max-iters <n>", "Retry loop iterations", "2").option("--audit-dir <path>", "Persist spike results to directory").option(
|
|
736
|
+
).option("--execute", "Execute implementer (default: true)", true).option("--dry-run", "Skip execution, show commands only").option("--implementer <name>", "codex|claude", "codex").option("--max-iters <n>", "Retry loop iterations", "2").option("--audit-dir <path>", "Persist spike results to directory").option(
|
|
737
|
+
"--verify <cmd>",
|
|
738
|
+
"Verification command to run after each implementation attempt; repeatable",
|
|
739
|
+
collectRepeatedOption,
|
|
740
|
+
[]
|
|
741
|
+
).option("--record-frame", "Record as real frame with anchors").option("--record", "Record plan & critique into StackMemory context").option(
|
|
742
|
+
"--deterministic-fixture",
|
|
743
|
+
"Use deterministic fixture planner/critic for replayable smoke runs"
|
|
744
|
+
).option("--json", "Emit single JSON result (UI-friendly)").option("--quiet", "Minimal output").option("--verbose", "Verbose sectioned output").option("--log", "Pretty print interaction log (default: true)", true).option("-C, --cwd <path>", "Working directory for implementation").action(async (taskArg, opts) => {
|
|
681
745
|
try {
|
|
682
746
|
const task = typeof taskArg === "string" && taskArg.length > 0 ? taskArg : opts.task;
|
|
683
747
|
if (!task) {
|
|
@@ -713,8 +777,10 @@ program.command("build").description(
|
|
|
713
777
|
maxIters: parseInt(opts.maxIters),
|
|
714
778
|
dryRun,
|
|
715
779
|
auditDir: opts.auditDir,
|
|
780
|
+
verificationCommands: opts.verify,
|
|
716
781
|
recordFrame: Boolean(opts.recordFrame),
|
|
717
|
-
record: Boolean(opts.record)
|
|
782
|
+
record: Boolean(opts.record),
|
|
783
|
+
deterministicFixture: Boolean(opts.deterministicFixture)
|
|
718
784
|
}
|
|
719
785
|
);
|
|
720
786
|
if (opts.log) {
|
|
@@ -13,6 +13,11 @@ import { program } from "commander";
|
|
|
13
13
|
import { v4 as uuidv4 } from "uuid";
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import { initializeTracing, trace } from "../core/trace/index.js";
|
|
16
|
+
import { resolveRealCliBin } from "./utils/real-cli-bin.js";
|
|
17
|
+
import {
|
|
18
|
+
startDeterminismWatcher,
|
|
19
|
+
stopDeterminismWatcher
|
|
20
|
+
} from "./utils/determinism-watcher.js";
|
|
16
21
|
const DEFAULT_SM_CONFIG = {
|
|
17
22
|
defaultWorktree: false,
|
|
18
23
|
defaultTracing: true
|
|
@@ -43,6 +48,7 @@ class OpencodeSM {
|
|
|
43
48
|
config;
|
|
44
49
|
stackmemoryPath;
|
|
45
50
|
smConfig;
|
|
51
|
+
determinismWatcher;
|
|
46
52
|
constructor() {
|
|
47
53
|
this.smConfig = loadSMConfig();
|
|
48
54
|
this.config = {
|
|
@@ -54,6 +60,7 @@ class OpencodeSM {
|
|
|
54
60
|
sessionStartTime: Date.now()
|
|
55
61
|
};
|
|
56
62
|
this.stackmemoryPath = this.findStackMemory();
|
|
63
|
+
this.determinismWatcher = null;
|
|
57
64
|
}
|
|
58
65
|
getRepoRoot() {
|
|
59
66
|
try {
|
|
@@ -127,27 +134,16 @@ class OpencodeSM {
|
|
|
127
134
|
}
|
|
128
135
|
}
|
|
129
136
|
resolveOpencodeBin() {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
for (const binPath of possiblePaths) {
|
|
141
|
-
if (fs.existsSync(binPath)) {
|
|
142
|
-
return binPath;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
execSync("which opencode", { stdio: "ignore" });
|
|
147
|
-
return "opencode";
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
return null;
|
|
137
|
+
return resolveRealCliBin({
|
|
138
|
+
explicitBin: this.config.opencodeBin,
|
|
139
|
+
envBin: process.env["OPENCODE_BIN"],
|
|
140
|
+
preferredPaths: [
|
|
141
|
+
path.join(os.homedir(), ".opencode", "bin", "opencode"),
|
|
142
|
+
"/usr/local/bin/opencode",
|
|
143
|
+
"/opt/homebrew/bin/opencode"
|
|
144
|
+
],
|
|
145
|
+
pathCommands: ["opencode"]
|
|
146
|
+
});
|
|
151
147
|
}
|
|
152
148
|
setupWorktree() {
|
|
153
149
|
if (!this.config.useWorktree || !this.isGitRepo()) {
|
|
@@ -251,6 +247,23 @@ class OpencodeSM {
|
|
|
251
247
|
);
|
|
252
248
|
}
|
|
253
249
|
}
|
|
250
|
+
startDeterminismWatcher() {
|
|
251
|
+
this.determinismWatcher = startDeterminismWatcher({
|
|
252
|
+
stackmemoryBin: this.stackmemoryPath,
|
|
253
|
+
cwd: process.cwd(),
|
|
254
|
+
task: this.config.task,
|
|
255
|
+
instanceId: this.config.instanceId,
|
|
256
|
+
tool: "opencode"
|
|
257
|
+
});
|
|
258
|
+
if (this.determinismWatcher) {
|
|
259
|
+
const modeLabel = this.determinismWatcher.mode === "targeted" ? "targeted" : "repo-root fallback";
|
|
260
|
+
console.log(chalk.gray(`Determinism: ${modeLabel}`));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
stopDeterminismWatcher() {
|
|
264
|
+
stopDeterminismWatcher(this.determinismWatcher);
|
|
265
|
+
this.determinismWatcher = null;
|
|
266
|
+
}
|
|
254
267
|
async run(args) {
|
|
255
268
|
const opencodeArgs = [];
|
|
256
269
|
let i = 0;
|
|
@@ -354,6 +367,7 @@ class OpencodeSM {
|
|
|
354
367
|
if (this.config.worktreePath) {
|
|
355
368
|
process.env["OPENCODE_WORKTREE_PATH"] = this.config.worktreePath;
|
|
356
369
|
}
|
|
370
|
+
this.startDeterminismWatcher();
|
|
357
371
|
console.log(chalk.gray(`Instance: ${this.config.instanceId}`));
|
|
358
372
|
console.log(chalk.gray(`Working in: ${process.cwd()}`));
|
|
359
373
|
if (this.config.tracingEnabled) {
|
|
@@ -391,6 +405,7 @@ class OpencodeSM {
|
|
|
391
405
|
process.exit(1);
|
|
392
406
|
});
|
|
393
407
|
opencode.on("exit", async (code) => {
|
|
408
|
+
this.stopDeterminismWatcher();
|
|
394
409
|
this.saveContext("OpenCode session ended", {
|
|
395
410
|
action: "session_end",
|
|
396
411
|
exitCode: code
|
|
@@ -411,12 +426,14 @@ class OpencodeSM {
|
|
|
411
426
|
process.exit(code || 0);
|
|
412
427
|
});
|
|
413
428
|
process.on("SIGINT", () => {
|
|
429
|
+
this.stopDeterminismWatcher();
|
|
414
430
|
this.saveContext("OpenCode session interrupted", {
|
|
415
431
|
action: "session_interrupt"
|
|
416
432
|
});
|
|
417
433
|
opencode.kill("SIGINT");
|
|
418
434
|
});
|
|
419
435
|
process.on("SIGTERM", () => {
|
|
436
|
+
this.stopDeterminismWatcher();
|
|
420
437
|
this.saveContext("OpenCode session terminated", {
|
|
421
438
|
action: "session_terminate"
|
|
422
439
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
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 { spawn } from "child_process";
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as path from "path";
|
|
8
|
+
import { getDeterminismWatchTargets } from "../../orchestrators/multimodal/determinism.js";
|
|
9
|
+
function shouldAutoStartDeterminismWatcher(cwd) {
|
|
10
|
+
if (process.env["STACKMEMORY_DETERMINISM_AUTO"] === "0") {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return fs.existsSync(path.join(cwd, ".git"));
|
|
14
|
+
}
|
|
15
|
+
function startDeterminismWatcher(options) {
|
|
16
|
+
if (!shouldAutoStartDeterminismWatcher(options.cwd)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const runs = process.env["STACKMEMORY_DETERMINISM_RUNS"] || "3";
|
|
20
|
+
const task = options.task || process.env["STACKMEMORY_DETERMINISM_TASK"] || "Determinism probe";
|
|
21
|
+
const targets = getDeterminismWatchTargets(options.cwd);
|
|
22
|
+
const mode = targets.length === 1 && targets[0] === "." ? "repo-root" : "targeted";
|
|
23
|
+
const child = spawn(
|
|
24
|
+
options.stackmemoryBin,
|
|
25
|
+
[
|
|
26
|
+
"bench",
|
|
27
|
+
"determinism",
|
|
28
|
+
"--task",
|
|
29
|
+
task,
|
|
30
|
+
"--runs",
|
|
31
|
+
runs,
|
|
32
|
+
"--watch",
|
|
33
|
+
"--json"
|
|
34
|
+
],
|
|
35
|
+
{
|
|
36
|
+
cwd: options.cwd,
|
|
37
|
+
stdio: "ignore",
|
|
38
|
+
env: {
|
|
39
|
+
...process.env,
|
|
40
|
+
STACKMEMORY_DETERMINISM_PARENT_TOOL: options.tool,
|
|
41
|
+
STACKMEMORY_DETERMINISM_PARENT_INSTANCE: options.instanceId || "",
|
|
42
|
+
STACKMEMORY_DETERMINISM_PARENT_SESSION: options.sessionId || ""
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
return {
|
|
47
|
+
child,
|
|
48
|
+
mode,
|
|
49
|
+
targets
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function stopDeterminismWatcher(handle) {
|
|
53
|
+
const child = handle?.child ?? null;
|
|
54
|
+
if (!child || child.killed) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
child.kill("SIGTERM");
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
shouldAutoStartDeterminismWatcher,
|
|
64
|
+
startDeterminismWatcher,
|
|
65
|
+
stopDeterminismWatcher
|
|
66
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
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 { execSync } from "child_process";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
const DEFAULT_WRAPPER_PATH_SNIPPETS = [
|
|
10
|
+
"/Applications/cmux.app/Contents/Resources/bin/"
|
|
11
|
+
];
|
|
12
|
+
function isWrapperPath(candidate, wrapperPathSnippets) {
|
|
13
|
+
const normalized = candidate.trim();
|
|
14
|
+
return wrapperPathSnippets.some((snippet) => normalized.includes(snippet));
|
|
15
|
+
}
|
|
16
|
+
function resolveRealCliBin(options) {
|
|
17
|
+
if (options.explicitBin?.trim()) {
|
|
18
|
+
return options.explicitBin.trim();
|
|
19
|
+
}
|
|
20
|
+
if (options.envBin?.trim()) {
|
|
21
|
+
return options.envBin.trim();
|
|
22
|
+
}
|
|
23
|
+
const wrapperPathSnippets = options.wrapperPathSnippets || DEFAULT_WRAPPER_PATH_SNIPPETS;
|
|
24
|
+
for (const candidate of options.preferredPaths || []) {
|
|
25
|
+
if (fs.existsSync(candidate) && !isWrapperPath(candidate, wrapperPathSnippets)) {
|
|
26
|
+
return candidate;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const command of options.pathCommands) {
|
|
30
|
+
try {
|
|
31
|
+
const output = execSync(`which -a ${command}`, {
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34
|
+
});
|
|
35
|
+
const resolved = output.split("\n").map((line) => line.trim()).filter(Boolean).find((candidate) => !isWrapperPath(candidate, wrapperPathSnippets));
|
|
36
|
+
if (resolved) {
|
|
37
|
+
return resolved;
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const CODEX_PLATFORM_TRIPLES = {
|
|
45
|
+
darwin: { x64: "x86_64-apple-darwin", arm64: "aarch64-apple-darwin" },
|
|
46
|
+
linux: {
|
|
47
|
+
x64: "x86_64-unknown-linux-musl",
|
|
48
|
+
arm64: "aarch64-unknown-linux-musl"
|
|
49
|
+
},
|
|
50
|
+
win32: { x64: "x86_64-pc-windows-msvc", arm64: "aarch64-pc-windows-msvc" }
|
|
51
|
+
};
|
|
52
|
+
function resolveNativeCodexBin() {
|
|
53
|
+
const triple = CODEX_PLATFORM_TRIPLES[process.platform]?.[process.arch];
|
|
54
|
+
if (!triple) return [];
|
|
55
|
+
const binaryName = process.platform === "win32" ? "codex.exe" : "codex";
|
|
56
|
+
const platformPkg = `@openai/codex-${process.platform}-${process.arch === "arm64" ? "arm64" : "x64"}`;
|
|
57
|
+
const candidates = [];
|
|
58
|
+
try {
|
|
59
|
+
const req = createRequire(
|
|
60
|
+
path.join(
|
|
61
|
+
process.execPath,
|
|
62
|
+
"..",
|
|
63
|
+
"..",
|
|
64
|
+
"lib",
|
|
65
|
+
"node_modules",
|
|
66
|
+
"@openai",
|
|
67
|
+
"codex",
|
|
68
|
+
"package.json"
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
const pkgJson = req.resolve(`${platformPkg}/package.json`);
|
|
72
|
+
const vendorBin = path.join(
|
|
73
|
+
path.dirname(pkgJson),
|
|
74
|
+
"vendor",
|
|
75
|
+
triple,
|
|
76
|
+
"bin",
|
|
77
|
+
binaryName
|
|
78
|
+
);
|
|
79
|
+
if (fs.existsSync(vendorBin)) candidates.push(vendorBin);
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const nodeDir = path.dirname(process.execPath);
|
|
84
|
+
const globalModules = path.join(nodeDir, "..", "lib", "node_modules");
|
|
85
|
+
const vendorBin = path.join(
|
|
86
|
+
globalModules,
|
|
87
|
+
"@openai",
|
|
88
|
+
"codex",
|
|
89
|
+
"node_modules",
|
|
90
|
+
platformPkg,
|
|
91
|
+
"vendor",
|
|
92
|
+
triple,
|
|
93
|
+
"bin",
|
|
94
|
+
binaryName
|
|
95
|
+
);
|
|
96
|
+
if (fs.existsSync(vendorBin) && !candidates.includes(vendorBin)) {
|
|
97
|
+
candidates.push(vendorBin);
|
|
98
|
+
}
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
return candidates;
|
|
102
|
+
}
|
|
103
|
+
function resolveNvmBin(name) {
|
|
104
|
+
try {
|
|
105
|
+
const nodeDir = path.dirname(process.execPath);
|
|
106
|
+
const candidate = path.join(nodeDir, name);
|
|
107
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
resolveNativeCodexBin,
|
|
114
|
+
resolveNvmBin,
|
|
115
|
+
resolveRealCliBin
|
|
116
|
+
};
|