@elevasis/sdk 1.31.0 → 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/cli.cjs +526 -225
  2. package/dist/index.d.ts +71 -5
  3. package/dist/node/index.d.ts +65 -2
  4. package/dist/test-utils/index.d.ts +71 -5
  5. package/package.json +3 -3
  6. package/reference/claude-config/Overview.md +123 -0
  7. package/reference/claude-config/registries/skill-coverage.json +19 -0
  8. package/reference/claude-config/skills/client/SKILL.md +201 -0
  9. package/reference/claude-config/skills/elevasis/SKILL.md +244 -235
  10. package/reference/claude-config/skills/om/SKILL.md +56 -5
  11. package/reference/claude-config/skills/om/operations/features.md +12 -5
  12. package/reference/claude-config/skills/om/operations/scaffold.md +10 -0
  13. package/reference/claude-config/skills/setup/SKILL.md +9 -0
  14. package/reference/claude-config/sync-notes/2026-05-30-client-source-and-om-profiles.md +39 -0
  15. package/reference/claude-config/sync-notes/2026-06-02-knowledge-nested-group-routing.md +27 -0
  16. package/reference/claude-config/sync-notes/2026-06-02-nest-projects-under-platform.md +45 -0
  17. package/reference/claude-config/sync-notes/2026-06-03-skill-autogen-and-client-skill.md +34 -0
  18. package/reference/rules/agent-start-here.md +8 -2
  19. package/reference/rules/organization-os.md +11 -7
  20. package/reference/rules/package-taxonomy.md +4 -0
  21. package/reference/scaffold/recipes/customize-knowledge-browser.md +23 -26
  22. package/reference/scaffold/reference/contracts.md +54 -0
  23. package/reference/scaffold/reference/feature-registry.md +1 -1
  24. package/reference/scaffold/ui/composition-extensibility.mdx +1 -1
  25. package/reference/sdk/cli-management.mdx +2 -2
  26. package/reference/sdk/framework/agent.mdx +1 -1
package/dist/cli.cjs CHANGED
@@ -5765,7 +5765,7 @@ var require_buffer_list = __commonJS({
5765
5765
  }
5766
5766
  }, {
5767
5767
  key: "join",
5768
- value: function join13(s) {
5768
+ value: function join15(s) {
5769
5769
  if (this.length === 0) return "";
5770
5770
  var p = this.head;
5771
5771
  var ret = "" + p.data;
@@ -23628,20 +23628,20 @@ var init_config = __esm({
23628
23628
 
23629
23629
  // src/cli/commands/om/project-layout.ts
23630
23630
  function assertSplitLayout(projectDir) {
23631
- const omDir = (0, import_node_path7.join)(projectDir, "core", "config", "organization-model");
23632
- const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs7.existsSync)((0, import_node_path7.join)(omDir, f)));
23631
+ const omDir = (0, import_node_path9.join)(projectDir, "core", "config", "organization-model");
23632
+ const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs8.existsSync)((0, import_node_path9.join)(omDir, f)));
23633
23633
  if (missing.length > 0) {
23634
23634
  throw new Error(
23635
23635
  "Legacy single-file OM layout detected. Split into `core/config/organization-model/{profile.ts, systems.ts, navigation.ts}` before scaffolding."
23636
23636
  );
23637
23637
  }
23638
23638
  }
23639
- var import_node_fs7, import_node_path7, REQUIRED_FILES;
23639
+ var import_node_fs8, import_node_path9, REQUIRED_FILES;
23640
23640
  var init_project_layout = __esm({
23641
23641
  "src/cli/commands/om/project-layout.ts"() {
23642
23642
  "use strict";
23643
- import_node_fs7 = require("node:fs");
23644
- import_node_path7 = require("node:path");
23643
+ import_node_fs8 = require("node:fs");
23644
+ import_node_path9 = require("node:path");
23645
23645
  REQUIRED_FILES = ["profile.ts", "systems.ts", "navigation.ts"];
23646
23646
  }
23647
23647
  });
@@ -23742,7 +23742,7 @@ async function withSnapshotRollback(filePaths, op) {
23742
23742
  const snapshots = /* @__PURE__ */ new Map();
23743
23743
  for (const filePath of filePaths) {
23744
23744
  try {
23745
- snapshots.set(filePath, (0, import_node_fs8.readFileSync)(filePath, "utf8"));
23745
+ snapshots.set(filePath, (0, import_node_fs9.readFileSync)(filePath, "utf8"));
23746
23746
  } catch {
23747
23747
  snapshots.set(filePath, null);
23748
23748
  }
@@ -23753,7 +23753,7 @@ async function withSnapshotRollback(filePaths, op) {
23753
23753
  for (const [filePath, snapshot] of snapshots) {
23754
23754
  if (snapshot !== null) {
23755
23755
  try {
23756
- (0, import_node_fs8.writeFileSync)(filePath, snapshot, "utf8");
23756
+ (0, import_node_fs9.writeFileSync)(filePath, snapshot, "utf8");
23757
23757
  } catch {
23758
23758
  }
23759
23759
  }
@@ -23774,14 +23774,14 @@ function insertBeforeAnchorInContent(content, code, anchor) {
23774
23774
  return lines.join("\n");
23775
23775
  }
23776
23776
  async function appendBeforeAnchor(filePath, code, anchor) {
23777
- const content = (0, import_node_fs8.readFileSync)(filePath, "utf8");
23777
+ const content = (0, import_node_fs9.readFileSync)(filePath, "utf8");
23778
23778
  const updated = insertBeforeAnchorInContent(content, code, anchor);
23779
- (0, import_node_fs8.writeFileSync)(filePath, updated, "utf8");
23779
+ (0, import_node_fs9.writeFileSync)(filePath, updated, "utf8");
23780
23780
  }
23781
23781
  async function applyConstImport(systemsFilePath, importLine, fieldLine, importAnchor, fieldAnchor, newConstFilePath, newConstFileCode) {
23782
- (0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(newConstFilePath), { recursive: true });
23783
- (0, import_node_fs8.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
23784
- const systemsContent = (0, import_node_fs8.readFileSync)(systemsFilePath, "utf8");
23782
+ (0, import_node_fs9.mkdirSync)((0, import_node_path10.dirname)(newConstFilePath), { recursive: true });
23783
+ (0, import_node_fs9.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
23784
+ const systemsContent = (0, import_node_fs9.readFileSync)(systemsFilePath, "utf8");
23785
23785
  const afterImport = insertBeforeAnchorInContent(systemsContent, importLine + "\n", importAnchor);
23786
23786
  const lines = afterImport.split("\n");
23787
23787
  const fieldAnchorIndex = lines.findIndex((line) => fieldAnchor.test(line));
@@ -23791,14 +23791,14 @@ async function applyConstImport(systemsFilePath, importLine, fieldLine, importAn
23791
23791
  );
23792
23792
  }
23793
23793
  lines.splice(fieldAnchorIndex + 1, 0, fieldLine);
23794
- (0, import_node_fs8.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
23794
+ (0, import_node_fs9.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
23795
23795
  }
23796
- var import_node_fs8, import_node_path8;
23796
+ var import_node_fs9, import_node_path10;
23797
23797
  var init_splice = __esm({
23798
23798
  "src/cli/commands/om/splice.ts"() {
23799
23799
  "use strict";
23800
- import_node_fs8 = require("node:fs");
23801
- import_node_path8 = require("node:path");
23800
+ import_node_fs9 = require("node:fs");
23801
+ import_node_path10 = require("node:path");
23802
23802
  }
23803
23803
  });
23804
23804
 
@@ -23861,7 +23861,7 @@ async function scaffoldSystem(opts) {
23861
23861
  }
23862
23862
  return;
23863
23863
  }
23864
- const systemsFilePath = (0, import_node_path9.join)(projectDir, "core", "config", "organization-model", "systems.ts");
23864
+ const systemsFilePath = (0, import_node_path11.join)(projectDir, "core", "config", "organization-model", "systems.ts");
23865
23865
  try {
23866
23866
  await withSnapshotRollback([systemsFilePath], async () => {
23867
23867
  await appendBeforeAnchor(systemsFilePath, code, anchor);
@@ -23882,11 +23882,11 @@ async function scaffoldSystem(opts) {
23882
23882
  );
23883
23883
  }
23884
23884
  }
23885
- var import_node_path9, import_node_child_process2;
23885
+ var import_node_path11, import_node_child_process2;
23886
23886
  var init_scaffold_system = __esm({
23887
23887
  "src/cli/commands/om/scaffold-system.ts"() {
23888
23888
  "use strict";
23889
- import_node_path9 = require("node:path");
23889
+ import_node_path11 = require("node:path");
23890
23890
  import_node_child_process2 = require("node:child_process");
23891
23891
  init_source();
23892
23892
  init_config();
@@ -23980,7 +23980,7 @@ async function scaffoldResource(opts) {
23980
23980
  console.log(code);
23981
23981
  return;
23982
23982
  }
23983
- const systemsFilePath = (0, import_node_path10.join)(projectDir, "core", "config", "organization-model", "systems.ts");
23983
+ const systemsFilePath = (0, import_node_path12.join)(projectDir, "core", "config", "organization-model", "systems.ts");
23984
23984
  try {
23985
23985
  await withSnapshotRollback([systemsFilePath], async () => {
23986
23986
  await appendBeforeAnchor(systemsFilePath, code, anchor);
@@ -23998,11 +23998,11 @@ Resource \`${id}\` references system \`${systemPath}\` which is not in \`templat
23998
23998
  }
23999
23999
  console.log(source_default.green(`Resource \`${id}\` scaffolded in core/config/organization-model/systems.ts`));
24000
24000
  }
24001
- var import_node_path10, import_node_child_process3;
24001
+ var import_node_path12, import_node_child_process3;
24002
24002
  var init_scaffold_resource = __esm({
24003
24003
  "src/cli/commands/om/scaffold-resource.ts"() {
24004
24004
  "use strict";
24005
- import_node_path10 = require("node:path");
24005
+ import_node_path12 = require("node:path");
24006
24006
  import_node_child_process3 = require("node:child_process");
24007
24007
  init_source();
24008
24008
  init_config();
@@ -24073,7 +24073,7 @@ async function scaffoldRole(opts) {
24073
24073
  console.log(code);
24074
24074
  return;
24075
24075
  }
24076
- const profileFilePath = (0, import_node_path11.join)(projectDir, "core", "config", "organization-model", "profile.ts");
24076
+ const profileFilePath = (0, import_node_path13.join)(projectDir, "core", "config", "organization-model", "profile.ts");
24077
24077
  try {
24078
24078
  await withSnapshotRollback([profileFilePath], async () => {
24079
24079
  await appendBeforeAnchor(profileFilePath, code, anchor);
@@ -24089,11 +24089,11 @@ async function scaffoldRole(opts) {
24089
24089
  }
24090
24090
  console.log(source_default.green(`Role \`${id}\` scaffolded in core/config/organization-model/profile.ts`));
24091
24091
  }
24092
- var import_node_path11, import_node_child_process4;
24092
+ var import_node_path13, import_node_child_process4;
24093
24093
  var init_scaffold_role = __esm({
24094
24094
  "src/cli/commands/om/scaffold-role.ts"() {
24095
24095
  "use strict";
24096
- import_node_path11 = require("node:path");
24096
+ import_node_path13 = require("node:path");
24097
24097
  import_node_child_process4 = require("node:child_process");
24098
24098
  init_source();
24099
24099
  init_config();
@@ -24168,25 +24168,25 @@ async function scaffoldKnowledge(opts) {
24168
24168
  console.log(source_default.yellow("Run `elevasis-sdk om:generate` to register this node."));
24169
24169
  return;
24170
24170
  }
24171
- const absoluteFilePath = (0, import_node_path12.join)(projectDir, relativeFilePath);
24172
- if ((0, import_node_fs9.existsSync)(absoluteFilePath)) {
24171
+ const absoluteFilePath = (0, import_node_path14.join)(projectDir, relativeFilePath);
24172
+ if ((0, import_node_fs10.existsSync)(absoluteFilePath)) {
24173
24173
  process.stderr.write(
24174
24174
  source_default.red(`Knowledge node file already exists at \`${relativeFilePath}\`. Choose a different id.
24175
24175
  `)
24176
24176
  );
24177
24177
  process.exit(1);
24178
24178
  }
24179
- (0, import_node_fs9.mkdirSync)((0, import_node_path12.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
24180
- (0, import_node_fs9.writeFileSync)(absoluteFilePath, content, "utf8");
24179
+ (0, import_node_fs10.mkdirSync)((0, import_node_path14.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
24180
+ (0, import_node_fs10.writeFileSync)(absoluteFilePath, content, "utf8");
24181
24181
  console.log(source_default.green(`Knowledge node \`${id}\` written to \`${relativeFilePath}\``));
24182
24182
  console.log(source_default.yellow("Run `elevasis-sdk om:generate` to register this node."));
24183
24183
  }
24184
- var import_node_path12, import_node_fs9, VALID_KINDS;
24184
+ var import_node_path14, import_node_fs10, VALID_KINDS;
24185
24185
  var init_scaffold_knowledge = __esm({
24186
24186
  "src/cli/commands/om/scaffold-knowledge.ts"() {
24187
24187
  "use strict";
24188
- import_node_path12 = require("node:path");
24189
- import_node_fs9 = require("node:fs");
24188
+ import_node_path14 = require("node:path");
24189
+ import_node_fs10 = require("node:fs");
24190
24190
  init_source();
24191
24191
  init_config();
24192
24192
  init_project_layout();
@@ -24240,7 +24240,7 @@ __export(scaffold_fill_exports, {
24240
24240
  default: () => scaffoldFill
24241
24241
  });
24242
24242
  function conformanceGapTempPath(orgName) {
24243
- return (0, import_node_path13.join)(os2.tmpdir(), `elevasis-conformance-${orgName}-${Date.now()}.json`);
24243
+ return (0, import_node_path15.join)(os2.tmpdir(), `elevasis-conformance-${orgName}-${Date.now()}.json`);
24244
24244
  }
24245
24245
  function runValidation4(projectDir) {
24246
24246
  for (const script of ["check-types", "check"]) {
@@ -24263,7 +24263,7 @@ async function scaffoldFill(opts) {
24263
24263
  process.stderr.write(source_default.red("Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.\n"));
24264
24264
  process.exit(1);
24265
24265
  }
24266
- if (!(0, import_node_fs10.existsSync)(options.gaps)) {
24266
+ if (!(0, import_node_fs11.existsSync)(options.gaps)) {
24267
24267
  process.stderr.write(
24268
24268
  source_default.red(
24269
24269
  `Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.
@@ -24275,7 +24275,7 @@ async function scaffoldFill(opts) {
24275
24275
  }
24276
24276
  let payload;
24277
24277
  try {
24278
- const raw = (0, import_node_fs10.readFileSync)(options.gaps, "utf8");
24278
+ const raw = (0, import_node_fs11.readFileSync)(options.gaps, "utf8");
24279
24279
  payload = JSON.parse(raw);
24280
24280
  } catch {
24281
24281
  process.stderr.write(
@@ -24300,7 +24300,7 @@ async function scaffoldFill(opts) {
24300
24300
  const systemPath = payload.systemPath;
24301
24301
  const skippedGaps = [];
24302
24302
  const appliedGaps = [];
24303
- const systemsFilePath = (0, import_node_path13.join)(projectDir, "core", "config", "organization-model", "systems.ts");
24303
+ const systemsFilePath = (0, import_node_path15.join)(projectDir, "core", "config", "organization-model", "systems.ts");
24304
24304
  const touchedFiles = [systemsFilePath];
24305
24305
  const emitResults = [];
24306
24306
  for (const gap of payload.gaps) {
@@ -24317,7 +24317,7 @@ async function scaffoldFill(opts) {
24317
24317
  resourceIds,
24318
24318
  message: gap.reason
24319
24319
  });
24320
- const constFilePath = (0, import_node_path13.join)(
24320
+ const constFilePath = (0, import_node_path15.join)(
24321
24321
  projectDir,
24322
24322
  "core",
24323
24323
  "config",
@@ -24365,7 +24365,7 @@ async function scaffoldFill(opts) {
24365
24365
  await withSnapshotRollback(touchedFiles, async () => {
24366
24366
  for (let i = 0; i < emitResults.length; i++) {
24367
24367
  const result = emitResults[i];
24368
- const constFilePath = (0, import_node_path13.join)(
24368
+ const constFilePath = (0, import_node_path15.join)(
24369
24369
  projectDir,
24370
24370
  "core",
24371
24371
  "config",
@@ -24395,8 +24395,8 @@ async function scaffoldFill(opts) {
24395
24395
  }
24396
24396
  }
24397
24397
  if (skippedGaps.length > 0) {
24398
- const skippedPath = options.skipped ?? (0, import_node_path13.join)(os2.tmpdir(), `elevasis-fill-skipped-${systemPath}-${Date.now()}.json`);
24399
- (0, import_node_fs10.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
24398
+ const skippedPath = options.skipped ?? (0, import_node_path15.join)(os2.tmpdir(), `elevasis-fill-skipped-${systemPath}-${Date.now()}.json`);
24399
+ (0, import_node_fs11.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
24400
24400
  console.log(
24401
24401
  source_default.yellow(
24402
24402
  `Partial fill: ${appliedGaps.length} gap(s) applied, ${skippedGaps.length} skipped \u2014 see \`${skippedPath}\` for fields requiring manual input.`
@@ -24410,13 +24410,13 @@ async function scaffoldFill(opts) {
24410
24410
  )
24411
24411
  );
24412
24412
  }
24413
- var import_node_path13, os2, import_node_fs10, import_node_child_process5;
24413
+ var import_node_path15, os2, import_node_fs11, import_node_child_process5;
24414
24414
  var init_scaffold_fill = __esm({
24415
24415
  "src/cli/commands/om/scaffold-fill.ts"() {
24416
24416
  "use strict";
24417
- import_node_path13 = require("node:path");
24417
+ import_node_path15 = require("node:path");
24418
24418
  os2 = __toESM(require("node:os"), 1);
24419
- import_node_fs10 = require("node:fs");
24419
+ import_node_fs11 = require("node:fs");
24420
24420
  import_node_child_process5 = require("node:child_process");
24421
24421
  init_source();
24422
24422
  init_config();
@@ -37935,6 +37935,7 @@ function buildOmCrossRefIndex(model) {
37935
37935
  systemsById.set(system.id, system);
37936
37936
  }
37937
37937
  const resourceIds = new Set(Object.keys(model.resources ?? {}));
37938
+ const clientIds = new Set(Object.keys(model.clients ?? {}));
37938
37939
  const knowledgeIds = new Set(Object.keys(model.knowledge ?? {}));
37939
37940
  const roleIds = new Set(Object.keys(model.roles ?? {}));
37940
37941
  const goalIds = new Set(Object.keys(model.goals ?? {}));
@@ -37968,6 +37969,7 @@ function buildOmCrossRefIndex(model) {
37968
37969
  return {
37969
37970
  systemsById,
37970
37971
  resourceIds,
37972
+ clientIds,
37971
37973
  knowledgeIds,
37972
37974
  roleIds,
37973
37975
  goalIds,
@@ -37981,6 +37983,7 @@ function buildOmCrossRefIndex(model) {
37981
37983
  }
37982
37984
  function knowledgeTargetExists(index, kind, id) {
37983
37985
  if (kind === "system") return index.systemsById.has(id);
37986
+ if (kind === "client") return index.clientIds.has(id);
37984
37987
  if (kind === "resource") return index.resourceIds.has(id);
37985
37988
  if (kind === "knowledge") return index.knowledgeIds.has(id);
37986
37989
  if (kind === "stage") return index.stageIds.has(id);
@@ -38924,6 +38927,7 @@ var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
38924
38927
  // ../core/src/organization-model/domains/knowledge.ts
38925
38928
  var KnowledgeTargetKindSchema = external_exports.enum([
38926
38929
  "system",
38930
+ "client",
38927
38931
  "resource",
38928
38932
  "knowledge",
38929
38933
  "stage",
@@ -39185,10 +39189,10 @@ function asRoleHolderArray(heldBy) {
39185
39189
  function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
39186
39190
  if (knowledgeKind === "reference") return true;
39187
39191
  if (knowledgeKind === "playbook") {
39188
- return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
39192
+ return ["system", "client", "resource", "stage", "action", "ontology"].includes(targetKind);
39189
39193
  }
39190
39194
  if (knowledgeKind === "strategy") {
39191
- return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
39195
+ return ["system", "client", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
39192
39196
  }
39193
39197
  return false;
39194
39198
  }
@@ -39717,9 +39721,68 @@ function refineOrganizationModel(model, ctx) {
39717
39721
  }
39718
39722
 
39719
39723
  // ../core/src/organization-model/schema.ts
39724
+ var ClientProfileIdSchema = external_exports.string().uuid();
39725
+ var ClientProfileStatusSchema = external_exports.enum(["active", "onboarding", "paused", "completed", "churned"]);
39726
+ var ClientProfileSourceSchema = external_exports.string().trim().min(1).max(64).regex(/^[a-z][a-z0-9_]*$/, "Source must use lowercase letters, numbers, and underscores");
39727
+ var ClientProfileIdentitySchema = external_exports.object({
39728
+ organizationName: LabelSchema.optional(),
39729
+ shortName: external_exports.string().trim().min(1).max(40).optional(),
39730
+ clientBrief: external_exports.string().trim().max(4e3).default(""),
39731
+ geographicFocus: external_exports.array(external_exports.string().trim().min(1).max(200)).default([]),
39732
+ timeZone: external_exports.string().trim().min(1).max(100).default("UTC")
39733
+ }).passthrough().default({
39734
+ clientBrief: "",
39735
+ geographicFocus: [],
39736
+ timeZone: "UTC"
39737
+ });
39738
+ var ClientProfileBrandingSchema = external_exports.object({
39739
+ voice: external_exports.string().trim().max(280).optional(),
39740
+ tagline: external_exports.string().trim().max(200).optional(),
39741
+ values: external_exports.array(external_exports.string().trim().min(1).max(100)).default([])
39742
+ }).passthrough().default({
39743
+ values: []
39744
+ });
39745
+ var ClientProfileWorkspaceSchema = external_exports.object({
39746
+ kind: external_exports.enum(["external-project", "internal-project", "none"]).optional(),
39747
+ owner: external_exports.enum(["developer", "client", "platform"]).optional(),
39748
+ projectId: external_exports.string().trim().min(1).max(200).optional(),
39749
+ workspacePath: external_exports.string().trim().min(1).max(500).optional()
39750
+ }).passthrough().default({});
39751
+ var ClientProfileLinksSchema = external_exports.object({
39752
+ projectIds: external_exports.array(external_exports.string().uuid()).default([]),
39753
+ primaryCompanyId: external_exports.string().uuid().optional(),
39754
+ primaryContactId: external_exports.string().uuid().optional(),
39755
+ sourceDealId: external_exports.string().uuid().optional()
39756
+ }).default({
39757
+ projectIds: []
39758
+ });
39759
+ var ClientProfilePromptsSchema = external_exports.object({
39760
+ defaultContext: external_exports.string().trim().max(8e3).default("")
39761
+ }).passthrough().default({
39762
+ defaultContext: ""
39763
+ });
39764
+ var ClientProfileSchema = external_exports.object({
39765
+ id: ClientProfileIdSchema,
39766
+ slug: ModelIdSchema,
39767
+ name: LabelSchema,
39768
+ status: ClientProfileStatusSchema.default("onboarding"),
39769
+ source: ClientProfileSourceSchema.optional(),
39770
+ identity: ClientProfileIdentitySchema,
39771
+ branding: ClientProfileBrandingSchema,
39772
+ workspace: ClientProfileWorkspaceSchema,
39773
+ links: ClientProfileLinksSchema,
39774
+ prompts: ClientProfilePromptsSchema,
39775
+ config: external_exports.record(external_exports.string().trim().min(1).max(200), JsonValueSchema).default({}),
39776
+ customValues: external_exports.record(external_exports.string().trim().min(1).max(200), JsonValueSchema).default({})
39777
+ }).strict();
39778
+ var ClientProfilesDomainSchema = external_exports.record(ClientProfileIdSchema, ClientProfileSchema).refine((record2) => Object.entries(record2).every(([key, entry]) => entry.id === key), {
39779
+ message: "Each client profile id must match its map key"
39780
+ }).default({});
39781
+ var DEFAULT_ORGANIZATION_MODEL_CLIENTS = {};
39720
39782
  var OrganizationModelDomainKeySchema = external_exports.enum([
39721
39783
  "branding",
39722
39784
  "identity",
39785
+ "clients",
39723
39786
  "customers",
39724
39787
  "offerings",
39725
39788
  "roles",
@@ -39740,6 +39803,7 @@ var OrganizationModelDomainMetadataSchema = external_exports.object({
39740
39803
  var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
39741
39804
  branding: { version: 1, lastModified: "2026-05-10" },
39742
39805
  identity: { version: 1, lastModified: "2026-05-10" },
39806
+ clients: { version: 1, lastModified: "2026-05-30" },
39743
39807
  customers: { version: 1, lastModified: "2026-05-10" },
39744
39808
  offerings: { version: 1, lastModified: "2026-05-10" },
39745
39809
  roles: { version: 1, lastModified: "2026-05-10" },
@@ -39756,6 +39820,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
39756
39820
  var OrganizationModelDomainMetadataByDomainSchema = external_exports.object({
39757
39821
  branding: OrganizationModelDomainMetadataSchema,
39758
39822
  identity: OrganizationModelDomainMetadataSchema,
39823
+ clients: OrganizationModelDomainMetadataSchema,
39759
39824
  customers: OrganizationModelDomainMetadataSchema,
39760
39825
  offerings: OrganizationModelDomainMetadataSchema,
39761
39826
  roles: OrganizationModelDomainMetadataSchema,
@@ -39787,6 +39852,7 @@ var OrganizationModelSchemaBase = external_exports.object({
39787
39852
  branding: OrganizationModelBrandingSchema.default(DEFAULT_ORGANIZATION_MODEL_BRANDING),
39788
39853
  navigation: OrganizationModelNavigationSchema,
39789
39854
  identity: IdentityDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_IDENTITY),
39855
+ clients: ClientProfilesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CLIENTS),
39790
39856
  customers: CustomersDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CUSTOMERS),
39791
39857
  offerings: OfferingsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_OFFERINGS),
39792
39858
  roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
@@ -39819,6 +39885,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
39819
39885
  branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
39820
39886
  navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
39821
39887
  identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
39888
+ clients: DEFAULT_ORGANIZATION_MODEL_CLIENTS,
39822
39889
  customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
39823
39890
  offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
39824
39891
  roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
@@ -39985,6 +40052,7 @@ function getAllProjectStatuses(model, appliesTo) {
39985
40052
  var OrganizationGraphNodeKindSchema = external_exports.enum([
39986
40053
  "organization",
39987
40054
  "system",
40055
+ "client",
39988
40056
  "role",
39989
40057
  "action",
39990
40058
  "entity",
@@ -40230,6 +40298,22 @@ function buildOrganizationGraph(input) {
40230
40298
  }
40231
40299
  const validSystemRefs = new Set(systemPathByRef.keys());
40232
40300
  const systemNodeId = (systemRef) => nodeId("system", systemPathByRef.get(systemRef) ?? systemRef);
40301
+ for (const client of Object.values(organizationModel.clients).sort((a, b) => a.slug.localeCompare(b.slug))) {
40302
+ const id = nodeId("client", client.id);
40303
+ pushUniqueNode(nodes, nodeIds, {
40304
+ id,
40305
+ kind: "client",
40306
+ label: client.name,
40307
+ sourceId: client.id,
40308
+ description: client.identity.clientBrief || void 0
40309
+ });
40310
+ pushUniqueEdge(edges, edgeIds, {
40311
+ id: edgeId("contains", organizationNode.id, id),
40312
+ kind: "contains",
40313
+ sourceId: organizationNode.id,
40314
+ targetId: id
40315
+ });
40316
+ }
40233
40317
  function topologyNodeId(ref) {
40234
40318
  if (ref.kind === "system") return systemNodeId(ref.id);
40235
40319
  if (ref.kind === "resource") return nodeId("resource", ref.id);
@@ -45632,7 +45716,7 @@ function wrapAction(commandName, fn) {
45632
45716
  // package.json
45633
45717
  var package_default = {
45634
45718
  name: "@elevasis/sdk",
45635
- version: "1.31.0",
45719
+ version: "1.33.0",
45636
45720
  description: "SDK for building Elevasis organization resources",
45637
45721
  type: "module",
45638
45722
  bin: {
@@ -45672,7 +45756,7 @@ var package_default = {
45672
45756
  ],
45673
45757
  scripts: {
45674
45758
  lint: "eslint src --max-warnings 0",
45675
- build: `node -e "require('fs').rmSync('dist',{recursive:true,force:true})" && tsc -p tsconfig.core-dts.json && tsc -p tsconfig.build.json && tsup && rollup -c rollup.dts.config.mjs && esbuild src/cli/index.ts --bundle --platform=node --outfile=dist/cli.cjs --format=cjs --external:esbuild --banner:js="#!/usr/bin/env node" && node scripts/copy-reference-docs.mjs && node ../../scripts/monorepo/generate-reference-artifacts.js`,
45759
+ build: `node -e "require('fs').rmSync('dist',{recursive:true,force:true})" && tsc -p tsconfig.core-dts.json && tsc -p tsconfig.build.json && tsup && rollup -c rollup.dts.config.mjs && esbuild src/cli/index.ts --bundle --platform=node --outfile=dist/cli.cjs --format=cjs --external:esbuild --banner:js="#!/usr/bin/env node" && node scripts/verify-skill-coverage.mjs && node scripts/copy-reference-docs.mjs && node ../../scripts/monorepo/generate-reference-artifacts.js`,
45676
45760
  "type-check": "tsc --noEmit",
45677
45761
  "check-types": "pnpm type-check",
45678
45762
  test: "pnpm build && node ../../scripts/monorepo/validate-reference-artifacts.js && vitest run --config vitest.bundle.config.ts",
@@ -46152,10 +46236,221 @@ import { startWorker } from '@elevasis/sdk/worker'
46152
46236
 
46153
46237
  // src/cli/commands/check.ts
46154
46238
  init_config();
46239
+
46240
+ // src/cli/commands/skill/skill-check-coverage.ts
46241
+ var import_node_path2 = require("node:path");
46242
+ init_source();
46243
+
46244
+ // src/cli/commands/cli/catalog.ts
46245
+ function buildCliCatalogFromProgram(program3, options = {}) {
46246
+ const commands = program3.commands.flatMap((command) => collectRuntimeCommands(command));
46247
+ return groupCommands(commands, "registered Commander commands", options.domain);
46248
+ }
46249
+ function groupCommands(commands, sourceRoot, domain2) {
46250
+ const filtered = domain2 ? commands.filter((command) => command.domain === domain2) : commands;
46251
+ const sorted = filtered.sort((a, b) => a.domain.localeCompare(b.domain) || a.syntax.localeCompare(b.syntax));
46252
+ const domainNames = [...new Set(sorted.map((command) => command.domain))];
46253
+ return {
46254
+ sourceRoot,
46255
+ domains: domainNames.map((name) => ({
46256
+ name,
46257
+ commands: sorted.filter((command) => command.domain === name)
46258
+ }))
46259
+ };
46260
+ }
46261
+ function collectRuntimeCommands(command, parent) {
46262
+ const commandName = command.name();
46263
+ const argSuffix = formatRuntimeArguments(command.registeredArguments);
46264
+ const syntaxSegment = argSuffix ? `${commandName} ${argSuffix}` : commandName;
46265
+ const syntax = parent ? `${parent.syntax} ${syntaxSegment}` : syntaxSegment;
46266
+ const domain2 = parent?.domain ?? domainFromCommand(commandName);
46267
+ const current = {
46268
+ command: commandName,
46269
+ syntax,
46270
+ domain: domain2
46271
+ };
46272
+ const aliases = command.aliases().map((alias) => parent ? `${parent.syntax} ${alias}` : alias);
46273
+ return [
46274
+ {
46275
+ syntax,
46276
+ command: commandName,
46277
+ domain: domain2,
46278
+ description: firstLine(command.description()),
46279
+ aliases,
46280
+ options: command.options.map((option) => ({
46281
+ flags: option.flags,
46282
+ description: option.description,
46283
+ required: option.mandatory
46284
+ })),
46285
+ source: "runtime"
46286
+ },
46287
+ ...command.commands.flatMap((child) => collectRuntimeCommands(child, current))
46288
+ ];
46289
+ }
46290
+ function formatRuntimeArguments(args) {
46291
+ return args.map((arg) => {
46292
+ const name = `${arg.name()}${arg.variadic ? "..." : ""}`;
46293
+ return arg.required ? `<${name}>` : `[${name}]`;
46294
+ }).join(" ");
46295
+ }
46296
+ function renderCliCatalogMarkdown(catalog) {
46297
+ const lines = [
46298
+ "# elevasis-sdk CLI Catalog",
46299
+ "",
46300
+ `Source: \`${catalog.sourceRoot}\``,
46301
+ ""
46302
+ ];
46303
+ if (catalog.domains.length === 0) {
46304
+ lines.push("No commands found.");
46305
+ return lines.join("\n");
46306
+ }
46307
+ for (const domain2 of catalog.domains) {
46308
+ lines.push(`## ${domain2.name}`, "");
46309
+ lines.push("| Command | Description | Aliases | Options | Source |");
46310
+ lines.push("| --- | --- | --- | --- | --- |");
46311
+ for (const command of domain2.commands) {
46312
+ const aliases = command.aliases.length > 0 ? command.aliases.map((alias) => `\`${alias}\``).join(", ") : "-";
46313
+ const options = command.options.length > 0 ? command.options.map((option) => `${option.required ? "required " : ""}\`${option.flags}\``).join("<br>") : "-";
46314
+ lines.push(
46315
+ `| \`elevasis-sdk ${command.syntax}\` | ${escapeMarkdownTable(command.description || "-")} | ${aliases} | ${options} | \`${command.source}\` |`
46316
+ );
46317
+ }
46318
+ lines.push("");
46319
+ }
46320
+ return lines.join("\n").trimEnd();
46321
+ }
46322
+ function renderCliCatalogJson(catalog) {
46323
+ return JSON.stringify(catalog, null, 2);
46324
+ }
46325
+ function domainFromCommand(command) {
46326
+ if (command.includes(":")) return command.split(":")[0];
46327
+ return "platform";
46328
+ }
46329
+ function firstLine(value) {
46330
+ return value.split("\n")[0]?.trim() ?? "";
46331
+ }
46332
+ function escapeMarkdownTable(value) {
46333
+ return value.replace(/\|/g, "\\|").replace(/\r?\n/g, "<br>");
46334
+ }
46335
+ function knownDomains(catalog) {
46336
+ return catalog.domains.map((domain2) => domain2.name);
46337
+ }
46338
+
46339
+ // src/cli/commands/skill/skill-coverage.ts
46340
+ var import_node_fs = require("node:fs");
46341
+ var import_node_path = require("node:path");
46342
+ function loadSkillCoverage(projectRoot) {
46343
+ const coveragePath = (0, import_node_path.join)(projectRoot, ".claude", "registries", "skill-coverage.json");
46344
+ if (!(0, import_node_fs.existsSync)(coveragePath)) return null;
46345
+ const raw = (0, import_node_fs.readFileSync)(coveragePath, "utf8");
46346
+ return JSON.parse(raw);
46347
+ }
46348
+ function runCoverageGate(knownDomains2, coverage, presentSkills, coverageFilePath) {
46349
+ const violations = [];
46350
+ const domainSet = new Set(knownDomains2);
46351
+ const ownedDomains = /* @__PURE__ */ new Set();
46352
+ for (const entry of Object.values(coverage.skills)) {
46353
+ for (const domain2 of entry.domains) {
46354
+ ownedDomains.add(domain2);
46355
+ }
46356
+ }
46357
+ const waivedDomains = new Set(Object.keys(coverage.waived));
46358
+ for (const domain2 of knownDomains2) {
46359
+ if (!ownedDomains.has(domain2) && !waivedDomains.has(domain2)) {
46360
+ violations.push({
46361
+ kind: "uncovered",
46362
+ domain: domain2,
46363
+ detail: `Domain "${domain2}" exists in the CLI but is neither skill-owned nor waived in ${coverageFilePath}. Add it to "skills" or "waived".`
46364
+ });
46365
+ }
46366
+ }
46367
+ for (const [skillName, entry] of Object.entries(coverage.skills)) {
46368
+ for (const domain2 of entry.domains) {
46369
+ if (!domainSet.has(domain2)) {
46370
+ violations.push({
46371
+ kind: "stale-owned",
46372
+ domain: domain2,
46373
+ detail: `Domain "${domain2}" is declared as owned by skill "${skillName}" in ${coverageFilePath} but no longer exists in the CLI catalog. Remove or update the entry.`
46374
+ });
46375
+ }
46376
+ }
46377
+ }
46378
+ for (const domain2 of waivedDomains) {
46379
+ if (!domainSet.has(domain2)) {
46380
+ violations.push({
46381
+ kind: "stale-waived",
46382
+ domain: domain2,
46383
+ detail: `Domain "${domain2}" is declared as waived in ${coverageFilePath} but no longer exists in the CLI catalog. Remove the waiver.`
46384
+ });
46385
+ }
46386
+ }
46387
+ return {
46388
+ violations,
46389
+ domainsChecked: knownDomains2,
46390
+ coverageFile: coverageFilePath
46391
+ };
46392
+ }
46393
+
46394
+ // src/cli/commands/skill/skill-check-coverage.ts
46395
+ init_config();
46396
+ async function runSkillCoverageCheck(program3, options = {}) {
46397
+ const projectRoot = tryFindProjectRoot(process.cwd());
46398
+ if (projectRoot === null) {
46399
+ return { passed: true, violationCount: 0 };
46400
+ }
46401
+ const coveragePath = (0, import_node_path2.join)(projectRoot, ".claude", "registries", "skill-coverage.json");
46402
+ const coverage = loadSkillCoverage(projectRoot);
46403
+ if (coverage === null) {
46404
+ if (!options.silent) {
46405
+ console.log(
46406
+ source_default.yellow(" warn skill-coverage.json not found \u2014 skipping coverage gate") + source_default.gray(`
46407
+ Expected: ${coveragePath}`)
46408
+ );
46409
+ }
46410
+ return { passed: true, violationCount: 0 };
46411
+ }
46412
+ const catalog = buildCliCatalogFromProgram(program3);
46413
+ const domains = knownDomains(catalog);
46414
+ const result = runCoverageGate(domains, coverage, /* @__PURE__ */ new Set(), coveragePath);
46415
+ if (result.violations.length === 0) {
46416
+ if (!options.silent) {
46417
+ console.log(
46418
+ source_default.green(" Skill coverage OK") + source_default.gray(` (${domains.length} domains checked, all covered or waived)`)
46419
+ );
46420
+ }
46421
+ return { passed: true, violationCount: 0 };
46422
+ }
46423
+ for (const violation of result.violations) {
46424
+ const prefix = violation.kind === "uncovered" ? source_default.red(" ERROR coverage") : source_default.yellow(" WARN coverage");
46425
+ console.error(`${prefix} ${violation.detail}`);
46426
+ }
46427
+ return { passed: false, violationCount: result.violations.length };
46428
+ }
46429
+ function registerSkillCheckCoverageCommand(program3) {
46430
+ program3.command("skill:check-coverage").description(
46431
+ "Verify CLI domains are covered by skills or waived in skill-coverage.json\n Example: elevasis-sdk skill:check-coverage"
46432
+ ).action(
46433
+ wrapAction("skill:check-coverage", async () => {
46434
+ const catalog = buildCliCatalogFromProgram(program3);
46435
+ const domains = knownDomains(catalog);
46436
+ console.log(source_default.cyan(`Checking skill coverage for ${domains.length} CLI domains...`));
46437
+ const { passed, violationCount } = await runSkillCoverageCheck(program3);
46438
+ if (!passed) {
46439
+ console.error("");
46440
+ console.error(
46441
+ source_default.red(`Skill coverage check failed: ${violationCount} violation(s).`) + "\n" + source_default.gray(' Update .claude/registries/skill-coverage.json to add the domain to "skills" or "waived".')
46442
+ );
46443
+ process.exitCode = 1;
46444
+ }
46445
+ })
46446
+ );
46447
+ }
46448
+
46449
+ // src/cli/commands/check.ts
46155
46450
  function registerCheckCommand(program3) {
46156
46451
  program3.command("check").description(
46157
46452
  "Validate project resources against the ResourceRegistry\n Example: elevasis-sdk check --entry ./src/index.ts"
46158
- ).option("--entry <path>", "Path to entry file (default: ./src/index.ts)").action(
46453
+ ).option("--entry <path>", "Path to entry file (default: ./src/index.ts)").option("--skip-coverage", "Skip the skill coverage gate").action(
46159
46454
  wrapAction("check", async (options) => {
46160
46455
  const entryPath = options.entry ?? "./src/index.ts";
46161
46456
  const spinner = ora("Validating resources...").start();
@@ -46206,6 +46501,20 @@ function registerCheckCommand(program3) {
46206
46501
  }
46207
46502
  console.log(source_default.gray(" Schemas will be unavailable on the platform for these resources."));
46208
46503
  }
46504
+ if (!options.skipCoverage) {
46505
+ console.log("");
46506
+ const coverageResult = await runSkillCoverageCheck(program3);
46507
+ if (!coverageResult.passed) {
46508
+ console.error("");
46509
+ console.error(
46510
+ source_default.red(`Skill coverage check failed: ${coverageResult.violationCount} violation(s).`) + "\n" + source_default.gray(
46511
+ ' Update .claude/registries/skill-coverage.json to add the domain to "skills" or "waived".\n Run with --skip-coverage to suppress this check.'
46512
+ )
46513
+ );
46514
+ process.exitCode = 1;
46515
+ return;
46516
+ }
46517
+ }
46209
46518
  } catch (error46) {
46210
46519
  if (error46 instanceof RegistryValidationError) {
46211
46520
  spinner.fail(source_default.red("Validation failed"));
@@ -46227,8 +46536,8 @@ function registerCheckCommand(program3) {
46227
46536
  }
46228
46537
 
46229
46538
  // src/cli/commands/exec.ts
46230
- var import_node_fs = require("node:fs");
46231
- var import_node_path = require("node:path");
46539
+ var import_node_fs2 = require("node:fs");
46540
+ var import_node_path3 = require("node:path");
46232
46541
  init_source();
46233
46542
  init_config();
46234
46543
  var POLL_INTERVAL_MS = 3e3;
@@ -46301,14 +46610,14 @@ function registerExecCommand(program3) {
46301
46610
  "exec",
46302
46611
  async (resourceId, options) => {
46303
46612
  const resolvedInputFile = options.inputFile ? resolveProjectRelative(options.inputFile) : void 0;
46304
- const input = resolvedInputFile ? JSON.parse((0, import_node_fs.readFileSync)(resolvedInputFile, "utf8")) : options.input ? JSON.parse(options.input) : {};
46613
+ const input = resolvedInputFile ? JSON.parse((0, import_node_fs2.readFileSync)(resolvedInputFile, "utf8")) : options.input ? JSON.parse(options.input) : {};
46305
46614
  const apiUrl = resolveApiUrl(options.apiUrl);
46306
46615
  const maybeCleanupInput = () => {
46307
46616
  if (!options.cleanupInput || !resolvedInputFile) return;
46308
- const tmpDir = (0, import_node_path.join)(getProjectRoot(), "tmp");
46617
+ const tmpDir = (0, import_node_path3.join)(getProjectRoot(), "tmp");
46309
46618
  if (resolvedInputFile.startsWith(tmpDir + "/") || resolvedInputFile.startsWith(tmpDir + "\\")) {
46310
46619
  try {
46311
- (0, import_node_fs.unlinkSync)(resolvedInputFile);
46620
+ (0, import_node_fs2.unlinkSync)(resolvedInputFile);
46312
46621
  } catch {
46313
46622
  }
46314
46623
  } else {
@@ -48973,11 +49282,11 @@ function bullet(items) {
48973
49282
  function field(label, value) {
48974
49283
  return value === void 0 || value === null || value === "" ? "" : `${label}: ${value}`;
48975
49284
  }
48976
- function join3(parts) {
49285
+ function join5(parts) {
48977
49286
  return parts.filter((p) => p.length > 0).join("\n\n");
48978
49287
  }
48979
49288
  function formatSystemDescribe(r) {
48980
- const header = join3([
49289
+ const header = join5([
48981
49290
  `System: ${r.id}`,
48982
49291
  [
48983
49292
  field("Label", r.label),
@@ -49006,10 +49315,10 @@ ${resourceLines.join("\n")}`;
49006
49315
  const ontologyEntries = Object.entries(r.ontologyCountsByKind);
49007
49316
  const ontologySection = ontologyEntries.length ? `Ontology: ${ontologyEntries.map(([k, n]) => `${k}s: ${n}`).join(", ")}` : "";
49008
49317
  const childSection = section("Subsystems", bullet(r.childSystemPaths));
49009
- return join3([header, govSection, resourceSection, ontologySection, childSection]);
49318
+ return join5([header, govSection, resourceSection, ontologySection, childSection]);
49010
49319
  }
49011
49320
  function formatResourceDescribe(r) {
49012
- const header = join3([
49321
+ const header = join5([
49013
49322
  `Resource: ${r.id}`,
49014
49323
  [
49015
49324
  field("Kind", r.resourceKind),
@@ -49033,10 +49342,10 @@ function formatResourceDescribe(r) {
49033
49342
  ${ontologyLines.join("\n")}` : "";
49034
49343
  const codeRefsSection = r.codeRefPaths.length ? `Code refs:
49035
49344
  ${bullet(r.codeRefPaths)}` : "";
49036
- return join3([header, ontologySection, codeRefsSection]);
49345
+ return join5([header, ontologySection, codeRefsSection]);
49037
49346
  }
49038
49347
  function formatKnowledgeDescribe(r) {
49039
- const header = join3([
49348
+ const header = join5([
49040
49349
  `Knowledge: ${r.id}`,
49041
49350
  [field("Kind", r.knowledgeKind), field("Title", r.title), field("Updated", r.updatedAt)].filter((s) => s.length > 0).join("\n"),
49042
49351
  r.summary ? `Summary: ${r.summary}` : ""
@@ -49046,28 +49355,28 @@ ${bullet(r.ownerIds)}` : "";
49046
49355
  const govSection = section("Governs", bullet(r.governs));
49047
49356
  const bodySection = `Body excerpt (${r.bodyLineCount} lines total \u2014 use knowledge:cat for full):
49048
49357
  ${r.bodyExcerpt}`;
49049
- return join3([header, ownerSection, govSection, bodySection]);
49358
+ return join5([header, ownerSection, govSection, bodySection]);
49050
49359
  }
49051
49360
  function formatOntologyDescribe(r) {
49052
- const header = join3([
49361
+ const header = join5([
49053
49362
  `Ontology: ${r.id}`,
49054
49363
  [field("Kind", r.ontologyKind), field("Scope", r.scope), field("Local id", r.localId), field("Label", r.label)].filter((s) => s.length > 0).join("\n"),
49055
49364
  r.description ? `Description: ${r.description}` : ""
49056
49365
  ]);
49057
49366
  const govSection = section("Governed by knowledge", bullet(r.governingKnowledgeIds));
49058
- return join3([header, govSection]);
49367
+ return join5([header, govSection]);
49059
49368
  }
49060
49369
  function formatRoleDescribe(r) {
49061
- const header = join3([
49370
+ const header = join5([
49062
49371
  `Role: ${r.id}`,
49063
49372
  [field("Title", r.title), field("Reports to", r.reportsToId)].filter((s) => s.length > 0).join("\n")
49064
49373
  ]);
49065
49374
  const respSection = section("Responsibilities", bullet(r.responsibilities));
49066
49375
  const responsibleForSection = section("Responsible for systems", bullet(r.responsibleFor));
49067
- return join3([header, respSection, responsibleForSection]);
49376
+ return join5([header, respSection, responsibleForSection]);
49068
49377
  }
49069
49378
  function formatPolicyDescribe(r) {
49070
- const header = join3([
49379
+ const header = join5([
49071
49380
  `Policy: ${r.id}`,
49072
49381
  [field("Label", r.label), field("Trigger", r.triggerKind)].filter((s) => s.length > 0).join("\n"),
49073
49382
  r.description ? `Description: ${r.description}` : ""
@@ -49080,7 +49389,7 @@ function formatPolicyDescribe(r) {
49080
49389
  if (r.appliesToRoleIds.length) appliesLines.push(` roles: ${r.appliesToRoleIds.join(", ")}`);
49081
49390
  const appliesSection = appliesLines.length ? `Applies to:
49082
49391
  ${appliesLines.join("\n")}` : "";
49083
- return join3([header, effectSection, appliesSection]);
49392
+ return join5([header, effectSection, appliesSection]);
49084
49393
  }
49085
49394
 
49086
49395
  // src/cli/commands/knowledge/ls.ts
@@ -49480,12 +49789,12 @@ function registerKnowledgeSkills(program3) {
49480
49789
  }
49481
49790
 
49482
49791
  // src/cli/commands/knowledge/generate.ts
49483
- var import_node_fs3 = require("node:fs");
49484
- var import_node_path3 = require("node:path");
49792
+ var import_node_fs4 = require("node:fs");
49793
+ var import_node_path5 = require("node:path");
49485
49794
 
49486
49795
  // src/knowledge-codegen.ts
49487
- var import_node_fs2 = require("node:fs");
49488
- var import_node_path2 = require("node:path");
49796
+ var import_node_fs3 = require("node:fs");
49797
+ var import_node_path4 = require("node:path");
49489
49798
  function targetFromNodeId2(nodeId2) {
49490
49799
  const [kind, ...idParts] = nodeId2.split(":");
49491
49800
  return {
@@ -49503,10 +49812,10 @@ function canonicalizeKnowledgeNodeLinks(node) {
49503
49812
  };
49504
49813
  }
49505
49814
  function listMdxFiles(directory) {
49506
- return (0, import_node_fs2.readdirSync)(directory, { withFileTypes: true }).flatMap((entry) => {
49507
- const path3 = (0, import_node_path2.join)(directory, entry.name);
49815
+ return (0, import_node_fs3.readdirSync)(directory, { withFileTypes: true }).flatMap((entry) => {
49816
+ const path3 = (0, import_node_path4.join)(directory, entry.name);
49508
49817
  if (entry.isDirectory()) return listMdxFiles(path3);
49509
- return entry.isFile() && (0, import_node_path2.extname)(entry.name) === ".mdx" ? [path3] : [];
49818
+ return entry.isFile() && (0, import_node_path4.extname)(entry.name) === ".mdx" ? [path3] : [];
49510
49819
  });
49511
49820
  }
49512
49821
  function parseScalar(value) {
@@ -49701,7 +50010,7 @@ function readCommandForNode(node, cliCommand = "elevasis") {
49701
50010
  ];
49702
50011
  }
49703
50012
  function readKnowledgeNodeMdx(filePath) {
49704
- const raw = (0, import_node_fs2.readFileSync)(filePath, "utf8");
50013
+ const raw = (0, import_node_fs3.readFileSync)(filePath, "utf8");
49705
50014
  const { frontmatter, body } = parseFrontmatter(raw, filePath);
49706
50015
  return {
49707
50016
  id: assertString(frontmatter, "id", filePath),
@@ -49799,25 +50108,25 @@ function generateKnowledgeNodesTs(options) {
49799
50108
  }
49800
50109
  function generateKnowledgeNodes(options) {
49801
50110
  const files = listMdxFiles(options.sourceDir).sort(
49802
- (a, b) => (0, import_node_path2.relative)(options.sourceDir, a).localeCompare((0, import_node_path2.relative)(options.sourceDir, b))
50111
+ (a, b) => (0, import_node_path4.relative)(options.sourceDir, a).localeCompare((0, import_node_path4.relative)(options.sourceDir, b))
49803
50112
  );
49804
50113
  const nodes = files.map((file2) => {
49805
- const relativePath = (0, import_node_path2.relative)(options.sourceDir, file2);
50114
+ const relativePath = (0, import_node_path4.relative)(options.sourceDir, file2);
49806
50115
  return {
49807
50116
  ...readKnowledgeNodeMdx(file2),
49808
50117
  sourceFilePath: toSourceFilePath(options.sourceLabel, relativePath)
49809
50118
  };
49810
50119
  });
49811
50120
  const sourcePaths = Object.fromEntries(
49812
- files.map((file2, index) => [nodes[index].id, toRegistryPath((0, import_node_path2.relative)(options.sourceDir, file2))])
50121
+ files.map((file2, index) => [nodes[index].id, toRegistryPath((0, import_node_path4.relative)(options.sourceDir, file2))])
49813
50122
  );
49814
50123
  const ids = /* @__PURE__ */ new Set();
49815
50124
  for (const node of nodes) {
49816
50125
  if (ids.has(node.id)) throw new Error(`[knowledge-node-codegen] Duplicate knowledge node id: ${node.id}`);
49817
50126
  ids.add(node.id);
49818
50127
  }
49819
- (0, import_node_fs2.mkdirSync)((0, import_node_path2.dirname)(options.outputPath), { recursive: true });
49820
- (0, import_node_fs2.writeFileSync)(
50128
+ (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(options.outputPath), { recursive: true });
50129
+ (0, import_node_fs3.writeFileSync)(
49821
50130
  options.outputPath,
49822
50131
  generateKnowledgeNodesTs({
49823
50132
  nodes,
@@ -49828,8 +50137,8 @@ function generateKnowledgeNodes(options) {
49828
50137
  "utf8"
49829
50138
  );
49830
50139
  if (options.knowledgeFlagsOutputPath) {
49831
- (0, import_node_fs2.mkdirSync)((0, import_node_path2.dirname)(options.knowledgeFlagsOutputPath), { recursive: true });
49832
- (0, import_node_fs2.writeFileSync)(
50140
+ (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(options.knowledgeFlagsOutputPath), { recursive: true });
50141
+ (0, import_node_fs3.writeFileSync)(
49833
50142
  options.knowledgeFlagsOutputPath,
49834
50143
  `${JSON.stringify(
49835
50144
  generateKnowledgeFlagRegistry(nodes, sourcePaths, {
@@ -49861,13 +50170,13 @@ function registerKnowledgeGenerate(program3) {
49861
50170
  ).action(
49862
50171
  wrapAction("knowledge:generate", async (options) => {
49863
50172
  const projectRoot = getProjectRoot();
49864
- const sourceDir = (0, import_node_path3.resolve)(projectRoot, options.source ?? "core/config/knowledge/nodes");
49865
- const outputPath = (0, import_node_path3.resolve)(projectRoot, options.output ?? "core/config/knowledge/_generated/nodes.ts");
49866
- const knowledgeFlagsOutputPath = (0, import_node_path3.resolve)(
50173
+ const sourceDir = (0, import_node_path5.resolve)(projectRoot, options.source ?? "core/config/knowledge/nodes");
50174
+ const outputPath = (0, import_node_path5.resolve)(projectRoot, options.output ?? "core/config/knowledge/_generated/nodes.ts");
50175
+ const knowledgeFlagsOutputPath = (0, import_node_path5.resolve)(
49867
50176
  projectRoot,
49868
50177
  options.flagsOutput ?? ".claude/registries/knowledge-flags.json"
49869
50178
  );
49870
- if (!(0, import_node_fs3.existsSync)(sourceDir)) {
50179
+ if (!(0, import_node_fs4.existsSync)(sourceDir)) {
49871
50180
  process.stderr.write(`knowledge:generate: source directory not found: ${sourceDir}
49872
50181
  `);
49873
50182
  process.exitCode = 1;
@@ -49979,8 +50288,8 @@ function registerKnowledgeCommands(program3) {
49979
50288
  }
49980
50289
 
49981
50290
  // src/cli/commands/request/request.ts
49982
- var import_node_fs4 = require("node:fs");
49983
- var import_node_path4 = require("node:path");
50291
+ var import_node_fs5 = require("node:fs");
50292
+ var import_node_path6 = require("node:path");
49984
50293
  init_source();
49985
50294
  init_config();
49986
50295
 
@@ -50044,7 +50353,7 @@ function registerRequestCommands(program3) {
50044
50353
  throw new Error("Provide --input <json> or --input-file <path>");
50045
50354
  }
50046
50355
  const resolvedInputFile = options.inputFile ? resolveProjectRelative(options.inputFile) : void 0;
50047
- const raw = resolvedInputFile ? JSON.parse((0, import_node_fs4.readFileSync)(resolvedInputFile, "utf8")) : JSON.parse(options.input);
50356
+ const raw = resolvedInputFile ? JSON.parse((0, import_node_fs5.readFileSync)(resolvedInputFile, "utf8")) : JSON.parse(options.input);
50048
50357
  const parsed = CreateRequestInputSchema.safeParse(raw);
50049
50358
  if (!parsed.success) {
50050
50359
  const issues = parsed.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
@@ -50065,10 +50374,10 @@ ${issues}`);
50065
50374
  console.log(JSON.stringify(result, null, 2));
50066
50375
  }
50067
50376
  if (options.cleanupInput && resolvedInputFile) {
50068
- const tmpDir = (0, import_node_path4.join)(getProjectRoot(), "tmp");
50377
+ const tmpDir = (0, import_node_path6.join)(getProjectRoot(), "tmp");
50069
50378
  if (resolvedInputFile.startsWith(tmpDir + "/") || resolvedInputFile.startsWith(tmpDir + "\\")) {
50070
50379
  try {
50071
- (0, import_node_fs4.unlinkSync)(resolvedInputFile);
50380
+ (0, import_node_fs5.unlinkSync)(resolvedInputFile);
50072
50381
  } catch {
50073
50382
  }
50074
50383
  } else {
@@ -50137,8 +50446,8 @@ ${rows.length} request${rows.length === 1 ? "" : "s"}`));
50137
50446
 
50138
50447
  // src/cli/commands/ui/ui-switcher.ts
50139
50448
  var import_node_child_process = require("node:child_process");
50140
- var import_node_fs5 = __toESM(require("node:fs"), 1);
50141
- var import_node_path5 = __toESM(require("node:path"), 1);
50449
+ var import_node_fs6 = __toESM(require("node:fs"), 1);
50450
+ var import_node_path7 = __toESM(require("node:path"), 1);
50142
50451
  init_config();
50143
50452
  function run(command, args, cwd) {
50144
50453
  (0, import_node_child_process.execFileSync)(command, args, {
@@ -50148,10 +50457,10 @@ function run(command, args, cwd) {
50148
50457
  });
50149
50458
  }
50150
50459
  function readJson(filePath) {
50151
- return JSON.parse(import_node_fs5.default.readFileSync(filePath, "utf8"));
50460
+ return JSON.parse(import_node_fs6.default.readFileSync(filePath, "utf8"));
50152
50461
  }
50153
50462
  function writeJson(filePath, value) {
50154
- import_node_fs5.default.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
50463
+ import_node_fs6.default.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
50155
50464
  `);
50156
50465
  }
50157
50466
  function requireDependencies(packageJson, filePath) {
@@ -50161,8 +50470,8 @@ function requireDependencies(packageJson, filePath) {
50161
50470
  return packageJson.dependencies;
50162
50471
  }
50163
50472
  function resolveExistingDir(label, dir) {
50164
- const resolved = import_node_path5.default.resolve(dir);
50165
- if (!import_node_fs5.default.existsSync(resolved) || !import_node_fs5.default.statSync(resolved).isDirectory()) {
50473
+ const resolved = import_node_path7.default.resolve(dir);
50474
+ if (!import_node_fs6.default.existsSync(resolved) || !import_node_fs6.default.statSync(resolved).isDirectory()) {
50166
50475
  throw new Error(`${label} not found: ${resolved}`);
50167
50476
  }
50168
50477
  return resolved;
@@ -50170,8 +50479,8 @@ function resolveExistingDir(label, dir) {
50170
50479
  function findRepoRootFromProject(projectRoot) {
50171
50480
  let dir = projectRoot;
50172
50481
  while (true) {
50173
- if (import_node_fs5.default.existsSync(import_node_path5.default.join(dir, "packages", "ui", "package.json"))) return dir;
50174
- const parent = import_node_path5.default.dirname(dir);
50482
+ if (import_node_fs6.default.existsSync(import_node_path7.default.join(dir, "packages", "ui", "package.json"))) return dir;
50483
+ const parent = import_node_path7.default.dirname(dir);
50175
50484
  if (parent === dir) return null;
50176
50485
  dir = parent;
50177
50486
  }
@@ -50184,13 +50493,13 @@ function resolveUiPackageRoot(projectRoot, explicitRoot) {
50184
50493
  "Could not find packages/ui from this Elevasis project. Pass --ui-package-root <path> from a monorepo checkout."
50185
50494
  );
50186
50495
  }
50187
- return import_node_path5.default.join(repoRoot, "packages", "ui");
50496
+ return import_node_path7.default.join(repoRoot, "packages", "ui");
50188
50497
  }
50189
50498
  function removeLocalUiTarballs(templateTmpDir) {
50190
- if (!import_node_fs5.default.existsSync(templateTmpDir)) return;
50191
- for (const entry of import_node_fs5.default.readdirSync(templateTmpDir)) {
50499
+ if (!import_node_fs6.default.existsSync(templateTmpDir)) return;
50500
+ for (const entry of import_node_fs6.default.readdirSync(templateTmpDir)) {
50192
50501
  if (entry.startsWith("elevasis-ui-") && entry.endsWith(".tgz")) {
50193
- import_node_fs5.default.rmSync(import_node_path5.default.join(templateTmpDir, entry), { force: true });
50502
+ import_node_fs6.default.rmSync(import_node_path7.default.join(templateTmpDir, entry), { force: true });
50194
50503
  }
50195
50504
  }
50196
50505
  }
@@ -50210,29 +50519,29 @@ function useLocalUi(options = {}) {
50210
50519
  const projectRoot = getProjectRoot();
50211
50520
  const repoRoot = findRepoRootFromProject(projectRoot);
50212
50521
  const uiPackageRoot = resolveUiPackageRoot(projectRoot, options.uiPackageRoot);
50213
- const commandRoot = repoRoot ?? import_node_path5.default.dirname(import_node_path5.default.dirname(uiPackageRoot));
50214
- const templateUiPackageJsonPath = import_node_path5.default.join(projectRoot, "ui", "package.json");
50215
- const templateTmpDir = import_node_path5.default.join(projectRoot, "tmp");
50216
- const uiPackageJsonPath = import_node_path5.default.join(uiPackageRoot, "package.json");
50217
- const uiPackageBackupPath = import_node_path5.default.join(uiPackageRoot, "package.json.local-pack.bak");
50218
- if (!import_node_fs5.default.existsSync(templateUiPackageJsonPath)) {
50522
+ const commandRoot = repoRoot ?? import_node_path7.default.dirname(import_node_path7.default.dirname(uiPackageRoot));
50523
+ const templateUiPackageJsonPath = import_node_path7.default.join(projectRoot, "ui", "package.json");
50524
+ const templateTmpDir = import_node_path7.default.join(projectRoot, "tmp");
50525
+ const uiPackageJsonPath = import_node_path7.default.join(uiPackageRoot, "package.json");
50526
+ const uiPackageBackupPath = import_node_path7.default.join(uiPackageRoot, "package.json.local-pack.bak");
50527
+ if (!import_node_fs6.default.existsSync(templateUiPackageJsonPath)) {
50219
50528
  throw new Error(`Template UI package.json not found: ${templateUiPackageJsonPath}`);
50220
50529
  }
50221
- import_node_fs5.default.mkdirSync(templateTmpDir, { recursive: true });
50530
+ import_node_fs6.default.mkdirSync(templateTmpDir, { recursive: true });
50222
50531
  removeLocalUiTarballs(templateTmpDir);
50223
50532
  run("pnpm", ["--filter", "@repo/ui", "build:publish"], commandRoot);
50224
50533
  try {
50225
- const raw = import_node_fs5.default.readFileSync(uiPackageJsonPath, "utf8");
50226
- import_node_fs5.default.writeFileSync(uiPackageBackupPath, raw);
50534
+ const raw = import_node_fs6.default.readFileSync(uiPackageJsonPath, "utf8");
50535
+ import_node_fs6.default.writeFileSync(uiPackageBackupPath, raw);
50227
50536
  writeJson(uiPackageJsonPath, prepareUiPackageForPack(JSON.parse(raw)));
50228
50537
  run("pnpm", ["-C", uiPackageRoot, "pack", "--pack-destination", templateTmpDir], commandRoot);
50229
50538
  } finally {
50230
- if (import_node_fs5.default.existsSync(uiPackageBackupPath)) {
50231
- import_node_fs5.default.copyFileSync(uiPackageBackupPath, uiPackageJsonPath);
50232
- import_node_fs5.default.rmSync(uiPackageBackupPath, { force: true });
50539
+ if (import_node_fs6.default.existsSync(uiPackageBackupPath)) {
50540
+ import_node_fs6.default.copyFileSync(uiPackageBackupPath, uiPackageJsonPath);
50541
+ import_node_fs6.default.rmSync(uiPackageBackupPath, { force: true });
50233
50542
  }
50234
50543
  }
50235
- const tarballName = import_node_fs5.default.readdirSync(templateTmpDir).find((entry) => entry.startsWith("elevasis-ui-") && entry.endsWith(".tgz"));
50544
+ const tarballName = import_node_fs6.default.readdirSync(templateTmpDir).find((entry) => entry.startsWith("elevasis-ui-") && entry.endsWith(".tgz"));
50236
50545
  if (!tarballName) {
50237
50546
  throw new Error(`Failed to create local @elevasis/ui tarball in ${templateTmpDir}`);
50238
50547
  }
@@ -50240,20 +50549,20 @@ function useLocalUi(options = {}) {
50240
50549
  requireDependencies(templateUiPackageJson, templateUiPackageJsonPath)["@elevasis/ui"] = `file:../tmp/${tarballName}`;
50241
50550
  writeJson(templateUiPackageJsonPath, templateUiPackageJson);
50242
50551
  run("pnpm", ["-C", projectRoot, "install"], commandRoot);
50243
- console.log(`${import_node_path5.default.basename(projectRoot)}/ui now uses local @elevasis/ui tarball: ${tarballName}`);
50552
+ console.log(`${import_node_path7.default.basename(projectRoot)}/ui now uses local @elevasis/ui tarball: ${tarballName}`);
50244
50553
  }
50245
50554
  function usePublishedUi(options = {}) {
50246
50555
  const projectRoot = getProjectRoot();
50247
50556
  const repoRoot = findRepoRootFromProject(projectRoot);
50248
50557
  const commandRoot = repoRoot ?? projectRoot;
50249
- const templateUiPackageJsonPath = import_node_path5.default.join(projectRoot, "ui", "package.json");
50250
- const templateTmpDir = import_node_path5.default.join(projectRoot, "tmp");
50558
+ const templateUiPackageJsonPath = import_node_path7.default.join(projectRoot, "ui", "package.json");
50559
+ const templateTmpDir = import_node_path7.default.join(projectRoot, "tmp");
50251
50560
  const uiPackageRoot = options.version ? void 0 : resolveUiPackageRoot(projectRoot, options.uiPackageRoot);
50252
- const uiVersion = options.version ?? readJson(import_node_path5.default.join(uiPackageRoot, "package.json")).version;
50561
+ const uiVersion = options.version ?? readJson(import_node_path7.default.join(uiPackageRoot, "package.json")).version;
50253
50562
  if (!uiVersion) {
50254
50563
  throw new Error("Could not determine @elevasis/ui version. Pass --version <version>.");
50255
50564
  }
50256
- if (!import_node_fs5.default.existsSync(templateUiPackageJsonPath)) {
50565
+ if (!import_node_fs6.default.existsSync(templateUiPackageJsonPath)) {
50257
50566
  throw new Error(`Template UI package.json not found: ${templateUiPackageJsonPath}`);
50258
50567
  }
50259
50568
  const templateUiPackageJson = readJson(templateUiPackageJsonPath);
@@ -50261,7 +50570,7 @@ function usePublishedUi(options = {}) {
50261
50570
  writeJson(templateUiPackageJsonPath, templateUiPackageJson);
50262
50571
  removeLocalUiTarballs(templateTmpDir);
50263
50572
  run("pnpm", ["-C", projectRoot, "install"], commandRoot);
50264
- console.log(`${import_node_path5.default.basename(projectRoot)}/ui restored to published @elevasis/ui ^${uiVersion}`);
50573
+ console.log(`${import_node_path7.default.basename(projectRoot)}/ui restored to published @elevasis/ui ^${uiVersion}`);
50265
50574
  }
50266
50575
 
50267
50576
  // src/cli/commands/ui/ui.ts
@@ -50279,8 +50588,8 @@ function registerUiCommands(program3) {
50279
50588
  }
50280
50589
 
50281
50590
  // src/cli/commands/doctor.ts
50282
- var import_node_fs6 = require("node:fs");
50283
- var import_node_path6 = __toESM(require("node:path"), 1);
50591
+ var import_node_fs7 = require("node:fs");
50592
+ var import_node_path8 = __toESM(require("node:path"), 1);
50284
50593
  init_source();
50285
50594
  init_config();
50286
50595
  function ok(label, detail) {
@@ -50318,8 +50627,8 @@ function registerDoctorCommand(program3) {
50318
50627
  printSummary(failCount);
50319
50628
  process.exit(1);
50320
50629
  }
50321
- const envPath2 = import_node_path6.default.join(projectRoot, ".env");
50322
- const envExists = (0, import_node_fs6.existsSync)(envPath2);
50630
+ const envPath2 = import_node_path8.default.join(projectRoot, ".env");
50631
+ const envExists = (0, import_node_fs7.existsSync)(envPath2);
50323
50632
  if (!envExists) {
50324
50633
  fail(".env", `Not found at ${envPath2}. Create it from .env.example and fill in ELEVASIS_PLATFORM_KEY.`);
50325
50634
  if (isVerbose) verbose(`Checked: ${envPath2}`);
@@ -50406,101 +50715,6 @@ function printSummary(failCount) {
50406
50715
  }
50407
50716
  }
50408
50717
 
50409
- // src/cli/commands/cli/catalog.ts
50410
- function buildCliCatalogFromProgram(program3, options = {}) {
50411
- const commands = program3.commands.flatMap((command) => collectRuntimeCommands(command));
50412
- return groupCommands(commands, "registered Commander commands", options.domain);
50413
- }
50414
- function groupCommands(commands, sourceRoot, domain2) {
50415
- const filtered = domain2 ? commands.filter((command) => command.domain === domain2) : commands;
50416
- const sorted = filtered.sort((a, b) => a.domain.localeCompare(b.domain) || a.syntax.localeCompare(b.syntax));
50417
- const domainNames = [...new Set(sorted.map((command) => command.domain))];
50418
- return {
50419
- sourceRoot,
50420
- domains: domainNames.map((name) => ({
50421
- name,
50422
- commands: sorted.filter((command) => command.domain === name)
50423
- }))
50424
- };
50425
- }
50426
- function collectRuntimeCommands(command, parent) {
50427
- const commandName = command.name();
50428
- const argSuffix = formatRuntimeArguments(command.registeredArguments);
50429
- const syntaxSegment = argSuffix ? `${commandName} ${argSuffix}` : commandName;
50430
- const syntax = parent ? `${parent.syntax} ${syntaxSegment}` : syntaxSegment;
50431
- const domain2 = parent?.domain ?? domainFromCommand(commandName);
50432
- const current = {
50433
- command: commandName,
50434
- syntax,
50435
- domain: domain2
50436
- };
50437
- const aliases = command.aliases().map((alias) => parent ? `${parent.syntax} ${alias}` : alias);
50438
- return [
50439
- {
50440
- syntax,
50441
- command: commandName,
50442
- domain: domain2,
50443
- description: firstLine(command.description()),
50444
- aliases,
50445
- options: command.options.map((option) => ({
50446
- flags: option.flags,
50447
- description: option.description,
50448
- required: option.mandatory
50449
- })),
50450
- source: "runtime"
50451
- },
50452
- ...command.commands.flatMap((child) => collectRuntimeCommands(child, current))
50453
- ];
50454
- }
50455
- function formatRuntimeArguments(args) {
50456
- return args.map((arg) => {
50457
- const name = `${arg.name()}${arg.variadic ? "..." : ""}`;
50458
- return arg.required ? `<${name}>` : `[${name}]`;
50459
- }).join(" ");
50460
- }
50461
- function renderCliCatalogMarkdown(catalog) {
50462
- const lines = [
50463
- "# elevasis-sdk CLI Catalog",
50464
- "",
50465
- `Source: \`${catalog.sourceRoot}\``,
50466
- ""
50467
- ];
50468
- if (catalog.domains.length === 0) {
50469
- lines.push("No commands found.");
50470
- return lines.join("\n");
50471
- }
50472
- for (const domain2 of catalog.domains) {
50473
- lines.push(`## ${domain2.name}`, "");
50474
- lines.push("| Command | Description | Aliases | Options | Source |");
50475
- lines.push("| --- | --- | --- | --- | --- |");
50476
- for (const command of domain2.commands) {
50477
- const aliases = command.aliases.length > 0 ? command.aliases.map((alias) => `\`${alias}\``).join(", ") : "-";
50478
- const options = command.options.length > 0 ? command.options.map((option) => `${option.required ? "required " : ""}\`${option.flags}\``).join("<br>") : "-";
50479
- lines.push(
50480
- `| \`elevasis-sdk ${command.syntax}\` | ${escapeMarkdownTable(command.description || "-")} | ${aliases} | ${options} | \`${command.source}\` |`
50481
- );
50482
- }
50483
- lines.push("");
50484
- }
50485
- return lines.join("\n").trimEnd();
50486
- }
50487
- function renderCliCatalogJson(catalog) {
50488
- return JSON.stringify(catalog, null, 2);
50489
- }
50490
- function domainFromCommand(command) {
50491
- if (command.includes(":")) return command.split(":")[0];
50492
- return "platform";
50493
- }
50494
- function firstLine(value) {
50495
- return value.split("\n")[0]?.trim() ?? "";
50496
- }
50497
- function escapeMarkdownTable(value) {
50498
- return value.replace(/\|/g, "\\|").replace(/\r?\n/g, "<br>");
50499
- }
50500
- function knownDomains(catalog) {
50501
- return catalog.domains.map((domain2) => domain2.name);
50502
- }
50503
-
50504
50718
  // src/cli/commands/cli/cli.ts
50505
50719
  var FORMATS = /* @__PURE__ */ new Set(["markdown", "json"]);
50506
50720
  function registerCliCatalogCommand(program3) {
@@ -50755,13 +50969,14 @@ function registerAcquisitionCommands(program3) {
50755
50969
  init_source();
50756
50970
  init_config();
50757
50971
  function registerClientCreate(program3) {
50758
- program3.command("client:create").description('Create a new client\n Example: elevasis-sdk client:create --name "Acme Corp"').requiredOption("--name <name>", "Client name").option("--status <status>", "Client status: active | onboarding | paused | completed | churned").option("--source-deal-id <uuid>", "UUID of the source deal").option("--primary-company-id <uuid>", "UUID of the primary company").option("--primary-contact-id <uuid>", "UUID of the primary contact").option("--metadata <json>", "Arbitrary metadata (JSON string)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
50972
+ program3.command("client:create").description('Create a new client\n Example: elevasis-sdk client:create --name "Acme Corp"').requiredOption("--name <name>", "Client name").option("--status <status>", "Client status: active | onboarding | paused | completed | churned").option("--source <source>", "Client source (for example: acquisition | word_of_mouth)").option("--source-deal-id <uuid>", "UUID of the source deal").option("--primary-company-id <uuid>", "UUID of the primary company").option("--primary-contact-id <uuid>", "UUID of the primary contact").option("--metadata <json>", "Arbitrary metadata (JSON string)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
50759
50973
  wrapAction(
50760
50974
  "client:create",
50761
50975
  async (options) => {
50762
50976
  const apiUrl = resolveApiUrl(options.apiUrl);
50763
50977
  const body = { name: options.name };
50764
50978
  if (options.status !== void 0) body.status = options.status;
50979
+ if (options.source !== void 0) body.source = options.source;
50765
50980
  if (options.sourceDealId !== void 0) body.sourceDealId = options.sourceDealId;
50766
50981
  if (options.primaryCompanyId !== void 0) body.primaryCompanyId = options.primaryCompanyId;
50767
50982
  if (options.primaryContactId !== void 0) body.primaryContactId = options.primaryContactId;
@@ -50781,7 +50996,7 @@ Client created: ${result.name}`));
50781
50996
  );
50782
50997
  }
50783
50998
  function registerClientUpdate(program3) {
50784
- program3.command("client:update <id>").description("Update a client\n Example: elevasis-sdk client:update <uuid> --status active").option("--name <name>", "New client name").option("--status <status>", "New status: active | onboarding | paused | completed | churned").option("--source-deal-id <uuid>", "Set source deal (UUID)").option("--clear-source-deal", "Remove the source deal link (sets sourceDealId to null)").option("--primary-company-id <uuid>", "Set primary company (UUID)").option("--clear-primary-company", "Remove the primary company link (sets primaryCompanyId to null)").option("--primary-contact-id <uuid>", "Set primary contact (UUID)").option("--clear-primary-contact", "Remove the primary contact link (sets primaryContactId to null)").option("--metadata <json>", "Arbitrary metadata (JSON string)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
50999
+ program3.command("client:update <id>").description("Update a client\n Example: elevasis-sdk client:update <uuid> --status active").option("--name <name>", "New client name").option("--status <status>", "New status: active | onboarding | paused | completed | churned").option("--source <source>", "Set client source (for example: acquisition | word_of_mouth)").option("--source-deal-id <uuid>", "Set source deal (UUID)").option("--clear-source-deal", "Remove the source deal link (sets sourceDealId to null)").option("--primary-company-id <uuid>", "Set primary company (UUID)").option("--clear-primary-company", "Remove the primary company link (sets primaryCompanyId to null)").option("--primary-contact-id <uuid>", "Set primary contact (UUID)").option("--clear-primary-contact", "Remove the primary contact link (sets primaryContactId to null)").option("--metadata <json>", "Arbitrary metadata (JSON string)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
50785
51000
  wrapAction(
50786
51001
  "client:update",
50787
51002
  async (id, options) => {
@@ -50816,6 +51031,7 @@ function registerClientUpdate(program3) {
50816
51031
  const body = {};
50817
51032
  if (options.name !== void 0) body.name = options.name;
50818
51033
  if (options.status !== void 0) body.status = options.status;
51034
+ if (options.source !== void 0) body.source = options.source;
50819
51035
  if (options.clearSourceDeal) {
50820
51036
  body.sourceDealId = null;
50821
51037
  } else if (options.sourceDealId !== void 0) {
@@ -50835,7 +51051,7 @@ function registerClientUpdate(program3) {
50835
51051
  if (Object.keys(body).length === 0) {
50836
51052
  process.stderr.write(
50837
51053
  JSON.stringify({
50838
- error: "At least one field must be provided (--name, --status, --source-deal-id, --clear-source-deal, --primary-company-id, --clear-primary-company, --primary-contact-id, --clear-primary-contact, --metadata)",
51054
+ error: "At least one field must be provided (--name, --status, --source, --source-deal-id, --clear-source-deal, --primary-company-id, --clear-primary-company, --primary-contact-id, --clear-primary-contact, --metadata)",
50839
51055
  code: "MISSING_FIELDS"
50840
51056
  }) + "\n"
50841
51057
  );
@@ -51552,10 +51768,93 @@ function registerOmScaffoldCommands(program3) {
51552
51768
  });
51553
51769
  }
51554
51770
 
51771
+ // src/cli/commands/skill/skill-scaffold.ts
51772
+ init_source();
51773
+ function buildSkillMd(domain2) {
51774
+ const name = domain2.name;
51775
+ const commandNames = domain2.commands.map((c) => c.command.replace(`${name}:`, ""));
51776
+ const argumentHint = `[${commandNames.join(" | ")}] [args]`;
51777
+ const descriptionText = `${name} domain operations \u2014 ${commandNames.join(", ")} \u2014 via the elevasis-sdk ${name}:* CLI.`;
51778
+ const lines = [
51779
+ "---",
51780
+ `name: ${name}`,
51781
+ `description: "${descriptionText}"`,
51782
+ `argument-hint: "${argumentHint}"`,
51783
+ `allowed-tools: Bash, Read, Write, Edit, Glob, Grep`,
51784
+ "---",
51785
+ "",
51786
+ `# ${name.charAt(0).toUpperCase() + name.slice(1)} Skill`,
51787
+ "",
51788
+ `> **Generated stub.** Curate the prose below: add vibe integration, confirm ceremony,`,
51789
+ `> and any operation-level detail. The usage table is pre-filled from the CLI catalog.`,
51790
+ "",
51791
+ "## Usage",
51792
+ "",
51793
+ "| Command | Description | Options |",
51794
+ "| --- | --- | --- |"
51795
+ ];
51796
+ for (const cmd of domain2.commands) {
51797
+ const syntax = `\`elevasis-sdk ${cmd.syntax}\``;
51798
+ const description = cmd.description || "-";
51799
+ const options = cmd.options.length > 0 ? cmd.options.map((o) => `${o.required ? "required " : ""}\`${o.flags}\``).join(", ") : "-";
51800
+ lines.push(`| ${syntax} | ${description} | ${options} |`);
51801
+ }
51802
+ lines.push("");
51803
+ const commandsWithAliases = domain2.commands.filter((c) => c.aliases.length > 0);
51804
+ if (commandsWithAliases.length > 0) {
51805
+ lines.push("## Aliases", "");
51806
+ for (const cmd of commandsWithAliases) {
51807
+ for (const alias of cmd.aliases) {
51808
+ lines.push(`- \`elevasis-sdk ${alias}\` \u2192 \`elevasis-sdk ${cmd.syntax}\``);
51809
+ }
51810
+ }
51811
+ lines.push("");
51812
+ }
51813
+ lines.push(
51814
+ "## Connection",
51815
+ "",
51816
+ "```bash",
51817
+ "# .env (project root)",
51818
+ "ELEVASIS_PLATFORM_KEY=sk_...",
51819
+ "```",
51820
+ "",
51821
+ "```bash",
51822
+ `pnpm elevasis-sdk ${name}:<command> [args]`,
51823
+ "```",
51824
+ ""
51825
+ );
51826
+ return lines.join("\n");
51827
+ }
51828
+ function registerSkillScaffoldCommand(program3) {
51829
+ program3.command("skill:scaffold <domain>").description(
51830
+ "Emit a SKILL.md stub for a CLI domain from the catalog\n Example: elevasis-sdk skill:scaffold client"
51831
+ ).option("--output", "Write the stub to stdout only (default behavior)").action(
51832
+ wrapAction("skill:scaffold", async (domain2) => {
51833
+ const catalog = buildCliCatalogFromProgram(program3, { domain: domain2 });
51834
+ if (catalog.domains.length === 0) {
51835
+ const fullCatalog = buildCliCatalogFromProgram(program3);
51836
+ const known = knownDomains(fullCatalog);
51837
+ throw new Error(`No CLI domain "${domain2}" found. Known domains: ${known.join(", ")}`);
51838
+ }
51839
+ const domainEntry = catalog.domains[0];
51840
+ const stub = buildSkillMd(domainEntry);
51841
+ console.log(
51842
+ source_default.gray(
51843
+ `# SKILL.md stub for domain "${domain2}" (${domainEntry.commands.length} commands)
51844
+ # Copy this to: external/_template/.claude/skills/${domain2}/SKILL.md
51845
+ # Then curate: add vibe integration, confirm ceremony, and operation prose.
51846
+ `
51847
+ )
51848
+ );
51849
+ console.log(stub);
51850
+ })
51851
+ );
51852
+ }
51853
+
51555
51854
  // src/cli/index.ts
51556
51855
  init_config();
51557
51856
  var PREFLIGHT_SKIP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h", "--version", "-V"]);
51558
- var PREFLIGHT_SKIP_COMMANDS = /* @__PURE__ */ new Set(["cli"]);
51857
+ var PREFLIGHT_SKIP_COMMANDS = /* @__PURE__ */ new Set(["cli", "skill:scaffold"]);
51559
51858
  var LOCAL_PROJECT_COMMANDS = /* @__PURE__ */ new Set([
51560
51859
  "ui:use-local",
51561
51860
  "ui:use-published",
@@ -51685,6 +51984,8 @@ registerUiCommands(program2);
51685
51984
  registerDoctorCommand(program2);
51686
51985
  registerCliCatalogCommand(program2);
51687
51986
  registerOmScaffoldCommands(program2);
51987
+ registerSkillScaffoldCommand(program2);
51988
+ registerSkillCheckCoverageCommand(program2);
51688
51989
  program2.parse();
51689
51990
  // Annotate the CommonJS export names for ESM import in node:
51690
51991
  0 && (module.exports = {