@odla-ai/cli 0.16.3 → 0.16.5

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/index.cjs CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  isTerminalHostedSecurityStatus: () => isTerminalHostedSecurityStatus,
62
62
  listGitHubSecuritySources: () => listGitHubSecuritySources,
63
63
  listHostedSecurityJobs: () => listHostedSecurityJobs,
64
+ prepareCodeImages: () => prepareCodeImages,
64
65
  printCapabilities: () => printCapabilities,
65
66
  provision: () => provision,
66
67
  redactSecrets: () => redactSecrets,
@@ -1992,8 +1993,8 @@ function printStatus(status, json, out) {
1992
1993
 
1993
1994
  // src/code-connect.ts
1994
1995
  var import_node_fs7 = require("fs");
1995
- var import_node_os = require("os");
1996
- var import_node_path4 = require("path");
1996
+ var import_node_os2 = require("os");
1997
+ var import_node_path5 = require("path");
1997
1998
 
1998
1999
  // ../harness/dist/chunk-QTUEF2HZ.js
1999
2000
  var HARNESS_PROTOCOL_VERSION = 1;
@@ -2076,7 +2077,7 @@ function encodeAgentInput(message2) {
2076
2077
  `;
2077
2078
  }
2078
2079
 
2079
- // ../harness/dist/chunk-IRFCMVKU.js
2080
+ // ../harness/dist/chunk-IONC45N6.js
2080
2081
  var import_child_process = require("child_process");
2081
2082
  var import_fs = require("fs");
2082
2083
  var import_promises2 = require("fs/promises");
@@ -2129,7 +2130,7 @@ async function selectContainerEngine(requested = "auto", options = {}) {
2129
2130
  throw new TypeError("no rootless Podman found; install Podman or explicitly choose --engine docker after reviewing its daemon boundary");
2130
2131
  }
2131
2132
  if (platform === "darwin") {
2132
- throw new TypeError("no Apple container or Podman Machine found; install one or explicitly choose --engine docker");
2133
+ throw new TypeError("Apple container is not installed; on Apple Silicon macOS 26 run `brew install container`, then retry (Podman Machine is the fallback)");
2133
2134
  }
2134
2135
  throw new TypeError("no supported container engine found");
2135
2136
  }
@@ -2534,7 +2535,7 @@ async function captureGitDiff(root, maxBytes) {
2534
2535
  if (code !== 0 && code !== 1) {
2535
2536
  throw new Error(`git diff failed: ${Buffer.concat(stderr).toString("utf8").slice(0, 1e3)}`);
2536
2537
  }
2537
- return Buffer.concat(stdout).toString("utf8").replaceAll("a/baseline/", "a/").replaceAll("b/workspace/", "b/").replaceAll("--- a/baseline", "--- a").replaceAll("+++ b/workspace", "+++ b");
2538
+ return Buffer.concat(stdout).toString("utf8").replaceAll("a/baseline/", "a/").replaceAll("a/workspace/", "a/").replaceAll("b/baseline/", "b/").replaceAll("b/workspace/", "b/").replaceAll("--- a/baseline", "--- a").replaceAll("+++ b/workspace", "+++ b");
2538
2539
  }
2539
2540
  async function stageWorkspace(source, options = {}) {
2540
2541
  const sourceDir = await (0, import_promises4.realpath)((0, import_path4.resolve)(source));
@@ -2593,7 +2594,7 @@ async function stageWorkspacePair(baselineSource, workspaceSource, options = {})
2593
2594
  }
2594
2595
  }
2595
2596
 
2596
- // ../harness/dist/chunk-4MOSEKB6.js
2597
+ // ../harness/dist/chunk-QGDLTDYH.js
2597
2598
  var import_crypto = require("crypto");
2598
2599
  var import_promises5 = require("fs/promises");
2599
2600
  var import_path5 = require("path");
@@ -2930,7 +2931,7 @@ function validateSnapshot(snapshot, limits) {
2930
2931
  }
2931
2932
  }
2932
2933
 
2933
- // ../harness/dist/chunk-4MOSEKB6.js
2934
+ // ../harness/dist/chunk-QGDLTDYH.js
2934
2935
  var import_child_process4 = require("child_process");
2935
2936
  var import_promises6 = require("fs/promises");
2936
2937
  var import_path6 = require("path");
@@ -3223,7 +3224,7 @@ function looksLikeDestination(value) {
3223
3224
  return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text);
3224
3225
  }
3225
3226
 
3226
- // ../harness/dist/chunk-4MOSEKB6.js
3227
+ // ../harness/dist/chunk-QGDLTDYH.js
3227
3228
  var import_crypto4 = require("crypto");
3228
3229
  async function digestStagedWorkspace(root, limits) {
3229
3230
  const files = [];
@@ -4589,6 +4590,7 @@ function runtimeResultError(value) {
4589
4590
  var CodePiRuntimeEngine = class {
4590
4591
  constructor(options) {
4591
4592
  this.options = options;
4593
+ if (options.imageAuthorization === "cli_embedded" && !/^odla-ai\/pi-agent:embedded-sha256-[0-9a-f]{64}$/.test(options.image)) throw new TypeError("CLI-embedded Pi image must use its content-addressed local tag");
4592
4594
  this.#run = options.runAttempt ?? runContainerAttempt;
4593
4595
  this.#buildPolicyDigest = digestRuntimeValue(JSON.stringify(options.recipes));
4594
4596
  this.#checkpoints = new CodeRuntimeCheckpointManager({
@@ -4754,6 +4756,7 @@ var CodePiRuntimeEngine = class {
4754
4756
  const result = await this.#run({
4755
4757
  engine: this.options.engine,
4756
4758
  image: this.options.image,
4759
+ allowUnpinnedImage: this.options.imageAuthorization === "cli_embedded",
4757
4760
  workspaceDir: active.workspace.workspaceDir,
4758
4761
  workspaceAccess: "none",
4759
4762
  task: lease.task,
@@ -5263,23 +5266,18 @@ function digestText(value) {
5263
5266
 
5264
5267
  // src/code-images.ts
5265
5268
  var import_node_child_process4 = require("child_process");
5266
- async function prepareCodeImages(engine, images) {
5267
- for (const image of images) {
5268
- await new Promise((accept, reject) => {
5269
- const args = engine === "container" ? ["image", "pull", image] : ["pull", image];
5270
- (0, import_node_child_process4.execFile)(engine, args, { encoding: "utf8", maxBuffer: 2 * 1024 * 1024, timeout: 10 * 6e4 }, (error) => {
5271
- if (error) reject(new Error(`could not prepare pinned Code image ${image}`));
5272
- else accept();
5273
- });
5274
- });
5275
- }
5276
- }
5269
+ var import_node_crypto2 = require("crypto");
5270
+ var import_promises10 = require("fs/promises");
5271
+ var import_node_os = require("os");
5272
+ var import_node_path4 = require("path");
5273
+ var import_node_url2 = require("url");
5277
5274
 
5278
5275
  // src/code-runtime-config.ts
5279
- var CODE_PI_IMAGE = "ghcr.io/cory/odla-pi-agent@sha256:2a52a1c8eed66ad167e7bccab4d603ed8fcd75c42dddfb320083436ed89b7c9c";
5276
+ var CODE_PI_IMAGE = "odla-ai/pi-agent:embedded";
5277
+ var CODE_NODE_IMAGE = "node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd";
5280
5278
  var CODE_BUILD_RECIPES = Object.freeze([{
5281
5279
  id: "odla-code-contracts",
5282
- image: "node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd",
5280
+ image: CODE_NODE_IMAGE,
5283
5281
  command: [
5284
5282
  "node",
5285
5283
  // The clean source mount deliberately has no node_modules. Reuse the
@@ -5299,10 +5297,84 @@ var CODE_BUILD_RECIPES = Object.freeze([{
5299
5297
  pids: 128
5300
5298
  }]);
5301
5299
 
5300
+ // src/code-images.ts
5301
+ var runCodeImageCommand = (command, args, stdio) => new Promise((accept, reject) => {
5302
+ const child = (0, import_node_child_process4.spawn)(command, [...args], { shell: false, stdio });
5303
+ child.once("error", reject);
5304
+ child.once("exit", (code, signal) => {
5305
+ if (code === 0) accept();
5306
+ else reject(new Error(`${command} ${args.join(" ")} exited ${code ?? signal ?? "without a status"}`));
5307
+ });
5308
+ });
5309
+ async function prepareCodeImages(engine, images, run = runCodeImageCommand, buildEmbedded = buildEmbeddedPiImage, nameEmbedded = embeddedPiImageName) {
5310
+ if (engine === "container") {
5311
+ try {
5312
+ await run(engine, ["system", "start"], "inherit");
5313
+ } catch {
5314
+ throw new Error("Apple container could not start; run `container system start` once to complete its lightweight VM setup, then retry");
5315
+ }
5316
+ }
5317
+ const prepared = [];
5318
+ for (const image of images) {
5319
+ const runtimeImage = image === CODE_PI_IMAGE ? await nameEmbedded() : image;
5320
+ const inspectArgs = ["image", "inspect", runtimeImage];
5321
+ try {
5322
+ await run(engine, inspectArgs, "ignore");
5323
+ prepared.push(runtimeImage);
5324
+ continue;
5325
+ } catch {
5326
+ }
5327
+ if (image === CODE_PI_IMAGE) {
5328
+ try {
5329
+ await buildEmbedded(engine, runtimeImage, run);
5330
+ } catch (error) {
5331
+ const detail = error instanceof Error && error.message ? `: ${error.message}` : "";
5332
+ throw new Error(`could not prepare CLI-embedded Code image${detail}`);
5333
+ }
5334
+ prepared.push(runtimeImage);
5335
+ continue;
5336
+ }
5337
+ const args = engine === "container" ? ["image", "pull", image] : ["pull", image];
5338
+ try {
5339
+ await run(engine, args, "inherit");
5340
+ } catch (error) {
5341
+ const detail = error instanceof Error && error.message ? `: ${error.message}` : "";
5342
+ throw new Error(`could not prepare pinned Code image ${image}${detail}`);
5343
+ }
5344
+ prepared.push(image);
5345
+ }
5346
+ return prepared;
5347
+ }
5348
+ function embeddedPiAssetPath() {
5349
+ return (0, import_node_url2.fileURLToPath)(new URL("./runtime/pi-agent.js", importMetaUrl));
5350
+ }
5351
+ async function embeddedPiImageName() {
5352
+ const bundle = await (0, import_promises10.readFile)(embeddedPiAssetPath()).catch(() => {
5353
+ throw new Error("CLI-embedded Pi runtime is missing; reinstall this exact @odla-ai/cli version");
5354
+ });
5355
+ return `odla-ai/pi-agent:embedded-sha256-${(0, import_node_crypto2.createHash)("sha256").update(bundle).digest("hex")}`;
5356
+ }
5357
+ async function buildEmbeddedPiImage(engine, image, run) {
5358
+ const context = await (0, import_promises10.mkdtemp)((0, import_node_path4.join)((0, import_node_os.tmpdir)(), "odla-code-pi-"));
5359
+ try {
5360
+ await (0, import_promises10.copyFile)(embeddedPiAssetPath(), (0, import_node_path4.join)(context, "pi-agent.js"));
5361
+ await (0, import_promises10.writeFile)((0, import_node_path4.join)(context, "Dockerfile"), [
5362
+ `FROM ${CODE_NODE_IMAGE}`,
5363
+ "COPY pi-agent.js /opt/odla/pi-agent.js",
5364
+ "WORKDIR /workspace",
5365
+ 'ENTRYPOINT ["node", "/opt/odla/pi-agent.js"]',
5366
+ ""
5367
+ ].join("\n"), { mode: 384 });
5368
+ await run(engine, ["build", "--tag", image, context], "inherit");
5369
+ } finally {
5370
+ await (0, import_promises10.rm)(context, { recursive: true, force: true });
5371
+ }
5372
+ }
5373
+
5302
5374
  // src/code-connect.ts
5303
5375
  async function codeConnect(options) {
5304
5376
  const cwd = options.cwd ?? process.cwd();
5305
- const configPath = (0, import_node_path4.resolve)(cwd, options.configPath);
5377
+ const configPath = (0, import_node_path5.resolve)(cwd, options.configPath);
5306
5378
  const cfg = (0, import_node_fs7.existsSync)(configPath) ? await loadProjectConfig(configPath) : null;
5307
5379
  const requestedAppId = options.appId?.trim();
5308
5380
  if (requestedAppId && !/^[a-z0-9][a-z0-9-]{1,62}$/.test(requestedAppId)) {
@@ -5331,12 +5403,13 @@ async function codeConnect(options) {
5331
5403
  const out = options.stdout ?? console;
5332
5404
  const doFetch = options.fetch ?? fetch;
5333
5405
  const engine = await (options.selectEngine ?? selectContainerEngine)(options.engine ?? "auto");
5334
- await (options.prepareImages ?? prepareCodeImages)(engine, [
5335
- CODE_PI_IMAGE,
5336
- ...new Set(CODE_BUILD_RECIPES.map((recipe2) => recipe2.image))
5337
- ]);
5406
+ const [piImage] = await (options.prepareImages ?? prepareCodeImages)(
5407
+ engine,
5408
+ [CODE_PI_IMAGE, ...new Set(CODE_BUILD_RECIPES.map((recipe2) => recipe2.image))]
5409
+ );
5410
+ if (!piImage || !/^odla-ai\/pi-agent:embedded-sha256-[0-9a-f]{64}$/.test(piImage)) throw new Error("Code image preflight did not produce the content-addressed embedded Pi runtime");
5338
5411
  const hostPlatform = process.platform === "darwin" ? "macos" : "linux";
5339
- const hostName = (options.name ?? (0, import_node_os.hostname)()).trim();
5412
+ const hostName = (options.name ?? (0, import_node_os2.hostname)()).trim();
5340
5413
  if (!hostName || hostName.length > 120) throw new Error("--name must contain 1 to 120 characters");
5341
5414
  const repository = await inferGitHubRepository(cwd, options.readGitOrigin);
5342
5415
  const localSource = await (options.prepareLocalSource ?? prepareCodeLocalSource)(
@@ -5373,12 +5446,13 @@ async function codeConnect(options) {
5373
5446
  platform: hostPlatform,
5374
5447
  arch: process.arch,
5375
5448
  engines: [engine],
5376
- cpuCount: (0, import_node_os.cpus)().length,
5377
- memoryBytes: (0, import_node_os.totalmem)(),
5449
+ cpuCount: (0, import_node_os2.cpus)().length,
5450
+ memoryBytes: (0, import_node_os2.totalmem)(),
5378
5451
  source: descriptor2,
5379
5452
  images: {
5380
5453
  ready: true,
5381
- pi: CODE_PI_IMAGE,
5454
+ pi: piImage,
5455
+ piSource: "cli_embedded",
5382
5456
  recipes: CODE_BUILD_RECIPES.map((recipe2) => ({ id: recipe2.id, image: recipe2.image }))
5383
5457
  }
5384
5458
  };
@@ -5393,6 +5467,7 @@ async function codeConnect(options) {
5393
5467
  engine,
5394
5468
  capabilities,
5395
5469
  localSource,
5470
+ piImage,
5396
5471
  heartbeatMs,
5397
5472
  once: options.once === true,
5398
5473
  signal: options.signal,
@@ -5422,7 +5497,8 @@ async function runCodeRuntime(input) {
5422
5497
  const commandEngine = new CodePiRuntimeEngine({
5423
5498
  control,
5424
5499
  engine: input.engine,
5425
- image: CODE_PI_IMAGE,
5500
+ image: input.piImage ?? input.capabilities.images.pi,
5501
+ imageAuthorization: "cli_embedded",
5426
5502
  recipes: CODE_BUILD_RECIPES,
5427
5503
  recipeAuthorization: "registered_recipe",
5428
5504
  localSource: input.localSource,
@@ -5519,12 +5595,12 @@ async function codeCommand(parsed, dependencies) {
5519
5595
  // src/doctor-checks.ts
5520
5596
  var import_node_child_process6 = require("child_process");
5521
5597
  var import_node_fs9 = require("fs");
5522
- var import_node_path6 = require("path");
5598
+ var import_node_path7 = require("path");
5523
5599
 
5524
5600
  // src/wrangler.ts
5525
5601
  var import_node_child_process5 = require("child_process");
5526
5602
  var import_node_fs8 = require("fs");
5527
- var import_node_path5 = require("path");
5603
+ var import_node_path6 = require("path");
5528
5604
  var defaultRunner = (cmd, args, opts) => new Promise((resolvePromise, reject) => {
5529
5605
  const child = (0, import_node_child_process5.spawn)(cmd, args, { cwd: opts?.cwd, stdio: ["pipe", "pipe", "pipe"] });
5530
5606
  let stdout = "";
@@ -5538,7 +5614,7 @@ var defaultRunner = (cmd, args, opts) => new Promise((resolvePromise, reject) =>
5538
5614
  var WRANGLER_CONFIG_FILES = ["wrangler.jsonc", "wrangler.json", "wrangler.toml"];
5539
5615
  function findWranglerConfig(rootDir) {
5540
5616
  for (const name of WRANGLER_CONFIG_FILES) {
5541
- const path = (0, import_node_path5.join)(rootDir, name);
5617
+ const path = (0, import_node_path6.join)(rootDir, name);
5542
5618
  if ((0, import_node_fs8.existsSync)(path)) return path;
5543
5619
  }
5544
5620
  return null;
@@ -5644,10 +5720,10 @@ function wranglerWarnings(rootDir) {
5644
5720
  for (const { label, block } of blocks) {
5645
5721
  const assets = block.assets;
5646
5722
  if (assets?.directory) {
5647
- const dir = (0, import_node_path6.resolve)(rootDir, assets.directory);
5648
- if (dir === (0, import_node_path6.resolve)(rootDir)) {
5723
+ const dir = (0, import_node_path7.resolve)(rootDir, assets.directory);
5724
+ if (dir === (0, import_node_path7.resolve)(rootDir)) {
5649
5725
  warnings.push(`${label}assets.directory is the project root \u2014 point it at a dedicated build dir (wrangler dev fails with "spawn EBADF")`);
5650
- } else if ((0, import_node_fs9.existsSync)((0, import_node_path6.join)(dir, "node_modules"))) {
5726
+ } else if ((0, import_node_fs9.existsSync)((0, import_node_path7.join)(dir, "node_modules"))) {
5651
5727
  warnings.push(`${label}assets.directory contains node_modules \u2014 wrangler dev's watcher will exhaust file descriptors`);
5652
5728
  }
5653
5729
  }
@@ -5682,7 +5758,7 @@ function o11yProjectWarnings(rootDir) {
5682
5758
  warnings.push("cannot verify o11y Worker instrumentation \u2014 add a parseable wrangler.jsonc/json config");
5683
5759
  return warnings;
5684
5760
  }
5685
- const main = typeof config.main === "string" ? (0, import_node_path6.resolve)(rootDir, config.main) : null;
5761
+ const main = typeof config.main === "string" ? (0, import_node_path7.resolve)(rootDir, config.main) : null;
5686
5762
  if (!main || !(0, import_node_fs9.existsSync)(main)) {
5687
5763
  warnings.push("cannot verify o11y Worker instrumentation \u2014 wrangler main is missing or unreadable");
5688
5764
  } else {
@@ -5712,7 +5788,7 @@ function calendarProjectWarnings(rootDir) {
5712
5788
  }
5713
5789
  function readPackageJson(rootDir) {
5714
5790
  try {
5715
- return JSON.parse((0, import_node_fs9.readFileSync)((0, import_node_path6.join)(rootDir, "package.json"), "utf8"));
5791
+ return JSON.parse((0, import_node_fs9.readFileSync)((0, import_node_path7.join)(rootDir, "package.json"), "utf8"));
5716
5792
  } catch {
5717
5793
  return null;
5718
5794
  }
@@ -5914,11 +5990,11 @@ function harnessOption(value, flag) {
5914
5990
 
5915
5991
  // src/init.ts
5916
5992
  var import_node_fs10 = require("fs");
5917
- var import_node_path7 = require("path");
5993
+ var import_node_path8 = require("path");
5918
5994
  function initProject(options) {
5919
5995
  const out = options.stdout ?? console;
5920
- const rootDir = (0, import_node_path7.resolve)(options.rootDir ?? process.cwd());
5921
- const configPath = (0, import_node_path7.resolve)(rootDir, options.configPath ?? "odla.config.mjs");
5996
+ const rootDir = (0, import_node_path8.resolve)(options.rootDir ?? process.cwd());
5997
+ const configPath = (0, import_node_path8.resolve)(rootDir, options.configPath ?? "odla.config.mjs");
5922
5998
  if ((0, import_node_fs10.existsSync)(configPath) && !options.force) {
5923
5999
  throw new Error(`${configPath} already exists. Pass --force to overwrite.`);
5924
6000
  }
@@ -5929,12 +6005,12 @@ function initProject(options) {
5929
6005
  const services = options.services?.length ? options.services : ["db", "ai"];
5930
6006
  if (services.includes("calendar") && !services.includes("db")) throw new Error("--services calendar requires db");
5931
6007
  const aiProvider = options.aiProvider ?? "anthropic";
5932
- (0, import_node_fs10.mkdirSync)((0, import_node_path7.dirname)(configPath), { recursive: true });
5933
- (0, import_node_fs10.mkdirSync)((0, import_node_path7.resolve)(rootDir, "src/odla"), { recursive: true });
5934
- (0, import_node_fs10.mkdirSync)((0, import_node_path7.resolve)(rootDir, ".odla"), { recursive: true });
6008
+ (0, import_node_fs10.mkdirSync)((0, import_node_path8.dirname)(configPath), { recursive: true });
6009
+ (0, import_node_fs10.mkdirSync)((0, import_node_path8.resolve)(rootDir, "src/odla"), { recursive: true });
6010
+ (0, import_node_fs10.mkdirSync)((0, import_node_path8.resolve)(rootDir, ".odla"), { recursive: true });
5935
6011
  (0, import_node_fs10.writeFileSync)(configPath, configTemplate({ appId: options.appId, name: options.name, envs, services, aiProvider }));
5936
- writeIfMissing((0, import_node_path7.resolve)(rootDir, "src/odla/schema.mjs"), schemaTemplate());
5937
- writeIfMissing((0, import_node_path7.resolve)(rootDir, "src/odla/rules.mjs"), rulesTemplate());
6012
+ writeIfMissing((0, import_node_path8.resolve)(rootDir, "src/odla/schema.mjs"), schemaTemplate());
6013
+ writeIfMissing((0, import_node_path8.resolve)(rootDir, "src/odla/rules.mjs"), rulesTemplate());
5938
6014
  ensureGitignore(rootDir);
5939
6015
  out.log(`created ${relativeDisplay(configPath, rootDir)}`);
5940
6016
  out.log("created src/odla/schema.mjs and src/odla/rules.mjs");
@@ -6584,7 +6660,7 @@ async function resolveVaultWrite(options) {
6584
6660
  }
6585
6661
 
6586
6662
  // src/security-command-context.ts
6587
- var import_promises10 = require("readline/promises");
6663
+ var import_promises11 = require("readline/promises");
6588
6664
  async function hostedSecurityContext(parsed, dependencies) {
6589
6665
  const configPath = stringOpt(parsed.options.config) ?? "odla.config.mjs";
6590
6666
  const cfg = await loadProjectConfig(configPath);
@@ -6610,7 +6686,7 @@ async function hostedSecurityContext(parsed, dependencies) {
6610
6686
  async function interactiveConfirmation(message2, dependencies) {
6611
6687
  if (dependencies.confirm) return dependencies.confirm(message2);
6612
6688
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
6613
- const prompt = (0, import_promises10.createInterface)({ input: process.stdin, output: process.stdout });
6689
+ const prompt = (0, import_promises11.createInterface)({ input: process.stdin, output: process.stdout });
6614
6690
  try {
6615
6691
  const answer = await prompt.question(`${message2} [y/N] `);
6616
6692
  return /^y(?:es)?$/i.test(answer.trim());
@@ -6737,7 +6813,7 @@ function hostedSeverity(value, flag) {
6737
6813
  var import_security2 = require("@odla-ai/security");
6738
6814
 
6739
6815
  // src/security.ts
6740
- var import_node_path8 = require("path");
6816
+ var import_node_path9 = require("path");
6741
6817
  var import_security = require("@odla-ai/security");
6742
6818
  var import_node3 = require("@odla-ai/security/node");
6743
6819
  async function runHostedSecurity(options) {
@@ -6749,9 +6825,9 @@ async function runHostedSecurity(options) {
6749
6825
  const appId = selfAudit ? "odla-ai" : cfg.app.id;
6750
6826
  const env = selfAudit ? "prod" : selectEnv(options.env, cfg.envs, cfg.configPath, cfg.rootDir);
6751
6827
  const platform = options.platform ?? cfg?.platformUrl ?? "https://odla.ai";
6752
- const target = (0, import_node_path8.resolve)(options.target ?? cfg?.rootDir ?? ".");
6753
- const output = (0, import_node_path8.resolve)(options.out ?? (0, import_node_path8.resolve)(target, ".odla/security/hosted"));
6754
- const outputRelative = (0, import_node_path8.relative)(target, output).split(import_node_path8.sep).join("/");
6828
+ const target = (0, import_node_path9.resolve)(options.target ?? cfg?.rootDir ?? ".");
6829
+ const output = (0, import_node_path9.resolve)(options.out ?? (0, import_node_path9.resolve)(target, ".odla/security/hosted"));
6830
+ const outputRelative = (0, import_node_path9.relative)(target, output).split(import_node_path9.sep).join("/");
6755
6831
  if (!outputRelative) throw new Error("Hosted security output cannot be the repository root");
6756
6832
  const profile = profileFor(options.profile ?? "odla", options.maxHuntTasks ?? 12);
6757
6833
  const tokenRequest = {
@@ -6763,7 +6839,7 @@ async function runHostedSecurity(options) {
6763
6839
  };
6764
6840
  const token = await injectedToken(options, tokenRequest);
6765
6841
  const snapshot = await (0, import_node3.snapshotDirectory)(target, {
6766
- exclude: !outputRelative.startsWith("../") && !(0, import_node_path8.isAbsolute)(outputRelative) ? [outputRelative] : []
6842
+ exclude: !outputRelative.startsWith("../") && !(0, import_node_path9.isAbsolute)(outputRelative) ? [outputRelative] : []
6767
6843
  });
6768
6844
  const hosted = await (0, import_security.createPlatformSecurityReasoners)({
6769
6845
  platform,
@@ -6781,7 +6857,7 @@ async function runHostedSecurity(options) {
6781
6857
  });
6782
6858
  const harness = (0, import_security.createSecurityHarness)({
6783
6859
  profile,
6784
- store: new import_node3.FileRunStore((0, import_node_path8.resolve)(output, "state")),
6860
+ store: new import_node3.FileRunStore((0, import_node_path9.resolve)(output, "state")),
6785
6861
  discoveryReasoner: hosted.discoveryReasoner,
6786
6862
  validationReasoner: hosted.validationReasoner,
6787
6863
  policy: {
@@ -6805,7 +6881,7 @@ async function runHostedSecurity(options) {
6805
6881
  function selectEnv(requested, declared, configPath, rootDir) {
6806
6882
  const env = requested ?? (declared.includes("dev") ? "dev" : declared[0]);
6807
6883
  if (!env || !declared.includes(env)) {
6808
- const shown = (0, import_node_path8.relative)(rootDir, configPath) || configPath;
6884
+ const shown = (0, import_node_path9.relative)(rootDir, configPath) || configPath;
6809
6885
  throw new Error(`env "${env ?? ""}" is not declared in ${shown}`);
6810
6886
  }
6811
6887
  return env;
@@ -6834,7 +6910,7 @@ function printSummary(out, appId, env, run, report2, output) {
6834
6910
  out.log(` coverage: ${report2.coverageStatus} ${complete}/${report2.coverage.length} blocked=${report2.metrics.blockedCells} shallow=${report2.metrics.shallowCells} unscheduled=${report2.metrics.unscheduledCells} budget_exhausted=${report2.metrics.budgetExhaustedCells}`);
6835
6911
  if (report2.callBudget) out.log(` calls: discovery=${formatBudget(report2.callBudget.discovery)} validation=${formatBudget(report2.callBudget.validation)}`);
6836
6912
  out.log(` findings: confirmed=${report2.metrics.confirmed} needs_reproduction=${report2.metrics.needsReproduction} candidates=${report2.metrics.candidates}`);
6837
- out.log(` report: ${(0, import_node_path8.resolve)(output, "REPORT.md")}`);
6913
+ out.log(` report: ${(0, import_node_path9.resolve)(output, "REPORT.md")}`);
6838
6914
  }
6839
6915
  function formatBudget(usage) {
6840
6916
  return usage ? `${usage.usedCalls}/${usage.maxCalls} skipped=${usage.skippedCalls}` : "caller-managed";
@@ -7284,9 +7360,9 @@ async function securityStatus(parsed, dependencies) {
7284
7360
 
7285
7361
  // src/skill.ts
7286
7362
  var import_node_fs11 = require("fs");
7287
- var import_node_os2 = require("os");
7288
- var import_node_path9 = require("path");
7289
- var import_node_url2 = require("url");
7363
+ var import_node_os3 = require("os");
7364
+ var import_node_path10 = require("path");
7365
+ var import_node_url3 = require("url");
7290
7366
 
7291
7367
  // src/skill-adapters.ts
7292
7368
  var PROJECT_INSTRUCTIONS = `<!-- odla-ai agent setup:start -->
@@ -7342,12 +7418,12 @@ runbook. Do not substitute a remote documentation page for the installed copy.
7342
7418
  var AGENT_HARNESSES = ["claude", "codex", "cursor", "copilot", "gemini", "agents"];
7343
7419
  function installSkill(options = {}) {
7344
7420
  const out = options.stdout ?? console;
7345
- const sourceDir = options.sourceDir ?? (0, import_node_url2.fileURLToPath)(new URL("../skills", importMetaUrl));
7421
+ const sourceDir = options.sourceDir ?? (0, import_node_url3.fileURLToPath)(new URL("../skills", importMetaUrl));
7346
7422
  const files = listFiles(sourceDir);
7347
7423
  if (files.length === 0) throw new Error(`no bundled skills found at ${sourceDir}`);
7348
7424
  const harnesses = normalizeHarnesses(options.harnesses, options.global === true);
7349
- const root = (0, import_node_path9.resolve)(options.dir ?? process.cwd());
7350
- const home = (0, import_node_path9.resolve)(options.homeDir ?? (0, import_node_os2.homedir)());
7425
+ const root = (0, import_node_path10.resolve)(options.dir ?? process.cwd());
7426
+ const home = (0, import_node_path10.resolve)(options.homeDir ?? (0, import_node_os3.homedir)());
7351
7427
  const plans = /* @__PURE__ */ new Map();
7352
7428
  const targets = /* @__PURE__ */ new Map();
7353
7429
  const rememberTarget = (harness, target) => {
@@ -7361,48 +7437,48 @@ function installSkill(options = {}) {
7361
7437
  plans.set(target, { target, content, boundary, managedMerge });
7362
7438
  };
7363
7439
  const planSkillTree = (targetDir2, boundary = root) => {
7364
- for (const rel of files) plan((0, import_node_path9.join)(targetDir2, rel), (0, import_node_fs11.readFileSync)((0, import_node_path9.join)(sourceDir, rel), "utf8"), false, boundary);
7440
+ for (const rel of files) plan((0, import_node_path10.join)(targetDir2, rel), (0, import_node_fs11.readFileSync)((0, import_node_path10.join)(sourceDir, rel), "utf8"), false, boundary);
7365
7441
  };
7366
7442
  let targetDir;
7367
7443
  if (options.global) {
7368
- const claudeRoot = (0, import_node_path9.join)(home, ".claude", "skills");
7369
- const codexRoot = (0, import_node_path9.resolve)(options.codexHomeDir ?? process.env.CODEX_HOME ?? (0, import_node_path9.join)(home, ".codex"), "skills");
7444
+ const claudeRoot = (0, import_node_path10.join)(home, ".claude", "skills");
7445
+ const codexRoot = (0, import_node_path10.resolve)(options.codexHomeDir ?? process.env.CODEX_HOME ?? (0, import_node_path10.join)(home, ".codex"), "skills");
7370
7446
  targetDir = harnesses[0] === "codex" ? codexRoot : claudeRoot;
7371
7447
  for (const harness of harnesses) {
7372
7448
  const skillRoot = harness === "claude" ? claudeRoot : codexRoot;
7373
- planSkillTree(skillRoot, harness === "claude" ? home : (0, import_node_path9.dirname)((0, import_node_path9.dirname)(codexRoot)));
7449
+ planSkillTree(skillRoot, harness === "claude" ? home : (0, import_node_path10.dirname)((0, import_node_path10.dirname)(codexRoot)));
7374
7450
  rememberTarget(harness, skillRoot);
7375
7451
  }
7376
7452
  } else {
7377
- const sharedRoot = (0, import_node_path9.join)(root, ".agents", "skills");
7453
+ const sharedRoot = (0, import_node_path10.join)(root, ".agents", "skills");
7378
7454
  planSkillTree(sharedRoot);
7379
- const claudeRoot = (0, import_node_path9.join)(root, ".claude", "skills");
7455
+ const claudeRoot = (0, import_node_path10.join)(root, ".claude", "skills");
7380
7456
  targetDir = harnesses.includes("claude") ? claudeRoot : sharedRoot;
7381
7457
  for (const harness of harnesses) rememberTarget(harness, sharedRoot);
7382
7458
  if (harnesses.includes("claude")) {
7383
7459
  for (const skill of skillNames(files)) {
7384
- const canonical = (0, import_node_fs11.readFileSync)((0, import_node_path9.join)(sourceDir, skill, "SKILL.md"), "utf8");
7385
- plan((0, import_node_path9.join)(claudeRoot, skill, "SKILL.md"), claudeAdapter(skill, canonical));
7460
+ const canonical = (0, import_node_fs11.readFileSync)((0, import_node_path10.join)(sourceDir, skill, "SKILL.md"), "utf8");
7461
+ plan((0, import_node_path10.join)(claudeRoot, skill, "SKILL.md"), claudeAdapter(skill, canonical));
7386
7462
  }
7387
7463
  rememberTarget("claude", claudeRoot);
7388
7464
  }
7389
7465
  if (harnesses.includes("cursor")) {
7390
- const cursorRule = (0, import_node_path9.join)(root, ".cursor", "rules", "odla.mdc");
7466
+ const cursorRule = (0, import_node_path10.join)(root, ".cursor", "rules", "odla.mdc");
7391
7467
  plan(cursorRule, CURSOR_RULE);
7392
7468
  rememberTarget("cursor", cursorRule);
7393
7469
  }
7394
7470
  if (harnesses.includes("agents")) {
7395
- const agentsFile = (0, import_node_path9.join)(root, "AGENTS.md");
7471
+ const agentsFile = (0, import_node_path10.join)(root, "AGENTS.md");
7396
7472
  plan(agentsFile, managedFileContent(agentsFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
7397
7473
  rememberTarget("agents", agentsFile);
7398
7474
  }
7399
7475
  if (harnesses.includes("copilot")) {
7400
- const copilotFile = (0, import_node_path9.join)(root, ".github", "copilot-instructions.md");
7476
+ const copilotFile = (0, import_node_path10.join)(root, ".github", "copilot-instructions.md");
7401
7477
  plan(copilotFile, managedFileContent(copilotFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
7402
7478
  rememberTarget("copilot", copilotFile);
7403
7479
  }
7404
7480
  if (harnesses.includes("gemini")) {
7405
- const geminiFile = (0, import_node_path9.join)(root, "GEMINI.md");
7481
+ const geminiFile = (0, import_node_path10.join)(root, "GEMINI.md");
7406
7482
  plan(geminiFile, managedFileContent(geminiFile, PROJECT_INSTRUCTIONS, options.force === true, root), true);
7407
7483
  rememberTarget("gemini", geminiFile);
7408
7484
  }
@@ -7438,7 +7514,7 @@ ${conflicts.map((f) => ` - ${f}`).join("\n")}`
7438
7514
  }
7439
7515
  for (const file of plans.values()) {
7440
7516
  if (!(0, import_node_fs11.existsSync)(file.target) || (0, import_node_fs11.readFileSync)(file.target, "utf8") !== file.content) {
7441
- (0, import_node_fs11.mkdirSync)((0, import_node_path9.dirname)(file.target), { recursive: true });
7517
+ (0, import_node_fs11.mkdirSync)((0, import_node_path10.dirname)(file.target), { recursive: true });
7442
7518
  (0, import_node_fs11.writeFileSync)(file.target, file.content);
7443
7519
  }
7444
7520
  }
@@ -7458,7 +7534,7 @@ ${conflicts.map((f) => ` - ${f}`).join("\n")}`
7458
7534
  };
7459
7535
  }
7460
7536
  function pathsUnder(root, paths) {
7461
- return [...paths].map((path) => (0, import_node_path9.relative)(root, path)).filter((path) => path !== ".." && !path.startsWith(`..${import_node_path9.sep}`) && !(0, import_node_path9.isAbsolute)(path)).sort();
7537
+ return [...paths].map((path) => (0, import_node_path10.relative)(root, path)).filter((path) => path !== ".." && !path.startsWith(`..${import_node_path10.sep}`) && !(0, import_node_path10.isAbsolute)(path)).sort();
7462
7538
  }
7463
7539
  function normalizeHarnesses(values, global) {
7464
7540
  const requested = values?.length ? values : ["claude"];
@@ -7503,13 +7579,13 @@ function managedFileContent(path, block, force, boundary) {
7503
7579
  return `${current.slice(0, startAt)}${block}${current.slice(afterEnd)}`;
7504
7580
  }
7505
7581
  function symlinkedComponent(boundary, target) {
7506
- const rel = (0, import_node_path9.relative)(boundary, target);
7507
- if (rel === ".." || rel.startsWith(`..${import_node_path9.sep}`) || (0, import_node_path9.isAbsolute)(rel)) {
7582
+ const rel = (0, import_node_path10.relative)(boundary, target);
7583
+ if (rel === ".." || rel.startsWith(`..${import_node_path10.sep}`) || (0, import_node_path10.isAbsolute)(rel)) {
7508
7584
  throw new Error(`agent setup target escapes its install root: ${target}`);
7509
7585
  }
7510
7586
  let current = boundary;
7511
- for (const part of rel.split(import_node_path9.sep).filter(Boolean)) {
7512
- current = (0, import_node_path9.join)(current, part);
7587
+ for (const part of rel.split(import_node_path10.sep).filter(Boolean)) {
7588
+ current = (0, import_node_path10.join)(current, part);
7513
7589
  try {
7514
7590
  if ((0, import_node_fs11.lstatSync)(current).isSymbolicLink()) return current;
7515
7591
  } catch (error) {
@@ -7526,9 +7602,9 @@ function listFiles(dir) {
7526
7602
  const results = [];
7527
7603
  const walk = (current) => {
7528
7604
  for (const entry of (0, import_node_fs11.readdirSync)(current, { withFileTypes: true })) {
7529
- const path = (0, import_node_path9.join)(current, entry.name);
7605
+ const path = (0, import_node_path10.join)(current, entry.name);
7530
7606
  if (entry.isDirectory()) walk(path);
7531
- else results.push((0, import_node_path9.relative)(dir, path));
7607
+ else results.push((0, import_node_path10.relative)(dir, path));
7532
7608
  }
7533
7609
  };
7534
7610
  walk(dir);
@@ -7900,6 +7976,7 @@ async function calendarCommand(parsed, dependencies) {
7900
7976
  isTerminalHostedSecurityStatus,
7901
7977
  listGitHubSecuritySources,
7902
7978
  listHostedSecurityJobs,
7979
+ prepareCodeImages,
7903
7980
  printCapabilities,
7904
7981
  provision,
7905
7982
  redactSecrets,