@odla-ai/cli 0.46.6 → 0.46.8

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-AVUBGTWE.js";
4
+ } from "./chunk-OW5WW5ET.js";
5
5
  import {
6
6
  exitCodeFor
7
7
  } from "./chunk-5MEO3BVF.js";
@@ -9,4 +9,4 @@ export {
9
9
  exitCodeFor,
10
10
  runCli
11
11
  };
12
- //# sourceMappingURL=cli-IAA6SOCV.js.map
12
+ //# sourceMappingURL=cli-CDIXAFN4.js.map
package/dist/index.cjs CHANGED
@@ -786,6 +786,7 @@ function audienceBoundEnvToken(token, platform) {
786
786
  }
787
787
  var SCOPE_PURPOSE = {
788
788
  "platform:status:read": "read the platform fleet health and deployment snapshot",
789
+ "platform:pm:read": "read the core PM inventory across all current odla projects",
789
790
  "app:config:read": "compare checked-in intent with an exact-id app Registry configuration",
790
791
  "app:config:write": "apply or inspect one revision-bound configuration operation for an app you own",
791
792
  "platform:runbook:write": "read and edit all of odla's operational runbooks, including admin-visible content",
@@ -6494,7 +6495,7 @@ async function stageWorkspacePair(baselineSource, workspaceSource, options = {})
6494
6495
  }
6495
6496
  }
6496
6497
 
6497
- // ../harness/dist/chunk-ISR434K7.js
6498
+ // ../harness/dist/chunk-IWVGSWY6.js
6498
6499
  var import_crypto = require("crypto");
6499
6500
  var import_promises5 = require("fs/promises");
6500
6501
  var import_path5 = require("path");
@@ -6831,7 +6832,7 @@ function validateSnapshot(snapshot, limits) {
6831
6832
  }
6832
6833
  }
6833
6834
 
6834
- // ../harness/dist/chunk-ISR434K7.js
6835
+ // ../harness/dist/chunk-IWVGSWY6.js
6835
6836
  var import_child_process4 = require("child_process");
6836
6837
  var import_promises6 = require("fs/promises");
6837
6838
  var import_path6 = require("path");
@@ -7135,7 +7136,7 @@ function looksLikeDestination(value2) {
7135
7136
  return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text4) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text4);
7136
7137
  }
7137
7138
 
7138
- // ../harness/dist/chunk-ISR434K7.js
7139
+ // ../harness/dist/chunk-IWVGSWY6.js
7139
7140
  var import_promises10 = require("fs/promises");
7140
7141
  var import_promises11 = require("fs/promises");
7141
7142
  var import_path10 = require("path");
@@ -7403,7 +7404,7 @@ async function buildCodeGraph(input) {
7403
7404
  return builder.build();
7404
7405
  }
7405
7406
 
7406
- // ../harness/dist/chunk-ISR434K7.js
7407
+ // ../harness/dist/chunk-IWVGSWY6.js
7407
7408
  var import_crypto4 = require("crypto");
7408
7409
  async function digestStagedWorkspace(root, limits) {
7409
7410
  const files = [];
@@ -8688,6 +8689,7 @@ async function runCodeAgentAttempt(options) {
8688
8689
  model: "brokered",
8689
8690
  surface,
8690
8691
  ...options.recipeIds ? { recipeIds: options.recipeIds } : {},
8692
+ ...options.extraSkills ? { extraSkills: options.extraSkills } : {},
8691
8693
  ...options.maxSteps === void 0 ? {} : { maxSteps: options.maxSteps },
8692
8694
  ...options.budget ? { budget: options.budget } : {},
8693
8695
  ...options.signal ? { signal: options.signal } : {},
@@ -9581,6 +9583,16 @@ function assertBudget(budget) {
9581
9583
  throw new TypeError("goal budget deadline must be epoch milliseconds");
9582
9584
  }
9583
9585
  }
9586
+ async function sessionSkillsFor(options, command) {
9587
+ try {
9588
+ return await options.sessionSkills?.(command) ?? [];
9589
+ } catch (cause) {
9590
+ options.onDiagnostic?.(
9591
+ `session skills unavailable, continuing with code tools only: ${cause instanceof Error ? cause.message : String(cause)}`
9592
+ );
9593
+ return [];
9594
+ }
9595
+ }
9584
9596
  function createCodeRuntimeToolBroker(input, lease, role) {
9585
9597
  const broker = createCodeToolBroker({
9586
9598
  recipes: input.recipes,
@@ -10064,6 +10076,7 @@ var TheseusRuntimeEngine = class {
10064
10076
  event: (event) => this.#event(command, event, active.conversationRefs)
10065
10077
  });
10066
10078
  await this.#event(command, { type: "status", status: "running" }, active.conversationRefs);
10079
+ const extraSkills = await sessionSkillsFor(this.options, command);
10067
10080
  const result = await this.#attempt({
10068
10081
  inference,
10069
10082
  broker,
@@ -10071,7 +10084,8 @@ var TheseusRuntimeEngine = class {
10071
10084
  workspaceDir: active.workspace.workspaceDir,
10072
10085
  prompt: metadata2.prompt,
10073
10086
  signal: active.abort.signal,
10074
- recipeIds: this.options.recipes.map((recipe2) => recipe2.id)
10087
+ recipeIds: this.options.recipes.map((recipe2) => recipe2.id),
10088
+ ...extraSkills.length ? { extraSkills } : {}
10075
10089
  });
10076
10090
  const closing = result.finalText.trim();
10077
10091
  const completed = result.status === "completed" && Boolean(closing);
@@ -11154,10 +11168,10 @@ Usage:
11154
11168
  odla-ai pm project add --app <product-id> --name <name> [--description <text>] [--json]
11155
11169
  odla-ai pm project use <project-id> [--json] [saved for this app, on this machine]
11156
11170
  odla-ai pm project set <project-id> [--name <n>|--description <text>|--status <active|completed|archived>] [--mutation-id <id>] [--json]
11157
- odla-ai pm goal list [--app <id>] [--project <id>] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11158
- odla-ai pm task list [--app <id>] [--column <backlog|ready|doing|review|done>] [--goal <id>] [--assignee <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11159
- odla-ai pm decision list [--app <id>] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11160
- odla-ai pm bug list [--app <id>] [--status <s>] [--severity <s>] [--goal <id>] [--assignee <id>] [--decision <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11171
+ odla-ai pm goal list [--app <id>] [--project <id>] [--platform-wide] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11172
+ odla-ai pm task list [--app <id>] [--platform-wide] [--column <backlog|ready|doing|review|done>] [--goal <id>] [--assignee <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11173
+ odla-ai pm decision list [--app <id>] [--platform-wide] [--status <s>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11174
+ odla-ai pm bug list [--app <id>|--platform-wide] [--status <s>] [--severity <s>] [--goal <id>] [--assignee <id>] [--decision <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
11161
11175
  odla-ai pm goal add --app <id> --title <t> [--status <s>] [--proof <text>] [--target <pct>] [--mutation-id <id>] [--json]
11162
11176
  odla-ai pm task add --app <id> --title <t> [--column <backlog|ready|doing|review|done>] [--goal <id>|--alignment-decision <id>] [--assignee <id>] [--description <text>|--body <text>] [--acceptance <text>] [--execution <human|agent|either>] [--due <epoch-ms>] [--mutation-id <id>] [--json]
11163
11177
  odla-ai pm next --app <id> [--project <id>] [--verbose] [--json]
@@ -11169,7 +11183,7 @@ Usage:
11169
11183
  odla-ai pm decision add --app <id> --title <t> --body <text> [--status <s>] [--mutation-id <id>] [--json]
11170
11184
  odla-ai pm bug add --app <id> --title <t> (--description <text>|--body <text>) [--status <s>] [--severity <s>] [--goal <id>] [--assignee <id>] [--decision <id>] [--mutation-id <id>] [--json]
11171
11185
  odla-ai bug report --app <id> --title <t> (--description <text>|--body <text>) [--severity <s>] [--json]
11172
- odla-ai pm <goal|task|decision|bug> get <id> [--json]
11186
+ odla-ai pm <goal|task|decision|bug> get <id-or-uuid-prefix> [--platform-wide] [--json]
11173
11187
  odla-ai pm <goal|task|decision|bug> link <id> [--json]
11174
11188
  odla-ai pm <goal|task|decision|bug> ref <id> [--json]
11175
11189
  odla-ai pm goal set <id> [--title <t>|--status <s>|--proof <text>|--no-proof|--target <pct>|--no-target] [--mutation-id <id>] [--json]
@@ -12261,8 +12275,39 @@ async function pmAdd(ctx, entity, parsed) {
12261
12275
  const record11 = { id: res.id, appId, title: String(input.title) };
12262
12276
  emit2(ctx, res, () => ctx.out.log(`created ${entity}: ${studioRecordLink(ctx, entity, record11)}`));
12263
12277
  }
12278
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
12279
+ var UUID_PREFIX = /^[0-9a-f-]{8,35}$/i;
12280
+ function looksLikeUuidPrefix(value2) {
12281
+ if (!UUID_PREFIX.test(value2) || !/[0-9a-f]/i.test(value2)) return false;
12282
+ return "00000000-0000-0000-0000-000000000000".slice(0, value2.length).split("").every((expected, index) => expected === "-" ? value2[index] === "-" : value2[index] !== "-");
12283
+ }
12284
+ async function resolvePmId(ctx, entity, supplied) {
12285
+ if (UUID.test(supplied) || !looksLikeUuidPrefix(supplied)) return supplied;
12286
+ const prefix = supplied.toLowerCase();
12287
+ const matches = [];
12288
+ const limit = 200;
12289
+ let offset = 0;
12290
+ for (; ; ) {
12291
+ const page2 = await pmRequest(
12292
+ ctx,
12293
+ "GET",
12294
+ `/${entity}?limit=${limit}&offset=${offset}`
12295
+ );
12296
+ matches.push(...page2.records.map((record11) => record11.id).filter((id2) => id2.toLowerCase().startsWith(prefix)));
12297
+ offset += page2.records.length;
12298
+ if (matches.length > 1 || page2.records.length === 0 || offset >= page2.total) break;
12299
+ }
12300
+ if (matches.length === 0) {
12301
+ throw new Error(`no ${entity} id matches prefix "${supplied}"`);
12302
+ }
12303
+ if (matches.length > 1) {
12304
+ throw new Error(`ambiguous ${entity} id prefix "${supplied}"`);
12305
+ }
12306
+ return matches[0];
12307
+ }
12264
12308
  async function pmGet(ctx, entity, id2) {
12265
- const { record: record11 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id2)}`);
12309
+ const resolved = await resolvePmId(ctx, entity, id2);
12310
+ const { record: record11 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(resolved)}`);
12266
12311
  emit2(ctx, record11, () => printRecord(ctx, entity, record11));
12267
12312
  }
12268
12313
  async function pmReference(ctx, entity, id2) {
@@ -12903,9 +12948,9 @@ var ALIASES = {
12903
12948
  };
12904
12949
  var COMMON_OPTIONS = ["config", "token", "email", "json", "platform", "context", "open"];
12905
12950
  var ACTION_OPTIONS = {
12906
- list: ["app", "project", "q", "limit", "offset"],
12951
+ list: ["app", "project", "q", "limit", "offset", "platform-wide"],
12907
12952
  add: ["app", "project", "title", "mutation-id"],
12908
- get: [],
12953
+ get: ["platform-wide"],
12909
12954
  set: ["mutation-id"],
12910
12955
  done: ["mutation-id"],
12911
12956
  comment: ["body", "mutation-id"],
@@ -12965,15 +13010,23 @@ async function buildContext2(parsed, deps) {
12965
13010
  const { cfg } = context;
12966
13011
  const doFetch = deps.fetch ?? fetch;
12967
13012
  const out = deps.stdout ?? console;
12968
- const token = await getDeveloperToken(
13013
+ const platformWide = parsed.options["platform-wide"] === true;
13014
+ const tokenOptions = {
13015
+ token: stringOpt(parsed.options.token),
13016
+ email: stringOpt(parsed.options.email),
13017
+ open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
13018
+ openApprovalUrl: deps.openUrl
13019
+ };
13020
+ const token = platformWide ? await resolveAdminPlatformToken({
13021
+ platform: cfg.platformUrl,
13022
+ scope: "platform:pm:read",
13023
+ rootDir: cfg.rootDir,
13024
+ fetch: doFetch,
13025
+ stdout: out,
13026
+ ...tokenOptions
13027
+ }) : await getDeveloperToken(
12969
13028
  cfg,
12970
- {
12971
- configPath: cfg.configPath,
12972
- token: stringOpt(parsed.options.token),
12973
- email: stringOpt(parsed.options.email),
12974
- open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
12975
- openApprovalUrl: deps.openUrl
12976
- },
13029
+ { configPath: cfg.configPath, ...tokenOptions },
12977
13030
  doFetch,
12978
13031
  out
12979
13032
  );
@@ -12988,8 +13041,8 @@ async function buildContext2(parsed, deps) {
12988
13041
  json: parsed.options.json === true,
12989
13042
  // Preserve PM's existing cross-project default when a config is present;
12990
13043
  // only an explicit remote-agent environment or profile selects an app.
12991
- appId: context.app.source === "environment" || context.app.source === "profile" ? context.app.value ?? void 0 : compatibleProject?.appId,
12992
- projectId: compatibleProject?.projectId,
13044
+ appId: platformWide ? void 0 : context.app.source === "environment" || context.app.source === "profile" ? context.app.value ?? void 0 : compatibleProject?.appId,
13045
+ projectId: platformWide ? void 0 : compatibleProject?.projectId,
12993
13046
  rootDir: cfg.rootDir,
12994
13047
  ...deps.sleep ? { sleep: deps.sleep } : {},
12995
13048
  ...deps.now ? { now: deps.now } : {}