@odla-ai/cli 0.36.1 → 0.37.1
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/dist/bin.cjs +77 -54
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-4QJ5NS64.js → chunk-XFIFFYNH.js} +70 -55
- package/dist/chunk-XFIFFYNH.js.map +1 -0
- package/dist/{cli-BFGY7F6X.js → cli-OH6PCYZ3.js} +2 -2
- package/dist/index.cjs +69 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-4QJ5NS64.js.map +0 -1
- /package/dist/{cli-BFGY7F6X.js.map → cli-OH6PCYZ3.js.map} +0 -0
package/dist/bin.js
CHANGED
|
@@ -174,7 +174,7 @@ function absoluteEntryPath(entryPath) {
|
|
|
174
174
|
|
|
175
175
|
// src/bin.ts
|
|
176
176
|
var argv = process.argv.slice(2);
|
|
177
|
-
requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-
|
|
177
|
+
requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-OH6PCYZ3.js")).runCli()).catch((err) => {
|
|
178
178
|
console.error(redactSecrets(`odla-ai: ${err instanceof Error ? err.message : String(err)}`));
|
|
179
179
|
process.exitCode = exitCodeFor(err);
|
|
180
180
|
});
|
|
@@ -551,6 +551,7 @@ var SCOPE_PURPOSE = {
|
|
|
551
551
|
"app:config:write": "apply or inspect one revision-bound configuration operation for an app you own",
|
|
552
552
|
"platform:runbook:write": "read and edit all of odla's operational runbooks, including admin-visible content",
|
|
553
553
|
"app:device:enroll": "enrol this machine so it can mint its own short-lived credentials without asking you again",
|
|
554
|
+
"platform:device:enroll:extended": "enrol this machine with a credential that outlives the seven-day owner ceiling \u2014 a durable secret on a machine you are vouching for",
|
|
554
555
|
"platform:ai:policy:write": "change System AI model routing",
|
|
555
556
|
"platform:ai:policy:read": "read System AI model routing",
|
|
556
557
|
"platform:ai:credential:write": "replace a stored AI provider key",
|
|
@@ -6882,7 +6883,7 @@ function createCodeRuntimeControlClient(options) {
|
|
|
6882
6883
|
throw new TypeError("modelRequestTimeoutMs must be an integer from 30000 to 1800000");
|
|
6883
6884
|
}
|
|
6884
6885
|
const request3 = options.fetch ?? fetch;
|
|
6885
|
-
const
|
|
6886
|
+
const call3 = async (path, body, timeoutMs = requestTimeoutMs) => {
|
|
6886
6887
|
const timeout = AbortSignal.timeout(timeoutMs);
|
|
6887
6888
|
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
6888
6889
|
let response2;
|
|
@@ -6912,17 +6913,17 @@ function createCodeRuntimeControlClient(options) {
|
|
|
6912
6913
|
return {
|
|
6913
6914
|
heartbeat: async (version, capabilities) => {
|
|
6914
6915
|
validateHeartbeat(version, capabilities);
|
|
6915
|
-
return parseSnapshot(await
|
|
6916
|
+
return parseSnapshot(await call3("/registry/code/runtime/heartbeat", { runtimeVersion: version, capabilities }));
|
|
6916
6917
|
},
|
|
6917
6918
|
acknowledge: async (commandId, result) => {
|
|
6918
6919
|
if (!/^ccmd_[0-9a-f]{32}$/.test(commandId)) throw new TypeError("invalid Code runtime command id");
|
|
6919
|
-
await
|
|
6920
|
+
await call3(`/registry/code/runtime/commands/${commandId}/ack`, result);
|
|
6920
6921
|
},
|
|
6921
6922
|
source: async (sessionId) => parseSource(
|
|
6922
|
-
await
|
|
6923
|
+
await call3(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/source`, {})
|
|
6923
6924
|
),
|
|
6924
6925
|
infer: async (sessionId, inference) => {
|
|
6925
|
-
const value2 = record5(await
|
|
6926
|
+
const value2 = record5(await call3(
|
|
6926
6927
|
`/registry/code/runtime/sessions/${validSessionId(sessionId)}/inference`,
|
|
6927
6928
|
inference,
|
|
6928
6929
|
modelRequestTimeoutMs
|
|
@@ -6933,11 +6934,11 @@ function createCodeRuntimeControlClient(options) {
|
|
|
6933
6934
|
return value2;
|
|
6934
6935
|
},
|
|
6935
6936
|
review: async (sessionId, review) => parseReview(
|
|
6936
|
-
await
|
|
6937
|
+
await call3(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/review`, review, modelRequestTimeoutMs)
|
|
6937
6938
|
),
|
|
6938
6939
|
submitCandidate: async (sessionId, checkpointId, verification) => {
|
|
6939
6940
|
if (!/^cpoint_[0-9a-f]{32}$/.test(checkpointId)) throw new TypeError("invalid Code checkpoint id");
|
|
6940
|
-
return parseCandidate(await
|
|
6941
|
+
return parseCandidate(await call3(
|
|
6941
6942
|
`/registry/code/runtime/sessions/${validSessionId(sessionId)}/candidates`,
|
|
6942
6943
|
{ checkpointId, verification }
|
|
6943
6944
|
));
|
|
@@ -6947,21 +6948,21 @@ function createCodeRuntimeControlClient(options) {
|
|
|
6947
6948
|
if (!/^[A-Za-z0-9._:-]{1,120}$/.test(eventId) || !event || typeof event !== "object" || new TextEncoder().encode(serialized).byteLength > 24e3) {
|
|
6948
6949
|
throw new TypeError("invalid Code session event");
|
|
6949
6950
|
}
|
|
6950
|
-
await
|
|
6951
|
+
await call3(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/chat/events`, { eventId, event });
|
|
6951
6952
|
},
|
|
6952
6953
|
recallMemories: async (sessionId, subjects, limit) => {
|
|
6953
|
-
const response2 = await
|
|
6954
|
+
const response2 = await call3(
|
|
6954
6955
|
`/registry/code/runtime/sessions/${validSessionId(sessionId)}/recall`,
|
|
6955
6956
|
{ subjects: [...subjects], limit }
|
|
6956
6957
|
);
|
|
6957
6958
|
return Array.isArray(response2.memories) ? response2.memories : [];
|
|
6958
6959
|
},
|
|
6959
6960
|
rememberMemory: async (sessionId, memory) => {
|
|
6960
|
-
await
|
|
6961
|
+
await call3(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/remember`, memory);
|
|
6961
6962
|
},
|
|
6962
6963
|
reportSessionFailure: async (sessionId, message2) => {
|
|
6963
6964
|
if (!message2.trim() || message2.length > 2e3) throw new TypeError("invalid Code session failure");
|
|
6964
|
-
await
|
|
6965
|
+
await call3(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/failure`, { message: message2 });
|
|
6965
6966
|
}
|
|
6966
6967
|
};
|
|
6967
6968
|
}
|
|
@@ -7850,7 +7851,7 @@ var SYSTEM_PROMPT_FOR = {
|
|
|
7850
7851
|
};
|
|
7851
7852
|
function codeSkill(opts) {
|
|
7852
7853
|
let seq = 0;
|
|
7853
|
-
const
|
|
7854
|
+
const call3 = async (tool, input, signal) => {
|
|
7854
7855
|
const startedAt = Date.now();
|
|
7855
7856
|
const response2 = await opts.broker.execute(
|
|
7856
7857
|
{ lease: opts.lease, workspaceDir: opts.workspaceDir, signal },
|
|
@@ -7872,7 +7873,7 @@ function codeSkill(opts) {
|
|
|
7872
7873
|
},
|
|
7873
7874
|
additionalProperties: false
|
|
7874
7875
|
},
|
|
7875
|
-
handler: (input, ctx) =>
|
|
7876
|
+
handler: (input, ctx) => call3("sandbox.read", input, ctx.signal)
|
|
7876
7877
|
};
|
|
7877
7878
|
const applyPatch = {
|
|
7878
7879
|
name: "odla_apply_git_diff",
|
|
@@ -7883,7 +7884,7 @@ function codeSkill(opts) {
|
|
|
7883
7884
|
properties: { patch: { type: "string", minLength: 1, maxLength: 262144 } },
|
|
7884
7885
|
additionalProperties: false
|
|
7885
7886
|
},
|
|
7886
|
-
handler: (input, ctx) =>
|
|
7887
|
+
handler: (input, ctx) => call3("sandbox.apply_patch", input, ctx.signal)
|
|
7887
7888
|
};
|
|
7888
7889
|
const runRecipe = {
|
|
7889
7890
|
name: "odla_run_recipe",
|
|
@@ -7894,7 +7895,7 @@ function codeSkill(opts) {
|
|
|
7894
7895
|
properties: { recipeId: { type: "string", minLength: 1, maxLength: 120, pattern: "^[a-zA-Z0-9._:-]+$" } },
|
|
7895
7896
|
additionalProperties: false
|
|
7896
7897
|
},
|
|
7897
|
-
handler: (input, ctx) =>
|
|
7898
|
+
handler: (input, ctx) => call3("sandbox.run_recipe", input, ctx.signal)
|
|
7898
7899
|
};
|
|
7899
7900
|
const listFiles2 = {
|
|
7900
7901
|
name: "odla_list",
|
|
@@ -7907,7 +7908,7 @@ function codeSkill(opts) {
|
|
|
7907
7908
|
},
|
|
7908
7909
|
additionalProperties: false
|
|
7909
7910
|
},
|
|
7910
|
-
handler: (input, ctx) =>
|
|
7911
|
+
handler: (input, ctx) => call3("sandbox.list", input, ctx.signal)
|
|
7911
7912
|
};
|
|
7912
7913
|
const searchFiles = {
|
|
7913
7914
|
name: "odla_search",
|
|
@@ -7923,7 +7924,7 @@ function codeSkill(opts) {
|
|
|
7923
7924
|
},
|
|
7924
7925
|
additionalProperties: false
|
|
7925
7926
|
},
|
|
7926
|
-
handler: (input, ctx) =>
|
|
7927
|
+
handler: (input, ctx) => call3("sandbox.search", input, ctx.signal)
|
|
7927
7928
|
};
|
|
7928
7929
|
const graphTool = (name, tool, description, required) => ({
|
|
7929
7930
|
name,
|
|
@@ -7934,7 +7935,7 @@ function codeSkill(opts) {
|
|
|
7934
7935
|
properties: { query: { type: "string", maxLength: 512 } },
|
|
7935
7936
|
additionalProperties: false
|
|
7936
7937
|
},
|
|
7937
|
-
handler: (input, ctx) =>
|
|
7938
|
+
handler: (input, ctx) => call3(tool, input, ctx.signal)
|
|
7938
7939
|
});
|
|
7939
7940
|
const orientation = [
|
|
7940
7941
|
graphTool(
|
|
@@ -7973,9 +7974,9 @@ async function runCodeAgent(options) {
|
|
|
7973
7974
|
lease: options.lease,
|
|
7974
7975
|
workspaceDir: options.workspaceDir,
|
|
7975
7976
|
surface,
|
|
7976
|
-
onToolCall: (
|
|
7977
|
-
toolCalls.push(
|
|
7978
|
-
options.onToolCall?.(
|
|
7977
|
+
onToolCall: (call3) => {
|
|
7978
|
+
toolCalls.push(call3);
|
|
7979
|
+
options.onToolCall?.(call3);
|
|
7979
7980
|
}
|
|
7980
7981
|
});
|
|
7981
7982
|
const compaction = options.compaction === void 0 ? keepRecentExchanges({ whenInputTokensExceed: 12e4, keep: 3 }) : options.compaction;
|
|
@@ -10287,7 +10288,7 @@ Usage:
|
|
|
10287
10288
|
odla-ai security run [target] --ack-redacted-source [--env dev] [--profile odla] [--fail-on high]
|
|
10288
10289
|
odla-ai security run [target] --self --ack-redacted-source
|
|
10289
10290
|
odla-ai provision [--live] [--config odla.config.mjs] [--email <odla-account>] [--request-grant] [--no-open] [--wait <seconds>] [--dry-run] [--push-secrets] [--rotate-o11y-token] [--write-dev-vars[=path]] [--yes]
|
|
10290
|
-
odla-ai device enroll [--app <id>[,<id>...]] [--name <label>] [--capability <c>[,<c>...]] [--email <odla-account>] [--no-open] [--json]
|
|
10291
|
+
odla-ai device enroll [--app <id>[,<id>...]] [--name <label>] [--capability <c>[,<c>...]] [--device-ttl <30d|6w|2y|forever>] [--email <odla-account>] [--no-open] [--json]
|
|
10291
10292
|
odla-ai device list [--email <odla-account>] [--json]
|
|
10292
10293
|
odla-ai device revoke <device-id> [--email <odla-account>] [--json]
|
|
10293
10294
|
odla-ai credentials list [--config odla.config.mjs] [--env dev] [--all] [--json]
|
|
@@ -12756,9 +12757,15 @@ async function provisionEnvCredentials(opts) {
|
|
|
12756
12757
|
if (o11yToken) {
|
|
12757
12758
|
opts.stdout.log(`${opts.env}: reusing local o11y ingest token`);
|
|
12758
12759
|
} else {
|
|
12759
|
-
o11yToken = await issueO11yToken(opts);
|
|
12760
|
-
|
|
12761
|
-
|
|
12760
|
+
o11yToken = await issueO11yToken(opts) ?? void 0;
|
|
12761
|
+
if (o11yToken) {
|
|
12762
|
+
credentials = save(opts, credentials, tenantId, { ...dbKey ? { dbKey } : {}, o11yToken });
|
|
12763
|
+
opts.stdout.log(`${opts.env}: ${opts.rotateO11y ? "rotated" : "issued"} o11y ingest token`);
|
|
12764
|
+
} else {
|
|
12765
|
+
opts.stdout.log(
|
|
12766
|
+
`${opts.env}: o11y token already exists and its shown-once value is not on this machine \u2014 leaving it alone (a co-owner provisioned this env). Nothing was rotated, and this env's running Worker keeps its token. To replace it deliberately \u2014 which invalidates the token on whatever is deployed \u2014 run "odla-ai provision --rotate-o11y-token --push-secrets".`
|
|
12767
|
+
);
|
|
12768
|
+
}
|
|
12762
12769
|
}
|
|
12763
12770
|
}
|
|
12764
12771
|
return save(opts, credentials, tenantId, {
|
|
@@ -12812,11 +12819,7 @@ async function issueO11yToken(opts) {
|
|
|
12812
12819
|
`${opts.cfg.platformUrl}/o11y/${encodeURIComponent(opts.cfg.app.id)}/token${suffix}?env=${encodeURIComponent(opts.env)}`,
|
|
12813
12820
|
{ method: "POST", headers: { authorization: `Bearer ${opts.developerToken}` } }
|
|
12814
12821
|
);
|
|
12815
|
-
if (res.status === 409 && !opts.rotateO11y)
|
|
12816
|
-
throw new Error(
|
|
12817
|
-
`o11y token already exists for env "${opts.env}", but its shown-once value is not in the local credentials file; run "odla-ai provision --push-secrets" to install a separate runtime credential without rotating siblings`
|
|
12818
|
-
);
|
|
12819
|
-
}
|
|
12822
|
+
if (res.status === 409 && !opts.rotateO11y) return null;
|
|
12820
12823
|
if (!res.ok) throw new Error(`o11y token ${opts.rotateO11y ? "rotation" : "issue"} (${opts.env}) failed: ${res.status} ${await safeText7(res)}`);
|
|
12821
12824
|
const body = await res.json();
|
|
12822
12825
|
if (!body.token) throw new Error(`o11y token ${opts.rotateO11y ? "rotation" : "issue"} (${opts.env}) returned no token`);
|
|
@@ -13378,6 +13381,24 @@ function renderAdvisories(out, advisories, env = process.env) {
|
|
|
13378
13381
|
}
|
|
13379
13382
|
}
|
|
13380
13383
|
|
|
13384
|
+
// src/device-ttl.ts
|
|
13385
|
+
var OWNER_DEVICE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
13386
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
13387
|
+
var UNITS = { d: DAY_MS, w: 7 * DAY_MS, y: 365 * DAY_MS };
|
|
13388
|
+
function parseDeviceTtl(raw) {
|
|
13389
|
+
if (raw === void 0 || raw === true) return void 0;
|
|
13390
|
+
const text3 = String(raw).trim().toLowerCase();
|
|
13391
|
+
if (!text3) return void 0;
|
|
13392
|
+
if (text3 === "forever" || text3 === "never") return 100 * 365 * DAY_MS;
|
|
13393
|
+
const match = /^(\d+)\s*([dwy])$/.exec(text3);
|
|
13394
|
+
if (!match) {
|
|
13395
|
+
throw new Error(
|
|
13396
|
+
`--device-ttl expects a duration like 30d, 6w, 2y, or "forever" (got "${raw}")`
|
|
13397
|
+
);
|
|
13398
|
+
}
|
|
13399
|
+
return Number(match[1]) * UNITS[match[2]];
|
|
13400
|
+
}
|
|
13401
|
+
|
|
13381
13402
|
// src/device-command.ts
|
|
13382
13403
|
import { chmodSync as chmodSync2, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
13383
13404
|
import { dirname as dirname10 } from "path";
|
|
@@ -13397,7 +13418,17 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13397
13418
|
const name = stringOpt(parsed.options.name) ?? defaultDeviceName();
|
|
13398
13419
|
const apps = (stringOpt(parsed.options.app) ?? cfg.app.id).split(",").map((id2) => id2.trim()).filter(Boolean);
|
|
13399
13420
|
if (apps.length === 0) throw new Error("device enroll needs --app <id>[,<id>\u2026]");
|
|
13400
|
-
const
|
|
13421
|
+
const deviceTtlMs = parseDeviceTtl(parsed.options["device-ttl"]);
|
|
13422
|
+
const extended = deviceTtlMs !== void 0 && deviceTtlMs > OWNER_DEVICE_TTL_MS;
|
|
13423
|
+
const token = await scopedToken2(
|
|
13424
|
+
parsed,
|
|
13425
|
+
deps,
|
|
13426
|
+
cfg,
|
|
13427
|
+
doFetch,
|
|
13428
|
+
out,
|
|
13429
|
+
`odla CLI (enroll ${name})`,
|
|
13430
|
+
extended ? "platform:device:enroll:extended" : "app:device:enroll"
|
|
13431
|
+
);
|
|
13401
13432
|
const response2 = await doFetch(`${cfg.platformUrl}/registry/devices`, {
|
|
13402
13433
|
method: "POST",
|
|
13403
13434
|
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
@@ -13405,7 +13436,8 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13405
13436
|
name,
|
|
13406
13437
|
platform: process16.platform,
|
|
13407
13438
|
appIds: apps,
|
|
13408
|
-
...parsed.options.capability ? { capabilities: String(parsed.options.capability).split(",").map((c) => c.trim()).filter(Boolean) } : {}
|
|
13439
|
+
...parsed.options.capability ? { capabilities: String(parsed.options.capability).split(",").map((c) => c.trim()).filter(Boolean) } : {},
|
|
13440
|
+
...deviceTtlMs === void 0 ? {} : { deviceTtlMs }
|
|
13409
13441
|
})
|
|
13410
13442
|
});
|
|
13411
13443
|
const body = await response2.json().catch(() => ({}));
|
|
@@ -13458,12 +13490,12 @@ async function revoke(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13458
13490
|
out.error(`device: revoked ${deviceId}; every credential it minted is revoked with it`);
|
|
13459
13491
|
if (json) out.log(JSON.stringify({ deviceId, revoked: true }, null, 2));
|
|
13460
13492
|
}
|
|
13461
|
-
async function scopedToken2(parsed, deps, cfg, doFetch, out, label) {
|
|
13493
|
+
async function scopedToken2(parsed, deps, cfg, doFetch, out, label, scope = "app:device:enroll") {
|
|
13462
13494
|
const { credentials } = await resolveOperatorContext(parsed, { allowMissingConfig: true });
|
|
13463
13495
|
const scopedTokenFile = credentials.scopedTokenFile;
|
|
13464
13496
|
return getScopedPlatformToken({
|
|
13465
13497
|
platform: cfg.platformUrl,
|
|
13466
|
-
scope
|
|
13498
|
+
scope,
|
|
13467
13499
|
email: stringOpt(parsed.options.email),
|
|
13468
13500
|
label,
|
|
13469
13501
|
fetch: doFetch,
|
|
@@ -13673,12 +13705,7 @@ ${counts.created} created, ${counts.updated} updated, ${counts.unchanged} unchan
|
|
|
13673
13705
|
);
|
|
13674
13706
|
}
|
|
13675
13707
|
async function upsert(ctx, r, visibility) {
|
|
13676
|
-
const
|
|
13677
|
-
ctx,
|
|
13678
|
-
"GET",
|
|
13679
|
-
`/runbook?app=${encodeURIComponent(ctx.appId)}&slug=${encodeURIComponent(r.slug)}&limit=1`
|
|
13680
|
-
);
|
|
13681
|
-
const found = page2.records[0];
|
|
13708
|
+
const found = await bySlug(ctx, r.slug).catch(() => null);
|
|
13682
13709
|
if (!found) {
|
|
13683
13710
|
await call(ctx, "POST", "/runbook", {
|
|
13684
13711
|
appId: ctx.appId,
|
|
@@ -14083,13 +14110,7 @@ async function runbookAsk(ctx, question, all) {
|
|
|
14083
14110
|
ctx.out.log(JSDOC_POINTER);
|
|
14084
14111
|
}
|
|
14085
14112
|
async function runbookComment(ctx, slug, body) {
|
|
14086
|
-
const
|
|
14087
|
-
ctx,
|
|
14088
|
-
"GET",
|
|
14089
|
-
`/runbook?app=${encodeURIComponent(ctx.appId)}&slug=${encodeURIComponent(slug)}&limit=1`
|
|
14090
|
-
);
|
|
14091
|
-
const found = page2.records[0];
|
|
14092
|
-
if (!found) throw new Error(`no runbook "${slug}" in ${ctx.appId}`);
|
|
14113
|
+
const found = await bySlug(ctx, slug);
|
|
14093
14114
|
await call(ctx, "POST", `/runbook/${encodeURIComponent(found.id)}/comments`, { body });
|
|
14094
14115
|
ctx.out.log(`commented on ${slug} (v${found.version})`);
|
|
14095
14116
|
}
|
|
@@ -14140,13 +14161,7 @@ var defaultRunOrInjected = (deps) => deps.run ?? defaultRun;
|
|
|
14140
14161
|
|
|
14141
14162
|
// src/runbook-edit-flow.ts
|
|
14142
14163
|
async function editRunbook(ctx, slug, deps = {}) {
|
|
14143
|
-
const
|
|
14144
|
-
ctx,
|
|
14145
|
-
"GET",
|
|
14146
|
-
`/runbook?app=${encodeURIComponent(ctx.appId)}&slug=${encodeURIComponent(slug)}&limit=1`
|
|
14147
|
-
);
|
|
14148
|
-
const found = page2.records[0];
|
|
14149
|
-
if (!found) throw new Error(`no runbook "${slug}" in ${ctx.appId}`);
|
|
14164
|
+
const found = await bySlug(ctx, slug);
|
|
14150
14165
|
ctx.out.log(`opening ${slug} v${found.version} in your editor\u2026`);
|
|
14151
14166
|
const body = await editText(found.body, slug, deps);
|
|
14152
14167
|
return body === null ? null : { body, expectedVersion: found.version };
|
|
@@ -15266,4 +15281,4 @@ export {
|
|
|
15266
15281
|
isTerminalHostedSecurityStatus,
|
|
15267
15282
|
runCli
|
|
15268
15283
|
};
|
|
15269
|
-
//# sourceMappingURL=chunk-
|
|
15284
|
+
//# sourceMappingURL=chunk-XFIFFYNH.js.map
|