@elevasis/sdk 0.4.11 → 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -43405,6 +43405,12 @@ var ResourceRegistry = class {
43405
43405
  if (existingOrg) {
43406
43406
  existingOrg.workflows = [...existingOrg.workflows ?? [], ...org.workflows ?? []];
43407
43407
  existingOrg.agents = [...existingOrg.agents ?? [], ...org.agents ?? []];
43408
+ if (org.relationships) {
43409
+ existingOrg.relationships = {
43410
+ ...existingOrg.relationships ?? {},
43411
+ ...org.relationships
43412
+ };
43413
+ }
43408
43414
  } else {
43409
43415
  this.registry[orgName] = org;
43410
43416
  }
@@ -43442,6 +43448,14 @@ var ResourceRegistry = class {
43442
43448
  orgResources.agents = (orgResources.agents ?? []).filter(
43443
43449
  (a) => !remoteIds.has(a.config.resourceId)
43444
43450
  );
43451
+ if (orgResources.relationships) {
43452
+ for (const id of remoteIds) {
43453
+ delete orgResources.relationships[id];
43454
+ }
43455
+ if (Object.keys(orgResources.relationships).length === 0) {
43456
+ delete orgResources.relationships;
43457
+ }
43458
+ }
43445
43459
  const remaining = (orgResources.workflows?.length ?? 0) + (orgResources.agents?.length ?? 0) + (orgResources.triggers?.length ?? 0) + (orgResources.integrations?.length ?? 0) + (orgResources.externalResources?.length ?? 0) + (orgResources.humanCheckpoints?.length ?? 0);
43446
43460
  if (remaining > 0) {
43447
43461
  this.serializedCache.set(orgName, serializeOrganization(orgResources));
@@ -43816,7 +43830,7 @@ async function apiDelete(endpoint, apiUrl = resolveApiUrl()) {
43816
43830
  // package.json
43817
43831
  var package_default = {
43818
43832
  name: "@elevasis/sdk",
43819
- version: "0.4.11",
43833
+ version: "0.4.12",
43820
43834
  description: "SDK for building Elevasis organization resources",
43821
43835
  "comment:bin": "IMPORTANT: This package shares the 'elevasis' binary name with @repo/cli. They never conflict because @elevasis/sdk must NEVER be added as a dependency of any workspace package (apps/*, packages/*, organizations/*). Workspace projects use @repo/cli for the 'elevasis' binary. External developers (outside the workspace) get this SDK's binary via npm install.",
43822
43836
  type: "module",
@@ -44046,6 +44060,16 @@ function registerDeployCommand(program3) {
44046
44060
  if (documentation) {
44047
44061
  console.log(source_default.gray(` docs ${source_default.white(String(documentation.length))} file${documentation.length !== 1 ? "s" : ""}`));
44048
44062
  }
44063
+ const triggerCount = org.triggers?.length ?? 0;
44064
+ const integrationCount = org.integrations?.length ?? 0;
44065
+ const checkpointCount = org.humanCheckpoints?.length ?? 0;
44066
+ if (triggerCount > 0) console.log(source_default.gray(` triggers ${source_default.white(String(triggerCount))}`));
44067
+ if (integrationCount > 0) console.log(source_default.gray(` integrations ${source_default.white(String(integrationCount))}`));
44068
+ if (checkpointCount > 0) console.log(source_default.gray(` checkpoints ${source_default.white(String(checkpointCount))}`));
44069
+ const relationshipCount = org.relationships ? Object.keys(org.relationships).length : 0;
44070
+ if (relationshipCount > 0) {
44071
+ console.log(source_default.gray(` rels ${source_default.white(String(relationshipCount))} resource${relationshipCount !== 1 ? "s" : ""}`));
44072
+ }
44049
44073
  const schemaWarnings = [];
44050
44074
  const workflows = (org.workflows ?? []).map((w) => {
44051
44075
  const meta = {
@@ -44148,7 +44172,8 @@ startWorker(org)
44148
44172
  sdkVersion: SDK_VERSION,
44149
44173
  mode: env2,
44150
44174
  resources: { workflows, agents },
44151
- ...documentation ? { documentation } : {}
44175
+ ...documentation ? { documentation } : {},
44176
+ ...org.relationships ? { relationships: org.relationships } : {}
44152
44177
  };
44153
44178
  const form = new FormData();
44154
44179
  form.append("bundle", new Blob([bundleBuffer]), "bundle.js");
@@ -44564,14 +44589,46 @@ var MANAGED_FILES = [
44564
44589
  ".claude/commands/work.md",
44565
44590
  ".claude/skills/creds/SKILL.md"
44566
44591
  ];
44592
+ var UI_INIT_FILES = [
44593
+ "ui/package.json",
44594
+ "ui/index.html",
44595
+ "ui/vite.config.ts",
44596
+ "ui/tsconfig.json",
44597
+ "ui/src/main.tsx",
44598
+ "ui/src/App.tsx",
44599
+ "ui/src/AuthRedirect.tsx",
44600
+ "ui/src/vite-env.d.ts",
44601
+ "ui/.env",
44602
+ "ui/.env.example"
44603
+ ];
44567
44604
  var SCAFFOLD_FILES = [...INIT_ONLY_FILES, ...MANAGED_FILES];
44605
+ function getManagedTemplates(ctx = {}) {
44606
+ return {
44607
+ "elevasis.config.ts": configTemplate,
44608
+ ".gitignore": () => gitignoreTemplate(ctx),
44609
+ "CLAUDE.md": () => claudeMdTemplate(ctx),
44610
+ ".claude/settings.json": claudeSettingsTemplate,
44611
+ ".claude/commands/docs.md": claudeDocsCommandTemplate,
44612
+ ".claude/commands/resource.md": claudeResourceCommandTemplate,
44613
+ ".claude/commands/tutorial.md": claudeTutorialCommandTemplate,
44614
+ ".claude/commands/help.md": claudeHelpCommandTemplate,
44615
+ ".claude/commands/templates.md": claudeTemplatesCommandTemplate,
44616
+ ".claude/commands/database.md": claudeDatabaseCommandTemplate,
44617
+ ".claude/commands/agent.md": claudeAgentCommandTemplate,
44618
+ ".claude/commands/profile.md": claudeProfileCommandTemplate,
44619
+ ".claude/commands/meta.md": claudeMetaCommandTemplate,
44620
+ ".claude/commands/work.md": claudeWorkCommandTemplate,
44621
+ ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate
44622
+ };
44623
+ }
44568
44624
  function registerInitCommand(program3) {
44569
- program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis init my-workspace").option("--force", "Overwrite existing files").action(wrapAction("init", async (directory, options2) => {
44625
+ program3.command("init [directory]").description("Scaffold a new Elevasis workspace\n Example: elevasis init my-workspace").option("--force", "Overwrite existing files").option("--ui", "Include a Vite + React UI app in ui/").action(wrapAction("init", async (directory, options2) => {
44570
44626
  const targetDir = directory ? (0, import_path3.resolve)(directory) : process.cwd();
44571
44627
  const orgSlug = toSlug((0, import_path3.basename)(targetDir));
44572
44628
  if (!options2.force) {
44629
+ const filesToCheck = options2.ui ? [...SCAFFOLD_FILES, ...UI_INIT_FILES] : SCAFFOLD_FILES;
44573
44630
  const conflicts = [];
44574
- for (const file2 of SCAFFOLD_FILES) {
44631
+ for (const file2 of filesToCheck) {
44575
44632
  try {
44576
44633
  await (0, import_promises2.access)((0, import_path3.resolve)(targetDir, file2));
44577
44634
  conflicts.push(file2);
@@ -44593,6 +44650,9 @@ function registerInitCommand(program3) {
44593
44650
  await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "docs/in-progress"), { recursive: true });
44594
44651
  await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/commands"), { recursive: true });
44595
44652
  await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/skills/creds"), { recursive: true });
44653
+ if (options2.ui) {
44654
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "ui/src"), { recursive: true });
44655
+ }
44596
44656
  const files = {
44597
44657
  "elevasis.config.ts": configTemplate(),
44598
44658
  "package.json": packageJsonTemplate(orgSlug),
@@ -44601,7 +44661,7 @@ function registerInitCommand(program3) {
44601
44661
  ".env": envTemplate(),
44602
44662
  ".env.example": envExampleTemplate(),
44603
44663
  ".npmrc": npmrcTemplate(),
44604
- ".gitignore": gitignoreTemplate(),
44664
+ ".gitignore": gitignoreTemplate({ hasUI: options2.ui }),
44605
44665
  "src/index.ts": starterTemplate(),
44606
44666
  "src/operations/platform-status.ts": platformStatusTemplate(),
44607
44667
  "src/operations/index.ts": operationsBarrelTemplate(),
@@ -44610,7 +44670,7 @@ function registerInitCommand(program3) {
44610
44670
  "src/shared/.gitkeep": "",
44611
44671
  "docs/index.mdx": docsIndexTemplate(orgSlug),
44612
44672
  "docs/in-progress/.gitkeep": "",
44613
- "CLAUDE.md": claudeMdTemplate(),
44673
+ "CLAUDE.md": claudeMdTemplate({ hasUI: options2.ui }),
44614
44674
  ".claude/settings.json": claudeSettingsTemplate(),
44615
44675
  ".claude/commands/docs.md": claudeDocsCommandTemplate(),
44616
44676
  ".claude/commands/resource.md": claudeResourceCommandTemplate(),
@@ -44624,6 +44684,9 @@ function registerInitCommand(program3) {
44624
44684
  ".claude/commands/work.md": claudeWorkCommandTemplate(),
44625
44685
  ".claude/skills/creds/SKILL.md": claudeCredsSkillTemplate()
44626
44686
  };
44687
+ if (options2.ui) {
44688
+ Object.assign(files, getUIFiles(orgSlug));
44689
+ }
44627
44690
  for (const [filePath, content] of Object.entries(files)) {
44628
44691
  await (0, import_promises2.writeFile)((0, import_path3.resolve)(targetDir, filePath), content, "utf-8");
44629
44692
  }
@@ -44637,6 +44700,13 @@ function registerInitCommand(program3) {
44637
44700
  console.log(source_default.gray(" # Copy .env.example to .env and add your API key"));
44638
44701
  console.log(source_default.gray(" elevasis check"));
44639
44702
  console.log(source_default.gray(" elevasis deploy"));
44703
+ if (options2.ui) {
44704
+ console.log("");
44705
+ console.log(source_default.gray(" UI app:"));
44706
+ console.log(source_default.gray(" cd ui && pnpm install"));
44707
+ console.log(source_default.gray(" # Set VITE_WORKOS_CLIENT_ID in ui/.env"));
44708
+ console.log(source_default.gray(" pnpm dev"));
44709
+ }
44640
44710
  }));
44641
44711
  }
44642
44712
  function toSlug(name) {
@@ -44704,14 +44774,20 @@ function npmrcTemplate() {
44704
44774
  return `auto-install-peers = true
44705
44775
  `;
44706
44776
  }
44707
- function gitignoreTemplate() {
44708
- return `node_modules/
44777
+ function gitignoreTemplate(ctx = {}) {
44778
+ let content = `node_modules/
44709
44779
  .env
44710
44780
  dist/
44711
44781
  __elevasis_worker.ts
44712
44782
  .claude/settings.local.json
44713
44783
  .claude/memory/
44714
44784
  `;
44785
+ if (ctx.hasUI) {
44786
+ content += `ui/node_modules/
44787
+ ui/dist/
44788
+ `;
44789
+ }
44790
+ return content;
44715
44791
  }
44716
44792
  function docsIndexTemplate(organization) {
44717
44793
  return `---
@@ -44787,7 +44863,7 @@ elevasis exec echo --input '{"message": "hello"}'
44787
44863
  function claudeSettingsTemplate() {
44788
44864
  return JSON.stringify({ autoCompact: false }, null, 2) + "\n";
44789
44865
  }
44790
- function claudeMdTemplate() {
44866
+ function claudeMdTemplate(ctx = {}) {
44791
44867
  return `<!-- initialized: false -->
44792
44868
 
44793
44869
  # CLAUDE.md
@@ -44840,7 +44916,8 @@ proactivity -- to their assessed levels.
44840
44916
  | Project resource map | \`docs/navigation.mdx\` | Understanding what's deployed |
44841
44917
  | Project priorities | \`docs/priorities.mdx\` | Deciding what to work on next |
44842
44918
  | User profile and skills | \`.claude/memory/profile/skills.md\` | Session start (mandatory) |
44843
- | Cross-session memory | \`.claude/memory/index.md\` | Session start, recalling past context |
44919
+ | Cross-session memory | \`.claude/memory/index.md\` | Session start, recalling past context |${ctx.hasUI ? `
44920
+ | UI app source | \`ui/src/\` | Modifying the frontend, adding routes or components |` : ""}
44844
44921
 
44845
44922
  All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
44846
44923
 
@@ -44862,7 +44939,17 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
44862
44939
  - When an error occurs, check \`.claude/memory/errors/\` first for past fixes.
44863
44940
  If the error is new, check \`reference/troubleshooting/common-errors.mdx\`.
44864
44941
  After resolving, record the error in \`memory/errors/\` with context and fix.
44865
- If an error recurs 3+ times, promote it to a rule in this section.
44942
+ If an error recurs 3+ times, promote it to a rule in this section.${ctx.hasUI ? `
44943
+
44944
+ ### UI App (\`ui/\`)
44945
+
44946
+ - \`ui/\` is a standalone Vite + React app with its own \`package.json\` -- not part of the pnpm workspace
44947
+ - Import from \`@elevasis/sdk-ui\`, never from \`@elevasis/sdk\` or \`@repo/ui\`
44948
+ - Dev server runs on port 5100: \`cd ui && pnpm dev\`
44949
+ - Set \`VITE_WORKOS_CLIENT_ID\` in \`ui/.env\` before running
44950
+ - \`ElevasisProvider\` is pre-configured in \`ui/src/App.tsx\` (oauth mode, redirectUri \`http://localhost:5100/auth-redirect\`, apiUrl \`http://localhost:5170\`)
44951
+ - OAuth redirect is handled by the \`AuthRedirect\` component at \`/auth-redirect\` -- it uses \`useAuthContext()\` from \`@elevasis/sdk-ui/auth\` and navigates home once \`user\` is set
44952
+ - API must be running on port 5170 for the UI to work (\`pnpm --filter api dev\` from the platform monorepo)` : ""}
44866
44953
 
44867
44954
  ## Interaction Guidance
44868
44955
 
@@ -45801,12 +45888,166 @@ export const workflows = [echo]
45801
45888
  export const agents = []
45802
45889
  `;
45803
45890
  }
45891
+ function getUIFiles(orgSlug) {
45892
+ return {
45893
+ "ui/package.json": uiPackageJsonTemplate(orgSlug),
45894
+ "ui/index.html": uiIndexHtmlTemplate(),
45895
+ "ui/vite.config.ts": uiViteConfigTemplate(),
45896
+ "ui/tsconfig.json": uiTsconfigTemplate(),
45897
+ "ui/src/main.tsx": uiMainTsxTemplate(),
45898
+ "ui/src/App.tsx": uiAppTsxTemplate(),
45899
+ "ui/src/AuthRedirect.tsx": uiAuthRedirectTemplate(),
45900
+ "ui/src/vite-env.d.ts": uiViteEnvDtsTemplate(),
45901
+ "ui/.env": uiEnvTemplate(),
45902
+ "ui/.env.example": uiEnvExampleTemplate()
45903
+ };
45904
+ }
45905
+ function uiPackageJsonTemplate(orgSlug) {
45906
+ return JSON.stringify({
45907
+ name: `${orgSlug}-ui`,
45908
+ private: true,
45909
+ type: "module",
45910
+ scripts: {
45911
+ dev: "vite",
45912
+ build: "tsc && vite build",
45913
+ preview: "vite preview"
45914
+ },
45915
+ dependencies: {
45916
+ "@elevasis/sdk-ui": "latest",
45917
+ "@mantine/core": "^8.0.0",
45918
+ "@mantine/hooks": "^8.0.0",
45919
+ "react": "^19.0.0",
45920
+ "react-dom": "^19.0.0",
45921
+ "react-router-dom": "^7.0.0"
45922
+ },
45923
+ devDependencies: {
45924
+ "@types/react": "^19.0.0",
45925
+ "@types/react-dom": "^19.0.0",
45926
+ "@vitejs/plugin-react": "^4.0.0",
45927
+ "typescript": "^5.7.0",
45928
+ "vite": "^6.0.0"
45929
+ }
45930
+ }, null, 2) + "\n";
45931
+ }
45932
+ function uiIndexHtmlTemplate() {
45933
+ return `<!doctype html>
45934
+ <html lang="en">
45935
+ <head>
45936
+ <meta charset="UTF-8" />
45937
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
45938
+ <title>Elevasis UI</title>
45939
+ </head>
45940
+ <body>
45941
+ <div id="root"></div>
45942
+ <script type="module" src="/src/main.tsx"></script>
45943
+ </body>
45944
+ </html>
45945
+ `;
45946
+ }
45947
+ function uiViteConfigTemplate() {
45948
+ return `import { defineConfig } from 'vite'
45949
+ import react from '@vitejs/plugin-react'
45950
+
45951
+ export default defineConfig({
45952
+ plugins: [react()],
45953
+ server: {
45954
+ port: 5100,
45955
+ },
45956
+ })
45957
+ `;
45958
+ }
45959
+ function uiTsconfigTemplate() {
45960
+ return JSON.stringify({
45961
+ compilerOptions: {
45962
+ target: "ES2022",
45963
+ lib: ["ES2022", "DOM", "DOM.Iterable"],
45964
+ module: "ESNext",
45965
+ moduleResolution: "bundler",
45966
+ jsx: "react-jsx",
45967
+ strict: true,
45968
+ esModuleInterop: true,
45969
+ skipLibCheck: true,
45970
+ forceConsistentCasingInFileNames: true,
45971
+ isolatedModules: true,
45972
+ noEmit: true
45973
+ },
45974
+ include: ["src"]
45975
+ }, null, 2) + "\n";
45976
+ }
45977
+ function uiMainTsxTemplate() {
45978
+ return `import { StrictMode } from 'react'
45979
+ import { createRoot } from 'react-dom/client'
45980
+ import { BrowserRouter } from 'react-router-dom'
45981
+ import { App } from './App'
45982
+
45983
+ createRoot(document.getElementById('root')!).render(
45984
+ <StrictMode>
45985
+ <BrowserRouter>
45986
+ <App />
45987
+ </BrowserRouter>
45988
+ </StrictMode>,
45989
+ )
45990
+ `;
45991
+ }
45992
+ function uiAppTsxTemplate() {
45993
+ return `import { Routes, Route } from 'react-router-dom'
45994
+ import { ElevasisProvider } from '@elevasis/sdk-ui'
45995
+ import { AuthRedirect } from './AuthRedirect'
45996
+
45997
+ export function App() {
45998
+ return (
45999
+ <ElevasisProvider
46000
+ mode="oauth"
46001
+ clientId={import.meta.env.VITE_WORKOS_CLIENT_ID}
46002
+ redirectUri="http://localhost:5100/auth-redirect"
46003
+ apiUrl="http://localhost:5170"
46004
+ >
46005
+ <Routes>
46006
+ <Route path="/" element={<h1>Home</h1>} />
46007
+ <Route path="/auth-redirect" element={<AuthRedirect />} />
46008
+ </Routes>
46009
+ </ElevasisProvider>
46010
+ )
46011
+ }
46012
+ `;
46013
+ }
46014
+ function uiAuthRedirectTemplate() {
46015
+ return `import { useEffect } from 'react'
46016
+ import { useNavigate } from 'react-router-dom'
46017
+ import { useAuthContext } from '@elevasis/sdk-ui/auth'
46018
+
46019
+ export function AuthRedirect() {
46020
+ const { user } = useAuthContext()
46021
+ const navigate = useNavigate()
46022
+
46023
+ useEffect(() => {
46024
+ if (user) {
46025
+ navigate('/', { replace: true })
46026
+ }
46027
+ }, [user, navigate])
46028
+
46029
+ return <p>Signing in...</p>
46030
+ }
46031
+ `;
46032
+ }
46033
+ function uiViteEnvDtsTemplate() {
46034
+ return `/// <reference types="vite/client" />
46035
+ `;
46036
+ }
46037
+ function uiEnvTemplate() {
46038
+ return `VITE_WORKOS_CLIENT_ID=
46039
+ `;
46040
+ }
46041
+ function uiEnvExampleTemplate() {
46042
+ return `VITE_WORKOS_CLIENT_ID=your_workos_client_id
46043
+ `;
46044
+ }
45804
46045
 
45805
46046
  // src/cli/commands/update.ts
45806
46047
  var import_path4 = require("path");
45807
46048
  var import_promises3 = require("fs/promises");
45808
46049
  function registerUpdateCommand(program3) {
45809
- program3.command("update").description("Update project scaffold to latest template version").action(wrapAction("update", async () => {
46050
+ program3.command("update").description("Update project scaffold to latest template version").option("--ui", "Add a Vite + React UI app in ui/").action(wrapAction("update", async (options2 = {}) => {
45810
46051
  const cwd = process.cwd();
45811
46052
  const configPath = (0, import_path4.resolve)(cwd, "elevasis.config.ts");
45812
46053
  let currentVersion = 0;
@@ -45819,32 +46060,28 @@ function registerUpdateCommand(program3) {
45819
46060
  }
45820
46061
  } catch {
45821
46062
  }
45822
- if (currentVersion >= TEMPLATE_VERSION) {
46063
+ const upToDate = currentVersion >= TEMPLATE_VERSION;
46064
+ if (upToDate && !options2.ui) {
45823
46065
  console.log(source_default.green(` Project is up to date (template version ${TEMPLATE_VERSION})`));
45824
46066
  return;
45825
46067
  }
45826
- const templateMap = {
45827
- "elevasis.config.ts": configTemplate,
45828
- ".gitignore": gitignoreTemplate,
45829
- "CLAUDE.md": claudeMdTemplate,
45830
- ".claude/settings.json": claudeSettingsTemplate,
45831
- ".claude/commands/docs.md": claudeDocsCommandTemplate,
45832
- ".claude/commands/resource.md": claudeResourceCommandTemplate,
45833
- ".claude/commands/tutorial.md": claudeTutorialCommandTemplate,
45834
- ".claude/commands/help.md": claudeHelpCommandTemplate,
45835
- ".claude/commands/templates.md": claudeTemplatesCommandTemplate,
45836
- ".claude/commands/database.md": claudeDatabaseCommandTemplate,
45837
- ".claude/commands/agent.md": claudeAgentCommandTemplate,
45838
- ".claude/commands/profile.md": claudeProfileCommandTemplate,
45839
- ".claude/commands/meta.md": claudeMetaCommandTemplate,
45840
- ".claude/commands/work.md": claudeWorkCommandTemplate
45841
- };
46068
+ let hasUI = !!options2.ui;
46069
+ if (!hasUI) {
46070
+ try {
46071
+ await (0, import_promises3.access)((0, import_path4.resolve)(cwd, "ui"));
46072
+ hasUI = true;
46073
+ } catch {
46074
+ }
46075
+ }
46076
+ const managedTemplates = getManagedTemplates({ hasUI });
45842
46077
  const added = [];
45843
46078
  const flagged = [];
45844
46079
  const appendedGitignore = [];
45845
- for (const file2 of MANAGED_FILES) {
46080
+ const uiAffectedFiles = /* @__PURE__ */ new Set([".gitignore", "CLAUDE.md"]);
46081
+ const filesToProcess = upToDate ? MANAGED_FILES.filter((f) => uiAffectedFiles.has(f)) : MANAGED_FILES;
46082
+ for (const file2 of filesToProcess) {
45846
46083
  const filePath = (0, import_path4.resolve)(cwd, file2);
45847
- const templateFn = templateMap[file2];
46084
+ const templateFn = managedTemplates[file2];
45848
46085
  if (!templateFn) continue;
45849
46086
  const templateContent = templateFn();
45850
46087
  if (file2 === ".gitignore") {
@@ -45913,8 +46150,34 @@ function registerUpdateCommand(program3) {
45913
46150
  }
45914
46151
  }
45915
46152
  }
46153
+ const uiAdded = [];
46154
+ const uiSkipped = [];
46155
+ if (options2.ui) {
46156
+ const orgSlug = (0, import_path4.basename)(cwd).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^[^a-z]+/, "").replace(/-+/g, "-").replace(/-$/, "") || "my-workspace";
46157
+ await (0, import_promises3.mkdir)((0, import_path4.resolve)(cwd, "ui/src"), { recursive: true });
46158
+ const uiFiles = getUIFiles(orgSlug);
46159
+ for (const [file2, content] of Object.entries(uiFiles)) {
46160
+ const filePath = (0, import_path4.resolve)(cwd, file2);
46161
+ let exists = false;
46162
+ try {
46163
+ await (0, import_promises3.access)(filePath);
46164
+ exists = true;
46165
+ } catch {
46166
+ }
46167
+ if (!exists) {
46168
+ await (0, import_promises3.writeFile)(filePath, content, "utf-8");
46169
+ uiAdded.push(file2);
46170
+ } else {
46171
+ uiSkipped.push(file2);
46172
+ }
46173
+ }
46174
+ }
45916
46175
  console.log("");
45917
- console.log(source_default.green.bold(` Updated @elevasis/sdk template v${currentVersion} -> v${TEMPLATE_VERSION}`));
46176
+ if (upToDate) {
46177
+ console.log(source_default.green.bold(` Added UI to project (template version ${TEMPLATE_VERSION})`));
46178
+ } else {
46179
+ console.log(source_default.green.bold(` Updated @elevasis/sdk template v${currentVersion} -> v${TEMPLATE_VERSION}`));
46180
+ }
45918
46181
  if (added.length > 0) {
45919
46182
  console.log("");
45920
46183
  console.log(" Added:");
@@ -45941,6 +46204,23 @@ function registerUpdateCommand(program3) {
45941
46204
  console.log(source_default.gray(" Run /meta update in Claude Code to merge flagged files."));
45942
46205
  console.log(source_default.gray(" Or run /meta fix to verify and repair the full framework."));
45943
46206
  }
46207
+ if (uiAdded.length > 0) {
46208
+ console.log("");
46209
+ console.log(" UI scaffold added:");
46210
+ for (const file2 of uiAdded) {
46211
+ console.log(source_default.green(` ${file2}`));
46212
+ }
46213
+ console.log("");
46214
+ console.log(source_default.gray(" Next: cd ui && pnpm install"));
46215
+ console.log(source_default.gray(" Set VITE_WORKOS_CLIENT_ID in ui/.env"));
46216
+ }
46217
+ if (uiSkipped.length > 0) {
46218
+ console.log("");
46219
+ console.log(" UI files already exist (skipped):");
46220
+ for (const file2 of uiSkipped) {
46221
+ console.log(source_default.gray(` ${file2}`));
46222
+ }
46223
+ }
45944
46224
  console.log("");
45945
46225
  }));
45946
46226
  }
package/dist/index.d.ts CHANGED
@@ -6355,4 +6355,4 @@ declare class ToolingError extends ExecutionError {
6355
6355
  }
6356
6356
 
6357
6357
  export { ExecutionError, RegistryValidationError, ResourceRegistry, StepType, ToolingError };
6358
- export type { AbsoluteScheduleConfig, AcqCompany, AcqContact, AcqDeal, AcqList, AddChecklistItemParams, AddChecklistItemResult, AddToCampaignLead, AddToCampaignParams, AddToCampaignResult, AgentConfig, AgentConstraints, AgentDefinition, AgentMemory, ApifyToolMap, AppendBlocksParams, AppendBlocksResult, AppendRowsParams, AppendRowsResult, ApprovalToolMap, AttioToolMap, BatchUpdateParams, BatchUpdateResult, BulkImportParams, BulkImportResult, CancelHitlByDealIdParams, CancelSchedulesAndHitlByEmailParams, ClearDealFieldsParams, ClearRangeParams, ClearRangeResult, CompanyFilters, ConditionalNext, ContactFilters, Contract, CreateAttributeParams, CreateAttributeResult, CreateAutoPaymentLinkParams, CreateAutoPaymentLinkResult, CreateCardParams, CreateCardResult, CreateChecklistParams, CreateChecklistResult, CreateCheckoutSessionParams, CreateCheckoutSessionResult, CreateCompanyParams, CreateContactParams, CreateEnvelopeParams, CreateEnvelopeResult, CreateFolderParams, CreateFolderResult, CreateListParams, CreateNoteParams, CreateNoteResult, CreatePageParams, CreatePageResult, CreatePaymentLinkParams, CreatePaymentLinkResult, CreateRecordParams, CreateRecordResult, CreateScheduleInput, DeleteBlocksParams, DeleteBlocksResult, DeleteDealParams, DeleteNoteParams, DeleteNoteResult, DeletePageParams, DeletePageResult, DeleteRecordParams, DeleteRecordResult, DeleteRowByValueParams, DeleteRowByValueResult, DomainDefinition, DownloadDocumentParams, DownloadDocumentResult, DropboxToolMap, ElevasConfig, EmailToolMap, EnvelopeDocument, EventTriggerConfig, ExecutionContext, ExecutionInterface, ExecutionMetadata, ExecutionToolMap, FilterExpression, FilterRowsParams, FilterRowsResult, FormField, FormFieldType, FormSchema, GetBoardParams, GetBoardResult, GetCardChecklistsParams, GetCardChecklistsResult, GetCardsParams, GetCardsResult, GetEmailsParams, GetEmailsResult, GetEnvelopeParams, GetEnvelopeResult, GetHeadersParams, GetHeadersResult, GetLastRowParams, GetLastRowResult, GetListsParams, GetListsResult, GetPaymentLinkParams, GetPaymentLinkResult, GetRecordParams, GetRecordResult, GetRowByValueParams, GetRowByValueResult, GetSpreadsheetMetadataParams, GetSpreadsheetMetadataResult, GmailSendEmailParams, GmailSendEmailResult, GmailToolMap, GoogleSheetsToolMap, InstantlyToolMap, IntegrationDefinition, LLMAdapterFactory, LLMGenerateRequest, LLMGenerateResponse, LLMMessage, LLMModel, LeadToolMap, LinearNext, ListAllPagesResult, ListAttributesParams, ListAttributesResult, ListNotesParams, ListNotesResult, ListObjectsResult, ListPaymentLinksParams, ListPaymentLinksResult, MailsoToolMap, MailsoVerifyEmailParams, MailsoVerifyEmailResult, MarkProposalReviewedParams, MarkProposalSentParams, MethodEntry, ModelConfig, NextConfig, NotificationSDKInput, NotificationToolMap, NotionToolMap, OrganizationResources, PageWithChildren, PaginatedResult, PaginationParams$1 as PaginationParams, PdfToolMap, QueryRecordsParams, QueryRecordsResult, ReadPageParams, ReadPageResult, ReadSheetParams, ReadSheetResult, Recipient, RecurringScheduleConfig, RelativeScheduleConfig, RemoveFromSubsequenceParams, RemoveFromSubsequenceResult, ResendGetEmailParams, ResendGetEmailResult, ResendSendEmailParams, ResendSendEmailResult, ResendToolMap, ResourceDefinition, ResourceDomain, ResourceMetricsConfig, ResourceStatus, ResourceType, RunActorParams, RunActorResult, ScheduleOriginTracking, ScheduleTarget, ScheduleTriggerConfig, SchedulerToolMap, SendReplyParams, SendReplyResult, SetContactNurtureParams, SheetInfo, SignatureApiFieldType, SignatureApiToolMap, SigningPlace, SortCriteria, StepHandler, StorageDeleteInput, StorageDeleteOutput, StorageDownloadInput, StorageDownloadOutput, StorageListInput, StorageListOutput, StorageSignedUrlInput, StorageSignedUrlOutput, StorageToolMap, StorageUploadInput, StorageUploadOutput, StripeToolMap, SyncDealStageParams, TaskSchedule, TaskScheduleConfig, Tool, ToolExecutionOptions, ToolMethodMap, ToolingErrorType, TrelloCreateListParams, TrelloCreateListResult, TrelloToolMap, TriggerConfig, TriggerDefinition, UpdateAttributeParams, UpdateAttributeResult, UpdateBlocksParams, UpdateBlocksResult, UpdateCardParams, UpdateCardResult, UpdateChecklistItemParams, UpdateChecklistItemResult, UpdateCloseLostReasonParams, UpdateCompanyParams, UpdateContactParams, UpdateDiscoveryDataParams, UpdateFeesParams, UpdateInterestStatusParams, UpdateInterestStatusResult, UpdateListParams, UpdatePageTitleParams, UpdatePageTitleResult, UpdatePaymentLinkParams, UpdatePaymentLinkResult, UpdateProposalDataParams, UpdateRecordParams, UpdateRecordResult, UpdateRowByValueParams, UpdateRowByValueResult, UploadFileParams, UploadFileResult, UpsertCompanyParams, UpsertContactParams, UpsertDealParams, UpsertRowParams, UpsertRowResult, VoidEnvelopeParams, VoidEnvelopeResult, WebhookProviderType, WebhookTriggerConfig, WorkflowConfig, WorkflowDefinition, WorkflowStep, WriteSheetParams, WriteSheetResult };
6358
+ export type { AbsoluteScheduleConfig, AcqCompany, AcqContact, AcqDeal, AcqList, AddChecklistItemParams, AddChecklistItemResult, AddToCampaignLead, AddToCampaignParams, AddToCampaignResult, AgentConfig, AgentConstraints, AgentDefinition, AgentMemory, ApifyToolMap, AppendBlocksParams, AppendBlocksResult, AppendRowsParams, AppendRowsResult, ApprovalToolMap, AttioToolMap, BatchUpdateParams, BatchUpdateResult, BulkImportParams, BulkImportResult, CancelHitlByDealIdParams, CancelSchedulesAndHitlByEmailParams, ClearDealFieldsParams, ClearRangeParams, ClearRangeResult, CompanyFilters, ConditionalNext, ContactFilters, Contract, CreateAttributeParams, CreateAttributeResult, CreateAutoPaymentLinkParams, CreateAutoPaymentLinkResult, CreateCardParams, CreateCardResult, CreateChecklistParams, CreateChecklistResult, CreateCheckoutSessionParams, CreateCheckoutSessionResult, CreateCompanyParams, CreateContactParams, CreateEnvelopeParams, CreateEnvelopeResult, CreateFolderParams, CreateFolderResult, CreateListParams, CreateNoteParams, CreateNoteResult, CreatePageParams, CreatePageResult, CreatePaymentLinkParams, CreatePaymentLinkResult, CreateRecordParams, CreateRecordResult, CreateScheduleInput, DeleteBlocksParams, DeleteBlocksResult, DeleteDealParams, DeleteNoteParams, DeleteNoteResult, DeletePageParams, DeletePageResult, DeleteRecordParams, DeleteRecordResult, DeleteRowByValueParams, DeleteRowByValueResult, DomainDefinition, DownloadDocumentParams, DownloadDocumentResult, DropboxToolMap, ElevasConfig, EmailToolMap, EnvelopeDocument, EventTriggerConfig, ExecutionContext, ExecutionInterface, ExecutionMetadata, ExecutionToolMap, FilterExpression, FilterRowsParams, FilterRowsResult, FormField, FormFieldType, FormSchema, GetBoardParams, GetBoardResult, GetCardChecklistsParams, GetCardChecklistsResult, GetCardsParams, GetCardsResult, GetEmailsParams, GetEmailsResult, GetEnvelopeParams, GetEnvelopeResult, GetHeadersParams, GetHeadersResult, GetLastRowParams, GetLastRowResult, GetListsParams, GetListsResult, GetPaymentLinkParams, GetPaymentLinkResult, GetRecordParams, GetRecordResult, GetRowByValueParams, GetRowByValueResult, GetSpreadsheetMetadataParams, GetSpreadsheetMetadataResult, GmailSendEmailParams, GmailSendEmailResult, GmailToolMap, GoogleSheetsToolMap, HumanCheckpointDefinition, InstantlyToolMap, IntegrationDefinition, LLMAdapterFactory, LLMGenerateRequest, LLMGenerateResponse, LLMMessage, LLMModel, LeadToolMap, LinearNext, ListAllPagesResult, ListAttributesParams, ListAttributesResult, ListNotesParams, ListNotesResult, ListObjectsResult, ListPaymentLinksParams, ListPaymentLinksResult, MailsoToolMap, MailsoVerifyEmailParams, MailsoVerifyEmailResult, MarkProposalReviewedParams, MarkProposalSentParams, MethodEntry, ModelConfig, NextConfig, NotificationSDKInput, NotificationToolMap, NotionToolMap, OrganizationResources, PageWithChildren, PaginatedResult, PaginationParams$1 as PaginationParams, PdfToolMap, QueryRecordsParams, QueryRecordsResult, ReadPageParams, ReadPageResult, ReadSheetParams, ReadSheetResult, Recipient, RecurringScheduleConfig, RelationshipDeclaration, RelativeScheduleConfig, RemoveFromSubsequenceParams, RemoveFromSubsequenceResult, ResendGetEmailParams, ResendGetEmailResult, ResendSendEmailParams, ResendSendEmailResult, ResendToolMap, ResourceDefinition, ResourceDomain, ResourceMetricsConfig, ResourceRelationships, ResourceStatus, ResourceType, RunActorParams, RunActorResult, ScheduleOriginTracking, ScheduleTarget, ScheduleTriggerConfig, SchedulerToolMap, SendReplyParams, SendReplyResult, SetContactNurtureParams, SheetInfo, SignatureApiFieldType, SignatureApiToolMap, SigningPlace, SortCriteria, StepHandler, StorageDeleteInput, StorageDeleteOutput, StorageDownloadInput, StorageDownloadOutput, StorageListInput, StorageListOutput, StorageSignedUrlInput, StorageSignedUrlOutput, StorageToolMap, StorageUploadInput, StorageUploadOutput, StripeToolMap, SyncDealStageParams, TaskSchedule, TaskScheduleConfig, Tool, ToolExecutionOptions, ToolMethodMap, ToolingErrorType, TrelloCreateListParams, TrelloCreateListResult, TrelloToolMap, TriggerConfig, TriggerDefinition, UpdateAttributeParams, UpdateAttributeResult, UpdateBlocksParams, UpdateBlocksResult, UpdateCardParams, UpdateCardResult, UpdateChecklistItemParams, UpdateChecklistItemResult, UpdateCloseLostReasonParams, UpdateCompanyParams, UpdateContactParams, UpdateDiscoveryDataParams, UpdateFeesParams, UpdateInterestStatusParams, UpdateInterestStatusResult, UpdateListParams, UpdatePageTitleParams, UpdatePageTitleResult, UpdatePaymentLinkParams, UpdatePaymentLinkResult, UpdateProposalDataParams, UpdateRecordParams, UpdateRecordResult, UpdateRowByValueParams, UpdateRowByValueResult, UploadFileParams, UploadFileResult, UpsertCompanyParams, UpsertContactParams, UpsertDealParams, UpsertRowParams, UpsertRowResult, VoidEnvelopeParams, VoidEnvelopeResult, WebhookProviderType, WebhookTriggerConfig, WorkflowConfig, WorkflowDefinition, WorkflowStep, WriteSheetParams, WriteSheetResult };
package/dist/index.js CHANGED
@@ -3337,6 +3337,12 @@ var ResourceRegistry = class {
3337
3337
  if (existingOrg) {
3338
3338
  existingOrg.workflows = [...existingOrg.workflows ?? [], ...org.workflows ?? []];
3339
3339
  existingOrg.agents = [...existingOrg.agents ?? [], ...org.agents ?? []];
3340
+ if (org.relationships) {
3341
+ existingOrg.relationships = {
3342
+ ...existingOrg.relationships ?? {},
3343
+ ...org.relationships
3344
+ };
3345
+ }
3340
3346
  } else {
3341
3347
  this.registry[orgName] = org;
3342
3348
  }
@@ -3374,6 +3380,14 @@ var ResourceRegistry = class {
3374
3380
  orgResources.agents = (orgResources.agents ?? []).filter(
3375
3381
  (a) => !remoteIds.has(a.config.resourceId)
3376
3382
  );
3383
+ if (orgResources.relationships) {
3384
+ for (const id of remoteIds) {
3385
+ delete orgResources.relationships[id];
3386
+ }
3387
+ if (Object.keys(orgResources.relationships).length === 0) {
3388
+ delete orgResources.relationships;
3389
+ }
3390
+ }
3377
3391
  const remaining = (orgResources.workflows?.length ?? 0) + (orgResources.agents?.length ?? 0) + (orgResources.triggers?.length ?? 0) + (orgResources.integrations?.length ?? 0) + (orgResources.externalResources?.length ?? 0) + (orgResources.humanCheckpoints?.length ?? 0);
3378
3392
  if (remaining > 0) {
3379
3393
  this.serializedCache.set(orgName, serializeOrganization(orgResources));
package/dist/templates.js CHANGED
@@ -1,17 +1,23 @@
1
1
  // package.json
2
- function gitignoreTemplate() {
3
- return `node_modules/
2
+ function gitignoreTemplate(ctx = {}) {
3
+ let content = `node_modules/
4
4
  .env
5
5
  dist/
6
6
  __elevasis_worker.ts
7
7
  .claude/settings.local.json
8
8
  .claude/memory/
9
9
  `;
10
+ if (ctx.hasUI) {
11
+ content += `ui/node_modules/
12
+ ui/dist/
13
+ `;
14
+ }
15
+ return content;
10
16
  }
11
17
  function claudeSettingsTemplate() {
12
18
  return JSON.stringify({ autoCompact: false }, null, 2) + "\n";
13
19
  }
14
- function claudeMdTemplate() {
20
+ function claudeMdTemplate(ctx = {}) {
15
21
  return `<!-- initialized: false -->
16
22
 
17
23
  # CLAUDE.md
@@ -64,7 +70,8 @@ proactivity -- to their assessed levels.
64
70
  | Project resource map | \`docs/navigation.mdx\` | Understanding what's deployed |
65
71
  | Project priorities | \`docs/priorities.mdx\` | Deciding what to work on next |
66
72
  | User profile and skills | \`.claude/memory/profile/skills.md\` | Session start (mandatory) |
67
- | Cross-session memory | \`.claude/memory/index.md\` | Session start, recalling past context |
73
+ | Cross-session memory | \`.claude/memory/index.md\` | Session start, recalling past context |${ctx.hasUI ? `
74
+ | UI app source | \`ui/src/\` | Modifying the frontend, adding routes or components |` : ""}
68
75
 
69
76
  All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
70
77
 
@@ -86,7 +93,17 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
86
93
  - When an error occurs, check \`.claude/memory/errors/\` first for past fixes.
87
94
  If the error is new, check \`reference/troubleshooting/common-errors.mdx\`.
88
95
  After resolving, record the error in \`memory/errors/\` with context and fix.
89
- If an error recurs 3+ times, promote it to a rule in this section.
96
+ If an error recurs 3+ times, promote it to a rule in this section.${ctx.hasUI ? `
97
+
98
+ ### UI App (\`ui/\`)
99
+
100
+ - \`ui/\` is a standalone Vite + React app with its own \`package.json\` -- not part of the pnpm workspace
101
+ - Import from \`@elevasis/sdk-ui\`, never from \`@elevasis/sdk\` or \`@repo/ui\`
102
+ - Dev server runs on port 5100: \`cd ui && pnpm dev\`
103
+ - Set \`VITE_WORKOS_CLIENT_ID\` in \`ui/.env\` before running
104
+ - \`ElevasisProvider\` is pre-configured in \`ui/src/App.tsx\` (oauth mode, redirectUri \`http://localhost:5100/auth-redirect\`, apiUrl \`http://localhost:5170\`)
105
+ - OAuth redirect is handled by the \`AuthRedirect\` component at \`/auth-redirect\` -- it uses \`useAuthContext()\` from \`@elevasis/sdk-ui/auth\` and navigates home once \`user\` is set
106
+ - API must be running on port 5170 for the UI to work (\`pnpm --filter api dev\` from the platform monorepo)` : ""}
90
107
 
91
108
  ## Interaction Guidance
92
109
 
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Message protocol:
8
8
  * Parent -> Worker: { type: 'manifest' }
9
- * Worker -> Parent: { type: 'manifest', workflows: [...], agents: [...] }
9
+ * Worker -> Parent: { type: 'manifest', workflows: [...], agents: [...],
10
+ * triggers?: [...], integrations?: [...], humanCheckpoints?: [...],
11
+ * relationships?: {...} }
10
12
  *
11
13
  * Parent -> Worker: { type: 'execute', resourceId, executionId, input, organizationId?, organizationName?,
12
14
  * sessionId?, sessionTurnNumber?, parentExecutionId?, executionDepth }
@@ -5130,7 +5130,11 @@ function startWorker(org) {
5130
5130
  status: a.config.status,
5131
5131
  description: a.config.description,
5132
5132
  version: a.config.version
5133
- }))
5133
+ })),
5134
+ triggers: org.triggers ?? [],
5135
+ integrations: org.integrations ?? [],
5136
+ humanCheckpoints: org.humanCheckpoints ?? [],
5137
+ relationships: org.relationships ?? void 0
5134
5138
  });
5135
5139
  return;
5136
5140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "comment:bin": "IMPORTANT: This package shares the 'elevasis' binary name with @repo/cli. They never conflict because @elevasis/sdk must NEVER be added as a dependency of any workspace package (apps/*, packages/*, organizations/*). Workspace projects use @repo/cli for the 'elevasis' binary. External developers (outside the workspace) get this SDK's binary via npm install.",
6
6
  "type": "module",
@@ -40,7 +40,7 @@ At the start of every session the agent runs these steps silently before respond
40
40
 
41
41
  Slash commands are short Markdown instruction files in `.claude/commands/`. When you type `/command-name` in a Claude Code session, the agent reads the corresponding file and follows its instructions.
42
42
 
43
- All nine commands are scaffolded by `elevasis init` and committed to version control so collaborators get the same experience:
43
+ Ten commands and one skill are scaffolded by `elevasis init` and committed to version control so collaborators get the same experience:
44
44
 
45
45
  | Command | File | Purpose |
46
46
  | --- | --- | --- |
@@ -53,6 +53,9 @@ All nine commands are scaffolded by `elevasis init` and committed to version con
53
53
  | `/tutorial` | `tutorial.md` | Progressive learning path for new developers |
54
54
  | `/help` | `help.md` | Displays the full command tree and navigation map |
55
55
  | `/profile` | `profile.md` | Views and updates the developer profile in `memory/profile/` |
56
+ | `/work` | `work.md` | In-progress task tracking -- save, resume, list |
57
+
58
+ The `/creds` skill (`.claude/skills/creds/SKILL.md`) is also scaffolded. It auto-triggers when the agent detects credential-related context and manages credential storage and retrieval.
56
59
 
57
60
  ### `/meta` Command
58
61
 
@@ -172,4 +175,4 @@ Applies when TypeScript level is `advanced` and automation level is `experienced
172
175
 
173
176
  ---
174
177
 
175
- **Last Updated:** 2026-02-26
178
+ **Last Updated:** 2026-03-02
@@ -853,7 +853,7 @@ Method names are compile-time checked against the type map keys -- misspelling a
853
853
  | Tool has a typed adapter (all integrations + platform tools) | Adapter |
854
854
  | Need autocomplete and type safety | Adapter |
855
855
  | New dispatcher method added server-side, no SDK update yet | `platform.call()` |
856
- | Tool without a typed adapter (supabase, session-memory, hitl, status, http) | `platform.call()` |
856
+ | Tool without a typed adapter (supabase, session-memory, status, http) | `platform.call()` |
857
857
 
858
858
  `platform.call()` remains the universal escape hatch. Every adapter call compiles down to it. Both approaches work simultaneously with no conflicts.
859
859
 
@@ -925,3 +925,5 @@ Timeouts: LLM calls have a 120s timeout. All other tool calls have a 60s timeout
925
925
  ---
926
926
 
927
927
  **Last Updated:** 2026-03-02
928
+
929
+
@@ -40,23 +40,22 @@ Both patterns return a Promise that resolves with the tool result or rejects wit
40
40
 
41
41
  ## Integration Adapters
42
42
 
43
- Thirteen integration adapters give you access to 70+ tool methods covering third-party APIs. Pass the `credential` field with the name of the stored credential for that service.
43
+ Twelve integration adapters give you access to 60+ tool methods covering third-party APIs. Pass the `credential` field with the name of the stored credential for that service. Supabase is listed separately under [Database Access](#database-access) below.
44
44
 
45
45
  | Adapter | Tools | Credential Shape |
46
46
  | --- | --- | --- |
47
- | Attio | 11 (CRUD + schema + notes) | `{ apiKey }` |
47
+ | Attio | 12 (CRUD + schema + notes) | `{ apiKey }` |
48
48
  | Google Sheets | 13 (read/write/filter/upsert) | OAuth2 / service account |
49
49
  | Trello | 10 (cards/lists/checklists) | `{ apiKey, token }` |
50
50
  | Notion | 8 (pages + blocks) | `{ token }` |
51
51
  | Stripe | 6 (payment links + checkout) | `{ secretKey }` |
52
52
  | Instantly | 5 (email campaigns) | `{ apiKey }` |
53
53
  | Gmail | 2 (send email) | OAuth2 / service account |
54
- | Resend | 3 (send/get email) | `{ apiKey }` |
55
- | SignatureAPI | 3 (envelopes) | `{ apiKey }` |
54
+ | Resend | 2 (send/get email) | `{ apiKey }` |
55
+ | SignatureAPI | 4 (envelopes) | `{ apiKey }` |
56
56
  | Dropbox | 2 (upload/folder) | `{ accessToken }` |
57
57
  | Apify | 1 (run actor) | `{ token }` |
58
58
  | Mailso | 1 (verify email) | `{ apiKey }` |
59
- | Supabase | 7 (insert/select/update/delete/upsert/rpc/count) | `{ url, serviceRoleKey }` |
60
59
 
61
60
  Credentials are stored in the Elevasis credentials table and injected server-side. The credential name you pass in `credential` must match the name you set when storing the credential.
62
61
 
@@ -188,7 +187,7 @@ const qualified = await platform.call({
188
187
 
189
188
  ## Documentation
190
189
 
191
- - [Typed Adapters](adapters.mdx) - Type-safe wrappers for all 12 integrations + 4 platform services with full autocomplete (recommended)
190
+ - [Typed Adapters](adapters.mdx) - Type-safe wrappers for all 12 integrations + 9 platform services with full autocomplete (recommended)
192
191
  - [Integration Examples](examples.mdx) - Working code examples for email, CRM, PDF, LLM, and more
193
192
 
194
193
  ---
@@ -63,42 +63,6 @@ This is the static SDK-level error catalog. Check `.claude/memory/errors/` first
63
63
 
64
64
  ---
65
65
 
66
- ## Relationship Validation Errors
67
-
68
- ### Relationship declared for non-existent resource
69
-
70
- **Message:** `Relationship source 'resource-id' is not a known resource in 'org-name'`
71
-
72
- **Cause:** The `relationships` map in your organization export contains a key that does not match any workflow, agent, trigger, or external resource ID.
73
-
74
- **Fix:** Check the resource ID in your `relationships` declaration. Each key must exactly match a `resourceId` defined in your workflows, agents, triggers, or external resources.
75
-
76
- ### Resource triggers non-existent agent
77
-
78
- **Message:** `Relationship target 'agent-id' (agent) not found in 'org-name'`
79
-
80
- **Cause:** A relationship's `triggers.agents` array references an agent ID that does not exist.
81
-
82
- **Fix:** Verify the agent ID spelling in `triggers: \{ agents: ['agent-id'] \}`. The ID must match the `resourceId` of an agent defined in your organization.
83
-
84
- ### Resource triggers non-existent workflow
85
-
86
- **Message:** `Relationship target 'workflow-id' (workflow) not found in 'org-name'`
87
-
88
- **Cause:** A relationship's `triggers.workflows` array references a workflow ID that does not exist.
89
-
90
- **Fix:** Verify the workflow ID spelling in `triggers: \{ workflows: ['workflow-id'] \}`. The ID must match the `resourceId` of a workflow defined in your organization.
91
-
92
- ### Resource uses non-existent integration
93
-
94
- **Message:** `Relationship target 'integration-id' (integration) not found in 'org-name'`
95
-
96
- **Cause:** A relationship's `uses.integrations` array references an integration ID that does not exist.
97
-
98
- **Fix:** Verify the integration ID spelling in `uses: \{ integrations: ['integration-id'] \}`. The ID must match the `resourceId` of an integration defined in your organization.
99
-
100
- ---
101
-
102
66
  ## Schema Validation Errors
103
67
 
104
68
  ### Schema validation failed (input)