codiedev 0.9.80 → 0.10.0-beta.10
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/README.md +12 -5
- package/dist/backup/cache.js +1 -5
- package/dist/backup/match.js +0 -6
- package/dist/backup/run.js +3 -35
- package/dist/captureExclusions.js +0 -12
- package/dist/captureLog.js +0 -28
- package/dist/captureReadiness.js +0 -58
- package/dist/captureSignals.js +0 -11
- package/dist/cli.js +11 -33
- package/dist/cliSession.js +3 -60
- package/dist/codexHookTrust.js +0 -28
- package/dist/codexLimitScan.js +0 -107
- package/dist/codie.js +64 -57
- package/dist/codieBrandInstall.js +0 -18
- package/dist/codieLauncher.js +1 -72
- package/dist/codieRuntime.js +27 -32
- package/dist/codieRuntimeInstall.js +11 -43
- package/dist/codieUsage.js +0 -49
- package/dist/commands/agentTemplates.generated.js +136 -0
- package/dist/commands/agents.js +1088 -0
- package/dist/commands/agentsSdk.generated.js +7 -0
- package/dist/commands/ask.js +0 -3
- package/dist/commands/capture.js +0 -2
- package/dist/commands/createTicket.js +0 -10
- package/dist/commands/doctor.js +2 -72
- package/dist/commands/evals.js +3 -9
- package/dist/commands/inbox.js +0 -2
- package/dist/commands/library.js +0 -3
- package/dist/commands/pack.js +0 -29
- package/dist/commands/ping.js +0 -2
- package/dist/commands/pull.js +0 -9
- package/dist/commands/push.js +0 -12
- package/dist/commands/search.js +0 -4
- package/dist/commands/send.js +0 -5
- package/dist/commands/share.js +0 -4
- package/dist/commands/shared.js +0 -35
- package/dist/commands/traces.js +0 -13
- package/dist/commands/tracesLabel.js +0 -8
- package/dist/configDir.js +1 -18
- package/dist/connect.js +3 -75
- package/dist/connectFlow.js +0 -15
- package/dist/copilotHooks.js +0 -67
- package/dist/copilotInstallation.js +0 -1
- package/dist/cursorHooks.js +1 -11
- package/dist/cursorLifecycle.js +1 -7
- package/dist/detection.js +0 -30
- package/dist/harnessDirs.js +0 -19
- package/dist/hook.js +43 -293
- package/dist/inboxFormat.js +0 -24
- package/dist/launchContext.js +0 -50
- package/dist/launcher.js +0 -33
- package/dist/limitEvent.js +2 -34
- package/dist/managedPi.js +2 -50
- package/dist/mcp.js +0 -48
- package/dist/nativeSteering.js +1 -4
- package/dist/packs/codie.js +0 -15
- package/dist/packs/harnesses.js +1 -38
- package/dist/packs/hookGate.js +0 -33
- package/dist/packs/install.js +0 -20
- package/dist/packs/manifest.js +1 -15
- package/dist/packs/paths.js +0 -8
- package/dist/packs/shim.js +0 -8
- package/dist/packs/store.js +0 -12
- package/dist/packs/sync.js +0 -20
- package/dist/piHooks.js +4 -45
- package/dist/piRuntime.js +0 -18
- package/dist/repoResolver.js +0 -19
- package/dist/secret.js +0 -3
- package/dist/selfUpdate.js +2 -77
- package/dist/skillMarker.js +0 -14
- package/dist/subagents.js +0 -18
- package/dist/teamSkillContext.js +0 -1
- package/dist/transcriptModels.js +0 -8
- package/dist/upgradeNudge.js +1 -30
- package/dist/utils.js +165 -768
- package/dist/version.js +0 -10
- package/dist/versionCheck.js +0 -33
- package/package.json +13 -8
- package/dist/backup/cache.d.ts +0 -14
- package/dist/backup/match.d.ts +0 -2
- package/dist/backup/run.d.ts +0 -25
- package/dist/captureExclusions.d.ts +0 -30
- package/dist/captureLog.d.ts +0 -20
- package/dist/captureReadiness.d.ts +0 -65
- package/dist/captureSignals.d.ts +0 -47
- package/dist/cli.d.ts +0 -15
- package/dist/cliSession.d.ts +0 -108
- package/dist/codexHookTrust.d.ts +0 -49
- package/dist/codexLimitScan.d.ts +0 -64
- package/dist/codie.d.ts +0 -2
- package/dist/codieBrandInstall.d.ts +0 -11
- package/dist/codieLauncher.d.ts +0 -87
- package/dist/codieRuntime.d.ts +0 -35
- package/dist/codieRuntimeInstall.d.ts +0 -56
- package/dist/codieUsage.d.ts +0 -64
- package/dist/commands/ask.d.ts +0 -1
- package/dist/commands/capture.d.ts +0 -14
- package/dist/commands/createTicket.d.ts +0 -27
- package/dist/commands/delete.d.ts +0 -1
- package/dist/commands/doctor.d.ts +0 -9
- package/dist/commands/evals.d.ts +0 -3
- package/dist/commands/inbox.d.ts +0 -3
- package/dist/commands/library.d.ts +0 -2
- package/dist/commands/note.d.ts +0 -1
- package/dist/commands/pack.d.ts +0 -54
- package/dist/commands/ping.d.ts +0 -1
- package/dist/commands/pull.d.ts +0 -2
- package/dist/commands/push.d.ts +0 -33
- package/dist/commands/search.d.ts +0 -2
- package/dist/commands/send.d.ts +0 -2
- package/dist/commands/share.d.ts +0 -2
- package/dist/commands/shared.d.ts +0 -64
- package/dist/commands/traces.d.ts +0 -72
- package/dist/commands/tracesLabel.d.ts +0 -24
- package/dist/configDir.d.ts +0 -10
- package/dist/connect.d.ts +0 -1
- package/dist/connectFlow.d.ts +0 -34
- package/dist/copilotHooks.d.ts +0 -85
- package/dist/copilotInstallation.d.ts +0 -10
- package/dist/cursorHooks.d.ts +0 -13
- package/dist/cursorLifecycle.d.ts +0 -2
- package/dist/detection.d.ts +0 -30
- package/dist/harnessDirs.d.ts +0 -15
- package/dist/hook.d.ts +0 -6
- package/dist/inboxFormat.d.ts +0 -38
- package/dist/launchContext.d.ts +0 -46
- package/dist/launcher.d.ts +0 -25
- package/dist/limitEvent.d.ts +0 -15
- package/dist/limitEventReporter.d.ts +0 -21
- package/dist/managedPi.d.ts +0 -48
- package/dist/mcp.d.ts +0 -12
- package/dist/nativeSteering.d.ts +0 -5
- package/dist/packs/codie.d.ts +0 -45
- package/dist/packs/harnesses.d.ts +0 -74
- package/dist/packs/hookGate.d.ts +0 -53
- package/dist/packs/install.d.ts +0 -46
- package/dist/packs/manifest.d.ts +0 -52
- package/dist/packs/paths.d.ts +0 -17
- package/dist/packs/shim.d.ts +0 -26
- package/dist/packs/store.d.ts +0 -42
- package/dist/packs/sync.d.ts +0 -40
- package/dist/piHooks.d.ts +0 -22
- package/dist/piRuntime.d.ts +0 -26
- package/dist/repoResolver.d.ts +0 -17
- package/dist/secret.d.ts +0 -1
- package/dist/selfUpdate.d.ts +0 -64
- package/dist/skillMarker.d.ts +0 -6
- package/dist/subagents.d.ts +0 -36
- package/dist/teamSkillContext.d.ts +0 -9
- package/dist/transcriptModels.d.ts +0 -20
- package/dist/upgradeNudge.d.ts +0 -24
- package/dist/utils.d.ts +0 -396
- package/dist/version.d.ts +0 -1
- package/dist/versionCheck.d.ts +0 -68
package/dist/codie.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
// `codie` — Codiedev's governed coding harness.
|
|
4
|
-
//
|
|
5
|
-
// Ships from the same package as `codiedev` so a developer runs one install and
|
|
6
|
-
// then picks their surface: Claude Code, Codex, and Cursor get session capture
|
|
7
|
-
// via `codiedev connect`; `codie` launches the governed harness against the
|
|
8
|
-
// same token. OpenCode is the embedded engine; all user-facing identity,
|
|
9
|
-
// credentials, models, policy, and capture belong to Codiedev.
|
|
10
|
-
//
|
|
11
|
-
// The engine is downloaded on first run (see codieRuntime.ts) so capture-only
|
|
12
|
-
// users never pay for it.
|
|
13
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
4
|
if (k2 === undefined) k2 = k;
|
|
15
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -60,12 +50,7 @@ const codie_1 = require("./packs/codie");
|
|
|
60
50
|
const paths_1 = require("./packs/paths");
|
|
61
51
|
const managedPi_1 = require("./managedPi");
|
|
62
52
|
const cliSession_1 = require("./cliSession");
|
|
63
|
-
// The engine reads its gateway key once, at launch. With browser sign-in the
|
|
64
|
-
// key is a 24h access token, so start every session with at least 12h left
|
|
65
|
-
// (refreshing first if needed) instead of one that dies mid-task.
|
|
66
53
|
const CODIE_MIN_TOKEN_VALIDITY_MS = 12 * 60 * 60_000;
|
|
67
|
-
// How long to let the gateway finish booking the last request before asking
|
|
68
|
-
// what the session cost.
|
|
69
54
|
const USAGE_SETTLE_MS = 1200;
|
|
70
55
|
function git(args) {
|
|
71
56
|
const result = (0, child_process_1.spawnSync)("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
@@ -95,9 +80,6 @@ function existingInlineConfig() {
|
|
|
95
80
|
throw new Error("OPENCODE_CONFIG_CONTENT is not valid JSON");
|
|
96
81
|
}
|
|
97
82
|
}
|
|
98
|
-
// The one credential. `codiedev connect` wrote it; the gateway validates the
|
|
99
|
-
// same userApiTokens row (a browser sign-in reports through its own row), so
|
|
100
|
-
// there is no second harness token to mint.
|
|
101
83
|
function connectedCodiedevConfig() {
|
|
102
84
|
try {
|
|
103
85
|
return JSON.parse(fs.readFileSync(path.join((0, configDir_1.codiedevStateDir)(), "config.json"), "utf8"));
|
|
@@ -106,12 +88,8 @@ function connectedCodiedevConfig() {
|
|
|
106
88
|
return {};
|
|
107
89
|
}
|
|
108
90
|
}
|
|
109
|
-
// Starter packs (`codiedev pack install`) reach Codie here: skills, agents and
|
|
110
|
-
// the hook shim are merged into the inline config at launch. Best-effort — a
|
|
111
|
-
// broken pack must never stop the harness from starting.
|
|
112
91
|
function withStarterPacks(existing, approved, catalog) {
|
|
113
92
|
try {
|
|
114
|
-
// Agent levels (opus/sonnet/haiku) resolve against this account's catalog.
|
|
115
93
|
const packs = (0, codie_1.codiePackConfig)((0, paths_1.packsRoot)(), { approvedModels: approved, catalog });
|
|
116
94
|
if (process.env.CODIEDEV_DEBUG) {
|
|
117
95
|
for (const note of packs.notes)
|
|
@@ -125,13 +103,8 @@ function withStarterPacks(existing, approved, catalog) {
|
|
|
125
103
|
}
|
|
126
104
|
}
|
|
127
105
|
function assetPath(name) {
|
|
128
|
-
// dist/codie.js → ../assets/<name>; src/codie.ts → ../assets/<name>.
|
|
129
106
|
return path.join(__dirname, "..", "assets", name);
|
|
130
107
|
}
|
|
131
|
-
// Remove the engine's boot/exit banner wordmark in place (see
|
|
132
|
-
// patchBrandWordmark). Best-effort like the TUI plugin: any failure rolls the
|
|
133
|
-
// bytes back and the stock banner keeps working. Runs once per install; an
|
|
134
|
-
// already-suppressed binary has no known source region and is skipped.
|
|
135
108
|
function installBrandWordmark(runtime) {
|
|
136
109
|
try {
|
|
137
110
|
installBrandWordmarkUnsafe(runtime);
|
|
@@ -145,10 +118,6 @@ function installBrandWordmarkUnsafe(runtime) {
|
|
|
145
118
|
const { changed, offset, replacement } = (0, codieLauncher_1.patchBrandWordmark)(binary);
|
|
146
119
|
if (!changed || !replacement)
|
|
147
120
|
return;
|
|
148
|
-
// In-place write (not copy+rename): opencode-ai/bin/opencode.exe and the
|
|
149
|
-
// platform package's binary are hardlinks to one inode, and this keeps them
|
|
150
|
-
// consistent. Restoring the original bytes is a true rollback — identical
|
|
151
|
-
// content revalidates the existing macOS signature.
|
|
152
121
|
const writeAt = (bytes) => {
|
|
153
122
|
const fd = fs.openSync(runtime, "r+");
|
|
154
123
|
try {
|
|
@@ -161,7 +130,6 @@ function installBrandWordmarkUnsafe(runtime) {
|
|
|
161
130
|
const restore = () => writeAt(binary.subarray(offset, offset + replacement.length));
|
|
162
131
|
writeAt(replacement);
|
|
163
132
|
if (process.platform === "darwin") {
|
|
164
|
-
// A modified Mach-O needs a fresh ad-hoc signature or the OS kills it.
|
|
165
133
|
const signed = (0, child_process_1.spawnSync)("codesign", ["--force", "--sign", "-", runtime], { stdio: "ignore" });
|
|
166
134
|
if (signed.status !== 0) {
|
|
167
135
|
restore();
|
|
@@ -175,6 +143,49 @@ function installBrandWordmarkUnsafe(runtime) {
|
|
|
175
143
|
(0, child_process_1.spawnSync)("codesign", ["--force", "--sign", "-", runtime], { stdio: "ignore" });
|
|
176
144
|
}
|
|
177
145
|
}
|
|
146
|
+
async function runNonInteractive(runtime, runtimeArgs, env) {
|
|
147
|
+
const detached = process.platform !== "win32";
|
|
148
|
+
const child = (0, child_process_1.spawn)(runtime, runtimeArgs, {
|
|
149
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
150
|
+
env,
|
|
151
|
+
detached,
|
|
152
|
+
});
|
|
153
|
+
if (child.stdin)
|
|
154
|
+
process.stdin.pipe(child.stdin);
|
|
155
|
+
const signalChild = (signal) => {
|
|
156
|
+
if (detached && child.pid) {
|
|
157
|
+
try {
|
|
158
|
+
process.kill(-child.pid, signal);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
child.kill(signal);
|
|
165
|
+
};
|
|
166
|
+
const forwardInterrupt = () => signalChild("SIGINT");
|
|
167
|
+
const forwardTermination = () => signalChild("SIGTERM");
|
|
168
|
+
process.once("SIGINT", forwardInterrupt);
|
|
169
|
+
process.once("SIGTERM", forwardTermination);
|
|
170
|
+
return await new Promise((resolve, reject) => {
|
|
171
|
+
child.stdout?.on("data", (chunk) => process.stdout.write(chunk));
|
|
172
|
+
child.stderr?.on("data", (chunk) => process.stderr.write(chunk));
|
|
173
|
+
child.once("error", (error) => {
|
|
174
|
+
if (child.stdin)
|
|
175
|
+
process.stdin.unpipe(child.stdin);
|
|
176
|
+
process.removeListener("SIGINT", forwardInterrupt);
|
|
177
|
+
process.removeListener("SIGTERM", forwardTermination);
|
|
178
|
+
reject(error);
|
|
179
|
+
});
|
|
180
|
+
child.once("close", (status) => {
|
|
181
|
+
if (child.stdin)
|
|
182
|
+
process.stdin.unpipe(child.stdin);
|
|
183
|
+
process.removeListener("SIGINT", forwardInterrupt);
|
|
184
|
+
process.removeListener("SIGTERM", forwardTermination);
|
|
185
|
+
resolve(status);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
178
189
|
async function main() {
|
|
179
190
|
(0, codieRuntime_1.assertCodieNodeVersion)(process.versions.node);
|
|
180
191
|
if (!process.env.CODIEDEV_GATEWAY_KEY && !process.env.CODIEDEV_TOKEN) {
|
|
@@ -184,9 +195,6 @@ async function main() {
|
|
|
184
195
|
}
|
|
185
196
|
}
|
|
186
197
|
const connected = connectedCodiedevConfig();
|
|
187
|
-
// Browser sign-in: let the engine's per-request hook keep the 24h key
|
|
188
|
-
// fresh for sessions that run longer (assets/session-key.mjs). Not for an
|
|
189
|
-
// explicit key from the environment, and not for pasted API tokens.
|
|
190
198
|
if (!process.env.CODIEDEV_GATEWAY_KEY && !process.env.CODIEDEV_TOKEN && connected.auth) {
|
|
191
199
|
process.env.CODIEDEV_SESSION_CONFIG = path.join((0, configDir_1.codiedevStateDir)(), "config.json");
|
|
192
200
|
process.env.CODIEDEV_CLI_JS = path.join(__dirname, "cli.js");
|
|
@@ -198,9 +206,6 @@ async function main() {
|
|
|
198
206
|
if (!key) {
|
|
199
207
|
throw new Error("Connect your Codiedev account first with `codiedev connect`");
|
|
200
208
|
}
|
|
201
|
-
// Before anything paints: once the OpenCode engine owns stdio, a prompt is
|
|
202
|
-
// unreadable. A successful in-place upgrade relaunches this command with the
|
|
203
|
-
// new package, so the stale process must stop here.
|
|
204
209
|
const update = await (0, upgradeNudge_1.maybeOfferUpgrade)();
|
|
205
210
|
if (update.relaunched) {
|
|
206
211
|
process.exitCode = update.status ?? 0;
|
|
@@ -208,8 +213,6 @@ async function main() {
|
|
|
208
213
|
}
|
|
209
214
|
const gatewayUrl = process.env.CODIEDEV_GATEWAY_URL || "https://gateway.codiedev.com/api/v1";
|
|
210
215
|
const catalog = await (0, codieLauncher_1.fetchApprovedCatalog)({ baseUrl: gatewayUrl, key });
|
|
211
|
-
// `codie --pi [args]`: pi instead of the OpenCode engine, on the same
|
|
212
|
-
// approved catalog and gateway key (see managedPi.ts).
|
|
213
216
|
if (process.argv[2] === "--pi") {
|
|
214
217
|
let skillPaths = [];
|
|
215
218
|
try {
|
|
@@ -222,8 +225,6 @@ async function main() {
|
|
|
222
225
|
try {
|
|
223
226
|
process.exitCode = (0, managedPi_1.runManagedPi)({
|
|
224
227
|
args: process.argv.slice(3), key, gatewayUrl, catalog, stateDir: (0, configDir_1.codiedevStateDir)(), skillPaths,
|
|
225
|
-
// This release line has no Agent Security hooks.
|
|
226
|
-
agentSecurityEnabled: false,
|
|
227
228
|
});
|
|
228
229
|
}
|
|
229
230
|
catch (error) {
|
|
@@ -240,11 +241,20 @@ async function main() {
|
|
|
240
241
|
}
|
|
241
242
|
(0, codieLauncher_1.validateCodieArgs)(parsed.args, catalog);
|
|
242
243
|
const stateDir = (0, configDir_1.codiedevStateDir)();
|
|
243
|
-
const runtime = (0, codieRuntimeInstall_1.ensureCodieRuntimeBinary)({
|
|
244
|
+
const runtime = await (0, codieRuntimeInstall_1.ensureCodieRuntimeBinary)({
|
|
244
245
|
resolve: () => (0, codieRuntime_1.resolveCodieRuntime)({
|
|
245
246
|
env: process.env,
|
|
246
247
|
stateDir,
|
|
247
248
|
existsSync: (candidate) => fs.existsSync(candidate),
|
|
249
|
+
readInstalledVersion: (candidate) => {
|
|
250
|
+
try {
|
|
251
|
+
const value = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
252
|
+
return typeof value.version === "string" ? value.version : null;
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
},
|
|
248
258
|
resolveBundled: () => {
|
|
249
259
|
try {
|
|
250
260
|
return require.resolve("opencode-ai/bin/opencode.exe");
|
|
@@ -257,18 +267,24 @@ async function main() {
|
|
|
257
267
|
}),
|
|
258
268
|
install: (missing) => (0, codieRuntimeInstall_1.installCodieRuntimeOnDisk)(missing, stateDir),
|
|
259
269
|
repair: (unlinked) => {
|
|
260
|
-
// npm 12 skips dependency install scripts; codie runs opencode-ai's own
|
|
261
|
-
// link step instead (not when npm is explicitly set to ignore scripts).
|
|
262
270
|
console.error("codie: finishing the engine setup npm skipped (opencode-ai's postinstall)…");
|
|
263
271
|
const linked = (0, codieRuntimeInstall_1.linkEngineOnDisk)(unlinked.packageDir);
|
|
264
|
-
// npm set to ignore scripts: a reinstall would hit the same wall, so stop
|
|
265
|
-
// with the one clear step instead of downloading again every run.
|
|
266
272
|
if (!linked.ok && linked.detail === codieRuntimeInstall_1.IGNORE_SCRIPTS)
|
|
267
273
|
throw new Error((0, codieRuntimeInstall_1.linkFailure)(linked, unlinked.packageDir));
|
|
268
274
|
if (!linked.ok)
|
|
269
275
|
console.error(`codie: ${(0, codieRuntimeInstall_1.linkFailure)(linked, unlinked.packageDir)} Reinstalling the engine.`);
|
|
270
276
|
return linked.ok;
|
|
271
277
|
},
|
|
278
|
+
confirmUpdate: async (outdated) => {
|
|
279
|
+
console.error("");
|
|
280
|
+
console.error(`Codie harness ${outdated.expectedVersion} is available (you're on ${outdated.currentVersion}).`);
|
|
281
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
282
|
+
console.error("Restart `codie` in an interactive terminal to update the harness.");
|
|
283
|
+
console.error("");
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
return await (0, upgradeNudge_1.promptYesNo)(" Update the harness now? [y/N] ");
|
|
287
|
+
},
|
|
272
288
|
});
|
|
273
289
|
const metadataPlugin = (0, url_1.pathToFileURL)(assetPath("opencode-plugin.mjs")).href;
|
|
274
290
|
const capturePlugin = (0, codieLauncher_1.resolveCapturePlugin)({ homeDir: os.homedir(), existsSync: fs.existsSync });
|
|
@@ -292,10 +308,6 @@ async function main() {
|
|
|
292
308
|
const runtimeArgs = (0, codieLauncher_1.withCodieWorkingDirectory)(parsed.args, process.cwd());
|
|
293
309
|
const nonInteractiveRun = runtimeArgs[0] === "run";
|
|
294
310
|
if (nonInteractiveRun) {
|
|
295
|
-
// The TUI paints its own live status line from the same endpoint. A
|
|
296
|
-
// non-interactive run has no TUI, so the budget arrives as two printed
|
|
297
|
-
// lines instead — and only for a human at a terminal, so a scripted run
|
|
298
|
-
// is neither slowed nor polluted.
|
|
299
311
|
const reportCost = Boolean(process.stderr.isTTY);
|
|
300
312
|
const startedAt = Date.now();
|
|
301
313
|
if (reportCost) {
|
|
@@ -303,13 +315,8 @@ async function main() {
|
|
|
303
315
|
if (line)
|
|
304
316
|
console.error(line);
|
|
305
317
|
}
|
|
306
|
-
|
|
307
|
-
if (result.error)
|
|
308
|
-
throw result.error;
|
|
309
|
-
process.exitCode = result.status === null ? 1 : result.status;
|
|
318
|
+
process.exitCode = (await runNonInteractive(runtime, runtimeArgs, env)) ?? 1;
|
|
310
319
|
if (reportCost) {
|
|
311
|
-
// The gateway books a request's cost after it has answered, so a poll
|
|
312
|
-
// fired the instant the run closes can miss the last one.
|
|
313
320
|
await new Promise((resolve) => setTimeout(resolve, USAGE_SETTLE_MS));
|
|
314
321
|
const cost = (0, codieUsage_1.formatSessionCostLine)(await (0, codieUsage_1.fetchCodieUsage)({ baseUrl: gatewayUrl, key, sinceMs: startedAt }));
|
|
315
322
|
if (cost)
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Stages the Codiedev TUI plugin into the engine's config directory.
|
|
3
|
-
//
|
|
4
|
-
// TUI plugins load only from tui.json in the OpenCode config dir, so the
|
|
5
|
-
// packaged template is copied there and referenced by a relative spec. The
|
|
6
|
-
// copy also carries the status line, which needs an absolute path back into
|
|
7
|
-
// this package — the plugin sits outside it and cannot reach it any other way.
|
|
8
|
-
//
|
|
9
|
-
// Every step is best-effort: a developer who cannot write this directory still
|
|
10
|
-
// gets a working harness, just the stock logo and no status line.
|
|
11
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
3
|
if (k2 === undefined) k2 = k;
|
|
13
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -50,15 +41,8 @@ const os = __importStar(require("os"));
|
|
|
50
41
|
const path = __importStar(require("path"));
|
|
51
42
|
const codieLauncher_1 = require("./codieLauncher");
|
|
52
43
|
function assetPath(name) {
|
|
53
|
-
// dist/codieBrandInstall.js → ../assets/<name>; src/… → ../assets/<name>.
|
|
54
44
|
return path.join(__dirname, "..", "assets", name);
|
|
55
45
|
}
|
|
56
|
-
/**
|
|
57
|
-
* The usage module this install should load. The shipped package has the
|
|
58
|
-
* compiled file; a source checkout (and the test run) has the TypeScript one.
|
|
59
|
-
* Naming a path that does not exist would cost the status line silently, so a
|
|
60
|
-
* miss raises instead and the caller falls back to the plain plugin.
|
|
61
|
-
*/
|
|
62
46
|
function usageModulePath() {
|
|
63
47
|
const candidates = [
|
|
64
48
|
path.join(__dirname, "codieUsage.js"),
|
|
@@ -69,8 +53,6 @@ function usageModulePath() {
|
|
|
69
53
|
throw new Error("this install has no Codiedev usage module");
|
|
70
54
|
return found;
|
|
71
55
|
}
|
|
72
|
-
/** The engine resolves its config dir per the XDG spec, so a customized
|
|
73
|
-
* XDG_CONFIG_HOME must be honored or tui.json lands where it never reads. */
|
|
74
56
|
function openCodeConfigDir() {
|
|
75
57
|
return path.join(process.env.XDG_CONFIG_HOME?.trim() || path.join(os.homedir(), ".config"), "opencode");
|
|
76
58
|
}
|
package/dist/codieLauncher.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Pure launcher logic for the Codie harness.
|
|
3
|
-
//
|
|
4
|
-
// Ported from codiedev-gateway-cli/npm/lib/launcher.js when the harness folded
|
|
5
|
-
// into this package so `npm i -g codiedev` is the only install a developer
|
|
6
|
-
// needs — Claude Code, Codex, Cursor, and Codie all come from one package and
|
|
7
|
-
// share the one token `codiedev connect` stored.
|
|
8
|
-
//
|
|
9
|
-
// Everything here is pure (no fs/network side effects beyond an injected
|
|
10
|
-
// fetch) so the governance rules can be tested without a live gateway.
|
|
11
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
3
|
if (k2 === undefined) k2 = k;
|
|
13
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -59,6 +50,7 @@ const path = __importStar(require("path"));
|
|
|
59
50
|
const url_1 = require("url");
|
|
60
51
|
const harnessDirs_1 = require("./harnessDirs");
|
|
61
52
|
const DEFAULT_NAMES = {
|
|
53
|
+
"openai/gpt-5.6-luna": "GPT-5.6 Luna",
|
|
62
54
|
"openai/gpt-5.3-codex": "GPT-5.3 Codex",
|
|
63
55
|
"openai/gpt-5.2-codex": "GPT-5.2 Codex",
|
|
64
56
|
"openai/gpt-5.1-codex-mini": "GPT-5.1 Codex Mini",
|
|
@@ -66,9 +58,6 @@ const DEFAULT_NAMES = {
|
|
|
66
58
|
"z-ai/glm-5.2": "GLM 5.2 · Fireworks ZDR",
|
|
67
59
|
"moonshotai/kimi-k2.7-code": "Kimi K2.7 Code · Fireworks ZDR",
|
|
68
60
|
};
|
|
69
|
-
/** A rate card is usable only when both sides are real, finite and not
|
|
70
|
-
* negative. Half a card prices a session wrong in a way nobody can see, so a
|
|
71
|
-
* partial one is dropped and the model stays unpriced. */
|
|
72
61
|
function usableModelCost(value) {
|
|
73
62
|
if (!value || typeof value !== "object")
|
|
74
63
|
return undefined;
|
|
@@ -81,10 +70,6 @@ function usableModelCost(value) {
|
|
|
81
70
|
return undefined;
|
|
82
71
|
return { input, output };
|
|
83
72
|
}
|
|
84
|
-
/** A context/output window is usable only when both sides are real, finite and
|
|
85
|
-
* positive. A partial window makes the engine's "% of context used" read wrong
|
|
86
|
-
* in a way nobody can see, so a partial one is dropped and the model keeps the
|
|
87
|
-
* engine's default. */
|
|
88
73
|
function usableModelLimit(value) {
|
|
89
74
|
if (!value || typeof value !== "object")
|
|
90
75
|
return undefined;
|
|
@@ -97,12 +82,6 @@ function usableModelLimit(value) {
|
|
|
97
82
|
return undefined;
|
|
98
83
|
return { context, output };
|
|
99
84
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Pin non-interactive runs to the directory where `codie` was launched.
|
|
102
|
-
* OpenCode can reuse a previously-known project instance; without an explicit
|
|
103
|
-
* --dir, a real smoke run launched in a throwaway repo resumed the caller's
|
|
104
|
-
* main checkout and executed there. TUI mode already owns its cwd directly.
|
|
105
|
-
*/
|
|
106
85
|
function withCodieWorkingDirectory(args, cwd) {
|
|
107
86
|
if (args[0] !== "run")
|
|
108
87
|
return args;
|
|
@@ -124,8 +103,6 @@ function governedModel(value, approved, fallback, label) {
|
|
|
124
103
|
return `codiedev/${model}`;
|
|
125
104
|
}
|
|
126
105
|
function economicalModel(catalog, primary) {
|
|
127
|
-
// Catalog ids arrive already normalized through bareModel(), so the
|
|
128
|
-
// gateway's `codiedev/fast` alias appears here as plain "fast".
|
|
129
106
|
const preferred = ["openai/gpt-5.1-codex-mini", "fast", "z-ai/glm-5.2"];
|
|
130
107
|
return preferred.find((id) => catalog.some((model) => model.id === id)) || primary;
|
|
131
108
|
}
|
|
@@ -157,11 +134,6 @@ function buildCodieConfig({ existing = {}, catalog, env = {}, plugin, plugins =
|
|
|
157
134
|
const existingPlugins = Array.isArray(existing.plugin) ? existing.plugin : [];
|
|
158
135
|
const requiredPlugins = [...plugins, plugin].filter(Boolean);
|
|
159
136
|
const models = Object.fromEntries(catalog.map((model) => {
|
|
160
|
-
// The engine prices a session from this rate card. Without it every
|
|
161
|
-
// model reads $0.00, which is how the harness came to show no spend at
|
|
162
|
-
// all. The gateway publishes prompt and completion prices only, so
|
|
163
|
-
// cached tokens are priced at zero here and the engine's session figure
|
|
164
|
-
// stays an estimate — the budget line from /me/usage is the true spend.
|
|
165
137
|
const cost = usableModelCost(model.cost);
|
|
166
138
|
const limit = usableModelLimit(model.limit);
|
|
167
139
|
return [
|
|
@@ -201,14 +173,6 @@ function buildCodieConfig({ existing = {}, catalog, env = {}, plugin, plugins =
|
|
|
201
173
|
};
|
|
202
174
|
}
|
|
203
175
|
exports.USAGE_MODULE_PLACEHOLDER = "__CODIEDEV_USAGE_MODULE__";
|
|
204
|
-
/**
|
|
205
|
-
* Point the staged TUI plugin at this install's usage module.
|
|
206
|
-
*
|
|
207
|
-
* The plugin is copied into the engine's own config directory, so it cannot
|
|
208
|
-
* reach the package by a relative path — the absolute path is baked in at
|
|
209
|
-
* stage time. It goes in as a JSON literal so a Windows path keeps its
|
|
210
|
-
* backslashes instead of turning into escape sequences.
|
|
211
|
-
*/
|
|
212
176
|
function stageUsageModule(source, modulePath) {
|
|
213
177
|
if (!source.includes(exports.USAGE_MODULE_PLACEHOLDER)) {
|
|
214
178
|
throw new Error(`plugin template is missing the ${exports.USAGE_MODULE_PLACEHOLDER} placeholder`);
|
|
@@ -216,8 +180,6 @@ function stageUsageModule(source, modulePath) {
|
|
|
216
180
|
return source.split(exports.USAGE_MODULE_PLACEHOLDER).join(JSON.stringify(modulePath));
|
|
217
181
|
}
|
|
218
182
|
exports.BRAND_PLUGIN_SPEC = "./plugins/codiedev-brand.tsx";
|
|
219
|
-
// Pure merge for ~/.config/opencode/tui.json: TUI plugins load from tui.json,
|
|
220
|
-
// not the opencode.json we inject via OPENCODE_CONFIG_CONTENT.
|
|
221
183
|
function withBrandPlugin(existing) {
|
|
222
184
|
const config = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
223
185
|
const plugins = Array.isArray(config.plugin) ? config.plugin : [];
|
|
@@ -226,13 +188,6 @@ function withBrandPlugin(existing) {
|
|
|
226
188
|
return { config, changed: false };
|
|
227
189
|
return { config: { ...config, plugin: [...plugins, exports.BRAND_PLUGIN_SPEC] }, changed: true };
|
|
228
190
|
}
|
|
229
|
-
// ── Engine wordmark suppression ─────────────────────────────────────────
|
|
230
|
-
// The OpenCode engine prints a block-letter "opencode" wordmark to terminal
|
|
231
|
-
// scrollback around each session (the boot/exit banner). A four-row terminal
|
|
232
|
-
// raster cannot reproduce the real Codiedev wordmark cleanly, so leave that
|
|
233
|
-
// surface blank and keep the proper brand mark on the plugin-driven home
|
|
234
|
-
// screen. The bundled JS table is replaced byte-for-byte so binary offsets do
|
|
235
|
-
// not move.
|
|
236
191
|
function escapeJsSource(row) {
|
|
237
192
|
let out = "";
|
|
238
193
|
for (const ch of row) {
|
|
@@ -245,7 +200,6 @@ function wordmarkRegion(left, right, { escapeUnicode = true } = {}) {
|
|
|
245
200
|
const rows = (list) => list.map((row) => `"${escapeUnicode ? escapeJsSource(row) : row}"`).join(",");
|
|
246
201
|
return `var vn={left:[${rows(left)}],right:[${rows(right)}]};`;
|
|
247
202
|
}
|
|
248
|
-
// o p e n | c o d e — must match the engine's bundle byte-for-byte.
|
|
249
203
|
exports.STOCK_WORDMARK = wordmarkRegion([
|
|
250
204
|
" ",
|
|
251
205
|
"█▀▀█ █▀▀█ █▀▀█ █▀▀▄",
|
|
@@ -257,12 +211,6 @@ exports.STOCK_WORDMARK = wordmarkRegion([
|
|
|
257
211
|
"█___ █__█ █__█ █^^^",
|
|
258
212
|
"▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀",
|
|
259
213
|
]);
|
|
260
|
-
// c o d i | e d e v, rasterized from public/codiedevlogo.svg at eight vertical
|
|
261
|
-
// pixels and packed into four terminal rows with half-block characters. This
|
|
262
|
-
// preserves the real mark's round lowercase bowls, linked c/o, ascenders, and
|
|
263
|
-
// compact v instead of approximating the letters with OpenCode's square font.
|
|
264
|
-
// The engine inserts one column between left and right, so the blank source
|
|
265
|
-
// column at the codi/edev boundary is intentionally omitted.
|
|
266
214
|
const CODIE_LEFT = [
|
|
267
215
|
" ▄ ▄",
|
|
268
216
|
" ▄▄█▄▄ ▄▄█▄▄ ▄████ █",
|
|
@@ -275,9 +223,6 @@ const CODIE_RIGHT = [
|
|
|
275
223
|
"██▀▀█ █ █ ██▄▀█ ▀█▄█ ",
|
|
276
224
|
"▀▀█▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀ ",
|
|
277
225
|
];
|
|
278
|
-
// Migration source for the first hand-drawn banner shipped during development.
|
|
279
|
-
// Recognizing it lets an existing install upgrade in place instead of keeping
|
|
280
|
-
// the old square letterforms until OpenCode happens to reinstall its binary.
|
|
281
226
|
const LEGACY_CODIE_LEFT = [
|
|
282
227
|
" ▄ ▄ ",
|
|
283
228
|
"█▀▀▀ █▀▀█ █▀▀█ █ ",
|
|
@@ -299,9 +244,6 @@ exports.LEGACY_CODIEDEV_WORDMARK = (() => {
|
|
|
299
244
|
return wordmarkRegion(LEGACY_CODIE_LEFT, padded);
|
|
300
245
|
})();
|
|
301
246
|
exports.CODIEDEV_WORDMARK = (() => {
|
|
302
|
-
// Raw Unicode is valid JavaScript and costs fewer source bytes than \uXXXX.
|
|
303
|
-
// Put the remaining byte padding outside the strings so it cannot widen the
|
|
304
|
-
// rendered banner or shift its centering.
|
|
305
247
|
const unpadded = wordmarkRegion(CODIE_LEFT, CODIE_RIGHT, { escapeUnicode: false });
|
|
306
248
|
const deficit = Buffer.byteLength(exports.STOCK_WORDMARK) - Buffer.byteLength(unpadded);
|
|
307
249
|
if (deficit < 0)
|
|
@@ -323,9 +265,6 @@ exports.HIDDEN_WORDMARK = (() => {
|
|
|
323
265
|
}
|
|
324
266
|
return region;
|
|
325
267
|
})();
|
|
326
|
-
// Pure: locate the stock or an earlier Codiedev wordmark in an engine binary.
|
|
327
|
-
// Refuses to touch the file unless exactly one known region appears; an
|
|
328
|
-
// already-hidden or reshaped upstream bundle is left alone.
|
|
329
268
|
function patchBrandWordmark(binary) {
|
|
330
269
|
const stock = Buffer.from(exports.STOCK_WORDMARK);
|
|
331
270
|
const candidates = [stock, Buffer.from(exports.LEGACY_CODIEDEV_WORDMARK), Buffer.from(exports.CODIEDEV_WORDMARK)];
|
|
@@ -349,15 +288,8 @@ function resolveCapturePlugin({ homeDir, existsSync, }) {
|
|
|
349
288
|
}
|
|
350
289
|
return (0, url_1.pathToFileURL)(capturePath).href;
|
|
351
290
|
}
|
|
352
|
-
// A definite answer from the gateway (harness off, token rejected): retrying
|
|
353
|
-
// can't change it.
|
|
354
291
|
class CatalogRejected extends Error {
|
|
355
292
|
}
|
|
356
|
-
/**
|
|
357
|
-
* The account's approved models. Every `codie` session starts here, so one
|
|
358
|
-
* dropped connection or slow gateway reply would end the session before it
|
|
359
|
-
* began; anything but a definite rejection is retried once.
|
|
360
|
-
*/
|
|
361
293
|
async function fetchApprovedCatalog({ baseUrl, key, fetchImpl = fetch, retryDelayMs = 1_000, }) {
|
|
362
294
|
try {
|
|
363
295
|
return await fetchCatalogOnce(baseUrl, key, fetchImpl);
|
|
@@ -377,9 +309,6 @@ async function fetchCatalogOnce(baseUrl, key, fetchImpl) {
|
|
|
377
309
|
headers: { Authorization: `Bearer ${key}` },
|
|
378
310
|
signal: controller.signal,
|
|
379
311
|
});
|
|
380
|
-
// The `codie` bin ships to every connected machine, including companies
|
|
381
|
-
// whose gateway is still switched off. Those developers must get an
|
|
382
|
-
// answer, not an HTTP status.
|
|
383
312
|
if (response.status === 403) {
|
|
384
313
|
throw new CatalogRejected("The Codie harness is not enabled for your company yet. Ask your Codiedev admin to turn it on — " +
|
|
385
314
|
"your session capture keeps working in the meantime.");
|
package/dist/codieRuntime.js
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Where the Codie harness gets its engine.
|
|
3
|
-
//
|
|
4
|
-
// The engine (`opencode-ai`) is a ~132MB platform binary. It is deliberately
|
|
5
|
-
// NOT a dependency of this package: the overwhelming majority of installs are
|
|
6
|
-
// capture-only (Claude Code, Codex, Cursor) and must not pay for a harness
|
|
7
|
-
// they never launch. So `npm i -g codiedev` stays small, and the first `codie`
|
|
8
|
-
// run downloads the engine into the Codiedev state dir.
|
|
9
|
-
//
|
|
10
|
-
// Resolution is pure and injectable so the precedence can be tested without
|
|
11
|
-
// touching the network or a real 132MB install.
|
|
12
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
3
|
if (k2 === undefined) k2 = k;
|
|
14
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -43,19 +33,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
43
33
|
};
|
|
44
34
|
})();
|
|
45
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.ENGINE_MIN_BYTES = exports.CODIE_MIN_NODE_MAJOR = exports.OPENCODE_RUNTIME_SPEC = void 0;
|
|
36
|
+
exports.ENGINE_MIN_BYTES = exports.CODIE_MIN_NODE_MAJOR = exports.OPENCODE_RUNTIME_VERSION = exports.OPENCODE_RUNTIME_SPEC = void 0;
|
|
47
37
|
exports.codieRuntimeDir = codieRuntimeDir;
|
|
48
38
|
exports.isEngineSize = isEngineSize;
|
|
39
|
+
exports.installedRuntimePackageJson = installedRuntimePackageJson;
|
|
49
40
|
exports.resolveCodieRuntime = resolveCodieRuntime;
|
|
50
41
|
exports.assertCodieNodeVersion = assertCodieNodeVersion;
|
|
51
42
|
const path = __importStar(require("path"));
|
|
52
|
-
// Pinned exactly, not a range. patchBrandWordmark() only rewrites bundles it
|
|
53
|
-
// recognizes byte-for-byte, so a floating version would silently regress the
|
|
54
|
-
// terminal branding whenever OpenCode ships a new build.
|
|
55
43
|
exports.OPENCODE_RUNTIME_SPEC = "opencode-ai@1.18.4";
|
|
56
|
-
|
|
57
|
-
// `codiedev connect` still installs for Node 18 users — this floor is enforced
|
|
58
|
-
// at `codie` launch instead.
|
|
44
|
+
exports.OPENCODE_RUNTIME_VERSION = exports.OPENCODE_RUNTIME_SPEC.slice(exports.OPENCODE_RUNTIME_SPEC.lastIndexOf("@") + 1);
|
|
59
45
|
exports.CODIE_MIN_NODE_MAJOR = 20;
|
|
60
46
|
function codieRuntimeDir(stateDir) {
|
|
61
47
|
return path.join(stateDir, "runtime");
|
|
@@ -63,21 +49,14 @@ function codieRuntimeDir(stateDir) {
|
|
|
63
49
|
function installedBinary(stateDir) {
|
|
64
50
|
return path.join(codieRuntimeDir(stateDir), "node_modules", "opencode-ai", "bin", "opencode.exe");
|
|
65
51
|
}
|
|
66
|
-
/**
|
|
67
|
-
* The real engine is a ~132MB native executable. opencode-ai ships
|
|
68
|
-
* bin/opencode.exe as a ~500-byte shell script that only prints "postinstall
|
|
69
|
-
* was not run" until its postinstall swaps the binary in; anything this small
|
|
70
|
-
* is that placeholder, not an engine. Pure.
|
|
71
|
-
*/
|
|
72
52
|
exports.ENGINE_MIN_BYTES = 1_000_000;
|
|
73
53
|
function isEngineSize(bytes) {
|
|
74
54
|
return bytes >= exports.ENGINE_MIN_BYTES;
|
|
75
55
|
}
|
|
76
|
-
function
|
|
77
|
-
return path.join(codieRuntimeDir(stateDir), "node_modules", "opencode-ai");
|
|
56
|
+
function installedRuntimePackageJson(stateDir) {
|
|
57
|
+
return path.join(codieRuntimeDir(stateDir), "node_modules", "opencode-ai", "package.json");
|
|
78
58
|
}
|
|
79
|
-
function resolveCodieRuntime({ env, stateDir, existsSync, resolveBundled, isEngine = () => true, }) {
|
|
80
|
-
// 1. Explicit override — the air-gapped / pre-provisioned escape hatch.
|
|
59
|
+
function resolveCodieRuntime({ env, stateDir, existsSync, readInstalledVersion, resolveBundled, isEngine = () => true, }) {
|
|
81
60
|
const override = env.CODIEDEV_OPENCODE_BINARY?.trim();
|
|
82
61
|
if (override) {
|
|
83
62
|
if (!existsSync(override)) {
|
|
@@ -85,16 +64,32 @@ function resolveCodieRuntime({ env, stateDir, existsSync, resolveBundled, isEngi
|
|
|
85
64
|
}
|
|
86
65
|
return { kind: "ready", binary: override };
|
|
87
66
|
}
|
|
88
|
-
// 2. A bundled engine, if this package was installed with one (dev checkout,
|
|
89
|
-
// or a future vendored distribution).
|
|
90
67
|
const bundled = resolveBundled();
|
|
91
68
|
if (bundled && isEngine(bundled))
|
|
92
69
|
return { kind: "ready", binary: bundled };
|
|
93
|
-
// 3. The lazily installed engine.
|
|
94
70
|
const binary = installedBinary(stateDir);
|
|
95
71
|
if (existsSync(binary)) {
|
|
96
|
-
|
|
97
|
-
|
|
72
|
+
const currentVersion = readInstalledVersion?.(installedRuntimePackageJson(stateDir)) ?? null;
|
|
73
|
+
if (!isEngine(binary) && (!currentVersion || currentVersion === exports.OPENCODE_RUNTIME_VERSION)) {
|
|
74
|
+
return {
|
|
75
|
+
kind: "unlinked",
|
|
76
|
+
installDir: codieRuntimeDir(stateDir),
|
|
77
|
+
binary,
|
|
78
|
+
spec: exports.OPENCODE_RUNTIME_SPEC,
|
|
79
|
+
packageDir: path.dirname(installedRuntimePackageJson(stateDir)),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (currentVersion && currentVersion !== exports.OPENCODE_RUNTIME_VERSION) {
|
|
83
|
+
return {
|
|
84
|
+
kind: "outdated",
|
|
85
|
+
installDir: codieRuntimeDir(stateDir),
|
|
86
|
+
binary,
|
|
87
|
+
spec: exports.OPENCODE_RUNTIME_SPEC,
|
|
88
|
+
currentVersion,
|
|
89
|
+
expectedVersion: exports.OPENCODE_RUNTIME_VERSION,
|
|
90
|
+
linked: isEngine(binary),
|
|
91
|
+
packageDir: path.dirname(installedRuntimePackageJson(stateDir)),
|
|
92
|
+
};
|
|
98
93
|
}
|
|
99
94
|
return { kind: "ready", binary };
|
|
100
95
|
}
|