@elevasis/sdk 1.5.3 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/cli.cjs +967 -57
  2. package/dist/index.d.ts +94 -110
  3. package/package.json +2 -2
  4. package/reference/_navigation.md +11 -1
  5. package/reference/_reference-manifest.json +70 -0
  6. package/reference/claude-config/commands/submit-issue.md +11 -0
  7. package/reference/claude-config/hooks/post-edit-validate.mjs +109 -0
  8. package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -0
  9. package/reference/claude-config/rules/deployment.md +57 -0
  10. package/reference/claude-config/rules/docs.md +26 -0
  11. package/reference/claude-config/rules/error-handling.md +56 -0
  12. package/reference/claude-config/rules/execution.md +40 -0
  13. package/reference/claude-config/rules/frontend.md +43 -0
  14. package/reference/claude-config/rules/observability.md +31 -0
  15. package/reference/claude-config/rules/organization-os.md +62 -0
  16. package/reference/claude-config/rules/platform.md +41 -0
  17. package/reference/claude-config/rules/shared-types.md +46 -0
  18. package/reference/claude-config/rules/task-tracking.md +47 -0
  19. package/reference/claude-config/scripts/statusline-command.js +18 -0
  20. package/reference/claude-config/settings.json +30 -0
  21. package/reference/claude-config/skills/deploy/SKILL.md +166 -0
  22. package/reference/claude-config/skills/dsp/SKILL.md +66 -0
  23. package/reference/claude-config/skills/elevasis/SKILL.md +239 -0
  24. package/reference/claude-config/skills/explore/SKILL.md +78 -0
  25. package/reference/claude-config/skills/project/SKILL.md +918 -0
  26. package/reference/claude-config/skills/save/SKILL.md +197 -0
  27. package/reference/claude-config/skills/setup/SKILL.md +210 -0
  28. package/reference/claude-config/skills/status/SKILL.md +60 -0
  29. package/reference/claude-config/skills/submit-issue/SKILL.md +165 -0
  30. package/reference/claude-config/skills/sync/SKILL.md +81 -0
  31. package/reference/cli.mdx +19 -4
  32. package/reference/deployment/provided-features.mdx +24 -2
  33. package/reference/framework/agent.mdx +12 -4
  34. package/reference/framework/project-structure.mdx +9 -3
  35. package/reference/packages/core/src/README.md +1 -1
  36. package/reference/packages/core/src/business/README.md +52 -0
  37. package/reference/packages/core/src/organization-model/README.md +25 -26
  38. package/reference/packages/ui/src/app/README.md +24 -0
  39. package/reference/platform-tools/type-safety.mdx +0 -10
  40. package/reference/scaffold/core/organization-graph.mdx +37 -28
  41. package/reference/scaffold/core/organization-model.mdx +34 -36
  42. package/reference/scaffold/index.mdx +1 -0
  43. package/reference/scaffold/operations/propagation-pipeline.md +7 -3
  44. package/reference/scaffold/operations/scaffold-maintenance.md +2 -2
  45. package/reference/scaffold/operations/workflow-recipes.md +18 -1
  46. package/reference/scaffold/recipes/add-a-feature.md +37 -21
  47. package/reference/scaffold/recipes/add-a-resource.md +4 -2
  48. package/reference/scaffold/recipes/customize-organization-model.md +400 -0
  49. package/reference/scaffold/recipes/extend-a-base-entity.md +140 -0
  50. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +18 -12
  51. package/reference/scaffold/recipes/index.md +3 -3
  52. package/reference/scaffold/reference/contracts.md +11 -32
  53. package/reference/scaffold/reference/feature-registry.md +10 -9
  54. package/reference/scaffold/reference/glossary.md +14 -18
  55. package/reference/scaffold/ui/customization.md +2 -2
  56. package/reference/scaffold/ui/feature-flags-and-gating.md +40 -54
  57. package/reference/scaffold/ui/feature-shell.mdx +22 -23
  58. package/reference/scaffold/ui/recipes.md +118 -3
package/dist/index.d.ts CHANGED
@@ -2275,113 +2275,6 @@ type Database = {
2275
2275
  }
2276
2276
  ];
2277
2277
  };
2278
- calibration_projects: {
2279
- Row: {
2280
- created_at: string | null;
2281
- description: string | null;
2282
- id: string;
2283
- name: string;
2284
- organization_id: string;
2285
- resource_id: string;
2286
- resource_type: string;
2287
- updated_at: string | null;
2288
- };
2289
- Insert: {
2290
- created_at?: string | null;
2291
- description?: string | null;
2292
- id?: string;
2293
- name: string;
2294
- organization_id: string;
2295
- resource_id: string;
2296
- resource_type: string;
2297
- updated_at?: string | null;
2298
- };
2299
- Update: {
2300
- created_at?: string | null;
2301
- description?: string | null;
2302
- id?: string;
2303
- name?: string;
2304
- organization_id?: string;
2305
- resource_id?: string;
2306
- resource_type?: string;
2307
- updated_at?: string | null;
2308
- };
2309
- Relationships: [
2310
- {
2311
- foreignKeyName: "calibration_projects_organization_id_fkey";
2312
- columns: ["organization_id"];
2313
- isOneToOne: false;
2314
- referencedRelation: "organizations";
2315
- referencedColumns: ["id"];
2316
- }
2317
- ];
2318
- };
2319
- calibration_runs: {
2320
- Row: {
2321
- completed_at: string | null;
2322
- config_variants: Json;
2323
- created_at: string | null;
2324
- description: string | null;
2325
- execution_mode: string;
2326
- grader_model: string | null;
2327
- grading_rubric: Json | null;
2328
- id: string;
2329
- name: string;
2330
- organization_id: string;
2331
- project_id: string;
2332
- results: Json;
2333
- status: string;
2334
- test_inputs: Json;
2335
- };
2336
- Insert: {
2337
- completed_at?: string | null;
2338
- config_variants: Json;
2339
- created_at?: string | null;
2340
- description?: string | null;
2341
- execution_mode?: string;
2342
- grader_model?: string | null;
2343
- grading_rubric?: Json | null;
2344
- id?: string;
2345
- name: string;
2346
- organization_id: string;
2347
- project_id: string;
2348
- results?: Json;
2349
- status?: string;
2350
- test_inputs: Json;
2351
- };
2352
- Update: {
2353
- completed_at?: string | null;
2354
- config_variants?: Json;
2355
- created_at?: string | null;
2356
- description?: string | null;
2357
- execution_mode?: string;
2358
- grader_model?: string | null;
2359
- grading_rubric?: Json | null;
2360
- id?: string;
2361
- name?: string;
2362
- organization_id?: string;
2363
- project_id?: string;
2364
- results?: Json;
2365
- status?: string;
2366
- test_inputs?: Json;
2367
- };
2368
- Relationships: [
2369
- {
2370
- foreignKeyName: "calibration_runs_organization_id_fkey";
2371
- columns: ["organization_id"];
2372
- isOneToOne: false;
2373
- referencedRelation: "organizations";
2374
- referencedColumns: ["id"];
2375
- },
2376
- {
2377
- foreignKeyName: "calibration_runs_project_id_fkey";
2378
- columns: ["project_id"];
2379
- isOneToOne: false;
2380
- referencedRelation: "calibration_projects";
2381
- referencedColumns: ["id"];
2382
- }
2383
- ];
2384
- };
2385
2278
  command_queue: {
2386
2279
  Row: {
2387
2280
  action_payload: Json | null;
@@ -3339,6 +3232,91 @@ type Database = {
3339
3232
  }
3340
3233
  ];
3341
3234
  };
3235
+ reported_issues: {
3236
+ Row: {
3237
+ affected_page: string | null;
3238
+ category: string;
3239
+ context: Json | null;
3240
+ created_at: string;
3241
+ description: string;
3242
+ evidence: Json | null;
3243
+ id: string;
3244
+ organization_id: string;
3245
+ project_id: string | null;
3246
+ reported_at: string;
3247
+ reporter_id: string | null;
3248
+ resolved_at: string | null;
3249
+ severity: string;
3250
+ source: string;
3251
+ status: string;
3252
+ task_id: string | null;
3253
+ title: string;
3254
+ updated_at: string;
3255
+ };
3256
+ Insert: {
3257
+ affected_page?: string | null;
3258
+ category: string;
3259
+ context?: Json | null;
3260
+ created_at?: string;
3261
+ description: string;
3262
+ evidence?: Json | null;
3263
+ id?: string;
3264
+ organization_id: string;
3265
+ project_id?: string | null;
3266
+ reported_at?: string;
3267
+ reporter_id?: string | null;
3268
+ resolved_at?: string | null;
3269
+ severity: string;
3270
+ source: string;
3271
+ status?: string;
3272
+ task_id?: string | null;
3273
+ title: string;
3274
+ updated_at?: string;
3275
+ };
3276
+ Update: {
3277
+ affected_page?: string | null;
3278
+ category?: string;
3279
+ context?: Json | null;
3280
+ created_at?: string;
3281
+ description?: string;
3282
+ evidence?: Json | null;
3283
+ id?: string;
3284
+ organization_id?: string;
3285
+ project_id?: string | null;
3286
+ reported_at?: string;
3287
+ reporter_id?: string | null;
3288
+ resolved_at?: string | null;
3289
+ severity?: string;
3290
+ source?: string;
3291
+ status?: string;
3292
+ task_id?: string | null;
3293
+ title?: string;
3294
+ updated_at?: string;
3295
+ };
3296
+ Relationships: [
3297
+ {
3298
+ foreignKeyName: "reported_issues_organization_id_fkey";
3299
+ columns: ["organization_id"];
3300
+ isOneToOne: false;
3301
+ referencedRelation: "organizations";
3302
+ referencedColumns: ["id"];
3303
+ },
3304
+ {
3305
+ foreignKeyName: "reported_issues_project_id_fkey";
3306
+ columns: ["project_id"];
3307
+ isOneToOne: false;
3308
+ referencedRelation: "prj_projects";
3309
+ referencedColumns: ["id"];
3310
+ },
3311
+ {
3312
+ foreignKeyName: "reported_issues_task_id_fkey";
3313
+ columns: ["task_id"];
3314
+ isOneToOne: false;
3315
+ referencedRelation: "prj_tasks";
3316
+ referencedColumns: ["id"];
3317
+ }
3318
+ ];
3319
+ };
3342
3320
  session_messages: {
3343
3321
  Row: {
3344
3322
  created_at: string | null;
@@ -6537,6 +6515,7 @@ declare const ProjectSchemas: {
6537
6515
  at_risk: "at_risk";
6538
6516
  blocked: "blocked";
6539
6517
  }>>;
6518
+ search: z.ZodOptional<z.ZodString>;
6540
6519
  }, z.core.$strict>;
6541
6520
  ProjectIdParams: z.ZodObject<{
6542
6521
  id: z.ZodString;
@@ -6568,6 +6547,11 @@ declare const ProjectSchemas: {
6568
6547
  due_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
6569
6548
  completed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
6570
6549
  sequence: z.ZodOptional<z.ZodNumber>;
6550
+ checklist: z.ZodOptional<z.ZodArray<z.ZodObject<{
6551
+ id: z.ZodString;
6552
+ label: z.ZodString;
6553
+ completed: z.ZodBoolean;
6554
+ }, z.core.$strip>>>;
6571
6555
  metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
6572
6556
  }, z.core.$strict>;
6573
6557
  ProjectIdPathParams: z.ZodObject<{
@@ -6583,9 +6567,9 @@ declare const ProjectSchemas: {
6583
6567
  code: "code";
6584
6568
  other: "other";
6585
6569
  documentation: "documentation";
6570
+ research: "research";
6586
6571
  report: "report";
6587
6572
  design: "design";
6588
- research: "research";
6589
6573
  refactor: "refactor";
6590
6574
  feature: "feature";
6591
6575
  bug: "bug";
@@ -6619,9 +6603,9 @@ declare const ProjectSchemas: {
6619
6603
  code: "code";
6620
6604
  other: "other";
6621
6605
  documentation: "documentation";
6606
+ research: "research";
6622
6607
  report: "report";
6623
6608
  design: "design";
6624
- research: "research";
6625
6609
  refactor: "refactor";
6626
6610
  feature: "feature";
6627
6611
  bug: "bug";
@@ -8035,7 +8019,7 @@ interface ResourceList {
8035
8019
  environment?: 'dev' | 'prod';
8036
8020
  }
8037
8021
  /** Webhook provider identifiers */
8038
- type WebhookProviderType = 'cal-com' | 'stripe' | 'signature-api' | 'instantly' | 'apify';
8022
+ type WebhookProviderType = 'cal-com' | 'stripe' | 'signature-api' | 'instantly' | 'apify' | 'test';
8039
8023
  /** Webhook trigger configuration */
8040
8024
  interface WebhookTriggerConfig {
8041
8025
  /** Provider identifier */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,7 +44,7 @@
44
44
  "tsup": "^8.0.0",
45
45
  "typescript": "5.9.2",
46
46
  "zod": "^4.1.0",
47
- "@repo/core": "0.2.1",
47
+ "@repo/core": "0.5.0",
48
48
  "@repo/typescript-config": "0.0.0"
49
49
  },
50
50
  "scripts": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Auto-generated from the package reference manifests.
4
4
 
5
- Package entries indexed: 36.
5
+ Package entries indexed: 41.
6
6
 
7
7
  ## @elevasis/core / Core
8
8
 
@@ -10,6 +10,12 @@ Package entries indexed: 36.
10
10
  | --- | --- | --- | --- |
11
11
  | Core | `packages/core/src/README.md` | Published core wrapper for the curated contract surface. | (not specified) |
12
12
 
13
+ ## @elevasis/core / Entities
14
+
15
+ | Resource | Location | Description | When to Load |
16
+ | --- | --- | --- | --- |
17
+ | Entities | `packages/core/src/business/README.md` | Published base entity contracts (Project, Milestone, Task, Deal, Company, Contact) generic over a metadata extension slot. | (not specified) |
18
+
13
19
  ## @elevasis/core / Organization Model
14
20
 
15
21
  | Resource | Location | Description | When to Load |
@@ -69,12 +75,15 @@ Package entries indexed: 36.
69
75
  | Router | `packages/ui/src/router/README.md` | Published router entry for downstream applications. | (not specified) |
70
76
  | Router Context | `packages/ui/src/router/README.md` | Published router context entry for downstream applications. | (not specified) |
71
77
  | Zustand | `packages/ui/src/zustand/README.md` | Published Zustand slice entry for downstream applications. | (not specified) |
78
+ | App | `packages/ui/src/app/README.md` | Published app factory that composes providers, router, auth, and theme into a mountable React app. | (not specified) |
72
79
 
73
80
  ## @elevasis/ui / Hooks
74
81
 
75
82
  | Resource | Location | Description | When to Load |
76
83
  | --- | --- | --- | --- |
77
84
  | Hooks | `packages/ui/src/hooks/README.md` | Headless hooks surface for executions, sessions, observability, and operations. | (not specified) |
85
+ | Hooks Delivery | `packages/ui/src/hooks/README.md` | Published delivery hooks for projects, milestones, tasks, and notes. | (not specified) |
86
+ | Transform Command View Data | `packages/ui/src/hooks/README.md` | Utility that transforms backend CommandViewData arrays into a unified frontend CommandViewGraph with nodes and edges. | (not specified) |
78
87
 
79
88
  ## @elevasis/ui / Provider
80
89
 
@@ -82,6 +91,7 @@ Package entries indexed: 36.
82
91
  | --- | --- | --- | --- |
83
92
  | Provider | `packages/ui/src/provider/README.md` | Published provider and feature-shell contract for downstream apps. | (not specified) |
84
93
  | Provider UI | `packages/ui/src/provider/README.md` | Published provider UI entry for downstream applications. | (not specified) |
94
+ | Elevasis Service Context | `packages/ui/src/provider/README.md` | Standalone service context and provider that supplies apiRequest, organizationId, and isReady to child components. | (not specified) |
85
95
 
86
96
  ## @elevasis/ui / Visual
87
97
 
@@ -15,6 +15,20 @@
15
15
  "referencePath": "packages/core/src/README.md",
16
16
  "publishedExportPath": "./dist/index.js"
17
17
  },
18
+ {
19
+ "packageName": "@elevasis/core",
20
+ "packageDir": "packages/core",
21
+ "subpath": "./entities",
22
+ "kind": "subpath",
23
+ "title": "Entities",
24
+ "description": "Published base entity contracts (Project, Milestone, Task, Deal, Company, Contact) generic over a metadata extension slot.",
25
+ "group": "Entities",
26
+ "order": 1,
27
+ "sourcePath": "packages/core/src/business/entities-published.ts",
28
+ "docPath": "packages/core/src/business/README.md",
29
+ "referencePath": "packages/core/src/business/README.md",
30
+ "publishedExportPath": "./dist/business/entities-published.js"
31
+ },
18
32
  {
19
33
  "packageName": "@elevasis/core",
20
34
  "packageDir": "packages/core",
@@ -435,6 +449,20 @@
435
449
  "referencePath": "packages/ui/src/zustand/README.md",
436
450
  "publishedExportPath": "./dist/zustand/index.js"
437
451
  },
452
+ {
453
+ "packageName": "@elevasis/ui",
454
+ "packageDir": "packages/ui",
455
+ "subpath": "./app",
456
+ "kind": "subpath",
457
+ "title": "App",
458
+ "description": "Published app factory that composes providers, router, auth, and theme into a mountable React app.",
459
+ "group": "Foundation",
460
+ "order": 14,
461
+ "sourcePath": "packages/ui/src/app/index.ts",
462
+ "docPath": "packages/ui/src/app/README.md",
463
+ "referencePath": "packages/ui/src/app/README.md",
464
+ "publishedExportPath": "./dist/app/index.js"
465
+ },
438
466
  {
439
467
  "packageName": "@elevasis/ui",
440
468
  "packageDir": "packages/ui",
@@ -449,6 +477,34 @@
449
477
  "referencePath": "packages/ui/src/hooks/README.md",
450
478
  "publishedExportPath": "./dist/hooks/published.js"
451
479
  },
480
+ {
481
+ "packageName": "@elevasis/ui",
482
+ "packageDir": "packages/ui",
483
+ "subpath": "./hooks/delivery",
484
+ "kind": "subpath",
485
+ "title": "Hooks Delivery",
486
+ "description": "Published delivery hooks for projects, milestones, tasks, and notes.",
487
+ "group": "Hooks",
488
+ "order": 2,
489
+ "sourcePath": "packages/ui/src/hooks/delivery/index.ts",
490
+ "docPath": "packages/ui/src/hooks/README.md",
491
+ "referencePath": "packages/ui/src/hooks/README.md",
492
+ "publishedExportPath": "./dist/hooks/delivery/index.js"
493
+ },
494
+ {
495
+ "packageName": "@elevasis/ui",
496
+ "packageDir": "packages/ui",
497
+ "subpath": "./hooks/operations/command-view/utils/transformCommandViewData",
498
+ "kind": "subpath",
499
+ "title": "Transform Command View Data",
500
+ "description": "Utility that transforms backend CommandViewData arrays into a unified frontend CommandViewGraph with nodes and edges.",
501
+ "group": "Hooks",
502
+ "order": 3,
503
+ "sourcePath": "packages/ui/src/hooks/operations/command-view/utils/transformCommandViewData.ts",
504
+ "docPath": "packages/ui/src/hooks/README.md",
505
+ "referencePath": "packages/ui/src/hooks/README.md",
506
+ "publishedExportPath": "./dist/hooks/operations/command-view/utils/transformCommandViewData.js"
507
+ },
452
508
  {
453
509
  "packageName": "@elevasis/ui",
454
510
  "packageDir": "packages/ui",
@@ -477,6 +533,20 @@
477
533
  "referencePath": "packages/ui/src/provider/README.md",
478
534
  "publishedExportPath": "./dist/provider/index.js"
479
535
  },
536
+ {
537
+ "packageName": "@elevasis/ui",
538
+ "packageDir": "packages/ui",
539
+ "subpath": "./provider/ElevasisServiceContext",
540
+ "kind": "subpath",
541
+ "title": "Elevasis Service Context",
542
+ "description": "Standalone service context and provider that supplies apiRequest, organizationId, and isReady to child components.",
543
+ "group": "Provider",
544
+ "order": 3,
545
+ "sourcePath": "packages/ui/src/provider/ElevasisServiceContext.tsx",
546
+ "docPath": "packages/ui/src/provider/README.md",
547
+ "referencePath": "packages/ui/src/provider/README.md",
548
+ "publishedExportPath": "./dist/provider/ElevasisServiceContext.js"
549
+ },
480
550
  {
481
551
  "packageName": "@elevasis/ui",
482
552
  "packageDir": "packages/ui",
@@ -0,0 +1,11 @@
1
+ # Submit Issue
2
+
3
+ **Usage:** `/submit-issue [optional one-line description]`
4
+
5
+ **Goal:** File a structured issue report to the Elevasis platform after agent-driven pre-analysis.
6
+
7
+ **EXECUTE:** `.claude/skills/submit-issue/SKILL.md`
8
+
9
+ ## Env Requirements
10
+
11
+ - `ELEVASIS_PLATFORM_KEY` (same key used by all `elevasis-sdk` commands — no extra setup if deploy already works)
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ // post-edit-validate.mjs
3
+ // PostToolUse hook — auto-formats with prettier, type-checks .ts/.tsx files.
4
+ // Fires after Edit|Write|MultiEdit succeeds.
5
+
6
+ import { existsSync, readFileSync } from 'node:fs'
7
+ import { resolve, normalize, extname, join, dirname, relative } from 'node:path'
8
+ import { execSync } from 'node:child_process'
9
+
10
+ const ROOT = process.env.CLAUDE_PROJECT_DIR ?? process.cwd()
11
+
12
+ // Extensions prettier should format
13
+ const PRETTIER_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json', '.css', '.md'])
14
+
15
+ // Extensions that trigger type-checking
16
+ const TS_EXTENSIONS = new Set(['.ts', '.tsx'])
17
+
18
+ function findNearestTsconfig(startDir) {
19
+ let dir = startDir
20
+ const root = normalize(ROOT)
21
+ while (dir.length >= root.length) {
22
+ const candidate = join(dir, 'tsconfig.json')
23
+ if (existsSync(candidate)) return candidate
24
+ const parent = dirname(dir)
25
+ if (parent === dir) break
26
+ dir = parent
27
+ }
28
+ return null
29
+ }
30
+
31
+ try {
32
+ const chunks = []
33
+ for await (const chunk of process.stdin) chunks.push(chunk)
34
+ const input = JSON.parse(Buffer.concat(chunks).toString())
35
+
36
+ const filePath = input.tool_input?.file_path
37
+ if (!filePath) process.exit(0)
38
+
39
+ const ext = extname(filePath).toLowerCase()
40
+ const absPath = normalize(resolve(filePath))
41
+ if (!existsSync(absPath)) process.exit(0)
42
+
43
+ const results = []
44
+
45
+ // 0. Frontmatter check for docs/*.md (except docs/index.md which is auto-generated)
46
+ const docsDir = normalize(join(ROOT, 'docs'))
47
+ const indexPath = normalize(join(docsDir, 'index.md'))
48
+ if (ext === '.md' && absPath.startsWith(docsDir) && absPath !== indexPath) {
49
+ const content = readFileSync(absPath, 'utf-8')
50
+ if (!content.startsWith('---\n') && !content.startsWith('---\r\n')) {
51
+ const rel = relative(ROOT, absPath).replace(/\\/g, '/')
52
+ results.push(`Missing frontmatter in ${rel}. All docs require:\n---\ntitle: ...\ndescription: ...\n---`)
53
+ }
54
+ }
55
+
56
+ // 1. Prettier (skip silently if not installed yet, e.g. before first pnpm install)
57
+ if (PRETTIER_EXTENSIONS.has(ext)) {
58
+ try {
59
+ execSync('pnpm exec prettier --version', { cwd: ROOT, stdio: 'pipe', timeout: 5_000 })
60
+ try {
61
+ execSync('pnpm exec prettier --write "' + absPath + '"', {
62
+ cwd: ROOT,
63
+ stdio: ['pipe', 'pipe', 'pipe'],
64
+ timeout: 10_000
65
+ })
66
+ } catch (err) {
67
+ const stderr = err.stderr?.toString().trim() || ''
68
+ if (stderr && !/ignored/i.test(stderr)) {
69
+ results.push('Prettier error: ' + stderr.slice(0, 300))
70
+ }
71
+ }
72
+ } catch {
73
+ // prettier not installed yet -- skip silently
74
+ }
75
+ }
76
+
77
+ // 2. Type-check for .ts/.tsx
78
+ if (TS_EXTENSIONS.has(ext)) {
79
+ const tsconfig = findNearestTsconfig(dirname(absPath))
80
+ if (tsconfig) {
81
+ try {
82
+ execSync('pnpm exec tsc --noEmit -p "' + tsconfig + '"', {
83
+ cwd: ROOT,
84
+ stdio: ['pipe', 'pipe', 'pipe'],
85
+ timeout: 30_000,
86
+ env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=4096' }
87
+ })
88
+ } catch (err) {
89
+ if (err.killed) process.exit(0) // Don't block on timeout
90
+ const stdout = err.stdout?.toString() || ''
91
+ if (stdout.includes('error TS')) {
92
+ const errorLines = stdout
93
+ .split('\n')
94
+ .filter((l) => l.includes('error TS'))
95
+ .slice(0, 10)
96
+ results.push('Type errors after editing ' + filePath + ':\n' + errorLines.join('\n'))
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ // Output errors to Claude's context (silence = success)
103
+ if (results.length > 0) {
104
+ process.stderr.write(results.join('\n\n'))
105
+ process.exit(2) // Exit 2 = send stderr as feedback to Claude
106
+ }
107
+ } catch {}
108
+
109
+ process.exit(0)
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ // tool-failure-recovery.mjs
3
+ // PostToolUseFailure hook — pattern-matches known Bash errors and returns
4
+ // recovery advice via stderr + exit 2 (feedback to Claude).
5
+
6
+ const RECOVERY_TABLE = [
7
+ {
8
+ test: (r) => /JavaScript heap out of memory/i.test(r),
9
+ advice: 'Out of memory.',
10
+ fix: 'Run the command with NODE_OPTIONS="--max-old-space-size=4096".',
11
+ why: 'Large TypeScript projects can exceed Node default heap limit.'
12
+ },
13
+ {
14
+ test: (r) => /ENOENT/.test(r) && /node_modules/.test(r),
15
+ advice: 'Missing node_modules dependency.',
16
+ fix: 'Run: pnpm install',
17
+ why: 'Dependencies are not installed or were cleared.'
18
+ },
19
+ {
20
+ test: (r) => /ERR_MODULE_NOT_FOUND/.test(r),
21
+ advice: 'Module not found at import path.',
22
+ fix: 'Check the import path and verify the package is installed (pnpm install).',
23
+ why: 'The import path does not match any installed package or local file.'
24
+ },
25
+ {
26
+ test: (r) => /TS2307/.test(r) || (/cannot find/i.test(r) && /declaration/i.test(r)),
27
+ advice: 'TypeScript cannot resolve module or declaration file.',
28
+ fix: 'Check that the package is installed and tsconfig paths are correct.',
29
+ why: 'Missing dependency or incorrect TypeScript configuration.'
30
+ },
31
+ {
32
+ test: (r) => /EPERM/.test(r) || /permission denied/i.test(r),
33
+ advice: 'Permission denied (EPERM).',
34
+ fix: 'Close the file in any other process (editor, terminal, or dev server) and retry.',
35
+ why: 'On Windows, files locked by another process cannot be written to.'
36
+ },
37
+ {
38
+ test: (r) => /lockfile/i.test(r) && /conflict|outdated|ERR_PNPM/i.test(r),
39
+ advice: 'pnpm lockfile conflict or outdated.',
40
+ fix: 'Run: pnpm install to regenerate the lockfile.',
41
+ why: 'The lockfile is out of sync with package.json changes.'
42
+ },
43
+ {
44
+ test: (r) => /EADDRINUSE/.test(r),
45
+ advice: 'Port already in use.',
46
+ fix: 'Find and kill the process using the port, or use a different port.',
47
+ why: 'A previous dev server or process is still holding the port.'
48
+ }
49
+ ]
50
+
51
+ function formatRecovery(entry) {
52
+ let msg = 'FAILED: ' + entry.advice + '\nFIX: ' + entry.fix
53
+ if (entry.why) msg += '\nWHY: ' + entry.why
54
+ if (entry.see) msg += '\nSEE: ' + entry.see
55
+ return msg
56
+ }
57
+
58
+ try {
59
+ const chunks = []
60
+ for await (const chunk of process.stdin) chunks.push(chunk)
61
+ const input = JSON.parse(Buffer.concat(chunks).toString())
62
+
63
+ const response = input.tool_response ?? ''
64
+
65
+ for (const entry of RECOVERY_TABLE) {
66
+ if (entry.test(response)) {
67
+ process.stderr.write(formatRecovery(entry))
68
+ process.exit(2)
69
+ }
70
+ }
71
+ } catch {}
72
+
73
+ process.exit(0)
@@ -0,0 +1,57 @@
1
+ ---
2
+ description: Deployment workflow -- check-first, dev vs prod, version bumping, common errors
3
+ paths:
4
+ - operations/**
5
+ ---
6
+
7
+ # Deployment
8
+
9
+ ## Always Check Before Deploy
10
+
11
+ ```bash
12
+ pnpm -C operations run check # Validate resource definitions
13
+ pnpm -C operations run check-types # TypeScript type-check
14
+ pnpm -C operations run deploy # Deploy to dev (only after both pass)
15
+ ```
16
+
17
+ `check` catches duplicate resourceIds, invalid step chains, broken relationships, and schema serialization issues. Same validation runs during deploy -- if `check` passes, deploy validation will pass.
18
+
19
+ ## Dev vs Prod
20
+
21
+ | Command | Target | When |
22
+ | ------------------------------------ | ----------------- | ----------------------- |
23
+ | `pnpm -C operations run deploy` | Local dev API | Development and testing |
24
+ | `pnpm -C operations run deploy:prod` | `api.elevasis.io` | Production release |
25
+
26
+ Always test in dev first, verify with `elevasis-sdk exec`, then deploy to prod.
27
+
28
+ ## Version Bumping
29
+
30
+ Deploy accepts `--major`, `--minor`, `--patch` flags to bump the deployment version. The bumped version is written back to `src/index.ts`. Bump on contract changes (input/output schema modifications).
31
+
32
+ ## What Gets Deployed
33
+
34
+ 1. **Bundle:** esbuild compiles `src/index.ts` + all dependencies into a single self-contained CJS file. No `node_modules` needed at runtime.
35
+ 2. **Metadata:** Resource definitions, Zod schemas (converted to JSON Schema), relationships, triggers.
36
+ 3. **Docs:** All `.md` and `.mdx` files in `docs/` (max 100KB per file, 1MB total). The SDK scans the directory configured as `docsDir` in `elevasis.config.ts` (defaults to `docs/`, set to `../docs/` in this template). Two auto-generated files are regenerated by `/deploy` and `/elevasis deploy` before upload: `docs/index.md` (navigation hub) and `docs/resources.md` (platform resource inventory).
37
+
38
+ ## Environment
39
+
40
+ - `ELEVASIS_PLATFORM_KEY` in `.env` is required for CLI auth
41
+ - `.env` is never included in the bundle -- it stays local
42
+ - Integration credentials live in Command Center, not `.env`
43
+
44
+ ## Common Errors
45
+
46
+ | Error | Fix |
47
+ | ---------------------------------------- | ------------------------------------------------------- |
48
+ | `401: Invalid API key` | Check `ELEVASIS_PLATFORM_KEY` in `.env` |
49
+ | `Duplicate resource ID` | Rename `resourceId` in the conflicting resource |
50
+ | `Step references non-existent next step` | Fix the `next:` field in the step chain |
51
+ | `Schema serialization failed` | Simplify the Zod schema (warning, still deploys) |
52
+ | `No default export found` | `src/index.ts` must `export default` a `DeploymentSpec` |
53
+ | `Documentation file exceeds 100KB` | Split the `.md` file |
54
+
55
+ ## Deployment Replaces Previous
56
+
57
+ Only one deployment can be `active` at a time. Deploying again automatically marks the previous deployment as `stopped`. Resources become executable immediately after deploy succeeds.