@elevasis/sdk 0.4.16 → 0.5.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.
- package/dist/cli.cjs +727 -509
- package/dist/templates.js +44 -328
- package/dist/types/templates.d.ts +1 -1
- package/package.json +10 -10
- package/reference/concepts/index.mdx +1 -1
- package/reference/framework/agent.mdx +62 -88
- package/reference/framework/index.mdx +17 -14
- package/reference/framework/project-structure.mdx +41 -46
- package/reference/getting-started/index.mdx +16 -12
- package/reference/index.mdx +2 -2
- package/reference/resources/index.mdx +80 -33
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.
|
|
43833
|
+
version: "0.5.1",
|
|
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
|
|
43952
|
+
async function generateProjectMap(org) {
|
|
43953
43953
|
const workflows = org.workflows ?? [];
|
|
43954
43954
|
const agents = org.agents ?? [];
|
|
43955
|
-
|
|
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" || typeof cfgObj.templateVersion === "number")) {
|
|
43961
|
+
templateVersion = String(cfgObj.templateVersion);
|
|
43962
|
+
}
|
|
43963
|
+
} catch {
|
|
43964
|
+
}
|
|
43965
|
+
const lastDeploy = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
43956
43966
|
const lines = [
|
|
43957
43967
|
"---",
|
|
43958
|
-
"title:
|
|
43959
|
-
"description: Auto-generated
|
|
43968
|
+
"title: Project Map",
|
|
43969
|
+
"description: Auto-generated project map (updated on each deploy)",
|
|
43960
43970
|
"order: 999",
|
|
43961
43971
|
"---",
|
|
43962
43972
|
"",
|
|
43963
|
-
"#
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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/
|
|
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
|
|
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
|
-
|
|
44562
|
-
|
|
44563
|
-
|
|
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
|
|
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
|
-
|
|
44930
|
-
-
|
|
44931
|
-
-
|
|
44932
|
-
|
|
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
|
-
|
|
44941
|
-
|
|
44942
|
-
|
|
44943
|
-
|
|
44944
|
-
|
|
44945
|
-
|
|
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,
|
|
45154
|
+
| \`/meta\` | Project lifecycle: init, status, fix, deploy, health |
|
|
44982
45155
|
| \`/docs\` | Documentation lifecycle: create, review, verify |
|
|
44983
|
-
| \`/work\` | Task tracking:
|
|
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
|
|
45065
|
-
return `# /
|
|
45231
|
+
function claudeTutorialCommandTemplate() {
|
|
45232
|
+
return `# /tutorial command
|
|
45066
45233
|
|
|
45067
|
-
You are a
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
**\`
|
|
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
|
-
**\`
|
|
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
|
-
|
|
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
|
}
|