@elevasis/sdk 0.5.13 → 0.5.15
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 +745 -409
- package/dist/index.d.ts +32 -0
- package/dist/index.js +68 -0
- package/dist/templates.js +254 -37
- package/dist/worker/index.js +3 -7
- package/package.json +1 -1
- package/reference/cli.mdx +568 -505
- package/reference/concepts.mdx +4 -43
- package/reference/deployment/api.mdx +297 -297
- package/reference/deployment/command-center.mdx +9 -12
- package/reference/deployment/index.mdx +7 -7
- package/reference/framework/agent.mdx +6 -18
- package/reference/framework/interaction-guidance.mdx +182 -182
- package/reference/framework/memory.mdx +3 -24
- package/reference/framework/project-structure.mdx +277 -298
- package/reference/framework/tutorial-system.mdx +13 -44
- package/reference/getting-started.mdx +152 -148
- package/reference/index.mdx +28 -14
- package/reference/platform-tools/adapters.mdx +868 -1072
- package/reference/platform-tools/index.mdx +3 -3
- package/reference/resources/index.mdx +339 -341
- package/reference/resources/patterns.mdx +355 -354
- package/reference/resources/types.mdx +207 -207
- package/reference/roadmap.mdx +163 -147
- package/reference/runtime.mdx +2 -25
- package/reference/troubleshooting.mdx +223 -210
package/dist/cli.cjs
CHANGED
|
@@ -40164,6 +40164,12 @@ var DOMAIN_MAP = {
|
|
|
40164
40164
|
[DOMAINS.DIAGNOSTIC]: DIAGNOSTIC_DOMAIN
|
|
40165
40165
|
};
|
|
40166
40166
|
|
|
40167
|
+
// ../core/src/platform/registry/reserved.ts
|
|
40168
|
+
var RESERVED_RESOURCE_IDS = /* @__PURE__ */ new Set(["command-center-assistant"]);
|
|
40169
|
+
function isReservedResourceId(resourceId) {
|
|
40170
|
+
return RESERVED_RESOURCE_IDS.has(resourceId);
|
|
40171
|
+
}
|
|
40172
|
+
|
|
40167
40173
|
// ../core/src/execution/engine/base/errors.ts
|
|
40168
40174
|
var ExecutionError = class extends Error {
|
|
40169
40175
|
/**
|
|
@@ -43363,6 +43369,13 @@ var ResourceRegistry = class {
|
|
|
43363
43369
|
}
|
|
43364
43370
|
seen.add(id);
|
|
43365
43371
|
}
|
|
43372
|
+
for (const id of incomingIds) {
|
|
43373
|
+
if (isReservedResourceId(id)) {
|
|
43374
|
+
throw new Error(
|
|
43375
|
+
`Resource ID '${id}' is reserved for platform use. External deployments cannot use reserved resource IDs.`
|
|
43376
|
+
);
|
|
43377
|
+
}
|
|
43378
|
+
}
|
|
43366
43379
|
if (this.isRemote(orgName)) {
|
|
43367
43380
|
this.unregisterOrganization(orgName);
|
|
43368
43381
|
}
|
|
@@ -43395,6 +43408,46 @@ var ResourceRegistry = class {
|
|
|
43395
43408
|
}
|
|
43396
43409
|
this.serializedCache.set(orgName, serializeOrganization(this.registry[orgName]));
|
|
43397
43410
|
}
|
|
43411
|
+
/**
|
|
43412
|
+
* Register built-in platform resources (static, local execution)
|
|
43413
|
+
*
|
|
43414
|
+
* Unlike registerOrganization(), these resources:
|
|
43415
|
+
* - Do NOT have remote config (execute in-process, not in worker threads)
|
|
43416
|
+
* - Are NOT removed by unregisterOrganization() (persist across redeployments)
|
|
43417
|
+
* - Use reserved resource IDs that external deployments cannot claim
|
|
43418
|
+
*
|
|
43419
|
+
* @param orgName - Organization name
|
|
43420
|
+
* @param org - Resource definitions with real handlers (not stubs)
|
|
43421
|
+
*/
|
|
43422
|
+
registerStaticResources(orgName, org) {
|
|
43423
|
+
const incomingWorkflowIds = (org.workflows ?? []).map((w) => w.config.resourceId);
|
|
43424
|
+
const incomingAgentIds = (org.agents ?? []).map((a) => a.config.resourceId);
|
|
43425
|
+
const incomingIds = [...incomingWorkflowIds, ...incomingAgentIds];
|
|
43426
|
+
const seen = /* @__PURE__ */ new Set();
|
|
43427
|
+
for (const id of incomingIds) {
|
|
43428
|
+
if (seen.has(id)) {
|
|
43429
|
+
throw new Error(`Duplicate resource ID '${id}' in static resources.`);
|
|
43430
|
+
}
|
|
43431
|
+
seen.add(id);
|
|
43432
|
+
}
|
|
43433
|
+
const existingOrg = this.registry[orgName];
|
|
43434
|
+
if (existingOrg) {
|
|
43435
|
+
const existingWorkflowIds = new Set((existingOrg.workflows ?? []).map((w) => w.config.resourceId));
|
|
43436
|
+
const existingAgentIds = new Set((existingOrg.agents ?? []).map((a) => a.config.resourceId));
|
|
43437
|
+
for (const id of incomingIds) {
|
|
43438
|
+
if (existingWorkflowIds.has(id) || existingAgentIds.has(id)) {
|
|
43439
|
+
throw new Error(`Static resource '${id}' conflicts with existing resource in '${orgName}'.`);
|
|
43440
|
+
}
|
|
43441
|
+
}
|
|
43442
|
+
}
|
|
43443
|
+
if (existingOrg) {
|
|
43444
|
+
existingOrg.workflows = [...existingOrg.workflows ?? [], ...org.workflows ?? []];
|
|
43445
|
+
existingOrg.agents = [...existingOrg.agents ?? [], ...org.agents ?? []];
|
|
43446
|
+
} else {
|
|
43447
|
+
this.registry[orgName] = org;
|
|
43448
|
+
}
|
|
43449
|
+
this.serializedCache.set(orgName, serializeOrganization(this.registry[orgName]));
|
|
43450
|
+
}
|
|
43398
43451
|
/**
|
|
43399
43452
|
* Unregister runtime-registered resources for an organization
|
|
43400
43453
|
*
|
|
@@ -43478,6 +43531,21 @@ var ResourceRegistry = class {
|
|
|
43478
43531
|
}
|
|
43479
43532
|
return null;
|
|
43480
43533
|
}
|
|
43534
|
+
/**
|
|
43535
|
+
* Get statistics about remotely-deployed resources
|
|
43536
|
+
* Used by the health endpoint for platform-wide deployment visibility.
|
|
43537
|
+
*/
|
|
43538
|
+
getRemoteStats() {
|
|
43539
|
+
const orgs = /* @__PURE__ */ new Set();
|
|
43540
|
+
for (const key of this.remoteResources.keys()) {
|
|
43541
|
+
const orgName = key.split("/")[0];
|
|
43542
|
+
orgs.add(orgName);
|
|
43543
|
+
}
|
|
43544
|
+
return {
|
|
43545
|
+
activeOrgs: orgs.size,
|
|
43546
|
+
totalResources: this.remoteResources.size
|
|
43547
|
+
};
|
|
43548
|
+
}
|
|
43481
43549
|
// ============================================================================
|
|
43482
43550
|
// Resource Manifest Accessors
|
|
43483
43551
|
// ============================================================================
|
|
@@ -43783,7 +43851,7 @@ async function apiDelete(endpoint, apiUrl = resolveApiUrl()) {
|
|
|
43783
43851
|
// package.json
|
|
43784
43852
|
var package_default = {
|
|
43785
43853
|
name: "@elevasis/sdk",
|
|
43786
|
-
version: "0.5.
|
|
43854
|
+
version: "0.5.15",
|
|
43787
43855
|
description: "SDK for building Elevasis organization resources",
|
|
43788
43856
|
type: "module",
|
|
43789
43857
|
bin: {
|
|
@@ -43869,9 +43937,7 @@ async function scanDocumentation() {
|
|
|
43869
43937
|
const raw = await (0, import_promises.readFile)(fullPath, "utf-8");
|
|
43870
43938
|
const fileSize = Buffer.byteLength(raw, "utf-8");
|
|
43871
43939
|
if (fileSize > 100 * 1024) {
|
|
43872
|
-
throw new Error(
|
|
43873
|
-
`Documentation file exceeds 100KB: docs/${relPath} (${Math.round(fileSize / 1024)}KB)`
|
|
43874
|
-
);
|
|
43940
|
+
throw new Error(`Documentation file exceeds 100KB: docs/${relPath} (${Math.round(fileSize / 1024)}KB)`);
|
|
43875
43941
|
}
|
|
43876
43942
|
totalSize += fileSize;
|
|
43877
43943
|
if (totalSize > 1024 * 1024) {
|
|
@@ -43924,7 +43990,9 @@ async function generateResourceMap(org) {
|
|
|
43924
43990
|
);
|
|
43925
43991
|
for (const w of workflows) {
|
|
43926
43992
|
const desc = escapeMdx(w.config.description);
|
|
43927
|
-
lines.push(
|
|
43993
|
+
lines.push(
|
|
43994
|
+
`| \`${w.config.resourceId}\` | ${escapeMdx(w.config.name)} | ${w.config.version} | ${w.config.status} | ${desc} |`
|
|
43995
|
+
);
|
|
43928
43996
|
}
|
|
43929
43997
|
lines.push("");
|
|
43930
43998
|
}
|
|
@@ -43937,11 +44005,16 @@ async function generateResourceMap(org) {
|
|
|
43937
44005
|
);
|
|
43938
44006
|
for (const a of agents) {
|
|
43939
44007
|
const desc = escapeMdx(a.config.description);
|
|
43940
|
-
lines.push(
|
|
44008
|
+
lines.push(
|
|
44009
|
+
`| \`${a.config.resourceId}\` | ${escapeMdx(a.config.name)} | ${a.config.version} | ${a.config.status} | ${desc} |`
|
|
44010
|
+
);
|
|
43941
44011
|
}
|
|
43942
44012
|
lines.push("");
|
|
43943
44013
|
}
|
|
43944
|
-
lines.push(
|
|
44014
|
+
lines.push(
|
|
44015
|
+
`**Total:** ${workflows.length + agents.length} resources (${workflows.length} workflows, ${agents.length} agents)`,
|
|
44016
|
+
""
|
|
44017
|
+
);
|
|
43945
44018
|
await (0, import_promises.mkdir)((0, import_path.resolve)("docs"), { recursive: true });
|
|
43946
44019
|
await (0, import_promises.writeFile)((0, import_path.resolve)("docs/resource-map.mdx"), lines.join("\n"), "utf-8");
|
|
43947
44020
|
}
|
|
@@ -44005,8 +44078,12 @@ async function generateProjectMap(org) {
|
|
|
44005
44078
|
if (resourceCount === 0) {
|
|
44006
44079
|
types = "(utilities)";
|
|
44007
44080
|
} else {
|
|
44008
|
-
const wCount = workflows.filter(
|
|
44009
|
-
|
|
44081
|
+
const wCount = workflows.filter(
|
|
44082
|
+
(w) => Array.isArray(w.config.domains) && w.config.domains.includes(domainName)
|
|
44083
|
+
).length;
|
|
44084
|
+
const aCount = agents.filter(
|
|
44085
|
+
(a) => Array.isArray(a.config.domains) && a.config.domains.includes(domainName)
|
|
44086
|
+
).length;
|
|
44010
44087
|
const parts = [];
|
|
44011
44088
|
if (wCount > 0) parts.push(`${wCount} workflow${wCount !== 1 ? "s" : ""}`);
|
|
44012
44089
|
if (aCount > 0) parts.push(`${aCount} agent${aCount !== 1 ? "s" : ""}`);
|
|
@@ -44118,10 +44195,7 @@ async function generateProjectMap(org) {
|
|
|
44118
44195
|
if (categories.length === 0) {
|
|
44119
44196
|
lines.push("SDK reference found but no categories parsed.", "");
|
|
44120
44197
|
} else {
|
|
44121
|
-
lines.push(
|
|
44122
|
-
"| Category | Files | Covers |",
|
|
44123
|
-
"| --- | --- | --- |"
|
|
44124
|
-
);
|
|
44198
|
+
lines.push("| Category | Files | Covers |", "| --- | --- | --- |");
|
|
44125
44199
|
for (const cat of categories) {
|
|
44126
44200
|
const covers = cat.titles.slice(0, 5).join(", ") + (cat.titles.length > 5 ? ", ..." : "");
|
|
44127
44201
|
lines.push(`| ${escapeMdx(cat.name)} | ${cat.count} | ${escapeMdx(covers)} |`);
|
|
@@ -44139,10 +44213,7 @@ async function generateProjectMap(org) {
|
|
|
44139
44213
|
if (cmdFiles.length === 0) {
|
|
44140
44214
|
lines.push("No commands found.", "");
|
|
44141
44215
|
} else {
|
|
44142
|
-
lines.push(
|
|
44143
|
-
"| Command | File | Purpose |",
|
|
44144
|
-
"| --- | --- | --- |"
|
|
44145
|
-
);
|
|
44216
|
+
lines.push("| Command | File | Purpose |", "| --- | --- | --- |");
|
|
44146
44217
|
for (const f of cmdFiles) {
|
|
44147
44218
|
const cmdName = f.name.replace(/\.md$/, "");
|
|
44148
44219
|
let purpose = "";
|
|
@@ -44171,10 +44242,7 @@ async function generateProjectMap(org) {
|
|
|
44171
44242
|
if (ruleFiles.length === 0) {
|
|
44172
44243
|
lines.push("No rules found.", "");
|
|
44173
44244
|
} else {
|
|
44174
|
-
lines.push(
|
|
44175
|
-
"| Rule | File | Scope |",
|
|
44176
|
-
"| --- | --- | --- |"
|
|
44177
|
-
);
|
|
44245
|
+
lines.push("| Rule | File | Scope |", "| --- | --- | --- |");
|
|
44178
44246
|
for (const f of ruleFiles) {
|
|
44179
44247
|
const ruleName = f.name.replace(/\.md$/, "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
44180
44248
|
let scope = "";
|
|
@@ -44205,10 +44273,7 @@ async function generateProjectMap(org) {
|
|
|
44205
44273
|
if (skillDirs.length === 0) {
|
|
44206
44274
|
lines.push("No skills found.", "");
|
|
44207
44275
|
} else {
|
|
44208
|
-
lines.push(
|
|
44209
|
-
"| Skill | File | Trigger |",
|
|
44210
|
-
"| --- | --- | --- |"
|
|
44211
|
-
);
|
|
44276
|
+
lines.push("| Skill | File | Trigger |", "| --- | --- | --- |");
|
|
44212
44277
|
for (const d of skillDirs) {
|
|
44213
44278
|
const skillFile = (0, import_path.resolve)(".claude/skills", d.name, "SKILL.md");
|
|
44214
44279
|
let trigger = "";
|
|
@@ -44264,10 +44329,7 @@ async function generateProjectMap(org) {
|
|
|
44264
44329
|
if (memoryFiles.length === 0) {
|
|
44265
44330
|
lines.push("No memory files found.", "");
|
|
44266
44331
|
} else {
|
|
44267
|
-
lines.push(
|
|
44268
|
-
"| File | Purpose | Last Modified |",
|
|
44269
|
-
"| --- | --- | --- |"
|
|
44270
|
-
);
|
|
44332
|
+
lines.push("| File | Purpose | Last Modified |", "| --- | --- | --- |");
|
|
44271
44333
|
for (const m of memoryFiles) {
|
|
44272
44334
|
lines.push(`| .claude/memory/${m.rel} | ${escapeMdx(m.purpose)} | ${m.mtime} |`);
|
|
44273
44335
|
}
|
|
@@ -44299,250 +44361,293 @@ async function generateProjectMap(org) {
|
|
|
44299
44361
|
await (0, import_promises.mkdir)((0, import_path.resolve)("docs"), { recursive: true });
|
|
44300
44362
|
await (0, import_promises.writeFile)((0, import_path.resolve)("docs/project-map.mdx"), lines.join("\n"), "utf-8");
|
|
44301
44363
|
}
|
|
44364
|
+
async function generateNavigationMap(docs) {
|
|
44365
|
+
const excludedFiles = /* @__PURE__ */ new Set(["docs/navigation-map.mdx", "docs/project-map.mdx", "docs/resource-map.mdx"]);
|
|
44366
|
+
const filtered = docs.filter((doc) => !excludedFiles.has(doc.path)).sort((a, b) => {
|
|
44367
|
+
const orderA = a.frontmatter.order ?? 9999;
|
|
44368
|
+
const orderB = b.frontmatter.order ?? 9999;
|
|
44369
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
44370
|
+
return a.frontmatter.title.localeCompare(b.frontmatter.title);
|
|
44371
|
+
});
|
|
44372
|
+
const lines = [
|
|
44373
|
+
"---",
|
|
44374
|
+
"title: Navigation Map",
|
|
44375
|
+
"description: Auto-generated table of contents for all documentation (updated on each deploy)",
|
|
44376
|
+
"order: 997",
|
|
44377
|
+
"---",
|
|
44378
|
+
"",
|
|
44379
|
+
"# Navigation Map",
|
|
44380
|
+
"",
|
|
44381
|
+
"> Auto-generated by `elevasis-sdk deploy`. Do not edit manually.",
|
|
44382
|
+
"",
|
|
44383
|
+
"| Title | Description | Path |",
|
|
44384
|
+
"| --- | --- | --- |"
|
|
44385
|
+
];
|
|
44386
|
+
for (const doc of filtered) {
|
|
44387
|
+
lines.push(`| ${escapeMdx(doc.frontmatter.title)} | ${escapeMdx(doc.frontmatter.description)} | ${doc.path} |`);
|
|
44388
|
+
}
|
|
44389
|
+
lines.push("");
|
|
44390
|
+
await (0, import_promises.mkdir)((0, import_path.resolve)("docs"), { recursive: true });
|
|
44391
|
+
await (0, import_promises.writeFile)((0, import_path.resolve)("docs/navigation-map.mdx"), lines.join("\n"), "utf-8");
|
|
44392
|
+
}
|
|
44302
44393
|
function registerDeployCommand(program3) {
|
|
44303
|
-
program3.command("deploy").description(
|
|
44304
|
-
|
|
44305
|
-
|
|
44306
|
-
|
|
44307
|
-
|
|
44308
|
-
|
|
44309
|
-
|
|
44310
|
-
|
|
44311
|
-
const
|
|
44312
|
-
orgName
|
|
44313
|
-
|
|
44314
|
-
|
|
44315
|
-
|
|
44316
|
-
|
|
44317
|
-
|
|
44318
|
-
|
|
44319
|
-
|
|
44320
|
-
|
|
44321
|
-
|
|
44322
|
-
|
|
44323
|
-
|
|
44324
|
-
|
|
44325
|
-
|
|
44394
|
+
program3.command("deploy").description(
|
|
44395
|
+
"Validate, bundle, upload, and deploy project resources\n Example: elevasis-sdk deploy --api-url http://localhost:5170"
|
|
44396
|
+
).option("--api-url <url>", "API URL").option("--entry <path>", "Path to entry file (default: ./src/index.ts)").option("--prod", "Deploy to production (overrides NODE_ENV=development)").action(
|
|
44397
|
+
wrapAction("deploy", async (options2) => {
|
|
44398
|
+
const startTime = Date.now();
|
|
44399
|
+
const apiUrl = resolveApiUrl(options2.apiUrl, options2.prod);
|
|
44400
|
+
const env2 = resolveEnvironment(options2.prod);
|
|
44401
|
+
const entryPath = options2.entry ?? "./src/index.ts";
|
|
44402
|
+
const authSpinner = ora("Authenticating...").start();
|
|
44403
|
+
let orgName;
|
|
44404
|
+
try {
|
|
44405
|
+
const me = await apiGet("/api/external/me", apiUrl);
|
|
44406
|
+
orgName = me.organizationName;
|
|
44407
|
+
authSpinner.succeed(
|
|
44408
|
+
source_default.green("Authenticating...") + source_default.white(" done") + source_default.gray(` (${orgName})`)
|
|
44409
|
+
);
|
|
44410
|
+
} catch (error46) {
|
|
44411
|
+
authSpinner.fail(source_default.red("Authentication failed"));
|
|
44412
|
+
const errMsg = error46 instanceof Error ? error46.message : String(error46);
|
|
44413
|
+
if (errMsg.includes("401") || errMsg.toLowerCase().includes("unauthorized")) {
|
|
44414
|
+
const keyVar = !options2.prod && process.env.NODE_ENV === "development" && process.env.ELEVASIS_PLATFORM_KEY_DEV ? "ELEVASIS_PLATFORM_KEY_DEV" : "ELEVASIS_PLATFORM_KEY";
|
|
44415
|
+
console.error(source_default.red(" Invalid API key."));
|
|
44416
|
+
console.error(source_default.gray(` Your ${keyVar} was rejected by the server.`));
|
|
44417
|
+
console.error(source_default.gray(" Check your .env file and verify the key in the Elevasis dashboard."));
|
|
44418
|
+
} else {
|
|
44419
|
+
console.error(source_default.gray(" Check your API key and API URL."));
|
|
44420
|
+
}
|
|
44421
|
+
throw error46;
|
|
44326
44422
|
}
|
|
44327
|
-
|
|
44328
|
-
|
|
44329
|
-
|
|
44330
|
-
|
|
44331
|
-
|
|
44332
|
-
|
|
44333
|
-
|
|
44334
|
-
|
|
44335
|
-
|
|
44336
|
-
|
|
44337
|
-
|
|
44338
|
-
|
|
44423
|
+
const validateSpinner = ora("Validating...").start();
|
|
44424
|
+
let org;
|
|
44425
|
+
try {
|
|
44426
|
+
const jiti = (0, import_jiti.createJiti)(import_meta.url);
|
|
44427
|
+
const entryModule = await jiti.import((0, import_path.resolve)(entryPath));
|
|
44428
|
+
org = entryModule.default;
|
|
44429
|
+
if (!org) {
|
|
44430
|
+
validateSpinner.fail("Invalid entry: no default export found");
|
|
44431
|
+
console.error(source_default.gray(` Entry file: ${(0, import_path.resolve)(entryPath)}`));
|
|
44432
|
+
throw new Error("Invalid entry: no default export found");
|
|
44433
|
+
}
|
|
44434
|
+
new ResourceRegistry({ [orgName]: org });
|
|
44435
|
+
const workflowCount = org.workflows?.length ?? 0;
|
|
44436
|
+
const agentCount = org.agents?.length ?? 0;
|
|
44437
|
+
const totalCount = workflowCount + agentCount;
|
|
44438
|
+
validateSpinner.succeed(
|
|
44439
|
+
source_default.green("Validating...") + source_default.white(" done") + source_default.gray(` (${totalCount} resource${totalCount !== 1 ? "s" : ""}, 0 errors)`)
|
|
44440
|
+
);
|
|
44441
|
+
console.log("");
|
|
44442
|
+
console.log(source_default.gray(` Org: ${orgName}`));
|
|
44443
|
+
console.log(source_default.gray(` Target: ${apiUrl} (${env2})`));
|
|
44444
|
+
console.log("");
|
|
44445
|
+
for (const w of org.workflows ?? []) {
|
|
44446
|
+
console.log(source_default.gray(` workflow ${source_default.white(w.config.resourceId)} v${w.config.version}`));
|
|
44447
|
+
}
|
|
44448
|
+
for (const a of org.agents ?? []) {
|
|
44449
|
+
console.log(source_default.gray(` agent ${source_default.white(a.config.resourceId)} v${a.config.version}`));
|
|
44450
|
+
}
|
|
44451
|
+
console.log("");
|
|
44452
|
+
} catch (error46) {
|
|
44453
|
+
if (error46 instanceof RegistryValidationError) {
|
|
44454
|
+
validateSpinner.fail(source_default.red("Validation failed"));
|
|
44455
|
+
console.error("");
|
|
44456
|
+
console.error(source_default.red(` ERROR ${error46.message}`));
|
|
44457
|
+
if (error46.resourceId) {
|
|
44458
|
+
console.error(source_default.gray(` Resource: ${error46.resourceId}`));
|
|
44459
|
+
}
|
|
44460
|
+
console.error("");
|
|
44461
|
+
console.error(source_default.gray(" Deploy aborted."));
|
|
44462
|
+
}
|
|
44463
|
+
throw error46;
|
|
44339
44464
|
}
|
|
44340
|
-
|
|
44341
|
-
|
|
44342
|
-
|
|
44343
|
-
|
|
44344
|
-
|
|
44345
|
-
|
|
44346
|
-
|
|
44347
|
-
|
|
44348
|
-
|
|
44349
|
-
|
|
44350
|
-
|
|
44351
|
-
for (const w of org.workflows ?? []) {
|
|
44352
|
-
console.log(source_default.gray(` workflow ${source_default.white(w.config.resourceId)} v${w.config.version}`));
|
|
44465
|
+
await generateResourceMap(org);
|
|
44466
|
+
await generateProjectMap(org);
|
|
44467
|
+
let documentation = await scanDocumentation();
|
|
44468
|
+
if (documentation) {
|
|
44469
|
+
await generateNavigationMap(documentation);
|
|
44470
|
+
documentation = await scanDocumentation();
|
|
44471
|
+
console.log(
|
|
44472
|
+
source_default.gray(
|
|
44473
|
+
` docs ${source_default.white(String(documentation.length))} file${documentation.length !== 1 ? "s" : ""}`
|
|
44474
|
+
)
|
|
44475
|
+
);
|
|
44353
44476
|
}
|
|
44354
|
-
|
|
44355
|
-
|
|
44477
|
+
const triggerCount = org.triggers?.length ?? 0;
|
|
44478
|
+
const integrationCount = org.integrations?.length ?? 0;
|
|
44479
|
+
const checkpointCount = org.humanCheckpoints?.length ?? 0;
|
|
44480
|
+
if (triggerCount > 0) console.log(source_default.gray(` triggers ${source_default.white(String(triggerCount))}`));
|
|
44481
|
+
if (integrationCount > 0) console.log(source_default.gray(` integrations ${source_default.white(String(integrationCount))}`));
|
|
44482
|
+
if (checkpointCount > 0) console.log(source_default.gray(` checkpoints ${source_default.white(String(checkpointCount))}`));
|
|
44483
|
+
const relationshipCount = org.relationships ? Object.keys(org.relationships).length : 0;
|
|
44484
|
+
if (relationshipCount > 0) {
|
|
44485
|
+
console.log(
|
|
44486
|
+
source_default.gray(
|
|
44487
|
+
` rels ${source_default.white(String(relationshipCount))} resource${relationshipCount !== 1 ? "s" : ""}`
|
|
44488
|
+
)
|
|
44489
|
+
);
|
|
44356
44490
|
}
|
|
44357
|
-
|
|
44358
|
-
|
|
44359
|
-
|
|
44360
|
-
|
|
44361
|
-
|
|
44362
|
-
|
|
44363
|
-
|
|
44364
|
-
|
|
44491
|
+
const schemaWarnings = [];
|
|
44492
|
+
const workflows = (org.workflows ?? []).map((w) => {
|
|
44493
|
+
const meta = {
|
|
44494
|
+
resourceId: w.config.resourceId,
|
|
44495
|
+
name: w.config.name,
|
|
44496
|
+
version: w.config.version,
|
|
44497
|
+
status: w.config.status,
|
|
44498
|
+
description: w.config.description,
|
|
44499
|
+
domains: w.config.domains
|
|
44500
|
+
};
|
|
44501
|
+
if (w.contract.inputSchema) {
|
|
44502
|
+
try {
|
|
44503
|
+
meta.inputSchema = external_exports.toJSONSchema(w.contract.inputSchema);
|
|
44504
|
+
} catch {
|
|
44505
|
+
schemaWarnings.push(`${w.config.resourceId}: inputSchema could not be serialized`);
|
|
44506
|
+
}
|
|
44365
44507
|
}
|
|
44366
|
-
|
|
44367
|
-
|
|
44368
|
-
|
|
44369
|
-
|
|
44370
|
-
|
|
44371
|
-
|
|
44372
|
-
await generateProjectMap(org);
|
|
44373
|
-
const documentation = await scanDocumentation();
|
|
44374
|
-
if (documentation) {
|
|
44375
|
-
console.log(source_default.gray(` docs ${source_default.white(String(documentation.length))} file${documentation.length !== 1 ? "s" : ""}`));
|
|
44376
|
-
}
|
|
44377
|
-
const triggerCount = org.triggers?.length ?? 0;
|
|
44378
|
-
const integrationCount = org.integrations?.length ?? 0;
|
|
44379
|
-
const checkpointCount = org.humanCheckpoints?.length ?? 0;
|
|
44380
|
-
if (triggerCount > 0) console.log(source_default.gray(` triggers ${source_default.white(String(triggerCount))}`));
|
|
44381
|
-
if (integrationCount > 0) console.log(source_default.gray(` integrations ${source_default.white(String(integrationCount))}`));
|
|
44382
|
-
if (checkpointCount > 0) console.log(source_default.gray(` checkpoints ${source_default.white(String(checkpointCount))}`));
|
|
44383
|
-
const relationshipCount = org.relationships ? Object.keys(org.relationships).length : 0;
|
|
44384
|
-
if (relationshipCount > 0) {
|
|
44385
|
-
console.log(source_default.gray(` rels ${source_default.white(String(relationshipCount))} resource${relationshipCount !== 1 ? "s" : ""}`));
|
|
44386
|
-
}
|
|
44387
|
-
const schemaWarnings = [];
|
|
44388
|
-
const workflows = (org.workflows ?? []).map((w) => {
|
|
44389
|
-
const meta = {
|
|
44390
|
-
resourceId: w.config.resourceId,
|
|
44391
|
-
name: w.config.name,
|
|
44392
|
-
version: w.config.version,
|
|
44393
|
-
status: w.config.status,
|
|
44394
|
-
description: w.config.description,
|
|
44395
|
-
domains: w.config.domains
|
|
44396
|
-
};
|
|
44397
|
-
if (w.contract.inputSchema) {
|
|
44398
|
-
try {
|
|
44399
|
-
meta.inputSchema = external_exports.toJSONSchema(w.contract.inputSchema);
|
|
44400
|
-
} catch {
|
|
44401
|
-
schemaWarnings.push(`${w.config.resourceId}: inputSchema could not be serialized`);
|
|
44508
|
+
if (w.contract.outputSchema) {
|
|
44509
|
+
try {
|
|
44510
|
+
meta.outputSchema = external_exports.toJSONSchema(w.contract.outputSchema);
|
|
44511
|
+
} catch {
|
|
44512
|
+
schemaWarnings.push(`${w.config.resourceId}: outputSchema could not be serialized`);
|
|
44513
|
+
}
|
|
44402
44514
|
}
|
|
44403
|
-
|
|
44404
|
-
|
|
44405
|
-
|
|
44406
|
-
|
|
44407
|
-
|
|
44408
|
-
|
|
44515
|
+
return meta;
|
|
44516
|
+
});
|
|
44517
|
+
const agents = (org.agents ?? []).map((a) => {
|
|
44518
|
+
const meta = {
|
|
44519
|
+
resourceId: a.config.resourceId,
|
|
44520
|
+
name: a.config.name,
|
|
44521
|
+
version: a.config.version,
|
|
44522
|
+
status: a.config.status,
|
|
44523
|
+
description: a.config.description,
|
|
44524
|
+
domains: a.config.domains
|
|
44525
|
+
};
|
|
44526
|
+
if (a.contract.inputSchema) {
|
|
44527
|
+
try {
|
|
44528
|
+
meta.inputSchema = external_exports.toJSONSchema(a.contract.inputSchema);
|
|
44529
|
+
} catch {
|
|
44530
|
+
schemaWarnings.push(`${a.config.resourceId}: inputSchema could not be serialized`);
|
|
44531
|
+
}
|
|
44409
44532
|
}
|
|
44410
|
-
|
|
44411
|
-
|
|
44412
|
-
|
|
44413
|
-
|
|
44414
|
-
|
|
44415
|
-
|
|
44416
|
-
name: a.config.name,
|
|
44417
|
-
version: a.config.version,
|
|
44418
|
-
status: a.config.status,
|
|
44419
|
-
description: a.config.description,
|
|
44420
|
-
domains: a.config.domains
|
|
44421
|
-
};
|
|
44422
|
-
if (a.contract.inputSchema) {
|
|
44423
|
-
try {
|
|
44424
|
-
meta.inputSchema = external_exports.toJSONSchema(a.contract.inputSchema);
|
|
44425
|
-
} catch {
|
|
44426
|
-
schemaWarnings.push(`${a.config.resourceId}: inputSchema could not be serialized`);
|
|
44533
|
+
if (a.contract.outputSchema) {
|
|
44534
|
+
try {
|
|
44535
|
+
meta.outputSchema = external_exports.toJSONSchema(a.contract.outputSchema);
|
|
44536
|
+
} catch {
|
|
44537
|
+
schemaWarnings.push(`${a.config.resourceId}: outputSchema could not be serialized`);
|
|
44538
|
+
}
|
|
44427
44539
|
}
|
|
44428
|
-
|
|
44429
|
-
|
|
44430
|
-
|
|
44431
|
-
|
|
44432
|
-
|
|
44433
|
-
schemaWarnings.push(`${a.config.resourceId}: outputSchema could not be serialized`);
|
|
44540
|
+
return meta;
|
|
44541
|
+
});
|
|
44542
|
+
if (schemaWarnings.length > 0) {
|
|
44543
|
+
for (const warning of schemaWarnings) {
|
|
44544
|
+
console.log(source_default.yellow(` warn ${warning}`));
|
|
44434
44545
|
}
|
|
44546
|
+
console.log(source_default.gray(" Schemas will be unavailable on the platform for these resources."));
|
|
44547
|
+
console.log("");
|
|
44435
44548
|
}
|
|
44436
|
-
|
|
44437
|
-
|
|
44438
|
-
|
|
44439
|
-
|
|
44440
|
-
|
|
44441
|
-
|
|
44442
|
-
console.log(source_default.gray(" Schemas will be unavailable on the platform for these resources."));
|
|
44443
|
-
console.log("");
|
|
44444
|
-
}
|
|
44445
|
-
const bundleSpinner = ora("Bundling...").start();
|
|
44446
|
-
const wrapperPath = (0, import_path.resolve)("__elevasis_worker.ts");
|
|
44447
|
-
const bundleOutfile = (0, import_path.resolve)("dist/bundle.js");
|
|
44448
|
-
try {
|
|
44449
|
-
const entryImport = entryPath.replace(/\.ts$/, ".js");
|
|
44450
|
-
const wrapperContent = `import org from ${JSON.stringify(entryImport)}
|
|
44549
|
+
const bundleSpinner = ora("Bundling...").start();
|
|
44550
|
+
const wrapperPath = (0, import_path.resolve)("__elevasis_worker.ts");
|
|
44551
|
+
const bundleOutfile = (0, import_path.resolve)("dist/bundle.js");
|
|
44552
|
+
try {
|
|
44553
|
+
const entryImport = entryPath.replace(/\.ts$/, ".js");
|
|
44554
|
+
const wrapperContent = `import org from ${JSON.stringify(entryImport)}
|
|
44451
44555
|
import { startWorker } from '@elevasis/sdk/worker'
|
|
44452
44556
|
startWorker(org)
|
|
44453
44557
|
`;
|
|
44454
|
-
|
|
44455
|
-
|
|
44456
|
-
|
|
44457
|
-
|
|
44458
|
-
|
|
44459
|
-
|
|
44460
|
-
|
|
44461
|
-
|
|
44462
|
-
|
|
44463
|
-
await (0, import_promises.unlink)(wrapperPath);
|
|
44464
|
-
const bundleBuffer = await (0, import_promises.readFile)(bundleOutfile);
|
|
44465
|
-
const bundleSizeKB = Math.round(bundleBuffer.length / 1024);
|
|
44466
|
-
bundleSpinner.succeed(
|
|
44467
|
-
source_default.green("Bundling...") + source_default.white(" done") + source_default.gray(` (${bundleSizeKB} KB)`)
|
|
44468
|
-
);
|
|
44469
|
-
} catch (error46) {
|
|
44470
|
-
try {
|
|
44558
|
+
await (0, import_promises.writeFile)(wrapperPath, wrapperContent, "utf-8");
|
|
44559
|
+
await (0, import_promises.mkdir)((0, import_path.resolve)("dist"), { recursive: true });
|
|
44560
|
+
await esbuild.build({
|
|
44561
|
+
entryPoints: [wrapperPath],
|
|
44562
|
+
bundle: true,
|
|
44563
|
+
platform: "node",
|
|
44564
|
+
format: "cjs",
|
|
44565
|
+
outfile: bundleOutfile
|
|
44566
|
+
});
|
|
44471
44567
|
await (0, import_promises.unlink)(wrapperPath);
|
|
44472
|
-
|
|
44568
|
+
const bundleBuffer = await (0, import_promises.readFile)(bundleOutfile);
|
|
44569
|
+
const bundleSizeKB = Math.round(bundleBuffer.length / 1024);
|
|
44570
|
+
bundleSpinner.succeed(
|
|
44571
|
+
source_default.green("Bundling...") + source_default.white(" done") + source_default.gray(` (${bundleSizeKB} KB)`)
|
|
44572
|
+
);
|
|
44573
|
+
} catch (error46) {
|
|
44574
|
+
try {
|
|
44575
|
+
await (0, import_promises.unlink)(wrapperPath);
|
|
44576
|
+
} catch {
|
|
44577
|
+
}
|
|
44578
|
+
bundleSpinner.fail(source_default.red("Bundling failed"));
|
|
44579
|
+
throw error46;
|
|
44473
44580
|
}
|
|
44474
|
-
|
|
44475
|
-
|
|
44476
|
-
|
|
44477
|
-
|
|
44478
|
-
|
|
44479
|
-
|
|
44480
|
-
|
|
44481
|
-
|
|
44482
|
-
|
|
44483
|
-
|
|
44484
|
-
|
|
44485
|
-
|
|
44486
|
-
|
|
44487
|
-
console.error(source_default.gray(" ELEVASIS_PLATFORM_KEY=sk_..."));
|
|
44488
|
-
}
|
|
44489
|
-
throw new Error("Missing API key environment variable");
|
|
44490
|
-
}
|
|
44491
|
-
const metadata = {
|
|
44492
|
-
sdkVersion: SDK_VERSION,
|
|
44493
|
-
mode: env2,
|
|
44494
|
-
resources: { workflows, agents },
|
|
44495
|
-
...documentation ? { documentation } : {},
|
|
44496
|
-
...org.relationships ? { relationships: org.relationships } : {}
|
|
44497
|
-
};
|
|
44498
|
-
const form = new FormData();
|
|
44499
|
-
form.append("bundle", new Blob([bundleBuffer]), "bundle.js");
|
|
44500
|
-
form.append("metadata", JSON.stringify(metadata));
|
|
44501
|
-
const response = await fetch(`${apiUrl}/api/external/deploy`, {
|
|
44502
|
-
method: "POST",
|
|
44503
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
44504
|
-
body: form
|
|
44505
|
-
});
|
|
44506
|
-
if (!response.ok) {
|
|
44507
|
-
const errorText = await response.text();
|
|
44508
|
-
uploadSpinner.fail(source_default.red("Upload failed"));
|
|
44509
|
-
console.error(source_default.red(` ${response.status}: ${errorText}`));
|
|
44510
|
-
throw new Error(`Deploy upload failed (${response.status}): ${errorText}`);
|
|
44511
|
-
}
|
|
44512
|
-
const result = await response.json();
|
|
44513
|
-
uploadSpinner.succeed(
|
|
44514
|
-
source_default.green("Uploading...") + source_default.white(" done")
|
|
44515
|
-
);
|
|
44516
|
-
const totalResources = (org.workflows?.length ?? 0) + (org.agents?.length ?? 0);
|
|
44517
|
-
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
44518
|
-
if (result.status === "active") {
|
|
44519
|
-
console.log("");
|
|
44520
|
-
console.log(source_default.green.bold(` Deployed! ${totalResources} resource${totalResources !== 1 ? "s" : ""} live.`));
|
|
44521
|
-
if (result.deployId) {
|
|
44522
|
-
console.log(source_default.gray(` Version: ${result.deployId}`));
|
|
44581
|
+
const uploadSpinner = ora("Uploading...").start();
|
|
44582
|
+
try {
|
|
44583
|
+
const bundleBuffer = await (0, import_promises.readFile)(bundleOutfile);
|
|
44584
|
+
const apiKey = resolveApiKey(options2.prod);
|
|
44585
|
+
if (!apiKey) {
|
|
44586
|
+
uploadSpinner.fail(source_default.red("Missing API key environment variable"));
|
|
44587
|
+
console.error(source_default.gray(" Set it in your .env file or shell environment:"));
|
|
44588
|
+
if (!options2.prod && process.env.NODE_ENV === "development") {
|
|
44589
|
+
console.error(source_default.gray(" ELEVASIS_PLATFORM_KEY_DEV=sk_... (or ELEVASIS_PLATFORM_KEY as fallback)"));
|
|
44590
|
+
} else {
|
|
44591
|
+
console.error(source_default.gray(" ELEVASIS_PLATFORM_KEY=sk_..."));
|
|
44592
|
+
}
|
|
44593
|
+
throw new Error("Missing API key environment variable");
|
|
44523
44594
|
}
|
|
44524
|
-
|
|
44525
|
-
|
|
44526
|
-
|
|
44527
|
-
|
|
44528
|
-
|
|
44529
|
-
|
|
44595
|
+
const metadata = {
|
|
44596
|
+
sdkVersion: SDK_VERSION,
|
|
44597
|
+
mode: env2,
|
|
44598
|
+
resources: { workflows, agents },
|
|
44599
|
+
...documentation ? { documentation } : {},
|
|
44600
|
+
...org.relationships ? { relationships: org.relationships } : {}
|
|
44601
|
+
};
|
|
44602
|
+
const form = new FormData();
|
|
44603
|
+
form.append("bundle", new Blob([bundleBuffer]), "bundle.js");
|
|
44604
|
+
form.append("metadata", JSON.stringify(metadata));
|
|
44605
|
+
const response = await fetch(`${apiUrl}/api/external/deploy`, {
|
|
44606
|
+
method: "POST",
|
|
44607
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
44608
|
+
body: form
|
|
44609
|
+
});
|
|
44610
|
+
if (!response.ok) {
|
|
44611
|
+
const errorText = await response.text();
|
|
44612
|
+
uploadSpinner.fail(source_default.red("Upload failed"));
|
|
44613
|
+
console.error(source_default.red(` ${response.status}: ${errorText}`));
|
|
44614
|
+
throw new Error(`Deploy upload failed (${response.status}): ${errorText}`);
|
|
44615
|
+
}
|
|
44616
|
+
const result = await response.json();
|
|
44617
|
+
uploadSpinner.succeed(source_default.green("Uploading...") + source_default.white(" done"));
|
|
44618
|
+
const totalResources = (org.workflows?.length ?? 0) + (org.agents?.length ?? 0);
|
|
44619
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
44620
|
+
if (result.status === "active") {
|
|
44621
|
+
console.log("");
|
|
44622
|
+
console.log(
|
|
44623
|
+
source_default.green.bold(` Deployed! ${totalResources} resource${totalResources !== 1 ? "s" : ""} live.`)
|
|
44624
|
+
);
|
|
44625
|
+
if (result.deployId) {
|
|
44626
|
+
console.log(source_default.gray(` Version: ${result.deployId}`));
|
|
44627
|
+
}
|
|
44628
|
+
console.log(source_default.gray(` Duration: ${elapsed}s`));
|
|
44629
|
+
} else if (result.status === "failed") {
|
|
44630
|
+
console.log("");
|
|
44631
|
+
console.log(source_default.red.bold(" Deploy failed."));
|
|
44632
|
+
if (result.error) {
|
|
44633
|
+
console.error(source_default.red(` ${result.error}`));
|
|
44634
|
+
}
|
|
44635
|
+
throw new Error(`Deploy failed: ${result.error ?? "unknown error"}`);
|
|
44636
|
+
} else {
|
|
44637
|
+
console.log("");
|
|
44638
|
+
console.log(source_default.yellow(` Deploy status: ${result.status ?? "unknown"}`));
|
|
44639
|
+
if (result.deployId) {
|
|
44640
|
+
console.log(source_default.gray(` Version: ${result.deployId}`));
|
|
44641
|
+
}
|
|
44530
44642
|
}
|
|
44531
|
-
|
|
44532
|
-
|
|
44533
|
-
|
|
44534
|
-
console.log(source_default.yellow(` Deploy status: ${result.status ?? "unknown"}`));
|
|
44535
|
-
if (result.deployId) {
|
|
44536
|
-
console.log(source_default.gray(` Version: ${result.deployId}`));
|
|
44643
|
+
} catch (error46) {
|
|
44644
|
+
if (uploadSpinner.isSpinning) {
|
|
44645
|
+
uploadSpinner.fail(source_default.red("Deploy failed"));
|
|
44537
44646
|
}
|
|
44647
|
+
throw error46;
|
|
44538
44648
|
}
|
|
44539
|
-
}
|
|
44540
|
-
|
|
44541
|
-
uploadSpinner.fail(source_default.red("Deploy failed"));
|
|
44542
|
-
}
|
|
44543
|
-
throw error46;
|
|
44544
|
-
}
|
|
44545
|
-
}));
|
|
44649
|
+
})
|
|
44650
|
+
);
|
|
44546
44651
|
}
|
|
44547
44652
|
|
|
44548
44653
|
// src/cli/commands/check.ts
|
|
@@ -45075,7 +45180,7 @@ var import_path3 = require("path");
|
|
|
45075
45180
|
var import_promises2 = require("fs/promises");
|
|
45076
45181
|
|
|
45077
45182
|
// src/cli/commands/templates/core/workspace.ts
|
|
45078
|
-
var TEMPLATE_VERSION =
|
|
45183
|
+
var TEMPLATE_VERSION = 28;
|
|
45079
45184
|
function configTemplate() {
|
|
45080
45185
|
return `import type { ElevasConfig } from '@elevasis/sdk'
|
|
45081
45186
|
|
|
@@ -45087,44 +45192,52 @@ export default {
|
|
|
45087
45192
|
`;
|
|
45088
45193
|
}
|
|
45089
45194
|
function packageJsonTemplate(organization) {
|
|
45090
|
-
return JSON.stringify(
|
|
45091
|
-
|
|
45092
|
-
|
|
45093
|
-
|
|
45094
|
-
|
|
45095
|
-
|
|
45096
|
-
|
|
45097
|
-
|
|
45098
|
-
|
|
45099
|
-
|
|
45100
|
-
|
|
45195
|
+
return JSON.stringify(
|
|
45196
|
+
{
|
|
45197
|
+
name: organization,
|
|
45198
|
+
private: true,
|
|
45199
|
+
type: "module",
|
|
45200
|
+
scripts: {
|
|
45201
|
+
"check-types": "tsc --noEmit",
|
|
45202
|
+
check: "elevasis-sdk check",
|
|
45203
|
+
deploy: "elevasis-sdk deploy"
|
|
45204
|
+
},
|
|
45205
|
+
dependencies: {
|
|
45206
|
+
"@elevasis/sdk": `^${SDK_VERSION}`
|
|
45207
|
+
},
|
|
45208
|
+
devDependencies: {
|
|
45209
|
+
typescript: "5.9.2",
|
|
45210
|
+
zod: "4.1.12"
|
|
45211
|
+
}
|
|
45101
45212
|
},
|
|
45102
|
-
|
|
45103
|
-
|
|
45104
|
-
|
|
45105
|
-
}
|
|
45106
|
-
}, null, 2) + "\n";
|
|
45213
|
+
null,
|
|
45214
|
+
2
|
|
45215
|
+
) + "\n";
|
|
45107
45216
|
}
|
|
45108
45217
|
function pnpmWorkspaceTemplate() {
|
|
45109
45218
|
return `packages: []
|
|
45110
45219
|
`;
|
|
45111
45220
|
}
|
|
45112
45221
|
function tsconfigTemplate() {
|
|
45113
|
-
return JSON.stringify(
|
|
45114
|
-
|
|
45115
|
-
|
|
45116
|
-
|
|
45117
|
-
|
|
45118
|
-
|
|
45119
|
-
|
|
45120
|
-
|
|
45121
|
-
|
|
45122
|
-
|
|
45123
|
-
|
|
45222
|
+
return JSON.stringify(
|
|
45223
|
+
{
|
|
45224
|
+
compilerOptions: {
|
|
45225
|
+
target: "ES2022",
|
|
45226
|
+
module: "ESNext",
|
|
45227
|
+
moduleResolution: "Bundler",
|
|
45228
|
+
strict: true,
|
|
45229
|
+
esModuleInterop: true,
|
|
45230
|
+
skipLibCheck: true,
|
|
45231
|
+
forceConsistentCasingInFileNames: true,
|
|
45232
|
+
isolatedModules: true,
|
|
45233
|
+
outDir: "./dist"
|
|
45234
|
+
},
|
|
45235
|
+
include: ["src"],
|
|
45236
|
+
exclude: ["node_modules", "dist"]
|
|
45124
45237
|
},
|
|
45125
|
-
|
|
45126
|
-
|
|
45127
|
-
|
|
45238
|
+
null,
|
|
45239
|
+
2
|
|
45240
|
+
) + "\n";
|
|
45128
45241
|
}
|
|
45129
45242
|
function envTemplate() {
|
|
45130
45243
|
return `ELEVASIS_PLATFORM_KEY=
|
|
@@ -45242,6 +45355,28 @@ function claudeSettingsTemplate() {
|
|
|
45242
45355
|
}
|
|
45243
45356
|
]
|
|
45244
45357
|
}
|
|
45358
|
+
],
|
|
45359
|
+
PostToolUse: [
|
|
45360
|
+
{
|
|
45361
|
+
matcher: "Write|Edit|MultiEdit",
|
|
45362
|
+
hooks: [
|
|
45363
|
+
{
|
|
45364
|
+
type: "command",
|
|
45365
|
+
command: "node .claude/hooks/post-edit-validate.mjs"
|
|
45366
|
+
}
|
|
45367
|
+
]
|
|
45368
|
+
}
|
|
45369
|
+
],
|
|
45370
|
+
PostToolUseFailure: [
|
|
45371
|
+
{
|
|
45372
|
+
matcher: "Bash",
|
|
45373
|
+
hooks: [
|
|
45374
|
+
{
|
|
45375
|
+
type: "command",
|
|
45376
|
+
command: "node .claude/hooks/tool-failure-recovery.mjs"
|
|
45377
|
+
}
|
|
45378
|
+
]
|
|
45379
|
+
}
|
|
45245
45380
|
]
|
|
45246
45381
|
}
|
|
45247
45382
|
},
|
|
@@ -45450,16 +45585,16 @@ proactivity -- to their assessed levels.
|
|
|
45450
45585
|
|
|
45451
45586
|
| Resource | Location | When to Load |
|
|
45452
45587
|
| --- | --- | --- |
|
|
45453
|
-
| Workspace concepts | \`reference/concepts
|
|
45588
|
+
| Workspace concepts | \`reference/concepts.mdx\` | User asks "what is...?" or needs conceptual grounding |
|
|
45454
45589
|
| SDK patterns and examples | \`reference/resources/patterns.mdx\` | Building or modifying a workflow |
|
|
45455
45590
|
| Platform tool catalog | \`reference/platform-tools/index.mdx\` | Connecting to external services |
|
|
45456
|
-
| CLI reference | \`reference/cli
|
|
45457
|
-
| Credential model | \`reference/
|
|
45458
|
-
| Interaction guidance | \`reference/
|
|
45591
|
+
| CLI reference | \`reference/cli.mdx\` | Running execution/platform operations |
|
|
45592
|
+
| Credential model | \`reference/platform-tools/index.mdx\` | Setting up integrations or credential security |
|
|
45593
|
+
| Interaction guidance | \`reference/framework/interaction-guidance.mdx\` | Unsure how to adapt for a skill combination |
|
|
45459
45594
|
| Error history | \`.claude/memory/errors/index.md\` | Debugging errors, checking past fixes |
|
|
45460
|
-
| Command View model | \`reference/deployment/command-
|
|
45461
|
-
| Command Center UI reference | \`reference/deployment/command-center
|
|
45462
|
-
| SDK error reference | \`reference/troubleshooting
|
|
45595
|
+
| Command View model | \`reference/deployment/command-center.mdx\` | Deploying or building resources that invoke other resources |
|
|
45596
|
+
| Command Center UI reference | \`reference/deployment/command-center.mdx\` | User asks about post-deployment UI or Command Center navigation |
|
|
45597
|
+
| SDK error reference | \`reference/troubleshooting.mdx\` | Unknown error not in workspace memory |
|
|
45463
45598
|
| Project map | \`docs/project-map.mdx\` | Session start, project orientation |
|
|
45464
45599
|
| Resource inventory | \`docs/resource-map.mdx\` | Finding a specific resource by name or ID |
|
|
45465
45600
|
| Project priorities | \`docs/priorities.mdx\` | Deciding what to work on next |
|
|
@@ -45485,7 +45620,7 @@ Use \`pnpm exec elevasis-sdk\` for runtime commands (resolves the locally instal
|
|
|
45485
45620
|
- \`pnpm exec elevasis-sdk execution <resource-id> <execution-id>\` -- inspect execution detail
|
|
45486
45621
|
|
|
45487
45622
|
Organization is derived from your API key -- no org prefix needed in the resource ID.
|
|
45488
|
-
For full CLI reference: \`reference/cli
|
|
45623
|
+
For full CLI reference: \`reference/cli.mdx\`
|
|
45489
45624
|
|
|
45490
45625
|
## Rules
|
|
45491
45626
|
|
|
@@ -45500,8 +45635,8 @@ SDK patterns (imports, source structure, platform tools) are auto-loaded from
|
|
|
45500
45635
|
|
|
45501
45636
|
When an error occurs:
|
|
45502
45637
|
1. Check \`.claude/memory/errors/\` first for past fixes
|
|
45503
|
-
2. If new, check \`reference/troubleshooting
|
|
45504
|
-
3. After resolving, record in
|
|
45638
|
+
2. If new, check \`reference/troubleshooting.mdx\`
|
|
45639
|
+
3. After resolving, record in \`.claude/memory/errors/\` with context and fix
|
|
45505
45640
|
4. If an error recurs 3+ times, add a rule to \`.claude/rules/workspace-patterns.md\`${ctx.hasUI ? `
|
|
45506
45641
|
|
|
45507
45642
|
### UI App (\`ui/\`)
|
|
@@ -45533,7 +45668,7 @@ based on what you find.
|
|
|
45533
45668
|
- When growth is observed, note it in the skills.md Growth Log.
|
|
45534
45669
|
|
|
45535
45670
|
For detailed per-dimension adaptation rules, read
|
|
45536
|
-
\`reference/
|
|
45671
|
+
\`reference/framework/interaction-guidance.mdx\`.
|
|
45537
45672
|
|
|
45538
45673
|
## Commands
|
|
45539
45674
|
|
|
@@ -45542,7 +45677,7 @@ For detailed per-dimension adaptation rules, read
|
|
|
45542
45677
|
| \`/meta\` | Project lifecycle: init, status, fix, deploy, health |
|
|
45543
45678
|
| \`/docs\` | Browse, create, and verify permanent documentation |
|
|
45544
45679
|
| \`/work\` | Task tracking: create, save, resume, complete |
|
|
45545
|
-
| \`/tutorial\` | Progressive learning path (
|
|
45680
|
+
| \`/tutorial\` | Progressive learning path (21 items across 4 sections) |
|
|
45546
45681
|
|
|
45547
45682
|
## Skills
|
|
45548
45683
|
|
|
@@ -45575,7 +45710,7 @@ Do not store in \`.claude/memory/\`:
|
|
|
45575
45710
|
|
|
45576
45711
|
### Structure
|
|
45577
45712
|
|
|
45578
|
-
-
|
|
45713
|
+
- \`.claude/memory/index.md\` is the root -- maps to topic files and subdirectories
|
|
45579
45714
|
- Every subdirectory has its own \`index.md\` mapping to children
|
|
45580
45715
|
- Start at the root index and drill down
|
|
45581
45716
|
- When a file outgrows a single document, split into a subdirectory
|
|
@@ -45599,14 +45734,14 @@ Read \`.claude/memory/profile/skills.md\` first. The \`automation\` skill level
|
|
|
45599
45734
|
controls which docs you load and which lesson variant you deliver.
|
|
45600
45735
|
|
|
45601
45736
|
**automation: none**
|
|
45602
|
-
- Load from \`reference/concepts
|
|
45737
|
+
- Load from \`reference/concepts.mdx\`: Glossary, What is a Workflow,
|
|
45603
45738
|
Platform Tools Overview only. Skip Zod, Execution Model, Design Decisions.
|
|
45604
|
-
- Load \`reference/deployment/command-center
|
|
45739
|
+
- Load \`reference/deployment/command-center.mdx\` for UI-first teaching.
|
|
45605
45740
|
- Do NOT load \`reference/resources/patterns.mdx\` or
|
|
45606
45741
|
\`reference/platform-tools/adapters.mdx\` during core lessons.
|
|
45607
45742
|
|
|
45608
45743
|
**automation: low-code**
|
|
45609
|
-
- Load all sections of \`reference/concepts
|
|
45744
|
+
- Load all sections of \`reference/concepts.mdx\`.
|
|
45610
45745
|
- Load \`reference/resources/patterns.mdx\` with Zapier/Make mapping in mind.
|
|
45611
45746
|
- Load \`reference/platform-tools/adapters.mdx\` on-demand (when tools are used).
|
|
45612
45747
|
|
|
@@ -45694,7 +45829,7 @@ Each lesson follows this flow:
|
|
|
45694
45829
|
|
|
45695
45830
|
When automation is none:
|
|
45696
45831
|
Skip the file tour. Start with what Elevasis does for their business -- use analogies
|
|
45697
|
-
from \`reference/
|
|
45832
|
+
from \`reference/framework/interaction-guidance.mdx\` (recipe, assembly line, kitchen
|
|
45698
45833
|
appliance). Explain deployment plainly: "You write the recipe here, then deploy it so
|
|
45699
45834
|
it's live." Deploy the starter echo workflow (\`elevasis-sdk check\` + \`elevasis-sdk deploy\`),
|
|
45700
45835
|
THEN tour the Command Center so the user sees populated pages, not empty ones. Tour:
|
|
@@ -45942,14 +46077,14 @@ Each module follows this flow:
|
|
|
45942
46077
|
## Modules
|
|
45943
46078
|
|
|
45944
46079
|
**Module: hitl -- Human-in-the-Loop**
|
|
45945
|
-
Read: \`reference/deployment/command-center
|
|
46080
|
+
Read: \`reference/deployment/command-center.mdx\` (Command Queue section).
|
|
45946
46081
|
Build: Add an approval gate using \`approval.requestApproval()\`. Test full lifecycle:
|
|
45947
46082
|
trigger, see pending in Command Queue, approve/reject, observe resume.
|
|
45948
46083
|
Key concepts: approval adapter, pending state, Command Queue UI, resume on decision.
|
|
45949
46084
|
Verify: Trigger workflow, open Command Queue, approve, confirm completion.
|
|
45950
46085
|
|
|
45951
46086
|
**Module: schedules -- Task Scheduling**
|
|
45952
|
-
Read: \`reference/deployment/command-center
|
|
46087
|
+
Read: \`reference/deployment/command-center.mdx\` (Task Scheduler section).
|
|
45953
46088
|
Build: Create all three schedule types (Recurring cron, Relative delay, Absolute
|
|
45954
46089
|
datetime). Use \`scheduler\` adapter for in-workflow scheduling.
|
|
45955
46090
|
Key concepts: schedule types, cron syntax, scheduler adapter, Task Scheduler UI.
|
|
@@ -45963,7 +46098,7 @@ Verify: Run workflow, check notification in Command Center, confirm email receiv
|
|
|
45963
46098
|
|
|
45964
46099
|
**Module: integrations -- Real-World Integrations**
|
|
45965
46100
|
Read: \`reference/platform-tools/index.mdx\`, \`reference/platform-tools/adapters.mdx\`,
|
|
45966
|
-
\`reference/
|
|
46101
|
+
\`reference/platform-tools/index.mdx\`.
|
|
45967
46102
|
Build: Pick a real integration adapter based on user's goals (read \`identity.md\`).
|
|
45968
46103
|
Set up credential (OAuth via UI, API key via CLI). Build end-to-end integration workflow.
|
|
45969
46104
|
Key concepts: adapter pattern, credential scoping, error handling for external calls.
|
|
@@ -45972,7 +46107,7 @@ handling with invalid credential.
|
|
|
45972
46107
|
|
|
45973
46108
|
**Module: error-handling -- Error Handling Mastery**
|
|
45974
46109
|
Read: \`reference/resources/patterns.mdx\` (error handling),
|
|
45975
|
-
\`reference/troubleshooting
|
|
46110
|
+
\`reference/troubleshooting.mdx\`.
|
|
45976
46111
|
Build: Create a workflow demonstrating all three error types. Add try/catch,
|
|
45977
46112
|
\`context.logger\`, and error recovery.
|
|
45978
46113
|
Key concepts: ExecutionError, PlatformToolError, ToolingError, recovery patterns.
|
|
@@ -45988,7 +46123,7 @@ Key concepts: context.store, context.logger, domain organization, schema depth.
|
|
|
45988
46123
|
Verify: Run workflow, confirm store values in step output, check logs in Execution Logs.
|
|
45989
46124
|
|
|
45990
46125
|
**Module: composition -- Resource Composition**
|
|
45991
|
-
Read: \`reference/deployment/command-
|
|
46126
|
+
Read: \`reference/deployment/command-center.mdx\`, \`reference/resources/patterns.mdx\`.
|
|
45992
46127
|
Build: Create two workflows where the first triggers the second using
|
|
45993
46128
|
\`execution.trigger()\`. Declare the relationship.
|
|
45994
46129
|
Key concepts: execution.trigger, relationship declarations, Command View graph edges.
|
|
@@ -46136,7 +46271,7 @@ Last Session: {today's date}
|
|
|
46136
46271
|
\`\`\`
|
|
46137
46272
|
|
|
46138
46273
|
Update rules:
|
|
46139
|
-
- \`Current\`: free-form, e.g. "
|
|
46274
|
+
- \`Current\`: free-form, e.g. "7: Using Platform Tools" or "M:integrations" or "20: Rules, Memory, and Customization"
|
|
46140
46275
|
- \`Last Session\`: update to today's date on each \`/tutorial\` invocation
|
|
46141
46276
|
- Completed Lessons: add a row when any numbered item (1-10, 20-21) finishes
|
|
46142
46277
|
- Completed Modules: add a row when any module (items 11-19) finishes
|
|
@@ -46232,9 +46367,9 @@ by the \`<!-- initialized: false -->\` flag in CLAUDE.md, or run manually.
|
|
|
46232
46367
|
- Create \`.claude/memory/profile/preferences.md\` (verbosity, guidance)
|
|
46233
46368
|
|
|
46234
46369
|
4. **Git check**
|
|
46235
|
-
- If \`.git/\` exists: note git is configured in memory/profile/preferences.md
|
|
46370
|
+
- If \`.git/\` exists: note git is configured in .claude/memory/profile/preferences.md
|
|
46236
46371
|
- If \`.git/\` does not exist: suggest \`git init\` and optionally GitHub
|
|
46237
|
-
- If git remote exists: note remote URL in memory/profile/preferences.md
|
|
46372
|
+
- If git remote exists: note remote URL in .claude/memory/profile/preferences.md
|
|
46238
46373
|
|
|
46239
46374
|
5. **Verify project**
|
|
46240
46375
|
Run \`elevasis-sdk check\` to confirm the starter resource is valid.
|
|
@@ -46255,9 +46390,9 @@ by the \`<!-- initialized: false -->\` flag in CLAUDE.md, or run manually.
|
|
|
46255
46390
|
|
|
46256
46391
|
Display a project health summary:
|
|
46257
46392
|
1. Template version (from elevasis.config.ts) and installed SDK version (from package.json). Suggest \`elevasis-sdk update\` to check for updates
|
|
46258
|
-
|
|
46259
|
-
|
|
46260
|
-
|
|
46393
|
+
2. Profile summary (from .claude/memory/profile/skills.md)
|
|
46394
|
+
3. Quick drift check: count of missing managed files, missing gitignore entries
|
|
46395
|
+
4. Last deployment status (from .claude/memory/deployment-state.md if it exists)
|
|
46261
46396
|
|
|
46262
46397
|
### \`/meta fix\` -- Maintenance and Upgrade
|
|
46263
46398
|
|
|
@@ -46275,9 +46410,9 @@ Detect and repair all drift. Optionally upgrades the SDK first.
|
|
|
46275
46410
|
3. **CLAUDE.md sections:** Add missing sections in correct position
|
|
46276
46411
|
4. **Memory structure:** Create base structure if missing, then verify index consistency.
|
|
46277
46412
|
If \`.claude/memory/\` does not exist or is empty:
|
|
46278
|
-
- Create
|
|
46279
|
-
- Create
|
|
46280
|
-
- Create
|
|
46413
|
+
- Create \`.claude/memory/index.md\` (root index with placeholder entries)
|
|
46414
|
+
- Create \`.claude/memory/errors/index.md\` (error category summary, empty tables)
|
|
46415
|
+
- Create \`.claude/memory/errors/deploy.md\`, \`.claude/memory/errors/runtime.md\`, \`.claude/memory/errors/typescript.md\`
|
|
46281
46416
|
If memory exists, verify: every file referenced in an index exists; every file
|
|
46282
46417
|
without an index entry gets one added; broken references are removed.
|
|
46283
46418
|
5. **Documentation verification:** For each file in docs/:
|
|
@@ -46288,7 +46423,7 @@ Detect and repair all drift. Optionally upgrades the SDK first.
|
|
|
46288
46423
|
e. Report discrepancies with suggested fixes
|
|
46289
46424
|
Note: \`/docs verify\` is available for standalone interactive verification outside this pipeline.
|
|
46290
46425
|
6. **Settings consistency:** Verify expected fields
|
|
46291
|
-
7. **Rules health:** Scan
|
|
46426
|
+
7. **Rules health:** Scan \`.claude/memory/errors/\` -- flag any entry that has recurred
|
|
46292
46427
|
3+ times and is not yet in \`.claude/rules/workspace-patterns.md\`.
|
|
46293
46428
|
If \`workspace-patterns.md\` has no rules yet and 5+ resources exist in \`src/\`,
|
|
46294
46429
|
suggest adding patterns. Surface suggestions only -- do not auto-generate.
|
|
@@ -46301,7 +46436,7 @@ Each step reports its result. Steps 1-8 run even if step 0 is skipped.
|
|
|
46301
46436
|
|
|
46302
46437
|
### \`/meta deploy\` -- Full Deploy Pipeline
|
|
46303
46438
|
|
|
46304
|
-
0. Read \`reference/deployment/command-
|
|
46439
|
+
0. Read \`reference/deployment/command-center.mdx\` -- understand the Command View
|
|
46305
46440
|
model, relationship declarations, and what deploy-time validation checks.
|
|
46306
46441
|
This context is essential for diagnosing validation failures in steps 1-2.
|
|
46307
46442
|
1. Run \`elevasis-sdk check\` (validation)
|
|
@@ -46311,18 +46446,18 @@ Each step reports its result. Steps 1-8 run even if step 0 is skipped.
|
|
|
46311
46446
|
5. Run \`elevasis-sdk deploy\`
|
|
46312
46447
|
6. \`docs/project-map.mdx\` is auto-regenerated by deploy (no manual bump needed)
|
|
46313
46448
|
7. Verify deployment via platform
|
|
46314
|
-
8. Update
|
|
46449
|
+
8. Update \`.claude/memory/deployment-state.md\` with count, timestamp, inventory
|
|
46315
46450
|
9. If git configured and remote exists: optionally push
|
|
46316
46451
|
|
|
46317
46452
|
Each step reports its result. Pipeline stops on failure with suggested fix.
|
|
46318
|
-
If validation fails with relationship errors, re-read \`reference/deployment/command-
|
|
46453
|
+
If validation fails with relationship errors, re-read \`reference/deployment/command-center.mdx\`
|
|
46319
46454
|
for the enforcement model and common fixes.
|
|
46320
46455
|
|
|
46321
46456
|
### \`/meta health\` -- Execution Debugging
|
|
46322
46457
|
|
|
46323
46458
|
Diagnose runtime failures and environment issues:
|
|
46324
46459
|
- Show recent executions with status (completed/failed)
|
|
46325
|
-
- For failed executions: analyze logs, cross-reference with memory/errors/
|
|
46460
|
+
- For failed executions: analyze logs, cross-reference with .claude/memory/errors/
|
|
46326
46461
|
- Check resource deployment status (deployed, outdated, never deployed)
|
|
46327
46462
|
- Verify environment: API key valid, credentials accessible, DB connected
|
|
46328
46463
|
|
|
@@ -46829,7 +46964,7 @@ This file is yours. The other \`.claude/rules/\` files are SDK-owned and updated
|
|
|
46829
46964
|
|
|
46830
46965
|
## When to Add a Rule
|
|
46831
46966
|
|
|
46832
|
-
- An error has recurred 3+ times (CLAUDE.md instructs you to promote from
|
|
46967
|
+
- An error has recurred 3+ times (CLAUDE.md instructs you to promote from \`.claude/memory/errors/\`)
|
|
46833
46968
|
- A pattern appears across 3+ resources and is worth documenting for consistency
|
|
46834
46969
|
- A naming or structural convention exists that future sessions would likely get wrong
|
|
46835
46970
|
|
|
@@ -46954,6 +47089,199 @@ When all plan steps are marked COMPLETE, suggest \`/work complete\` to finalize
|
|
|
46954
47089
|
- Completed tasks move OUT of \`docs/in-progress/\` to \`docs/<relevant-dir>/\`
|
|
46955
47090
|
`;
|
|
46956
47091
|
}
|
|
47092
|
+
function claudePostEditValidateHookTemplate() {
|
|
47093
|
+
return `#!/usr/bin/env node
|
|
47094
|
+
// post-edit-validate.mjs
|
|
47095
|
+
// PostToolUse hook \u2014 auto-formats with prettier, type-checks .ts/.tsx files.
|
|
47096
|
+
// Fires after Edit|Write|MultiEdit succeeds.
|
|
47097
|
+
|
|
47098
|
+
import { existsSync } from 'node:fs'
|
|
47099
|
+
import { resolve, normalize, extname, join, dirname } from 'node:path'
|
|
47100
|
+
import { execSync } from 'node:child_process'
|
|
47101
|
+
|
|
47102
|
+
const ROOT = process.env.CLAUDE_PROJECT_DIR ?? process.cwd()
|
|
47103
|
+
|
|
47104
|
+
// Extensions prettier should format
|
|
47105
|
+
const PRETTIER_EXTENSIONS = new Set([
|
|
47106
|
+
'.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json', '.css', '.md', '.mdx'
|
|
47107
|
+
])
|
|
47108
|
+
|
|
47109
|
+
// Extensions that trigger type-checking
|
|
47110
|
+
const TS_EXTENSIONS = new Set(['.ts', '.tsx'])
|
|
47111
|
+
|
|
47112
|
+
function findNearestTsconfig(startDir) {
|
|
47113
|
+
let dir = startDir
|
|
47114
|
+
const root = normalize(ROOT)
|
|
47115
|
+
while (dir.length >= root.length) {
|
|
47116
|
+
const candidate = join(dir, 'tsconfig.json')
|
|
47117
|
+
if (existsSync(candidate)) return candidate
|
|
47118
|
+
const parent = dirname(dir)
|
|
47119
|
+
if (parent === dir) break
|
|
47120
|
+
dir = parent
|
|
47121
|
+
}
|
|
47122
|
+
return null
|
|
47123
|
+
}
|
|
47124
|
+
|
|
47125
|
+
try {
|
|
47126
|
+
const chunks = []
|
|
47127
|
+
for await (const chunk of process.stdin) chunks.push(chunk)
|
|
47128
|
+
const input = JSON.parse(Buffer.concat(chunks).toString())
|
|
47129
|
+
|
|
47130
|
+
const filePath = input.tool_input?.file_path
|
|
47131
|
+
if (!filePath) process.exit(0)
|
|
47132
|
+
|
|
47133
|
+
const ext = extname(filePath).toLowerCase()
|
|
47134
|
+
const absPath = normalize(resolve(filePath))
|
|
47135
|
+
if (!existsSync(absPath)) process.exit(0)
|
|
47136
|
+
|
|
47137
|
+
const results = []
|
|
47138
|
+
|
|
47139
|
+
// 1. Prettier
|
|
47140
|
+
if (PRETTIER_EXTENSIONS.has(ext)) {
|
|
47141
|
+
try {
|
|
47142
|
+
execSync('pnpm exec prettier --write "' + absPath + '"', {
|
|
47143
|
+
cwd: ROOT,
|
|
47144
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
47145
|
+
timeout: 10_000
|
|
47146
|
+
})
|
|
47147
|
+
} catch (err) {
|
|
47148
|
+
const stderr = err.stderr?.toString().trim() || ''
|
|
47149
|
+
if (stderr && !/ignored/i.test(stderr)) {
|
|
47150
|
+
results.push('Prettier error: ' + stderr.slice(0, 300))
|
|
47151
|
+
}
|
|
47152
|
+
}
|
|
47153
|
+
}
|
|
47154
|
+
|
|
47155
|
+
// 2. Type-check for .ts/.tsx
|
|
47156
|
+
if (TS_EXTENSIONS.has(ext)) {
|
|
47157
|
+
const tsconfig = findNearestTsconfig(dirname(absPath))
|
|
47158
|
+
if (tsconfig) {
|
|
47159
|
+
try {
|
|
47160
|
+
execSync('pnpm exec tsc --noEmit -p "' + tsconfig + '"', {
|
|
47161
|
+
cwd: ROOT,
|
|
47162
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
47163
|
+
timeout: 30_000,
|
|
47164
|
+
env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=4096' }
|
|
47165
|
+
})
|
|
47166
|
+
} catch (err) {
|
|
47167
|
+
if (err.killed) process.exit(0) // Don't block on timeout
|
|
47168
|
+
const stdout = err.stdout?.toString() || ''
|
|
47169
|
+
if (stdout.includes('error TS')) {
|
|
47170
|
+
const errorLines = stdout
|
|
47171
|
+
.split('\\n')
|
|
47172
|
+
.filter(l => l.includes('error TS'))
|
|
47173
|
+
.slice(0, 10)
|
|
47174
|
+
results.push('Type errors after editing ' + filePath + ':\\n' + errorLines.join('\\n'))
|
|
47175
|
+
}
|
|
47176
|
+
}
|
|
47177
|
+
}
|
|
47178
|
+
}
|
|
47179
|
+
|
|
47180
|
+
// Output errors to Claude's context (silence = success)
|
|
47181
|
+
if (results.length > 0) {
|
|
47182
|
+
process.stderr.write(results.join('\\n\\n'))
|
|
47183
|
+
process.exit(2) // Exit 2 = send stderr as feedback to Claude
|
|
47184
|
+
}
|
|
47185
|
+
} catch {}
|
|
47186
|
+
|
|
47187
|
+
process.exit(0)
|
|
47188
|
+
`;
|
|
47189
|
+
}
|
|
47190
|
+
function claudeToolFailureRecoveryHookTemplate() {
|
|
47191
|
+
return `#!/usr/bin/env node
|
|
47192
|
+
// tool-failure-recovery.mjs
|
|
47193
|
+
// PostToolUseFailure hook \u2014 pattern-matches known Bash errors and returns
|
|
47194
|
+
// recovery advice via stderr + exit 2 (feedback to Claude).
|
|
47195
|
+
|
|
47196
|
+
const RECOVERY_TABLE = [
|
|
47197
|
+
{
|
|
47198
|
+
test: r => /JavaScript heap out of memory/i.test(r),
|
|
47199
|
+
advice: 'Out of memory.',
|
|
47200
|
+
fix: 'Run the command with NODE_OPTIONS="--max-old-space-size=4096".',
|
|
47201
|
+
why: 'Large TypeScript projects can exceed Node default heap limit.',
|
|
47202
|
+
},
|
|
47203
|
+
{
|
|
47204
|
+
test: r => /boundary hook/i.test(r) && /block|denied/i.test(r),
|
|
47205
|
+
advice: 'Command blocked by SDK boundary hook.',
|
|
47206
|
+
fix: 'Ask the user to run this command manually.',
|
|
47207
|
+
why: 'The boundary hook blocks gh CLI, destructive git operations, and file writes outside the project.',
|
|
47208
|
+
see: 'CLAUDE.md',
|
|
47209
|
+
},
|
|
47210
|
+
{
|
|
47211
|
+
test: r => /ENOENT/.test(r) && /node_modules/.test(r),
|
|
47212
|
+
advice: 'Missing node_modules dependency.',
|
|
47213
|
+
fix: 'Run: pnpm install',
|
|
47214
|
+
why: 'Dependencies are not installed or were cleared.',
|
|
47215
|
+
},
|
|
47216
|
+
{
|
|
47217
|
+
test: r => /ERR_MODULE_NOT_FOUND/.test(r) && /@elevasis\\/sdk/.test(r),
|
|
47218
|
+
advice: '@elevasis/sdk module not found.',
|
|
47219
|
+
fix: 'Run: pnpm install \u2014 then verify @elevasis/sdk is in package.json dependencies.',
|
|
47220
|
+
why: 'The SDK package is not installed or the version is mismatched.',
|
|
47221
|
+
},
|
|
47222
|
+
{
|
|
47223
|
+
test: r => /ERR_MODULE_NOT_FOUND/.test(r),
|
|
47224
|
+
advice: 'Module not found at import path.',
|
|
47225
|
+
fix: 'Check the import path and verify the package is installed (pnpm install).',
|
|
47226
|
+
why: 'The import path does not match any installed package or local file.',
|
|
47227
|
+
},
|
|
47228
|
+
{
|
|
47229
|
+
test: r => /TS2307/.test(r) || (/cannot find/i.test(r) && /declaration/i.test(r)),
|
|
47230
|
+
advice: 'TypeScript cannot resolve module or declaration file.',
|
|
47231
|
+
fix: 'Check that the package is installed and tsconfig paths are correct.',
|
|
47232
|
+
why: 'Missing dependency or incorrect TypeScript configuration.',
|
|
47233
|
+
},
|
|
47234
|
+
{
|
|
47235
|
+
test: r => /EPERM/.test(r) || /permission denied/i.test(r),
|
|
47236
|
+
advice: 'Permission denied (EPERM).',
|
|
47237
|
+
fix: 'Close the file in any other process (editor, terminal, or dev server) and retry.',
|
|
47238
|
+
why: 'On Windows, files locked by another process cannot be written to.',
|
|
47239
|
+
},
|
|
47240
|
+
{
|
|
47241
|
+
test: r => /lockfile/i.test(r) && /conflict|outdated|ERR_PNPM/i.test(r),
|
|
47242
|
+
advice: 'pnpm lockfile conflict or outdated.',
|
|
47243
|
+
fix: 'Run: pnpm install to regenerate the lockfile.',
|
|
47244
|
+
why: 'The lockfile is out of sync with package.json changes.',
|
|
47245
|
+
},
|
|
47246
|
+
{
|
|
47247
|
+
test: r => /elevasis-sdk check/.test(r) || /elevasis-sdk deploy/.test(r),
|
|
47248
|
+
advice: 'elevasis-sdk CLI command failed.',
|
|
47249
|
+
fix: 'Check the error output above. Common causes: missing .env ELEVASIS_API_KEY, invalid resource schemas, or network issues.',
|
|
47250
|
+
why: 'The SDK CLI validates resources and communicates with the platform API.',
|
|
47251
|
+
},
|
|
47252
|
+
{
|
|
47253
|
+
test: r => /EADDRINUSE/.test(r),
|
|
47254
|
+
advice: 'Port already in use.',
|
|
47255
|
+
fix: 'Find and kill the process using the port, or use a different port.',
|
|
47256
|
+
why: 'A previous dev server or process is still holding the port.',
|
|
47257
|
+
},
|
|
47258
|
+
]
|
|
47259
|
+
|
|
47260
|
+
function formatRecovery(entry) {
|
|
47261
|
+
let msg = 'FAILED: ' + entry.advice + '\\nFIX: ' + entry.fix
|
|
47262
|
+
if (entry.why) msg += '\\nWHY: ' + entry.why
|
|
47263
|
+
if (entry.see) msg += '\\nSEE: ' + entry.see
|
|
47264
|
+
return msg
|
|
47265
|
+
}
|
|
47266
|
+
|
|
47267
|
+
try {
|
|
47268
|
+
const chunks = []
|
|
47269
|
+
for await (const chunk of process.stdin) chunks.push(chunk)
|
|
47270
|
+
const input = JSON.parse(Buffer.concat(chunks).toString())
|
|
47271
|
+
|
|
47272
|
+
const response = input.tool_response ?? ''
|
|
47273
|
+
|
|
47274
|
+
for (const entry of RECOVERY_TABLE) {
|
|
47275
|
+
if (entry.test(response)) {
|
|
47276
|
+
process.stderr.write(formatRecovery(entry))
|
|
47277
|
+
process.exit(2)
|
|
47278
|
+
}
|
|
47279
|
+
}
|
|
47280
|
+
} catch {}
|
|
47281
|
+
|
|
47282
|
+
process.exit(0)
|
|
47283
|
+
`;
|
|
47284
|
+
}
|
|
46957
47285
|
|
|
46958
47286
|
// src/cli/commands/templates/core/resources.ts
|
|
46959
47287
|
function starterTemplate() {
|
|
@@ -47129,6 +47457,8 @@ function getManagedTemplates(ctx = {}) {
|
|
|
47129
47457
|
".claude/settings.json": claudeSettingsTemplate,
|
|
47130
47458
|
".claude/scripts/statusline-command.js": claudeStatuslineScriptTemplate,
|
|
47131
47459
|
".claude/hooks/enforce-sdk-boundary.mjs": claudeSdkBoundaryHookTemplate,
|
|
47460
|
+
".claude/hooks/post-edit-validate.mjs": claudePostEditValidateHookTemplate,
|
|
47461
|
+
".claude/hooks/tool-failure-recovery.mjs": claudeToolFailureRecoveryHookTemplate,
|
|
47132
47462
|
".claude/commands/tutorial.md": claudeTutorialCommandTemplate,
|
|
47133
47463
|
".claude/commands/meta.md": claudeMetaCommandTemplate,
|
|
47134
47464
|
".claude/commands/work.md": claudeWorkCommandTemplate,
|
|
@@ -47341,6 +47671,8 @@ var MANAGED_FILES = [
|
|
|
47341
47671
|
"CLAUDE.md",
|
|
47342
47672
|
".claude/settings.json",
|
|
47343
47673
|
".claude/hooks/enforce-sdk-boundary.mjs",
|
|
47674
|
+
".claude/hooks/post-edit-validate.mjs",
|
|
47675
|
+
".claude/hooks/tool-failure-recovery.mjs",
|
|
47344
47676
|
".claude/commands/tutorial.md",
|
|
47345
47677
|
".claude/commands/meta.md",
|
|
47346
47678
|
".claude/commands/work.md",
|
|
@@ -47355,96 +47687,100 @@ var MANAGED_FILES = [
|
|
|
47355
47687
|
];
|
|
47356
47688
|
var SCAFFOLD_FILES = [...INIT_ONLY_FILES, ...MANAGED_FILES];
|
|
47357
47689
|
function registerInitCommand(program3) {
|
|
47358
|
-
program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis-sdk init my-workspace").option("--force", "Overwrite existing files").option("--ui", "Include a Vite + React UI app in ui/").action(
|
|
47359
|
-
|
|
47360
|
-
|
|
47361
|
-
|
|
47362
|
-
|
|
47363
|
-
|
|
47364
|
-
|
|
47365
|
-
|
|
47366
|
-
|
|
47367
|
-
|
|
47368
|
-
|
|
47369
|
-
|
|
47370
|
-
|
|
47371
|
-
if (conflicts.length > 0) {
|
|
47372
|
-
console.error(source_default.red("Files already exist:"));
|
|
47373
|
-
for (const f of conflicts) {
|
|
47374
|
-
console.error(source_default.gray(` ${f}`));
|
|
47690
|
+
program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis-sdk init my-workspace").option("--force", "Overwrite existing files").option("--ui", "Include a Vite + React UI app in ui/").action(
|
|
47691
|
+
wrapAction("init", async (directory, options2) => {
|
|
47692
|
+
const targetDir = directory ? (0, import_path3.resolve)(directory) : process.cwd();
|
|
47693
|
+
const orgSlug = toSlug((0, import_path3.basename)(targetDir));
|
|
47694
|
+
if (!options2.force) {
|
|
47695
|
+
const filesToCheck = options2.ui ? [...SCAFFOLD_FILES, ...UI_INIT_FILES] : SCAFFOLD_FILES;
|
|
47696
|
+
const conflicts = [];
|
|
47697
|
+
for (const file2 of filesToCheck) {
|
|
47698
|
+
try {
|
|
47699
|
+
await (0, import_promises2.access)((0, import_path3.resolve)(targetDir, file2));
|
|
47700
|
+
conflicts.push(file2);
|
|
47701
|
+
} catch {
|
|
47702
|
+
}
|
|
47375
47703
|
}
|
|
47376
|
-
|
|
47377
|
-
|
|
47378
|
-
|
|
47379
|
-
|
|
47380
|
-
|
|
47381
|
-
|
|
47382
|
-
|
|
47383
|
-
|
|
47384
|
-
|
|
47385
|
-
|
|
47386
|
-
|
|
47387
|
-
|
|
47388
|
-
|
|
47389
|
-
|
|
47390
|
-
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "
|
|
47391
|
-
|
|
47392
|
-
|
|
47393
|
-
|
|
47394
|
-
|
|
47395
|
-
|
|
47396
|
-
|
|
47397
|
-
|
|
47398
|
-
|
|
47399
|
-
|
|
47400
|
-
|
|
47401
|
-
|
|
47402
|
-
|
|
47403
|
-
|
|
47404
|
-
|
|
47405
|
-
|
|
47406
|
-
|
|
47407
|
-
|
|
47408
|
-
|
|
47409
|
-
|
|
47410
|
-
|
|
47411
|
-
|
|
47412
|
-
|
|
47413
|
-
|
|
47414
|
-
|
|
47415
|
-
|
|
47416
|
-
|
|
47417
|
-
|
|
47418
|
-
|
|
47419
|
-
|
|
47420
|
-
|
|
47421
|
-
|
|
47422
|
-
|
|
47423
|
-
|
|
47424
|
-
|
|
47425
|
-
|
|
47426
|
-
|
|
47427
|
-
|
|
47428
|
-
|
|
47429
|
-
|
|
47430
|
-
|
|
47431
|
-
|
|
47432
|
-
|
|
47433
|
-
|
|
47434
|
-
|
|
47435
|
-
|
|
47436
|
-
|
|
47437
|
-
|
|
47438
|
-
console.log(source_default.gray(" elevasis-sdk check"));
|
|
47439
|
-
console.log(source_default.gray(" elevasis-sdk deploy"));
|
|
47440
|
-
if (options2.ui) {
|
|
47704
|
+
if (conflicts.length > 0) {
|
|
47705
|
+
console.error(source_default.red("Files already exist:"));
|
|
47706
|
+
for (const f of conflicts) {
|
|
47707
|
+
console.error(source_default.gray(` ${f}`));
|
|
47708
|
+
}
|
|
47709
|
+
console.error(source_default.gray("\n Use --force to overwrite."));
|
|
47710
|
+
throw new Error("Scaffold conflict");
|
|
47711
|
+
}
|
|
47712
|
+
}
|
|
47713
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/operations"), { recursive: true });
|
|
47714
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/example"), { recursive: true });
|
|
47715
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/shared"), { recursive: true });
|
|
47716
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "docs/in-progress"), { recursive: true });
|
|
47717
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/hooks"), { recursive: true });
|
|
47718
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/scripts"), { recursive: true });
|
|
47719
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/commands"), { recursive: true });
|
|
47720
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/skills/creds"), { recursive: true });
|
|
47721
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/rules"), { recursive: true });
|
|
47722
|
+
if (options2.ui) {
|
|
47723
|
+
await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "ui/src"), { recursive: true });
|
|
47724
|
+
}
|
|
47725
|
+
const files = {
|
|
47726
|
+
"elevasis.config.ts": configTemplate(),
|
|
47727
|
+
"package.json": packageJsonTemplate(orgSlug),
|
|
47728
|
+
"pnpm-workspace.yaml": pnpmWorkspaceTemplate(),
|
|
47729
|
+
"tsconfig.json": tsconfigTemplate(),
|
|
47730
|
+
".env": envTemplate(),
|
|
47731
|
+
".npmrc": npmrcTemplate(),
|
|
47732
|
+
".gitignore": gitignoreTemplate({ hasUI: options2.ui }),
|
|
47733
|
+
"src/index.ts": starterTemplate(),
|
|
47734
|
+
"src/operations/platform-status.ts": platformStatusTemplate(),
|
|
47735
|
+
"src/operations/index.ts": operationsBarrelTemplate(),
|
|
47736
|
+
"src/example/echo.ts": starterWorkflowTemplate(),
|
|
47737
|
+
"src/example/index.ts": exampleBarrelTemplate(),
|
|
47738
|
+
"src/shared/.gitkeep": "",
|
|
47739
|
+
"docs/index.mdx": docsIndexTemplate(orgSlug),
|
|
47740
|
+
"docs/in-progress/.gitkeep": "",
|
|
47741
|
+
"CLAUDE.md": claudeMdTemplate({ hasUI: options2.ui }),
|
|
47742
|
+
".claude/settings.json": claudeSettingsTemplate(),
|
|
47743
|
+
".claude/hooks/enforce-sdk-boundary.mjs": claudeSdkBoundaryHookTemplate(),
|
|
47744
|
+
".claude/hooks/post-edit-validate.mjs": claudePostEditValidateHookTemplate(),
|
|
47745
|
+
".claude/hooks/tool-failure-recovery.mjs": claudeToolFailureRecoveryHookTemplate(),
|
|
47746
|
+
".claude/commands/tutorial.md": claudeTutorialCommandTemplate(),
|
|
47747
|
+
".claude/commands/meta.md": claudeMetaCommandTemplate(),
|
|
47748
|
+
".claude/commands/work.md": claudeWorkCommandTemplate(),
|
|
47749
|
+
".claude/commands/docs.md": claudeDocsCommandTemplate(),
|
|
47750
|
+
".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate(),
|
|
47751
|
+
".claude/rules/sdk-patterns.md": claudeSdkPatternsRuleTemplate(),
|
|
47752
|
+
".claude/rules/workspace-patterns.md": claudeWorkspaceRulesTemplate(),
|
|
47753
|
+
".claude/rules/docs-authoring.md": claudeDocsAuthoringRuleTemplate(),
|
|
47754
|
+
".claude/rules/memory-conventions.md": claudeMemoryConventionsRuleTemplate(),
|
|
47755
|
+
".claude/rules/project-map.md": claudeProjectMapRuleTemplate(),
|
|
47756
|
+
".claude/rules/task-tracking.md": claudeTaskTrackingRuleTemplate(),
|
|
47757
|
+
".claude/scripts/statusline-command.js": claudeStatuslineScriptTemplate()
|
|
47758
|
+
};
|
|
47759
|
+
if (options2.ui) {
|
|
47760
|
+
Object.assign(files, getUIFiles(orgSlug));
|
|
47761
|
+
}
|
|
47762
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
47763
|
+
await (0, import_promises2.writeFile)((0, import_path3.resolve)(targetDir, filePath), content, "utf-8");
|
|
47764
|
+
}
|
|
47765
|
+
console.log(source_default.green.bold(" Workspace created!"));
|
|
47441
47766
|
console.log("");
|
|
47442
|
-
console.log(source_default.gray("
|
|
47443
|
-
|
|
47444
|
-
|
|
47445
|
-
|
|
47446
|
-
|
|
47447
|
-
|
|
47767
|
+
console.log(source_default.gray(" Next steps:"));
|
|
47768
|
+
if (directory) {
|
|
47769
|
+
console.log(source_default.gray(` cd ${directory}`));
|
|
47770
|
+
}
|
|
47771
|
+
console.log(source_default.gray(" pnpm install"));
|
|
47772
|
+
console.log(source_default.gray(" # Add your API key to .env"));
|
|
47773
|
+
console.log(source_default.gray(" elevasis-sdk check"));
|
|
47774
|
+
console.log(source_default.gray(" elevasis-sdk deploy"));
|
|
47775
|
+
if (options2.ui) {
|
|
47776
|
+
console.log("");
|
|
47777
|
+
console.log(source_default.gray(" UI app:"));
|
|
47778
|
+
console.log(source_default.gray(" cd ui && pnpm install"));
|
|
47779
|
+
console.log(source_default.gray(" # Set VITE_WORKOS_CLIENT_ID in ui/.env"));
|
|
47780
|
+
console.log(source_default.gray(" pnpm dev"));
|
|
47781
|
+
}
|
|
47782
|
+
})
|
|
47783
|
+
);
|
|
47448
47784
|
}
|
|
47449
47785
|
function toSlug(name) {
|
|
47450
47786
|
const slug = name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^[^a-z]+/, "").replace(/-+/g, "-").replace(/-$/, "");
|