@elevasis/sdk 0.4.15 → 0.5.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.
package/dist/cli.cjs CHANGED
@@ -43830,7 +43830,7 @@ async function apiDelete(endpoint, apiUrl = resolveApiUrl()) {
43830
43830
  // package.json
43831
43831
  var package_default = {
43832
43832
  name: "@elevasis/sdk",
43833
- version: "0.4.14",
43833
+ version: "0.5.0",
43834
43834
  description: "SDK for building Elevasis organization resources",
43835
43835
  "comment:bin": "IMPORTANT: This package shares the 'elevasis' binary name with @repo/cli. They never conflict because @elevasis/sdk must NEVER be added as a dependency of any workspace package (apps/*, packages/*, organizations/*). Workspace projects use @repo/cli for the 'elevasis' binary. External developers (outside the workspace) get this SDK's binary via npm install.",
43836
43836
  type: "module",
@@ -43949,51 +43949,376 @@ function escapeMdx(text) {
43949
43949
  if (!text) return "";
43950
43950
  return text.replace(/\|/g, "\\|").replace(/\{/g, "\\{").replace(/\}/g, "\\}");
43951
43951
  }
43952
- async function generateResourceMap(org) {
43952
+ async function generateProjectMap(org) {
43953
43953
  const workflows = org.workflows ?? [];
43954
43954
  const agents = org.agents ?? [];
43955
- if (workflows.length === 0 && agents.length === 0) return;
43955
+ let templateVersion = "unknown";
43956
+ try {
43957
+ const jiti = (0, import_jiti2.createJiti)(import_meta2.url);
43958
+ const cfg = await jiti.import((0, import_path2.resolve)("elevasis.config.ts"));
43959
+ const cfgObj = cfg.default ?? cfg;
43960
+ if (cfgObj && typeof cfgObj.templateVersion === "string") {
43961
+ templateVersion = cfgObj.templateVersion;
43962
+ }
43963
+ } catch {
43964
+ }
43965
+ const lastDeploy = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
43956
43966
  const lines = [
43957
43967
  "---",
43958
- "title: Resource Map",
43959
- "description: Auto-generated resource inventory (updated on each deploy)",
43968
+ "title: Project Map",
43969
+ "description: Auto-generated project map (updated on each deploy)",
43960
43970
  "order: 999",
43961
43971
  "---",
43962
43972
  "",
43963
- "# Resource Map",
43973
+ "# Project Map",
43964
43974
  "",
43965
- "> Auto-generated by `elevasis deploy`. Do not edit manually.",
43975
+ "> Auto-generated by `elevasis deploy` and `/meta fix`. Do not edit manually.",
43976
+ "",
43977
+ "## Project Overview",
43978
+ "",
43979
+ "| Field | Value |",
43980
+ "| --- | --- |",
43981
+ `| SDK Version | ${SDK_VERSION} |`,
43982
+ `| Template Version | ${templateVersion} |`,
43983
+ `| Last Deploy | ${lastDeploy} |`,
43984
+ `| Resources | ${workflows.length} workflows, ${agents.length} agents |`,
43966
43985
  ""
43967
43986
  ];
43987
+ lines.push(
43988
+ "## Source Domains",
43989
+ "",
43990
+ "Scanned from `src/*/` subdirectories.",
43991
+ "",
43992
+ "| Domain | Path | Resources | Types |",
43993
+ "| --- | --- | --- | --- |"
43994
+ );
43995
+ try {
43996
+ const srcEntries = await (0, import_promises.readdir)((0, import_path2.resolve)("src"), { withFileTypes: true });
43997
+ const domainDirs = srcEntries.filter((e) => e.isDirectory());
43998
+ if (domainDirs.length === 0) {
43999
+ lines.push("| (none) | src/ | 0 | \u2014 |");
44000
+ } else {
44001
+ for (const d of domainDirs) {
44002
+ const domainName = d.name;
44003
+ const allResources = [...workflows, ...agents];
44004
+ const domainResources = allResources.filter(
44005
+ (r) => Array.isArray(r.config.domains) && r.config.domains.includes(domainName)
44006
+ );
44007
+ const resourceCount = domainResources.length;
44008
+ let types;
44009
+ if (resourceCount === 0) {
44010
+ types = "(utilities)";
44011
+ } else {
44012
+ const wCount = workflows.filter((w) => Array.isArray(w.config.domains) && w.config.domains.includes(domainName)).length;
44013
+ const aCount = agents.filter((a) => Array.isArray(a.config.domains) && a.config.domains.includes(domainName)).length;
44014
+ const parts = [];
44015
+ if (wCount > 0) parts.push(`${wCount} workflow${wCount !== 1 ? "s" : ""}`);
44016
+ if (aCount > 0) parts.push(`${aCount} agent${aCount !== 1 ? "s" : ""}`);
44017
+ types = parts.join(", ");
44018
+ }
44019
+ lines.push(`| ${domainName} | src/${domainName}/ | ${resourceCount} | ${types} |`);
44020
+ }
44021
+ }
44022
+ } catch {
44023
+ lines.push("| (src/ not found) | \u2014 | 0 | \u2014 |");
44024
+ }
44025
+ lines.push("");
44026
+ lines.push("## Resources", "");
43968
44027
  if (workflows.length > 0) {
43969
44028
  lines.push(
43970
- "## Workflows",
44029
+ "### Workflows",
43971
44030
  "",
43972
44031
  "| Resource ID | Name | Version | Status | Description |",
43973
44032
  "| --- | --- | --- | --- | --- |"
43974
44033
  );
43975
44034
  for (const w of workflows) {
43976
44035
  const desc = escapeMdx(w.config.description);
43977
- lines.push(`| \`${w.config.resourceId}\` | ${w.config.name} | ${w.config.version} | ${w.config.status} | ${desc} |`);
44036
+ lines.push(`| \`${w.config.resourceId}\` | ${escapeMdx(w.config.name)} | ${w.config.version} | ${w.config.status} | ${desc} |`);
43978
44037
  }
43979
44038
  lines.push("");
43980
44039
  }
43981
44040
  if (agents.length > 0) {
43982
44041
  lines.push(
43983
- "## Agents",
44042
+ "### Agents",
43984
44043
  "",
43985
44044
  "| Resource ID | Name | Version | Status | Description |",
43986
44045
  "| --- | --- | --- | --- | --- |"
43987
44046
  );
43988
44047
  for (const a of agents) {
43989
44048
  const desc = escapeMdx(a.config.description);
43990
- lines.push(`| \`${a.config.resourceId}\` | ${a.config.name} | ${a.config.version} | ${a.config.status} | ${desc} |`);
44049
+ lines.push(`| \`${a.config.resourceId}\` | ${escapeMdx(a.config.name)} | ${a.config.version} | ${a.config.status} | ${desc} |`);
43991
44050
  }
43992
44051
  lines.push("");
43993
44052
  }
43994
44053
  lines.push(`**Total:** ${workflows.length + agents.length} resources (${workflows.length} workflows, ${agents.length} agents)`, "");
44054
+ lines.push(
44055
+ "## Documentation Index",
44056
+ "",
44057
+ "Scanned from `docs/*.mdx` frontmatter.",
44058
+ "",
44059
+ "| Title | Path | Description |",
44060
+ "| --- | --- | --- |"
44061
+ );
44062
+ try {
44063
+ const docEntries = [];
44064
+ async function scanDocsDir(dir, relPrefix) {
44065
+ let entries;
44066
+ try {
44067
+ entries = await (0, import_promises.readdir)(dir, { withFileTypes: true });
44068
+ } catch {
44069
+ return;
44070
+ }
44071
+ for (const entry of entries) {
44072
+ const relPath = relPrefix ? `${relPrefix}/${entry.name}` : entry.name;
44073
+ if (entry.isDirectory()) {
44074
+ await scanDocsDir((0, import_path2.resolve)(dir, entry.name), relPath);
44075
+ } else if (entry.isFile() && entry.name.endsWith(".mdx") && relPath !== "project-map.mdx") {
44076
+ try {
44077
+ const raw = await (0, import_promises.readFile)((0, import_path2.resolve)(dir, entry.name), "utf-8");
44078
+ const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
44079
+ let title = relPath;
44080
+ let description = "";
44081
+ let order = 9999;
44082
+ if (fmMatch) {
44083
+ const fm = fmMatch[1];
44084
+ const titleMatch = fm.match(/^title:\s*(.+)$/m);
44085
+ const descMatch = fm.match(/^description:\s*(.+)$/m);
44086
+ const orderMatch = fm.match(/^order:\s*(\d+)$/m);
44087
+ if (titleMatch) title = titleMatch[1].trim();
44088
+ if (descMatch) description = descMatch[1].trim();
44089
+ if (orderMatch) order = parseInt(orderMatch[1], 10);
44090
+ }
44091
+ docEntries.push({ title, path: `docs/${relPath}`, description, order });
44092
+ } catch {
44093
+ }
44094
+ }
44095
+ }
44096
+ }
44097
+ await scanDocsDir((0, import_path2.resolve)("docs"), "");
44098
+ docEntries.sort((a, b) => {
44099
+ if (a.order !== b.order) return a.order - b.order;
44100
+ return a.title.localeCompare(b.title);
44101
+ });
44102
+ if (docEntries.length === 0) {
44103
+ lines.push("| (none) | \u2014 | \u2014 |");
44104
+ } else {
44105
+ for (const doc of docEntries) {
44106
+ lines.push(`| ${escapeMdx(doc.title)} | ${doc.path} | ${escapeMdx(doc.description)} |`);
44107
+ }
44108
+ }
44109
+ } catch {
44110
+ lines.push("| (docs/ not found) | \u2014 | \u2014 |");
44111
+ }
44112
+ lines.push("");
44113
+ lines.push("## SDK Reference", "");
44114
+ try {
44115
+ const navPath = (0, import_path2.resolve)("node_modules/@elevasis/sdk/reference/_navigation.md");
44116
+ const navContent = await (0, import_promises.readFile)(navPath, "utf-8");
44117
+ const navLines = navContent.split(/\r?\n/);
44118
+ const categories = [];
44119
+ let current = null;
44120
+ for (const line of navLines) {
44121
+ const headingMatch = line.match(/^##\s+(.+)$/);
44122
+ if (headingMatch) {
44123
+ if (current) categories.push(current);
44124
+ current = { name: headingMatch[1].trim(), titles: [], count: 0 };
44125
+ continue;
44126
+ }
44127
+ if (current) {
44128
+ const rowMatch = line.match(/^\|\s*([^|]+?)\s*\|/);
44129
+ if (rowMatch && !line.match(/^[\s|:-]+$/)) {
44130
+ const cellText = rowMatch[1].trim();
44131
+ if (cellText && cellText !== "File" && cellText !== "Title" && cellText !== "---") {
44132
+ current.titles.push(cellText);
44133
+ current.count++;
44134
+ }
44135
+ }
44136
+ }
44137
+ }
44138
+ if (current) categories.push(current);
44139
+ if (categories.length === 0) {
44140
+ lines.push("SDK reference found but no categories parsed.", "");
44141
+ } else {
44142
+ lines.push(
44143
+ "| Category | Files | Covers |",
44144
+ "| --- | --- | --- |"
44145
+ );
44146
+ for (const cat of categories) {
44147
+ const covers = cat.titles.slice(0, 5).join(", ") + (cat.titles.length > 5 ? ", ..." : "");
44148
+ lines.push(`| ${escapeMdx(cat.name)} | ${cat.count} | ${escapeMdx(covers)} |`);
44149
+ }
44150
+ lines.push("");
44151
+ lines.push("Full reference: `reference/_navigation.md`", "");
44152
+ }
44153
+ } catch {
44154
+ lines.push("SDK reference not found. Run `pnpm install`.", "");
44155
+ }
44156
+ lines.push("## Command and Rules System", "", "### Commands", "");
44157
+ try {
44158
+ const cmdEntries = await (0, import_promises.readdir)((0, import_path2.resolve)(".claude/commands"), { withFileTypes: true });
44159
+ const cmdFiles = cmdEntries.filter((e) => e.isFile() && e.name.endsWith(".md"));
44160
+ if (cmdFiles.length === 0) {
44161
+ lines.push("No commands found.", "");
44162
+ } else {
44163
+ lines.push(
44164
+ "| Command | File | Purpose |",
44165
+ "| --- | --- | --- |"
44166
+ );
44167
+ for (const f of cmdFiles) {
44168
+ const cmdName = f.name.replace(/\.md$/, "");
44169
+ let purpose = "";
44170
+ try {
44171
+ const raw = await (0, import_promises.readFile)((0, import_path2.resolve)(".claude/commands", f.name), "utf-8");
44172
+ const goalMatch = raw.match(/\*\*Goal:\*\*\s*(.+)/);
44173
+ if (goalMatch) {
44174
+ purpose = goalMatch[1].trim();
44175
+ } else {
44176
+ const firstNonEmpty = raw.split(/\r?\n/).find((l) => l.trim() && !l.startsWith("#"));
44177
+ purpose = firstNonEmpty ? firstNonEmpty.trim() : "";
44178
+ }
44179
+ } catch {
44180
+ }
44181
+ lines.push(`| ${cmdName} | .claude/commands/${f.name} | ${escapeMdx(purpose.slice(0, 80))} |`);
44182
+ }
44183
+ lines.push("");
44184
+ }
44185
+ } catch {
44186
+ lines.push("No .claude/commands/ directory found.", "");
44187
+ }
44188
+ lines.push("### Rules (auto-injected)", "");
44189
+ try {
44190
+ const ruleEntries = await (0, import_promises.readdir)((0, import_path2.resolve)(".claude/rules"), { withFileTypes: true });
44191
+ const ruleFiles = ruleEntries.filter((e) => e.isFile() && e.name.endsWith(".md"));
44192
+ if (ruleFiles.length === 0) {
44193
+ lines.push("No rules found.", "");
44194
+ } else {
44195
+ lines.push(
44196
+ "| Rule | File | Scope |",
44197
+ "| --- | --- | --- |"
44198
+ );
44199
+ for (const f of ruleFiles) {
44200
+ const ruleName = f.name.replace(/\.md$/, "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
44201
+ let scope = "";
44202
+ try {
44203
+ const raw = await (0, import_promises.readFile)((0, import_path2.resolve)(".claude/rules", f.name), "utf-8");
44204
+ const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
44205
+ if (fmMatch) {
44206
+ const descMatch = fmMatch[1].match(/^description:\s*(.+)$/m);
44207
+ if (descMatch) scope = descMatch[1].trim();
44208
+ }
44209
+ if (!scope) {
44210
+ const firstNonEmpty = raw.split(/\r?\n/).find((l) => l.trim() && !l.startsWith("#") && !l.startsWith("---"));
44211
+ scope = firstNonEmpty ? firstNonEmpty.trim() : "";
44212
+ }
44213
+ } catch {
44214
+ }
44215
+ lines.push(`| ${ruleName} | .claude/rules/${f.name} | ${escapeMdx(scope.slice(0, 80))} |`);
44216
+ }
44217
+ lines.push("");
44218
+ }
44219
+ } catch {
44220
+ lines.push("No .claude/rules/ directory found.", "");
44221
+ }
44222
+ lines.push("### Skills", "");
44223
+ try {
44224
+ const skillEntries = await (0, import_promises.readdir)((0, import_path2.resolve)(".claude/skills"), { withFileTypes: true });
44225
+ const skillDirs = skillEntries.filter((e) => e.isDirectory());
44226
+ if (skillDirs.length === 0) {
44227
+ lines.push("No skills found.", "");
44228
+ } else {
44229
+ lines.push(
44230
+ "| Skill | File | Trigger |",
44231
+ "| --- | --- | --- |"
44232
+ );
44233
+ for (const d of skillDirs) {
44234
+ const skillFile = (0, import_path2.resolve)(".claude/skills", d.name, "SKILL.md");
44235
+ let trigger = "";
44236
+ try {
44237
+ const raw = await (0, import_promises.readFile)(skillFile, "utf-8");
44238
+ const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
44239
+ if (fmMatch) {
44240
+ const descMatch = fmMatch[1].match(/^description:\s*(.+)$/m);
44241
+ if (descMatch) trigger = descMatch[1].trim();
44242
+ }
44243
+ if (!trigger) {
44244
+ const firstNonEmpty = raw.split(/\r?\n/).find((l) => l.trim() && !l.startsWith("#") && !l.startsWith("---"));
44245
+ trigger = firstNonEmpty ? firstNonEmpty.trim() : "";
44246
+ }
44247
+ } catch {
44248
+ }
44249
+ lines.push(`| ${d.name} | .claude/skills/${d.name}/SKILL.md | ${escapeMdx(trigger.slice(0, 80))} |`);
44250
+ }
44251
+ lines.push("");
44252
+ }
44253
+ } catch {
44254
+ lines.push("No .claude/skills/ directory found.", "");
44255
+ }
44256
+ lines.push("## Memory System", "", "Scanned from `.claude/memory/` structure.", "");
44257
+ try {
44258
+ const memoryFiles = [];
44259
+ async function scanMemory(dir, relPrefix) {
44260
+ let entries;
44261
+ try {
44262
+ entries = await (0, import_promises.readdir)(dir, { withFileTypes: true });
44263
+ } catch {
44264
+ return;
44265
+ }
44266
+ for (const entry of entries) {
44267
+ const fullPath = (0, import_path2.resolve)(dir, entry.name);
44268
+ const relPath = relPrefix ? `${relPrefix}/${entry.name}` : entry.name;
44269
+ if (entry.isDirectory()) {
44270
+ await scanMemory(fullPath, relPath);
44271
+ } else if (entry.isFile()) {
44272
+ try {
44273
+ const s = await (0, import_promises.stat)(fullPath);
44274
+ const mtime = s.mtime.toISOString().split("T")[0];
44275
+ let purpose = entry.name.replace(/\.[^.]+$/, "").replace(/-/g, " ").replace(/_/g, " ");
44276
+ if (purpose === "index") purpose = "Memory root";
44277
+ else purpose = purpose.replace(/\b\w/g, (c) => c.toUpperCase());
44278
+ memoryFiles.push({ rel: relPath, purpose, mtime });
44279
+ } catch {
44280
+ }
44281
+ }
44282
+ }
44283
+ }
44284
+ await scanMemory((0, import_path2.resolve)(".claude/memory"), "");
44285
+ if (memoryFiles.length === 0) {
44286
+ lines.push("No memory files found.", "");
44287
+ } else {
44288
+ lines.push(
44289
+ "| File | Purpose | Last Modified |",
44290
+ "| --- | --- | --- |"
44291
+ );
44292
+ for (const m of memoryFiles) {
44293
+ lines.push(`| .claude/memory/${m.rel} | ${escapeMdx(m.purpose)} | ${m.mtime} |`);
44294
+ }
44295
+ lines.push("");
44296
+ }
44297
+ } catch {
44298
+ lines.push("Not configured", "");
44299
+ }
44300
+ lines.push("## Configuration", "");
44301
+ let apiKeySet = "no";
44302
+ let nodeEnv = "not set";
44303
+ try {
44304
+ const envContent = await (0, import_promises.readFile)((0, import_path2.resolve)(".env"), "utf-8");
44305
+ const apiKeyMatch = envContent.match(/^ELEVASIS_API_KEY=(.+)$/m);
44306
+ if (apiKeyMatch && apiKeyMatch[1].trim()) apiKeySet = "yes";
44307
+ const nodeEnvMatch = envContent.match(/^NODE_ENV=(.+)$/m);
44308
+ if (nodeEnvMatch && nodeEnvMatch[1].trim()) nodeEnv = nodeEnvMatch[1].trim();
44309
+ } catch {
44310
+ }
44311
+ lines.push(
44312
+ "| Setting | Source | Value |",
44313
+ "| --- | --- | --- |",
44314
+ `| Template Version | elevasis.config.ts | ${templateVersion} |`,
44315
+ `| SDK Version | package.json | ${SDK_VERSION} |`,
44316
+ `| API Key Set | .env | ${apiKeySet} |`,
44317
+ `| Node Env | .env | ${nodeEnv} |`,
44318
+ ""
44319
+ );
43995
44320
  await (0, import_promises.mkdir)((0, import_path2.resolve)("docs"), { recursive: true });
43996
- await (0, import_promises.writeFile)((0, import_path2.resolve)("docs/resource-map.mdx"), lines.join("\n"), "utf-8");
44321
+ await (0, import_promises.writeFile)((0, import_path2.resolve)("docs/project-map.mdx"), lines.join("\n"), "utf-8");
43997
44322
  }
43998
44323
  function registerDeployCommand(program3) {
43999
44324
  program3.command("deploy").description("Validate, bundle, upload, and deploy project resources\n Example: elevasis deploy --api-url http://localhost:5170").option("--api-url <url>", "API URL").option("--entry <path>", "Path to entry file (default: ./src/index.ts)").action(wrapAction("deploy", async (options2) => {
@@ -44056,7 +44381,11 @@ function registerDeployCommand(program3) {
44056
44381
  }
44057
44382
  throw error46;
44058
44383
  }
44059
- await generateResourceMap(org);
44384
+ await generateProjectMap(org);
44385
+ try {
44386
+ await (0, import_promises.unlink)((0, import_path2.resolve)("docs/resource-map.mdx"));
44387
+ } catch {
44388
+ }
44060
44389
  const documentation = await scanDocumentation();
44061
44390
  if (documentation) {
44062
44391
  console.log(source_default.gray(` docs ${source_default.white(String(documentation.length))} file${documentation.length !== 1 ? "s" : ""}`));
@@ -44558,164 +44887,9 @@ function registerDescribeCommand(program3) {
44558
44887
  // src/cli/commands/init.ts
44559
44888
  var import_path3 = require("path");
44560
44889
  var import_promises2 = require("fs/promises");
44561
- var TEMPLATE_VERSION = 9;
44562
- var INIT_ONLY_FILES = [
44563
- "package.json",
44564
- "pnpm-workspace.yaml",
44565
- "tsconfig.json",
44566
- ".env",
44567
- ".env.example",
44568
- ".npmrc",
44569
- "src/index.ts",
44570
- "src/operations/platform-status.ts",
44571
- "src/operations/index.ts",
44572
- "src/example/echo.ts",
44573
- "src/example/index.ts",
44574
- "src/shared/.gitkeep",
44575
- "docs/index.mdx",
44576
- "docs/in-progress/.gitkeep"
44577
- ];
44578
- var MANAGED_FILES = [
44579
- "elevasis.config.ts",
44580
- ".gitignore",
44581
- "CLAUDE.md",
44582
- ".claude/settings.json",
44583
- ".claude/commands/docs.md",
44584
- ".claude/commands/resource.md",
44585
- ".claude/commands/tutorial.md",
44586
- ".claude/commands/help.md",
44587
- ".claude/commands/templates.md",
44588
- ".claude/commands/database.md",
44589
- ".claude/commands/agent.md",
44590
- ".claude/commands/profile.md",
44591
- ".claude/commands/meta.md",
44592
- ".claude/commands/work.md",
44593
- ".claude/skills/creds/SKILL.md"
44594
- ];
44595
- var UI_INIT_FILES = [
44596
- "ui/package.json",
44597
- "ui/index.html",
44598
- "ui/vite.config.ts",
44599
- "ui/tsconfig.json",
44600
- "ui/src/main.tsx",
44601
- "ui/src/App.tsx",
44602
- "ui/src/AuthRedirect.tsx",
44603
- "ui/src/vite-env.d.ts",
44604
- "ui/.env",
44605
- "ui/.env.example"
44606
- ];
44607
- var SCAFFOLD_FILES = [...INIT_ONLY_FILES, ...MANAGED_FILES];
44608
- function getManagedTemplates(ctx = {}) {
44609
- return {
44610
- "elevasis.config.ts": configTemplate,
44611
- ".gitignore": () => gitignoreTemplate(ctx),
44612
- "CLAUDE.md": () => claudeMdTemplate(ctx),
44613
- ".claude/settings.json": claudeSettingsTemplate,
44614
- ".claude/commands/docs.md": claudeDocsCommandTemplate,
44615
- ".claude/commands/resource.md": claudeResourceCommandTemplate,
44616
- ".claude/commands/tutorial.md": claudeTutorialCommandTemplate,
44617
- ".claude/commands/help.md": claudeHelpCommandTemplate,
44618
- ".claude/commands/templates.md": claudeTemplatesCommandTemplate,
44619
- ".claude/commands/database.md": claudeDatabaseCommandTemplate,
44620
- ".claude/commands/agent.md": claudeAgentCommandTemplate,
44621
- ".claude/commands/profile.md": claudeProfileCommandTemplate,
44622
- ".claude/commands/meta.md": claudeMetaCommandTemplate,
44623
- ".claude/commands/work.md": claudeWorkCommandTemplate,
44624
- ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate
44625
- };
44626
- }
44627
- function registerInitCommand(program3) {
44628
- program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis init my-workspace").option("--force", "Overwrite existing files").option("--ui", "Include a Vite + React UI app in ui/").action(wrapAction("init", async (directory, options2) => {
44629
- const targetDir = directory ? (0, import_path3.resolve)(directory) : process.cwd();
44630
- const orgSlug = toSlug((0, import_path3.basename)(targetDir));
44631
- if (!options2.force) {
44632
- const filesToCheck = options2.ui ? [...SCAFFOLD_FILES, ...UI_INIT_FILES] : SCAFFOLD_FILES;
44633
- const conflicts = [];
44634
- for (const file2 of filesToCheck) {
44635
- try {
44636
- await (0, import_promises2.access)((0, import_path3.resolve)(targetDir, file2));
44637
- conflicts.push(file2);
44638
- } catch {
44639
- }
44640
- }
44641
- if (conflicts.length > 0) {
44642
- console.error(source_default.red("Files already exist:"));
44643
- for (const f of conflicts) {
44644
- console.error(source_default.gray(` ${f}`));
44645
- }
44646
- console.error(source_default.gray("\n Use --force to overwrite."));
44647
- throw new Error("Scaffold conflict");
44648
- }
44649
- }
44650
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/operations"), { recursive: true });
44651
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/example"), { recursive: true });
44652
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/shared"), { recursive: true });
44653
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "docs/in-progress"), { recursive: true });
44654
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/commands"), { recursive: true });
44655
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/skills/creds"), { recursive: true });
44656
- if (options2.ui) {
44657
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "ui/src"), { recursive: true });
44658
- }
44659
- const files = {
44660
- "elevasis.config.ts": configTemplate(),
44661
- "package.json": packageJsonTemplate(orgSlug),
44662
- "pnpm-workspace.yaml": pnpmWorkspaceTemplate(),
44663
- "tsconfig.json": tsconfigTemplate(),
44664
- ".env": envTemplate(),
44665
- ".env.example": envExampleTemplate(),
44666
- ".npmrc": npmrcTemplate(),
44667
- ".gitignore": gitignoreTemplate({ hasUI: options2.ui }),
44668
- "src/index.ts": starterTemplate(),
44669
- "src/operations/platform-status.ts": platformStatusTemplate(),
44670
- "src/operations/index.ts": operationsBarrelTemplate(),
44671
- "src/example/echo.ts": starterWorkflowTemplate(),
44672
- "src/example/index.ts": exampleBarrelTemplate(),
44673
- "src/shared/.gitkeep": "",
44674
- "docs/index.mdx": docsIndexTemplate(orgSlug),
44675
- "docs/in-progress/.gitkeep": "",
44676
- "CLAUDE.md": claudeMdTemplate({ hasUI: options2.ui }),
44677
- ".claude/settings.json": claudeSettingsTemplate(),
44678
- ".claude/commands/docs.md": claudeDocsCommandTemplate(),
44679
- ".claude/commands/resource.md": claudeResourceCommandTemplate(),
44680
- ".claude/commands/tutorial.md": claudeTutorialCommandTemplate(),
44681
- ".claude/commands/help.md": claudeHelpCommandTemplate(),
44682
- ".claude/commands/templates.md": claudeTemplatesCommandTemplate(),
44683
- ".claude/commands/database.md": claudeDatabaseCommandTemplate(),
44684
- ".claude/commands/agent.md": claudeAgentCommandTemplate(),
44685
- ".claude/commands/profile.md": claudeProfileCommandTemplate(),
44686
- ".claude/commands/meta.md": claudeMetaCommandTemplate(),
44687
- ".claude/commands/work.md": claudeWorkCommandTemplate(),
44688
- ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate()
44689
- };
44690
- if (options2.ui) {
44691
- Object.assign(files, getUIFiles(orgSlug));
44692
- }
44693
- for (const [filePath, content] of Object.entries(files)) {
44694
- await (0, import_promises2.writeFile)((0, import_path3.resolve)(targetDir, filePath), content, "utf-8");
44695
- }
44696
- console.log(source_default.green.bold(" Workspace created!"));
44697
- console.log("");
44698
- console.log(source_default.gray(" Next steps:"));
44699
- if (directory) {
44700
- console.log(source_default.gray(` cd ${directory}`));
44701
- }
44702
- console.log(source_default.gray(" pnpm install"));
44703
- console.log(source_default.gray(" # Copy .env.example to .env and add your API key"));
44704
- console.log(source_default.gray(" elevasis check"));
44705
- console.log(source_default.gray(" elevasis deploy"));
44706
- if (options2.ui) {
44707
- console.log("");
44708
- console.log(source_default.gray(" UI app:"));
44709
- console.log(source_default.gray(" cd ui && pnpm install"));
44710
- console.log(source_default.gray(" # Set VITE_WORKOS_CLIENT_ID in ui/.env"));
44711
- console.log(source_default.gray(" pnpm dev"));
44712
- }
44713
- }));
44714
- }
44715
- function toSlug(name) {
44716
- const slug = name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^[^a-z]+/, "").replace(/-+/g, "-").replace(/-$/, "");
44717
- return slug.length >= 3 ? slug : "my-workspace";
44718
- }
44890
+
44891
+ // src/cli/commands/templates/core/workspace.ts
44892
+ var TEMPLATE_VERSION = 14;
44719
44893
  function configTemplate() {
44720
44894
  return `import type { ElevasConfig } from '@elevasis/sdk'
44721
44895
 
@@ -44733,6 +44907,7 @@ function packageJsonTemplate(organization) {
44733
44907
  type: "module",
44734
44908
  scripts: {
44735
44909
  "check-types": "tsc --noEmit",
44910
+ check: "elevasis check",
44736
44911
  deploy: "elevasis deploy"
44737
44912
  },
44738
44913
  dependencies: {
@@ -44863,6 +45038,8 @@ elevasis exec echo --input '{"message": "hello"}'
44863
45038
  **Output:** \`{ "echo": string }\`
44864
45039
  `;
44865
45040
  }
45041
+
45042
+ // src/cli/commands/templates/core/claude.ts
44866
45043
  function claudeSettingsTemplate() {
44867
45044
  return JSON.stringify({ autoCompact: false }, null, 2) + "\n";
44868
45045
  }
@@ -44916,7 +45093,7 @@ proactivity -- to their assessed levels.
44916
45093
  | Error history | \`.claude/memory/errors/index.md\` | Debugging errors, checking past fixes |
44917
45094
  | Command View model | \`reference/deployment/command-view.mdx\` | Deploying or building resources that invoke other resources |
44918
45095
  | SDK error reference | \`reference/troubleshooting/common-errors.mdx\` | Unknown error not in workspace memory |
44919
- | Project resource map | \`docs/navigation.mdx\` | Understanding what's deployed |
45096
+ | Project map | \`docs/project-map.mdx\` | Session start, project orientation |
44920
45097
  | Project priorities | \`docs/priorities.mdx\` | Deciding what to work on next |
44921
45098
  | User profile and skills | \`.claude/memory/profile/skills.md\` | Session start (mandatory) |
44922
45099
  | Cross-session memory | \`.claude/memory/index.md\` | Session start, recalling past context |${ctx.hasUI ? `
@@ -44926,23 +45103,19 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
44926
45103
 
44927
45104
  ## Rules
44928
45105
 
44929
- - All resource definitions must be in \`src/\` and exported via \`src/index.ts\`
44930
- - Organize resources by business domain (e.g., src/operations/, src/acquisition/)
44931
- - Each domain exports \`workflows\` and \`agents\` arrays via an index.ts barrel
44932
- - src/shared/ is for cross-domain utilities; domain-specific shared code goes in <domain>/shared/
44933
- - The default export must be an \`OrganizationResources\` object
44934
- - Do not import from \`@repo/core\` -- use \`@elevasis/sdk\` types only
44935
- - \`StepType\`, \`ExecutionError\`, \`ToolingError\` are runtime imports from \`'@elevasis/sdk'\`
44936
- - \`platform\`, \`PlatformToolError\` are runtime imports from \`'@elevasis/sdk/worker'\`
44937
- - \`.env\` is for CLI authentication only (\`ELEVASIS_API_KEY\`) -- never deployed, never in workers
44938
- - Integration credentials are managed via the \`creds\` skill (auto-triggers when you mention credentials) or the Command Center UI
45106
+ SDK patterns (imports, source structure, platform tools) are auto-loaded from
45107
+ \`.claude/rules/sdk-patterns.md\`. Project-specific patterns live in
45108
+ \`.claude/rules/workspace-patterns.md\`.
45109
+
44939
45110
  - Documentation goes in \`docs/\` as \`.mdx\` files
44940
- - \`dist/\` is generated by deploy -- never commit it
44941
- - \`resourceId\` must be lowercase with hyphens, unique per organization
44942
- - When an error occurs, check \`.claude/memory/errors/\` first for past fixes.
44943
- If the error is new, check \`reference/troubleshooting/common-errors.mdx\`.
44944
- After resolving, record the error in \`memory/errors/\` with context and fix.
44945
- If an error recurs 3+ times, promote it to a rule in this section.${ctx.hasUI ? `
45111
+
45112
+ ### Error Handling
45113
+
45114
+ When an error occurs:
45115
+ 1. Check \`.claude/memory/errors/\` first for past fixes
45116
+ 2. If new, check \`reference/troubleshooting/common-errors.mdx\`
45117
+ 3. After resolving, record in \`memory/errors/\` with context and fix
45118
+ 4. If an error recurs 3+ times, add a rule to \`.claude/rules/workspace-patterns.md\`${ctx.hasUI ? `
44946
45119
 
44947
45120
  ### UI App (\`ui/\`)
44948
45121
 
@@ -44978,16 +45151,10 @@ For detailed per-dimension adaptation rules, read
44978
45151
 
44979
45152
  | Command | Purpose |
44980
45153
  | --- | --- |
44981
- | \`/meta\` | Project lifecycle: init, status, update, fix, deploy, health, develop |
45154
+ | \`/meta\` | Project lifecycle: init, status, fix, deploy, health |
44982
45155
  | \`/docs\` | Documentation lifecycle: create, review, verify |
44983
- | \`/work\` | Task tracking: start, save, resume, done, list |
44984
- | \`/database\` | Database operations: init, browse, query, schema, import |
44985
- | \`/resource\` | Scaffold a new workflow or agent |
44986
- | \`/templates\` | Discover and apply workflow templates |
44987
- | \`/agent\` | Agent development (placeholder) |
45156
+ | \`/work\` | Task tracking: create, save, resume, complete |
44988
45157
  | \`/tutorial\` | Progressive learning path |
44989
- | \`/help\` | Command tree and navigation map |
44990
- | \`/profile\` | View and update developer profile |
44991
45158
 
44992
45159
  ## Skills
44993
45160
 
@@ -45061,67 +45228,10 @@ code (resource IDs, schema fields, platform tools used), and report
45061
45228
  discrepancies. Useful before \`/meta deploy\` to ensure docs are accurate.
45062
45229
  `;
45063
45230
  }
45064
- function claudeResourceCommandTemplate() {
45065
- return `# /resource command
45231
+ function claudeTutorialCommandTemplate() {
45232
+ return `# /tutorial command
45066
45233
 
45067
- You are a resource scaffolding assistant for this Elevasis workspace.
45068
-
45069
- ## Context
45070
-
45071
- Read CLAUDE.md for navigation to SDK patterns (reference/resources/patterns.mdx).
45072
- Read src/index.ts for the registry and domain directories for existing resources.
45073
-
45074
- Before suggesting tools, read \`.claude/memory/profile/identity.md\` if it exists
45075
- to check the user's known integrations and suggest relevant platform tools.
45076
-
45077
- ## Guided Mode
45078
-
45079
- Before any operation, check \`.claude/memory/profile/skills.md\`. If the user's
45080
- programming level is \`none\` or \`minimal\`, or automation level is \`none\`,
45081
- activate Guided Mode:
45082
-
45083
- 1. Ask: "What does this workflow need to do?" -- let user describe in plain English
45084
- 2. Based on description, suggest a resourceId, input schema fields, output schema
45085
- fields, and whether platform tools are needed
45086
- 3. Show suggestions and ask for confirmation before generating code
45087
- 4. Generate the complete resource using the confirmed structure
45088
-
45089
- This wraps existing operations with conversational discovery for users who
45090
- cannot specify schemas directly.
45091
-
45092
- ## Operations
45093
-
45094
- **\`workflow <name>\`:** Create a new workflow in the appropriate domain directory (e.g., \`src/<domain>/<name>.ts\`) with:
45095
- - Zod input/output schemas with \`z.infer\` type aliases
45096
- - Config object (resourceId, name, type, description, version, status)
45097
- - Contract with schemas
45098
- - Step definition with handler
45099
- - Add the import to \`src/index.ts\` registry
45100
-
45101
- **\`multi-step <name>\`:** Create a multi-step workflow with:
45102
- - Multiple steps connected via StepType.LINEAR or StepType.CONDITIONAL
45103
- - Import \`{ StepType }\` from '@elevasis/sdk' (runtime value, not type)
45104
- - Each step has its own inputSchema/outputSchema
45105
- - Linear: \`next: { type: StepType.LINEAR, target: 'step-two' }\`
45106
- - Conditional: \`next: { type: StepType.CONDITIONAL, routes: [...], default: 'fallback' }\`
45107
- - Last step: \`next: null\`
45108
- - Add to \`src/index.ts\` registry
45109
-
45110
- **\`tool-step <name>\`:** Create a step that calls a platform tool:
45111
- - Prefer typed adapters: \`import { createAttioAdapter, scheduler, llm } from '@elevasis/sdk/worker'\`
45112
- - Integration tools: \`const attio = createAttioAdapter('cred'); await attio.listRecords({...})\`
45113
- - Platform singletons: \`await scheduler.createSchedule({...})\`, \`await llm.generate({...})\`
45114
- - Fallback for tools without adapters: \`await platform.call({ tool, method, params, credential })\`
45115
- - Import \`{ PlatformToolError }\` from '@elevasis/sdk/worker' for error handling
45116
- - Wrap in try/catch for PlatformToolError
45117
- - Note: 60s timeout per call, credential required for integration tools
45118
- - See reference/platform-tools/adapters.mdx for the full adapter API
45119
- `;
45120
- }
45121
- function claudeTutorialCommandTemplate() {
45122
- return `# /tutorial command
45123
-
45124
- You are a tutorial guide for this Elevasis workspace.
45234
+ You are a tutorial guide for this Elevasis workspace.
45125
45235
 
45126
45236
  ## Context
45127
45237
 
@@ -45208,215 +45318,6 @@ Store in \`.claude/memory/tutorial-progress.md\`:
45208
45318
  - Assessment Notes (bullet points)
45209
45319
  `;
45210
45320
  }
45211
- function claudeHelpCommandTemplate() {
45212
- return `# /help command
45213
-
45214
- You are a navigation assistant for this Elevasis workspace.
45215
-
45216
- ## Operations
45217
-
45218
- **\`/help\` (no args):** Display the full command tree:
45219
-
45220
- \`\`\`
45221
- Available Commands:
45222
-
45223
- /meta Project lifecycle
45224
- /meta init First-run setup and onboarding
45225
- /meta status Project health and template version
45226
- /meta update SDK upgrade and template merge
45227
- /meta fix Drift repair
45228
- /meta deploy Full deploy pipeline (validate, git, deploy, verify)
45229
- /meta health Execution debugging and resource status
45230
- /meta develop Development navigation hub (resources, tools, examples)
45231
-
45232
- /docs Documentation lifecycle
45233
- /docs Show documentation status
45234
- /docs create Create new documentation page
45235
- /docs review Review docs for accuracy
45236
- /docs verify Cross-reference docs with codebase for accuracy
45237
-
45238
- /work Task tracking
45239
- /work Show current tasks
45240
- /work start Create new task
45241
- /work save Save progress for session resume
45242
- /work resume Resume in-progress work
45243
- /work done Complete and move task
45244
- /work list List all tasks with status
45245
-
45246
- /database Database operations
45247
- /database init Connect Supabase project
45248
- /database browse Query and display table contents
45249
- /database query Run filtered queries
45250
- /database schema View/compare schema documentation
45251
- /database import Import CSV/JSON data
45252
-
45253
- /resource Scaffold a new workflow or agent
45254
- /templates Discover and apply workflow templates
45255
- /agent Agent development (placeholder)
45256
- /tutorial Progressive learning path
45257
- /profile View and update developer profile
45258
- /help This help menu
45259
-
45260
- Navigation:
45261
- - docs/navigation.mdx Resource and documentation map
45262
- - docs/priorities.mdx Current goals and priorities
45263
- - memory/index.md Cross-session knowledge
45264
- \`\`\`
45265
-
45266
- **\`/help <command>\`:** Show detailed help for a specific command with its
45267
- subcommands and usage examples. Read the corresponding command file at
45268
- \`.claude/commands/<command>.md\` and present a summary.
45269
- `;
45270
- }
45271
- function claudeTemplatesCommandTemplate() {
45272
- return `# /templates command
45273
-
45274
- You are a workflow template assistant for this Elevasis workspace.
45275
-
45276
- ## Context
45277
-
45278
- Read \`reference/templates/\` in node_modules/@elevasis/sdk/reference/templates/
45279
- for available template definitions. Read src/index.ts for the current registry.
45280
- Read \`.claude/memory/profile/skills.md\` to adapt generated code to skill level.
45281
-
45282
- ## Operations
45283
-
45284
- **\`/templates\` (no args):** Show available template categories:
45285
- - Data Collection (web scraper, RSS feed reader, form handler)
45286
- - Data Processing (CSV import, data enrichment, deduplication)
45287
- - Communication (email sender, notification dispatcher)
45288
- - CRM (contact sync, lead scoring, pipeline update)
45289
- - Documents (PDF generator, report builder, invoice creator)
45290
- - AI (text classifier, data extractor, summarizer)
45291
- - Scheduling (recurring job, delayed task, batch processor)
45292
-
45293
- **\`/templates <category>\`:** Show templates in the category with descriptions.
45294
-
45295
- **\`/templates apply <name>\`:** Generate a workflow from the template:
45296
- 1. Read the template definition from reference/templates/<name>.mdx
45297
- 2. Generate a workflow file in the appropriate domain directory
45298
- 3. Add the import to src/index.ts registry
45299
- 4. If the template uses platform tools, prompt for credential setup
45300
- 5. If the template uses the database, check that /database init has been run
45301
- 6. Run \`elevasis check\` to validate
45302
-
45303
- Templates are documentation-based. The agent reads the template definition
45304
- and generates context-aware code adapted to the user's existing schemas,
45305
- credentials, skill level, and naming conventions.
45306
- `;
45307
- }
45308
- function claudeDatabaseCommandTemplate() {
45309
- return `# /database command
45310
-
45311
- You are a database assistant for this Elevasis workspace.
45312
-
45313
- ## Context
45314
-
45315
- Read \`data/schema.ts\` if it exists for the current schema documentation.
45316
- Read \`.claude/memory/deployment-state.md\` for database connection status.
45317
- Read \`.claude/memory/profile/skills.md\` to adapt explanations.
45318
-
45319
- ## Operations
45320
-
45321
- **\`/database init\`:** Guide user through Supabase project setup:
45322
- 1. Explain Supabase (free, great dashboard, integrates with workflows)
45323
- 2. Walk through: create project at supabase.com/dashboard
45324
- 3. Collect Project URL and service_role key
45325
- 4. Store as platform credential named 'my-database' via command center
45326
- 5. Test connection
45327
- 6. Create data/schema.ts with initial table documentation
45328
- 7. Record database connection in memory/deployment-state.md
45329
-
45330
- **\`/database\` (no args):** Show database connection status, tables, row counts.
45331
-
45332
- **\`/database add <table>\`:** Create a migration script:
45333
- 1. Generate scripts/migrations/NNN-create-<table>.ts
45334
- 2. Show the script and explain each statement
45335
- 3. Confirm before execution
45336
- 4. Update data/schema.ts and docs/database.mdx
45337
-
45338
- **\`/database browse <table>\`:** Query and display table contents via CLI.
45339
-
45340
- **\`/database schema\`:** Show data/schema.ts contents, compare against live DB.
45341
-
45342
- **\`/database import <table> --file <path>\`:** Import CSV/JSON into a table.
45343
-
45344
- ## Database Safety
45345
-
45346
- ALWAYS confirm with the user before:
45347
- - DROP TABLE or DROP COLUMN operations
45348
- - DELETE without a WHERE clause (bulk delete)
45349
- - TRUNCATE operations
45350
- - ALTER TABLE that removes columns
45351
- - Any operation that cannot be undone
45352
-
45353
- For read operations and targeted writes (INSERT, UPDATE with WHERE),
45354
- proceed normally.
45355
-
45356
- ## Supabase Platform Tool
45357
-
45358
- Workflows access the database via platform.call({ tool: 'supabase', ... }).
45359
- Methods: insert, select, update, delete, upsert, rpc, count.
45360
- Filter syntax uses PostgREST format (eq, neq, gt, gte, lt, lte, like, ilike, in, is).
45361
- `;
45362
- }
45363
- function claudeAgentCommandTemplate() {
45364
- return `# /agent command
45365
-
45366
- You are an agent development assistant for this Elevasis workspace.
45367
-
45368
- ## Current State
45369
-
45370
- Agent definitions are accepted by the SDK and appear in the registry.
45371
- Autonomous agent execution (multi-turn tool use loops) is deferred.
45372
- LLM calls are available via the \`llm\` typed adapter: \`import { llm } from '@elevasis/sdk/worker'\`, then \`await llm.generate({ messages: [...] })\`.
45373
-
45374
- ## Operations
45375
-
45376
- **\`/agent\` (no args):** Explain the current state:
45377
- - Agent definitions are accepted by the SDK and appear in the registry
45378
- - Autonomous agent execution (multi-turn tool use loops) is deferred
45379
- - LLM calls are available via the \`llm\` typed adapter (\`import { llm } from '@elevasis/sdk/worker'\`)
45380
- - Show the AgentDefinition pattern for future use
45381
-
45382
- **\`/agent scaffold <name>\`:** Create an agent definition with:
45383
- - Config (resourceId, name, type, description, version, status)
45384
- - System prompt
45385
- - Available tools list
45386
- - Note that execution will fail until agent runtime is implemented
45387
- - Add to src/index.ts registry
45388
- `;
45389
- }
45390
- function claudeProfileCommandTemplate() {
45391
- return `# /profile command
45392
-
45393
- You are a profile management assistant for this Elevasis workspace.
45394
-
45395
- ## Context
45396
-
45397
- Read \`.claude/memory/profile/index.md\` to discover profile sub-files.
45398
- Read the sub-files (identity.md, skills.md, preferences.md) to load the current profile.
45399
-
45400
- If \`.claude/memory/profile/\` does not exist, suggest running \`/meta init\` to create it.
45401
-
45402
- ## Operations
45403
-
45404
- **No arguments (default):** Display the current profile in a readable format.
45405
- Show organization, industry, experience level, goals, known integrations, and preferences.
45406
- Ask if anything needs updating.
45407
-
45408
- **\`update\`:** Walk through each profile section, showing current values and
45409
- asking if they should change. Only update fields the user wants to change.
45410
- Write changes to the appropriate memory/profile/ file.
45411
-
45412
- **\`level\`:** Assess the user's current skill level based on their project
45413
- history (resources created, successful deploys, error handling patterns).
45414
- Suggest updating memory/profile/skills.md if the assessment differs from the stored level.
45415
-
45416
- **\`assess\`:** Re-run the competency assessment questions from /meta init.
45417
- Update all skill dimensions in memory/profile/skills.md.
45418
- `;
45419
- }
45420
45321
  function claudeMetaCommandTemplate() {
45421
45322
  return `# /meta command
45422
45323
 
@@ -45504,32 +45405,35 @@ Display a project health summary:
45504
45405
  2. SDK package version from package.json
45505
45406
  3. Profile summary (from memory/profile/skills.md)
45506
45407
  4. Quick drift check: count of missing managed files, missing gitignore entries
45408
+ 5. Last deployment status (from memory/deployment-state.md if it exists)
45507
45409
 
45508
- ### \`/meta update\` -- Full Upgrade
45509
-
45510
- Upgrade the SDK and merge template changes:
45511
-
45512
- 1. Run \`pnpm update @elevasis/sdk\` to pull the latest SDK
45513
- 2. Run \`elevasis update\` to add missing files and flag conflicts
45514
- 3. For each flagged file in the output:
45515
- - Read the current project file
45516
- - Read the new template from \`@elevasis/sdk/templates\`
45517
- - Compare and merge intelligently:
45518
- - Add new sections that don't exist
45519
- - Preserve user customizations
45520
- - If a section differs, show both versions and let user choose
45521
- 4. Return a report of changes
45410
+ ### \`/meta fix\` -- Maintenance and Upgrade
45522
45411
 
45523
- ### \`/meta fix\` -- Fix Drift
45524
-
45525
- Detect and repair drift without a version upgrade:
45412
+ Detect and repair all drift. Optionally upgrades the SDK first.
45526
45413
 
45414
+ 0. **SDK version check** -- Compare installed \`@elevasis/sdk\` against the latest
45415
+ available. If behind, offer to run \`pnpm update @elevasis/sdk\` before
45416
+ continuing. If the user accepts, run it, then run \`elevasis update\` to add
45417
+ any new managed files and flag conflicts. For each flagged file:
45418
+ - Read the current project file and the new template from \`@elevasis/sdk/templates\`
45419
+ - Add new sections that don't exist; preserve user customizations
45420
+ - If a section differs, show both versions and let the user choose
45527
45421
  1. **Missing managed files:** Regenerate from templates
45528
45422
  2. **Gitignore drift:** Append missing entries
45529
45423
  3. **CLAUDE.md sections:** Add missing sections in correct position
45530
45424
  4. **Memory structure:** Verify index consistency
45531
45425
  5. **Doc cross-references:** Scan for broken links
45532
45426
  6. **Settings consistency:** Verify expected fields
45427
+ 7. **Rules health:** Scan \`memory/errors/\` -- flag any entry that has recurred
45428
+ 3+ times and is not yet in \`.claude/rules/workspace-patterns.md\`.
45429
+ If \`workspace-patterns.md\` has no rules yet and 5+ resources exist in \`src/\`,
45430
+ suggest adding patterns. Surface suggestions only -- do not auto-generate.
45431
+ 8. **Project map freshness:** Check whether \`docs/project-map.mdx\` reflects the
45432
+ current project state (resources, commands, rules, skills, memory files).
45433
+ Compare filesystem state against the map. If stale, run \`elevasis deploy\`
45434
+ to regenerate, or patch inline for minor drift.
45435
+
45436
+ Each step reports its result. Steps 1-8 run even if step 0 is skipped.
45533
45437
 
45534
45438
  ### \`/meta deploy\` -- Full Deploy Pipeline
45535
45439
 
@@ -45541,7 +45445,7 @@ Detect and repair drift without a version upgrade:
45541
45445
  3. Verify docs reflect current resources
45542
45446
  4. If git configured: stage changes, commit with deploy message
45543
45447
  5. Run \`elevasis deploy\`
45544
- 6. Bump deployment version in \`docs/navigation.mdx\` metadata
45448
+ 6. \`docs/project-map.mdx\` is auto-regenerated by deploy (no manual bump needed)
45545
45449
  7. Verify deployment via platform
45546
45450
  8. Update \`memory/deployment-state.md\` with count, timestamp, inventory
45547
45451
  9. If git configured and remote exists: optionally push
@@ -45552,29 +45456,12 @@ for the enforcement model and common fixes.
45552
45456
 
45553
45457
  ### \`/meta health\` -- Execution Debugging
45554
45458
 
45555
- Renamed from /inspect. Checks:
45459
+ Diagnose runtime failures and environment issues:
45556
45460
  - Show recent executions with status (completed/failed)
45557
45461
  - For failed executions: analyze logs, cross-reference with memory/errors/
45558
45462
  - Check resource deployment status (deployed, outdated, never deployed)
45559
45463
  - Verify environment: API key valid, credentials accessible, DB connected
45560
45464
 
45561
- ### \`/meta develop\` -- Development Navigation Hub
45562
-
45563
- Primary development entry point. Loads a navigation map and offers actions.
45564
-
45565
- 1. **Project Resource Map** -- from docs/navigation.mdx. Shows deployed
45566
- resources: resourceId, name, status, tools used, last deployment.
45567
- 2. **Development Actions** -- contextual based on resource map:
45568
- - Edit/extend a workflow
45569
- - Test a workflow
45570
- - Debug a failed execution
45571
- - Browse platform tools (read reference/platform-tools/index.mdx)
45572
- - Set up credentials
45573
- - View examples (read reference/resources/patterns.mdx)
45574
- 3. **SDK Reference Navigation** -- pointers to reference files
45575
- 4. **Upkeep Detection** -- check navigation freshness, in-progress items,
45576
- pending priorities. Suggest /docs cleanup or /docs resume if needed.
45577
-
45578
45465
  ## Merge Strategy
45579
45466
 
45580
45467
  - **CLAUDE.md:** Add new sections in correct position. Preserve customizations.
@@ -45599,10 +45486,11 @@ Scan \`docs/in-progress/\` for task documents with \`status\` frontmatter.
45599
45486
 
45600
45487
  ## Operations
45601
45488
 
45602
- **No arguments (default):** Show tasks from \`docs/in-progress/\` with status
45489
+ **No arguments (default):** Show all tasks from \`docs/in-progress/\` with status
45603
45490
  from frontmatter, cross-referenced with \`docs/priorities.mdx\`.
45491
+ Display as a status table sorted by status (in-progress first).
45604
45492
 
45605
- **\`start <description>\`:** Create a task doc in \`docs/in-progress/<name>.mdx\`:
45493
+ **\`create <description>\`:** Create a task doc in \`docs/in-progress/<name>.mdx\`:
45606
45494
  1. Derive a kebab-case filename from the description
45607
45495
  2. Create the file with frontmatter (\`status: in-progress\`)
45608
45496
  3. Add sections: Objective, Plan, Progress, Resume Context
@@ -45625,15 +45513,11 @@ from frontmatter, cross-referenced with \`docs/priorities.mdx\`.
45625
45513
  3. Parse Resume Context section
45626
45514
  4. Present: "Resuming [task]. Last completed: [step]. Next: [step]."
45627
45515
 
45628
- **\`done [name]\`:** Mark task complete:
45516
+ **\`complete [name]\`:** Mark task complete:
45629
45517
  1. Find the task doc
45630
45518
  2. Set \`status: complete\` in frontmatter
45631
45519
  3. Move from \`docs/in-progress/\` to final \`docs/\` location
45632
45520
  4. Update \`docs/priorities.mdx\`
45633
-
45634
- **\`list\`:** Show all tasks with status:
45635
- 1. Scan \`docs/in-progress/*.mdx\` for frontmatter
45636
- 2. Display status table sorted by status (in-progress first)
45637
45521
  `;
45638
45522
  }
45639
45523
  function claudeCredsSkillTemplate() {
@@ -45728,6 +45612,174 @@ Ask for provider, org UUID, resource ID, and credential name. Construct:
45728
45612
  - OAuth credentials cannot be created via CLI -- redirect to Command Center UI
45729
45613
  `;
45730
45614
  }
45615
+ function claudeSdkPatternsRuleTemplate() {
45616
+ return `---
45617
+ description: Elevasis SDK patterns -- imports, source structure, runtime, and platform tools
45618
+ ---
45619
+
45620
+ # SDK Patterns
45621
+
45622
+ ## Imports
45623
+
45624
+ - \`@elevasis/sdk\` -- types and constants: \`WorkflowDefinition\`, \`StepType\`, \`ExecutionError\`, \`ToolingError\`
45625
+ - \`@elevasis/sdk/worker\` -- runtime: \`platform\`, \`PlatformToolError\`, typed adapters
45626
+ - **Never import from \`@repo/core\`** -- monorepo-internal, not available in external projects
45627
+
45628
+ ## Source Structure
45629
+
45630
+ - All resource definitions live in \`src/\` and are exported via \`src/index.ts\`
45631
+ - Organize by business domain: \`src/<domain>/\` (e.g., \`src/operations/\`, \`src/acquisition/\`)
45632
+ - Each domain barrel (\`src/<domain>/index.ts\`) exports \`workflows\` and \`agents\` arrays
45633
+ - Cross-domain utilities go in \`src/shared/\`; domain-specific utilities in \`src/<domain>/shared/\`
45634
+ - The default export in \`src/index.ts\` must be an \`OrganizationResources\` object
45635
+ - \`resourceId\` must be lowercase with hyphens, unique per organization
45636
+ - \`dist/\` is generated by deploy -- never commit it
45637
+
45638
+ ## Runtime
45639
+
45640
+ - \`.env\` contains only \`ELEVASIS_API_KEY\` for CLI auth -- never deployed, never in worker memory
45641
+ - Integration credentials are managed via the \`creds\` skill or Command Center UI
45642
+
45643
+ ## Platform Tools
45644
+
45645
+ Prefer typed adapters over raw \`platform.call()\`.
45646
+
45647
+ ### Singleton adapters (no credential needed)
45648
+
45649
+ \`\`\`typescript
45650
+ import { scheduler, storage, llm, notifications, lead, pdf, approval, execution, email } from '@elevasis/sdk/worker'
45651
+ \`\`\`
45652
+
45653
+ ### Factory adapters (credential-bound)
45654
+
45655
+ \`\`\`typescript
45656
+ import { createAttioAdapter, createResendAdapter } from '@elevasis/sdk/worker'
45657
+ const attio = createAttioAdapter('credential-name')
45658
+ \`\`\`
45659
+
45660
+ Use \`platform.call()\` directly only for tools without adapters: \`supabase\`, \`session-memory\`, \`hitl\`, \`status\`, \`http\`.
45661
+ `;
45662
+ }
45663
+ function claudeWorkspaceRulesTemplate() {
45664
+ return `---
45665
+ description: Project-specific patterns for this workspace, promoted as the project grows
45666
+ ---
45667
+
45668
+ # Workspace Patterns
45669
+
45670
+ Add project-specific patterns here as they emerge. Only add patterns that have already
45671
+ occurred multiple times or represent a deliberate convention -- not speculative rules.
45672
+
45673
+ ## Rule File Ownership
45674
+
45675
+ This file is yours. The other \`.claude/rules/\` files are SDK-owned and updated by
45676
+ \`elevasis update\` -- do not add project-specific notes to them, add them here instead:
45677
+
45678
+ - \`sdk-patterns.md\` -- SDK imports, source structure, runtime, adapter patterns
45679
+ - \`docs-authoring.md\` -- MDX escaping, frontmatter, docs conventions
45680
+ - \`memory-conventions.md\` -- memory system structure and pruning
45681
+ - \`project-map.md\` -- auto-generated project map conventions
45682
+ - \`task-tracking.md\` -- in-progress task conventions
45683
+
45684
+ ## When to Add a Rule
45685
+
45686
+ - An error has recurred 3+ times (CLAUDE.md instructs you to promote from \`memory/errors/\`)
45687
+ - A pattern appears across 3+ resources and is worth documenting for consistency
45688
+ - A naming or structural convention exists that future sessions would likely get wrong
45689
+
45690
+ ## Patterns
45691
+
45692
+ <!-- Rules are added here as the project grows. Examples:
45693
+ - "All Attio records use 'attio-main' as the credential name"
45694
+ - "Workflow IDs follow the pattern: <domain>-<verb>-<noun>"
45695
+ - "Shared LLM prompt templates live in src/shared/prompts.ts"
45696
+ -->
45697
+ `;
45698
+ }
45699
+ function claudeDocsAuthoringRuleTemplate() {
45700
+ return `---
45701
+ description: Documentation conventions for docs/ files -- MDX escaping, frontmatter, structure
45702
+ ---
45703
+
45704
+ # Docs Authoring
45705
+
45706
+ ## MDX Escaping
45707
+
45708
+ - Less-than \`<\` must be \`\\<\` (MDX interprets bare \`<\` as JSX tag)
45709
+ - Curly braces \`{var}\` must be in backticks or escaped: \`\\{var\\}\`
45710
+ - Greater-than \`>\` must be \`\\>\`
45711
+
45712
+ ## Frontmatter
45713
+
45714
+ Every \`.mdx\` file requires \`title\` and \`description\`:
45715
+
45716
+ \`\`\`yaml
45717
+ ---
45718
+ title: Feature Name
45719
+ description: Concise description
45720
+ ---
45721
+ \`\`\`
45722
+
45723
+ ## Structure
45724
+
45725
+ - \`docs/project-map.mdx\` is auto-generated -- do not edit manually
45726
+ - \`docs/in-progress/\` for task tracking docs
45727
+ - Sort order via \`order\` frontmatter field (lower = earlier)
45728
+ `;
45729
+ }
45730
+ function claudeMemoryConventionsRuleTemplate() {
45731
+ return `---
45732
+ description: Memory system conventions -- what to store, structure, pruning
45733
+ ---
45734
+
45735
+ # Memory Conventions
45736
+
45737
+ ## What Memory Is
45738
+
45739
+ Memory stores persistent agent state: skills, errors, tutorial progress.
45740
+ It is NOT for instructions (commands), reference docs, or templates.
45741
+
45742
+ ## Structure
45743
+
45744
+ - \`index.md\` at every level maps to children
45745
+ - Start at root index and drill down
45746
+ - When a file outgrows a single document, split into a subdirectory
45747
+
45748
+ ## Pruning
45749
+
45750
+ - Keep ~20 recent entries per table; drop stale patterns (30+ days)
45751
+ - If an error recurs 3+ times, promote to \`.claude/rules/workspace-patterns.md\`
45752
+ `;
45753
+ }
45754
+ function claudeProjectMapRuleTemplate() {
45755
+ return `---
45756
+ description: Project map conventions -- auto-generated, do not edit, maintained by deploy and /meta fix
45757
+ ---
45758
+
45759
+ # Project Map
45760
+
45761
+ - \`docs/project-map.mdx\` is fully auto-generated by \`elevasis deploy\`
45762
+ - Do not edit manually -- changes are overwritten on next deploy
45763
+ - \`/meta fix\` step 8 checks for drift and patches the map
45764
+ - If a new command, rule, skill, or memory file is added, run \`/meta fix\` or \`elevasis deploy\` to update
45765
+ `;
45766
+ }
45767
+ function claudeTaskTrackingRuleTemplate() {
45768
+ return `---
45769
+ description: In-progress task conventions -- /work command, doc format, status values
45770
+ ---
45771
+
45772
+ # Task Tracking
45773
+
45774
+ - Task docs managed via \`/work\` command (create, save, resume, complete)
45775
+ - Frontmatter \`status\`: \`planned\`, \`in-progress\`, \`blocked\`, \`complete\`
45776
+ - Sections: Objective, Plan, Progress, Resume Context
45777
+ - Update Progress section only on step transitions, not every action
45778
+ - When context is heavy, suggest \`/work save\`
45779
+ `;
45780
+ }
45781
+
45782
+ // src/cli/commands/templates/core/resources.ts
45731
45783
  function starterTemplate() {
45732
45784
  return `import type { OrganizationResources } from '@elevasis/sdk'
45733
45785
  import * as operations from './operations/index.js'
@@ -45891,6 +45943,28 @@ export const workflows = [echo]
45891
45943
  export const agents = []
45892
45944
  `;
45893
45945
  }
45946
+
45947
+ // src/cli/commands/templates/core/index.ts
45948
+ function getManagedTemplates(ctx = {}) {
45949
+ return {
45950
+ "elevasis.config.ts": configTemplate,
45951
+ ".gitignore": () => gitignoreTemplate(ctx),
45952
+ "CLAUDE.md": () => claudeMdTemplate(ctx),
45953
+ ".claude/settings.json": claudeSettingsTemplate,
45954
+ ".claude/commands/docs.md": claudeDocsCommandTemplate,
45955
+ ".claude/commands/tutorial.md": claudeTutorialCommandTemplate,
45956
+ ".claude/commands/meta.md": claudeMetaCommandTemplate,
45957
+ ".claude/commands/work.md": claudeWorkCommandTemplate,
45958
+ ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate,
45959
+ ".claude/rules/sdk-patterns.md": claudeSdkPatternsRuleTemplate,
45960
+ ".claude/rules/docs-authoring.md": claudeDocsAuthoringRuleTemplate,
45961
+ ".claude/rules/memory-conventions.md": claudeMemoryConventionsRuleTemplate,
45962
+ ".claude/rules/project-map.md": claudeProjectMapRuleTemplate,
45963
+ ".claude/rules/task-tracking.md": claudeTaskTrackingRuleTemplate
45964
+ };
45965
+ }
45966
+
45967
+ // src/cli/commands/templates/ui/files.ts
45894
45968
  function getUIFiles(orgSlug) {
45895
45969
  return {
45896
45970
  "ui/package.json": uiPackageJsonTemplate(orgSlug),
@@ -46046,6 +46120,149 @@ function uiEnvExampleTemplate() {
46046
46120
  `;
46047
46121
  }
46048
46122
 
46123
+ // src/cli/commands/templates/ui/index.ts
46124
+ var UI_INIT_FILES = [
46125
+ "ui/package.json",
46126
+ "ui/index.html",
46127
+ "ui/vite.config.ts",
46128
+ "ui/tsconfig.json",
46129
+ "ui/src/main.tsx",
46130
+ "ui/src/App.tsx",
46131
+ "ui/src/AuthRedirect.tsx",
46132
+ "ui/src/vite-env.d.ts",
46133
+ "ui/.env",
46134
+ "ui/.env.example"
46135
+ ];
46136
+
46137
+ // src/cli/commands/init.ts
46138
+ var INIT_ONLY_FILES = [
46139
+ "package.json",
46140
+ "pnpm-workspace.yaml",
46141
+ "tsconfig.json",
46142
+ ".env",
46143
+ ".env.example",
46144
+ ".npmrc",
46145
+ "src/index.ts",
46146
+ "src/operations/platform-status.ts",
46147
+ "src/operations/index.ts",
46148
+ "src/example/echo.ts",
46149
+ "src/example/index.ts",
46150
+ "src/shared/.gitkeep",
46151
+ "docs/index.mdx",
46152
+ "docs/in-progress/.gitkeep",
46153
+ ".claude/rules/workspace-patterns.md"
46154
+ ];
46155
+ var MANAGED_FILES = [
46156
+ "elevasis.config.ts",
46157
+ ".gitignore",
46158
+ "CLAUDE.md",
46159
+ ".claude/settings.json",
46160
+ ".claude/commands/docs.md",
46161
+ ".claude/commands/tutorial.md",
46162
+ ".claude/commands/meta.md",
46163
+ ".claude/commands/work.md",
46164
+ ".claude/skills/creds/SKILL.md",
46165
+ ".claude/rules/sdk-patterns.md",
46166
+ ".claude/rules/docs-authoring.md",
46167
+ ".claude/rules/memory-conventions.md",
46168
+ ".claude/rules/project-map.md",
46169
+ ".claude/rules/task-tracking.md"
46170
+ ];
46171
+ var SCAFFOLD_FILES = [...INIT_ONLY_FILES, ...MANAGED_FILES];
46172
+ function registerInitCommand(program3) {
46173
+ program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis init my-workspace").option("--force", "Overwrite existing files").option("--ui", "Include a Vite + React UI app in ui/").action(wrapAction("init", async (directory, options2) => {
46174
+ const targetDir = directory ? (0, import_path3.resolve)(directory) : process.cwd();
46175
+ const orgSlug = toSlug((0, import_path3.basename)(targetDir));
46176
+ if (!options2.force) {
46177
+ const filesToCheck = options2.ui ? [...SCAFFOLD_FILES, ...UI_INIT_FILES] : SCAFFOLD_FILES;
46178
+ const conflicts = [];
46179
+ for (const file2 of filesToCheck) {
46180
+ try {
46181
+ await (0, import_promises2.access)((0, import_path3.resolve)(targetDir, file2));
46182
+ conflicts.push(file2);
46183
+ } catch {
46184
+ }
46185
+ }
46186
+ if (conflicts.length > 0) {
46187
+ console.error(source_default.red("Files already exist:"));
46188
+ for (const f of conflicts) {
46189
+ console.error(source_default.gray(` ${f}`));
46190
+ }
46191
+ console.error(source_default.gray("\n Use --force to overwrite."));
46192
+ throw new Error("Scaffold conflict");
46193
+ }
46194
+ }
46195
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/operations"), { recursive: true });
46196
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/example"), { recursive: true });
46197
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/shared"), { recursive: true });
46198
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "docs/in-progress"), { recursive: true });
46199
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/commands"), { recursive: true });
46200
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/skills/creds"), { recursive: true });
46201
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/rules"), { recursive: true });
46202
+ if (options2.ui) {
46203
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "ui/src"), { recursive: true });
46204
+ }
46205
+ const files = {
46206
+ "elevasis.config.ts": configTemplate(),
46207
+ "package.json": packageJsonTemplate(orgSlug),
46208
+ "pnpm-workspace.yaml": pnpmWorkspaceTemplate(),
46209
+ "tsconfig.json": tsconfigTemplate(),
46210
+ ".env": envTemplate(),
46211
+ ".env.example": envExampleTemplate(),
46212
+ ".npmrc": npmrcTemplate(),
46213
+ ".gitignore": gitignoreTemplate({ hasUI: options2.ui }),
46214
+ "src/index.ts": starterTemplate(),
46215
+ "src/operations/platform-status.ts": platformStatusTemplate(),
46216
+ "src/operations/index.ts": operationsBarrelTemplate(),
46217
+ "src/example/echo.ts": starterWorkflowTemplate(),
46218
+ "src/example/index.ts": exampleBarrelTemplate(),
46219
+ "src/shared/.gitkeep": "",
46220
+ "docs/index.mdx": docsIndexTemplate(orgSlug),
46221
+ "docs/in-progress/.gitkeep": "",
46222
+ "CLAUDE.md": claudeMdTemplate({ hasUI: options2.ui }),
46223
+ ".claude/settings.json": claudeSettingsTemplate(),
46224
+ ".claude/commands/docs.md": claudeDocsCommandTemplate(),
46225
+ ".claude/commands/tutorial.md": claudeTutorialCommandTemplate(),
46226
+ ".claude/commands/meta.md": claudeMetaCommandTemplate(),
46227
+ ".claude/commands/work.md": claudeWorkCommandTemplate(),
46228
+ ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate(),
46229
+ ".claude/rules/sdk-patterns.md": claudeSdkPatternsRuleTemplate(),
46230
+ ".claude/rules/workspace-patterns.md": claudeWorkspaceRulesTemplate(),
46231
+ ".claude/rules/docs-authoring.md": claudeDocsAuthoringRuleTemplate(),
46232
+ ".claude/rules/memory-conventions.md": claudeMemoryConventionsRuleTemplate(),
46233
+ ".claude/rules/project-map.md": claudeProjectMapRuleTemplate(),
46234
+ ".claude/rules/task-tracking.md": claudeTaskTrackingRuleTemplate()
46235
+ };
46236
+ if (options2.ui) {
46237
+ Object.assign(files, getUIFiles(orgSlug));
46238
+ }
46239
+ for (const [filePath, content] of Object.entries(files)) {
46240
+ await (0, import_promises2.writeFile)((0, import_path3.resolve)(targetDir, filePath), content, "utf-8");
46241
+ }
46242
+ console.log(source_default.green.bold(" Workspace created!"));
46243
+ console.log("");
46244
+ console.log(source_default.gray(" Next steps:"));
46245
+ if (directory) {
46246
+ console.log(source_default.gray(` cd ${directory}`));
46247
+ }
46248
+ console.log(source_default.gray(" pnpm install"));
46249
+ console.log(source_default.gray(" # Copy .env.example to .env and add your API key"));
46250
+ console.log(source_default.gray(" elevasis check"));
46251
+ console.log(source_default.gray(" elevasis deploy"));
46252
+ if (options2.ui) {
46253
+ console.log("");
46254
+ console.log(source_default.gray(" UI app:"));
46255
+ console.log(source_default.gray(" cd ui && pnpm install"));
46256
+ console.log(source_default.gray(" # Set VITE_WORKOS_CLIENT_ID in ui/.env"));
46257
+ console.log(source_default.gray(" pnpm dev"));
46258
+ }
46259
+ }));
46260
+ }
46261
+ function toSlug(name) {
46262
+ const slug = name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^[^a-z]+/, "").replace(/-+/g, "-").replace(/-$/, "");
46263
+ return slug.length >= 3 ? slug : "my-workspace";
46264
+ }
46265
+
46049
46266
  // src/cli/commands/update.ts
46050
46267
  var import_path4 = require("path");
46051
46268
  var import_promises3 = require("fs/promises");
@@ -46147,7 +46364,8 @@ function registerUpdateCommand(program3) {
46147
46364
  added.push(file2);
46148
46365
  } else {
46149
46366
  const existingContent = await (0, import_promises3.readFile)(filePath, "utf-8");
46150
- if (existingContent === templateContent) {
46367
+ const normalize = (s) => s.replace(/\r\n/g, "\n");
46368
+ if (normalize(existingContent) === normalize(templateContent)) {
46151
46369
  } else {
46152
46370
  flagged.push(file2);
46153
46371
  }