@elevasis/sdk 1.19.0 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/cli.cjs +1718 -72
  2. package/dist/index.d.ts +661 -7
  3. package/dist/index.js +565 -42
  4. package/dist/node/index.d.ts +2 -0
  5. package/dist/node/index.js +219 -2
  6. package/dist/test-utils/index.d.ts +459 -4
  7. package/dist/test-utils/index.js +509 -37
  8. package/dist/types/worker/platform.d.ts +15 -1
  9. package/dist/worker/index.js +365 -37
  10. package/package.json +2 -2
  11. package/reference/_navigation.md +2 -1
  12. package/reference/_reference-manifest.json +14 -0
  13. package/reference/claude-config/registries/knowledge-flags.json +156 -0
  14. package/reference/claude-config/rules/agent-start-here.md +5 -5
  15. package/reference/claude-config/rules/deployment.md +4 -3
  16. package/reference/claude-config/rules/frontend.md +2 -2
  17. package/reference/claude-config/rules/operations.md +17 -13
  18. package/reference/claude-config/rules/organization-model.md +7 -5
  19. package/reference/claude-config/rules/organization-os.md +13 -11
  20. package/reference/claude-config/rules/ui.md +3 -3
  21. package/reference/claude-config/rules/vibe.md +4 -4
  22. package/reference/claude-config/skills/explore/SKILL.md +4 -4
  23. package/reference/claude-config/skills/knowledge/SKILL.md +8 -8
  24. package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +7 -7
  25. package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +13 -13
  26. package/reference/claude-config/skills/knowledge/operations/customers.md +1 -1
  27. package/reference/claude-config/skills/knowledge/operations/goals.md +1 -1
  28. package/reference/claude-config/skills/knowledge/operations/identity.md +1 -1
  29. package/reference/claude-config/skills/knowledge/operations/offerings.md +1 -1
  30. package/reference/claude-config/skills/knowledge/operations/roles.md +1 -1
  31. package/reference/claude-config/skills/knowledge/operations/techStack.md +19 -91
  32. package/reference/claude-config/skills/project/SKILL.md +73 -13
  33. package/reference/claude-config/skills/save/SKILL.md +5 -5
  34. package/reference/claude-config/skills/tutorial/technical.md +5 -6
  35. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -0
  36. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -0
  37. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -0
  38. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -0
  39. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -0
  40. package/reference/examples/organization-model.ts +17 -5
  41. package/reference/framework/index.mdx +1 -1
  42. package/reference/framework/project-structure.mdx +10 -8
  43. package/reference/packages/core/src/business/README.md +2 -2
  44. package/reference/packages/core/src/organization-model/README.md +10 -3
  45. package/reference/resources/index.mdx +27 -17
  46. package/reference/scaffold/core/organization-model.mdx +33 -14
  47. package/reference/scaffold/operations/workflow-recipes.md +35 -29
  48. package/reference/scaffold/recipes/add-a-feature.md +18 -3
  49. package/reference/scaffold/recipes/add-a-resource.md +50 -10
  50. package/reference/scaffold/recipes/customize-crm-actions.md +12 -6
  51. package/reference/scaffold/recipes/customize-organization-model.md +18 -3
  52. package/reference/scaffold/recipes/extend-crm.md +17 -19
  53. package/reference/scaffold/recipes/extend-lead-gen.md +31 -31
  54. package/reference/scaffold/recipes/index.md +1 -1
  55. package/reference/scaffold/reference/contracts.md +501 -303
  56. package/reference/scaffold/reference/feature-registry.md +1 -1
  57. package/reference/scaffold/reference/glossary.md +8 -3
  58. package/reference/scaffold/ui/recipes.md +21 -6
@@ -18,6 +18,8 @@ interface GenerateKnowledgeNodesOptions {
18
18
  sourceDir: string;
19
19
  outputPath: string;
20
20
  graphSkillsOutputPath?: string;
21
+ knowledgeFlagsOutputPath?: string;
22
+ knowledgeFlagsCliCommand?: string;
21
23
  typeImportPath?: string;
22
24
  exportedName?: string;
23
25
  sourceLabel?: string;
@@ -68,6 +68,132 @@ function optionalStringArray(frontmatter, key, filePath) {
68
68
  }
69
69
  return value.map((entry) => entry.trim()).filter(Boolean);
70
70
  }
71
+ var ROUTING_STOPWORDS = /* @__PURE__ */ new Set([
72
+ "about",
73
+ "after",
74
+ "again",
75
+ "against",
76
+ "all",
77
+ "also",
78
+ "and",
79
+ "any",
80
+ "are",
81
+ "before",
82
+ "but",
83
+ "can",
84
+ "cannot",
85
+ "could",
86
+ "for",
87
+ "from",
88
+ "has",
89
+ "have",
90
+ "how",
91
+ "into",
92
+ "its",
93
+ "may",
94
+ "more",
95
+ "must",
96
+ "not",
97
+ "now",
98
+ "off",
99
+ "one",
100
+ "only",
101
+ "our",
102
+ "out",
103
+ "over",
104
+ "per",
105
+ "run",
106
+ "same",
107
+ "should",
108
+ "than",
109
+ "that",
110
+ "the",
111
+ "their",
112
+ "then",
113
+ "there",
114
+ "this",
115
+ "through",
116
+ "use",
117
+ "uses",
118
+ "using",
119
+ "when",
120
+ "where",
121
+ "with",
122
+ "workflow",
123
+ "workflows",
124
+ "would",
125
+ "you",
126
+ "your"
127
+ ]);
128
+ function toRegistryPath(path) {
129
+ return path.replace(/\\/g, "/");
130
+ }
131
+ function slugify(value) {
132
+ return value.trim().toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
133
+ }
134
+ function toTitle(value) {
135
+ return value.split(/[-:\s]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
136
+ }
137
+ function tokenizeRoutingText(...values) {
138
+ return values.join(" ").toLowerCase().replace(/```[\s\S]*?```/g, " ").replace(/[\\/]/g, " ").match(/[a-z0-9]+(?:[.-][a-z0-9]+)*/g)?.flatMap((token) => {
139
+ const expanded = token.includes(".") ? [token, ...token.split(".")] : [token];
140
+ return expanded.flatMap((entry) => entry.includes("-") ? [entry, ...entry.split("-")] : [entry]);
141
+ }) ?? [];
142
+ }
143
+ function rankedTerms(values, limit) {
144
+ const counts = /* @__PURE__ */ new Map();
145
+ for (const value of values) {
146
+ const token = slugify(value);
147
+ if (!token || ROUTING_STOPWORDS.has(token)) continue;
148
+ if (token.length < 3 && token !== "ai") continue;
149
+ counts.set(token, (counts.get(token) ?? 0) + 1);
150
+ }
151
+ return [...counts.entries()].sort(([termA, countA], [termB, countB]) => countB - countA || termA.localeCompare(termB)).slice(0, limit).map(([term]) => term);
152
+ }
153
+ function uniqueSorted(values) {
154
+ return [...new Set(values.filter(Boolean))].sort((a, b) => a.localeCompare(b));
155
+ }
156
+ function nodeRoutingTerms(node, sourcePath, limit) {
157
+ return rankedTerms(
158
+ tokenizeRoutingText(
159
+ node.id,
160
+ node.kind,
161
+ node.title,
162
+ node.summary,
163
+ node.body,
164
+ node.domain ?? "",
165
+ sourcePath,
166
+ ...node.links.map((link) => link.nodeId),
167
+ ...node.skills
168
+ ),
169
+ limit
170
+ );
171
+ }
172
+ function nodeTags(node, sourcePath) {
173
+ return uniqueSorted([
174
+ ...node.domain ? [node.domain] : [],
175
+ node.kind,
176
+ ...tokenizeRoutingText(
177
+ node.title,
178
+ node.summary,
179
+ sourcePath,
180
+ ...node.links.map((link) => link.nodeId),
181
+ ...node.skills
182
+ ).map(slugify).filter((term) => term && !ROUTING_STOPWORDS.has(term) && (term.length >= 3 || term === "ai")).slice(0, 20)
183
+ ]);
184
+ }
185
+ function readCommandForNode(node, cliCommand = "elevasis") {
186
+ return [
187
+ {
188
+ command: `pnpm exec ${cliCommand} knowledge:cat ${node.id}`,
189
+ description: `Read ${node.title}`
190
+ },
191
+ {
192
+ command: `pnpm exec ${cliCommand} knowledge:ls /by-kind/${node.kind}`,
193
+ description: `List ${node.kind} knowledge nodes`
194
+ }
195
+ ];
196
+ }
71
197
  function readKnowledgeNodeMdx(filePath) {
72
198
  const raw = readFileSync(filePath, "utf8");
73
199
  const { frontmatter, body } = parseFrontmatter(raw, filePath);
@@ -108,6 +234,79 @@ function generateGraphSkillsRegistry(nodes) {
108
234
  domains: Object.fromEntries(Object.entries(domains).sort(([a], [b]) => a.localeCompare(b)))
109
235
  };
110
236
  }
237
+ function generateKnowledgeFlagRegistry(nodes, sourcePaths = {}, options = {}) {
238
+ const routes = /* @__PURE__ */ new Map();
239
+ for (const node of nodes) {
240
+ const routeKey = node.domain ?? `kind-${node.kind}`;
241
+ const flag = `--${slugify(routeKey)}`;
242
+ const sourcePath = toRegistryPath(sourcePaths[node.id] ?? "");
243
+ const routingTerms = nodeRoutingTerms(node, sourcePath, 24);
244
+ const tags = nodeTags(node, sourcePath);
245
+ const skills = uniqueSorted(node.skills);
246
+ const cliBindings = readCommandForNode(node, options.cliCommand);
247
+ const route = routes.get(flag) ?? {
248
+ flag,
249
+ label: toTitle(routeKey),
250
+ ...node.domain ? { domain: node.domain } : { kind: node.kind },
251
+ tags: [],
252
+ queryTerms: [],
253
+ skills: [],
254
+ cliBindings: [],
255
+ nodes: []
256
+ };
257
+ route.tags = uniqueSorted([...route.tags, ...tags]);
258
+ route.queryTerms = rankedTerms([...route.queryTerms, ...routingTerms], 40);
259
+ route.skills = uniqueSorted([...route.skills, ...skills]);
260
+ route.cliBindings = [...route.cliBindings, ...cliBindings].filter(
261
+ (binding, index, bindings) => bindings.findIndex((candidate) => candidate.command === binding.command) === index
262
+ );
263
+ route.nodes.push({
264
+ id: node.id,
265
+ title: node.title,
266
+ kind: node.kind,
267
+ ...node.domain ? { domain: node.domain } : {},
268
+ sourcePath,
269
+ tags,
270
+ routingTerms,
271
+ links: node.links.map((link) => link.nodeId),
272
+ skills,
273
+ cliBindings
274
+ });
275
+ routes.set(flag, route);
276
+ }
277
+ const sortedRoutes = [...routes.values()].sort((a, b) => a.flag.localeCompare(b.flag));
278
+ const aliasCandidates = sortedRoutes.flatMap((route) => {
279
+ const aliasTerms = uniqueSorted([
280
+ route.flag.replace(/^--/, ""),
281
+ route.label.toLowerCase(),
282
+ ...route.tags.slice(0, 12),
283
+ ...route.queryTerms.slice(0, 12)
284
+ ]);
285
+ return aliasTerms.map((alias) => [alias, route.flag]);
286
+ });
287
+ const aliasCounts = aliasCandidates.reduce((counts, [alias]) => {
288
+ counts.set(alias, (counts.get(alias) ?? 0) + 1);
289
+ return counts;
290
+ }, /* @__PURE__ */ new Map());
291
+ const aliases = Object.fromEntries(
292
+ aliasCandidates.filter(([alias]) => aliasCounts.get(alias) === 1).sort(([aliasA], [aliasB]) => aliasA.localeCompare(aliasB))
293
+ );
294
+ return {
295
+ generatedBy: "generate-knowledge-nodes",
296
+ routingMode: "deterministic-keyword",
297
+ flags: Object.fromEntries(
298
+ sortedRoutes.map((route) => [
299
+ route.flag,
300
+ {
301
+ ...route,
302
+ cliBindings: route.cliBindings.sort((a, b) => a.command.localeCompare(b.command)),
303
+ nodes: route.nodes.sort((a, b) => a.id.localeCompare(b.id))
304
+ }
305
+ ])
306
+ ),
307
+ aliases
308
+ };
309
+ }
111
310
  function generateKnowledgeNodesTs(options) {
112
311
  const exportedName = options.exportedName ?? "mdxKnowledgeNodes";
113
312
  const typeImport = options.typeImportPath ? [`import type { OrgKnowledgeNode } from '${options.typeImportPath}'`, ""] : [];
@@ -127,6 +326,9 @@ function generateKnowledgeNodes(options) {
127
326
  (a, b) => relative(options.sourceDir, a).localeCompare(relative(options.sourceDir, b))
128
327
  );
129
328
  const nodes = files.map(readKnowledgeNodeMdx);
329
+ const sourcePaths = Object.fromEntries(
330
+ files.map((file, index) => [nodes[index].id, toRegistryPath(relative(options.sourceDir, file))])
331
+ );
130
332
  const ids = /* @__PURE__ */ new Set();
131
333
  for (const node of nodes) {
132
334
  if (ids.has(node.id)) throw new Error(`[knowledge-node-codegen] Duplicate knowledge node id: ${node.id}`);
@@ -148,6 +350,21 @@ function generateKnowledgeNodes(options) {
148
350
  writeFileSync(
149
351
  options.graphSkillsOutputPath,
150
352
  `${JSON.stringify(generateGraphSkillsRegistry(nodes), null, 2)}
353
+ `,
354
+ "utf8"
355
+ );
356
+ }
357
+ if (options.knowledgeFlagsOutputPath) {
358
+ mkdirSync(dirname(options.knowledgeFlagsOutputPath), { recursive: true });
359
+ writeFileSync(
360
+ options.knowledgeFlagsOutputPath,
361
+ `${JSON.stringify(
362
+ generateKnowledgeFlagRegistry(nodes, sourcePaths, {
363
+ cliCommand: options.knowledgeFlagsCliCommand ?? "elevasis-sdk"
364
+ }),
365
+ null,
366
+ 2
367
+ )}
151
368
  `,
152
369
  "utf8"
153
370
  );
@@ -188,7 +405,7 @@ function stripToPlainText(body) {
188
405
  var BODIES_HEADER = [
189
406
  "// @generated by generate-knowledge-bodies -- DO NOT EDIT",
190
407
  "// Regenerate: pnpm scaffold:sync",
191
- "// Source: packages/elevasis-core/src/organization-model.ts",
408
+ "// Source: packages/elevasis-core/src/organization-model/index.ts",
192
409
  "",
193
410
  "import { Fragment, jsx, jsxs } from 'react/jsx-runtime'",
194
411
  "import type { ComponentType } from 'react'",
@@ -236,7 +453,7 @@ async function generateKnowledgeBodies(nodes) {
236
453
  const bodiesTsx2 = [
237
454
  "// @generated by generate-knowledge-bodies -- DO NOT EDIT",
238
455
  "// Regenerate: pnpm scaffold:sync",
239
- "// Source: packages/elevasis-core/src/organization-model.ts",
456
+ "// Source: packages/elevasis-core/src/organization-model/index.ts",
240
457
  "",
241
458
  "import type { ComponentType } from 'react'",
242
459
  "",