terse-cli 0.2.0 → 0.2.2

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 (196) hide show
  1. package/dist/_tmp_create_project.d.ts +2 -0
  2. package/dist/_tmp_create_project.d.ts.map +1 -0
  3. package/dist/_tmp_create_project.js +17 -0
  4. package/dist/_tmp_create_project.js.map +1 -0
  5. package/dist/_tmp_delete_agent.d.ts +2 -0
  6. package/dist/_tmp_delete_agent.d.ts.map +1 -0
  7. package/dist/_tmp_delete_agent.js +14 -0
  8. package/dist/_tmp_delete_agent.js.map +1 -0
  9. package/dist/_tmp_manual_trigger.d.ts +2 -0
  10. package/dist/_tmp_manual_trigger.d.ts.map +1 -0
  11. package/dist/_tmp_manual_trigger.js +17 -0
  12. package/dist/_tmp_manual_trigger.js.map +1 -0
  13. package/dist/_tmp_patch_active.d.ts +2 -0
  14. package/dist/_tmp_patch_active.d.ts.map +1 -0
  15. package/dist/_tmp_patch_active.js +21 -0
  16. package/dist/_tmp_patch_active.js.map +1 -0
  17. package/dist/codegen.d.ts +15 -0
  18. package/dist/codegen.d.ts.map +1 -1
  19. package/dist/codegen.js +466 -81
  20. package/dist/codegen.js.map +1 -1
  21. package/dist/commands/deployTheme.d.ts +28 -0
  22. package/dist/commands/deployTheme.d.ts.map +1 -0
  23. package/dist/commands/deployTheme.js +68 -0
  24. package/dist/commands/deployTheme.js.map +1 -0
  25. package/dist/commands/dev.d.ts +3 -0
  26. package/dist/commands/dev.d.ts.map +1 -0
  27. package/dist/commands/dev.js +47 -0
  28. package/dist/commands/dev.js.map +1 -0
  29. package/dist/commands/fsExec.d.ts +8 -0
  30. package/dist/commands/fsExec.d.ts.map +1 -0
  31. package/dist/commands/fsExec.js +46 -0
  32. package/dist/commands/fsExec.js.map +1 -0
  33. package/dist/commands/generate.d.ts.map +1 -1
  34. package/dist/commands/generate.js +11 -0
  35. package/dist/commands/generate.js.map +1 -1
  36. package/dist/commands/integrate.d.ts +6 -0
  37. package/dist/commands/integrate.d.ts.map +1 -1
  38. package/dist/commands/integrate.js +79 -2
  39. package/dist/commands/integrate.js.map +1 -1
  40. package/dist/commands/run.d.ts.map +1 -1
  41. package/dist/commands/run.js +2 -23
  42. package/dist/commands/run.js.map +1 -1
  43. package/dist/commands/secrets.d.ts +2 -0
  44. package/dist/commands/secrets.d.ts.map +1 -1
  45. package/dist/commands/secrets.js +7 -0
  46. package/dist/commands/secrets.js.map +1 -1
  47. package/dist/commands/serve.d.ts +1 -0
  48. package/dist/commands/serve.d.ts.map +1 -0
  49. package/dist/commands/serve.js +2 -0
  50. package/dist/commands/serve.js.map +1 -0
  51. package/dist/commands/state.d.ts +19 -0
  52. package/dist/commands/state.d.ts.map +1 -0
  53. package/dist/commands/state.js +109 -0
  54. package/dist/commands/state.js.map +1 -0
  55. package/dist/commands/terseCliTheme.d.ts +28 -0
  56. package/dist/commands/terseCliTheme.d.ts.map +1 -0
  57. package/dist/commands/terseCliTheme.js +68 -0
  58. package/dist/commands/terseCliTheme.js.map +1 -0
  59. package/dist/commands/test.d.ts.map +1 -1
  60. package/dist/commands/test.js +5 -33
  61. package/dist/commands/test.js.map +1 -1
  62. package/dist/commands/tool.d.ts +6 -0
  63. package/dist/commands/tool.d.ts.map +1 -0
  64. package/dist/commands/tool.js +34 -0
  65. package/dist/commands/tool.js.map +1 -0
  66. package/dist/data/standardSlackEmoji.d.ts +2 -0
  67. package/dist/data/standardSlackEmoji.d.ts.map +1 -0
  68. package/dist/data/standardSlackEmoji.js +1978 -0
  69. package/dist/data/standardSlackEmoji.js.map +1 -0
  70. package/dist/data/standardSlackEmoji.json +1974 -0
  71. package/dist/deploy.d.ts +2 -1
  72. package/dist/deploy.d.ts.map +1 -1
  73. package/dist/deploy.js +61 -38
  74. package/dist/deploy.js.map +1 -1
  75. package/dist/envMirror.d.ts +3 -0
  76. package/dist/envMirror.d.ts.map +1 -0
  77. package/dist/envMirror.js +121 -0
  78. package/dist/envMirror.js.map +1 -0
  79. package/dist/eventFixture.d.ts +3 -0
  80. package/dist/eventFixture.d.ts.map +1 -0
  81. package/dist/eventFixture.js +36 -0
  82. package/dist/eventFixture.js.map +1 -0
  83. package/dist/generate.d.ts +2 -1
  84. package/dist/generate.d.ts.map +1 -1
  85. package/dist/generate.js +67 -69
  86. package/dist/generate.js.map +1 -1
  87. package/dist/index.js +26 -7
  88. package/dist/index.js.map +1 -1
  89. package/dist/init.d.ts +2 -1
  90. package/dist/init.d.ts.map +1 -1
  91. package/dist/init.js +45 -96
  92. package/dist/init.js.map +1 -1
  93. package/dist/integrate.d.ts +1 -0
  94. package/dist/integrate.d.ts.map +1 -1
  95. package/dist/integrate.js +191 -11
  96. package/dist/integrate.js.map +1 -1
  97. package/dist/nonInteractive.d.ts +4 -2
  98. package/dist/nonInteractive.d.ts.map +1 -1
  99. package/dist/nonInteractive.js +5 -2
  100. package/dist/nonInteractive.js.map +1 -1
  101. package/dist/perf.d.ts +9 -0
  102. package/dist/perf.d.ts.map +1 -0
  103. package/dist/perf.js +59 -0
  104. package/dist/perf.js.map +1 -0
  105. package/dist/providers/codegen.test.d.ts +2 -0
  106. package/dist/providers/codegen.test.d.ts.map +1 -0
  107. package/dist/providers/codegen.test.js +45 -0
  108. package/dist/providers/codegen.test.js.map +1 -0
  109. package/dist/providers/codegenTypes.d.ts +1 -0
  110. package/dist/providers/codegenTypes.d.ts.map +1 -1
  111. package/dist/providers/python/PythonProvider.js +1 -0
  112. package/dist/providers/python/PythonProvider.js.map +1 -1
  113. package/dist/providers/python/PythonProvider.test.d.ts +2 -0
  114. package/dist/providers/python/PythonProvider.test.d.ts.map +1 -0
  115. package/dist/providers/python/PythonProvider.test.js +169 -0
  116. package/dist/providers/python/PythonProvider.test.js.map +1 -0
  117. package/dist/providers/typescript/prepareCodegenData.d.ts +1 -0
  118. package/dist/providers/typescript/prepareCodegenData.d.ts.map +1 -1
  119. package/dist/providers/typescript/prepareCodegenData.js +1 -0
  120. package/dist/providers/typescript/prepareCodegenData.js.map +1 -1
  121. package/dist/providers/typescript/prepareCodegenData.test.d.ts +2 -0
  122. package/dist/providers/typescript/prepareCodegenData.test.d.ts.map +1 -0
  123. package/dist/providers/typescript/prepareCodegenData.test.js +54 -0
  124. package/dist/providers/typescript/prepareCodegenData.test.js.map +1 -0
  125. package/dist/providers/typescript/projectedTypes.d.ts +11 -0
  126. package/dist/providers/typescript/projectedTypes.d.ts.map +1 -0
  127. package/dist/providers/typescript/projectedTypes.js +53 -0
  128. package/dist/providers/typescript/projectedTypes.js.map +1 -0
  129. package/dist/providers/typescript/triggerPayloads.d.ts +7 -0
  130. package/dist/providers/typescript/triggerPayloads.d.ts.map +1 -0
  131. package/dist/providers/typescript/triggerPayloads.js +60 -0
  132. package/dist/providers/typescript/triggerPayloads.js.map +1 -0
  133. package/dist/run.d.ts +2 -11
  134. package/dist/run.d.ts.map +1 -1
  135. package/dist/run.js +42 -153
  136. package/dist/run.js.map +1 -1
  137. package/dist/sampleEventId.d.ts +0 -4
  138. package/dist/sampleEventId.d.ts.map +1 -1
  139. package/dist/sampleEventId.js +0 -4
  140. package/dist/sampleEventId.js.map +1 -1
  141. package/dist/shared/ApiRoutes.d.ts +19 -0
  142. package/dist/shared/ApiRoutes.d.ts.map +1 -1
  143. package/dist/shared/ApiRoutes.js +17 -1
  144. package/dist/shared/ApiRoutes.js.map +1 -1
  145. package/dist/shared/Configs.d.ts +24 -2
  146. package/dist/shared/Configs.d.ts.map +1 -1
  147. package/dist/shared/Configs.js +32 -2
  148. package/dist/shared/Configs.js.map +1 -1
  149. package/dist/shared/Integrations.d.ts +18 -1
  150. package/dist/shared/Integrations.d.ts.map +1 -1
  151. package/dist/shared/Integrations.js +10 -1
  152. package/dist/shared/Integrations.js.map +1 -1
  153. package/dist/shared/InvalidationKeys.d.ts +1 -0
  154. package/dist/shared/InvalidationKeys.d.ts.map +1 -1
  155. package/dist/shared/InvalidationKeys.js +3 -0
  156. package/dist/shared/InvalidationKeys.js.map +1 -1
  157. package/dist/shared/ModelEvents.d.ts +9 -0
  158. package/dist/shared/ModelEvents.d.ts.map +1 -1
  159. package/dist/shared/ModelEvents.js +15 -0
  160. package/dist/shared/ModelEvents.js.map +1 -1
  161. package/dist/shared/ToolDisplayUtils.d.ts.map +1 -1
  162. package/dist/shared/ToolDisplayUtils.js +107 -11
  163. package/dist/shared/ToolDisplayUtils.js.map +1 -1
  164. package/dist/shared/types.d.ts +1013 -108
  165. package/dist/shared/types.d.ts.map +1 -1
  166. package/dist/shared/types.js.map +1 -1
  167. package/dist/test.d.ts +2 -1
  168. package/dist/test.d.ts.map +1 -1
  169. package/dist/test.js +43 -23
  170. package/dist/test.js.map +1 -1
  171. package/dist/toolCatalog.d.ts +12 -0
  172. package/dist/toolCatalog.d.ts.map +1 -0
  173. package/dist/toolCatalog.js +33 -0
  174. package/dist/toolCatalog.js.map +1 -0
  175. package/dist/util.d.ts +2 -3
  176. package/dist/util.d.ts.map +1 -1
  177. package/dist/util.js +3 -3
  178. package/dist/util.js.map +1 -1
  179. package/package.json +3 -3
  180. package/templates/typescript/codegen/partials/header.hbs +5 -0
  181. package/dist/jsonOutput.d.ts +0 -19
  182. package/dist/jsonOutput.d.ts.map +0 -1
  183. package/dist/jsonOutput.js +0 -25
  184. package/dist/jsonOutput.js.map +0 -1
  185. package/dist/providers/typescript/parkSignals.d.ts +0 -7
  186. package/dist/providers/typescript/parkSignals.d.ts.map +0 -1
  187. package/dist/providers/typescript/parkSignals.js +0 -45
  188. package/dist/providers/typescript/parkSignals.js.map +0 -1
  189. package/dist/replay.d.ts +0 -3
  190. package/dist/replay.d.ts.map +0 -1
  191. package/dist/replay.js +0 -20
  192. package/dist/replay.js.map +0 -1
  193. package/dist/urls.d.ts +0 -3
  194. package/dist/urls.d.ts.map +0 -1
  195. package/dist/urls.js +0 -27
  196. package/dist/urls.js.map +0 -1
package/dist/deploy.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export declare function deploy(): Promise<void>;
1
+ import type { LanguageProvider } from "./providers/LanguageProvider.js";
2
+ export declare function deploy(provider?: LanguageProvider, entryFile?: string): Promise<void>;
2
3
  //# sourceMappingURL=deploy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAeA,wBAAsB,MAAM,kBA2D3B"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAGvE,wBAAsB,MAAM,CAAC,QAAQ,GAAE,gBAAoC,EAAE,SAAS,CAAC,EAAE,MAAM,iBA2F9F"}
package/dist/deploy.js CHANGED
@@ -1,35 +1,45 @@
1
+ import chalk from "chalk";
2
+ import { zipSync } from "fflate";
1
3
  import fs from "node:fs";
2
4
  import path from "node:path";
3
- import chalk from "chalk";
4
5
  import ora from "ora";
5
- import { zipSync } from "fflate";
6
- import { fetchWithAuth, readApiKey } from "./api.js";
7
- import { assertProjectRoot } from "./assertProjectRoot.js";
6
+ import { ApiRoutes, sdkDeployRequestBodySchema } from "terse-types";
7
+ import { fetchWithAuth, readApiKeyOrBail, readEnvVar } from "./api.js";
8
8
  import { loadJobRegistry } from "./loadJob.js";
9
- import { ApiRoutes } from "./shared/ApiRoutes.js";
10
- const EXCLUDED_DIRS = new Set(["node_modules", ".git", "dist", ".next", ".turbo"]);
11
- const EXCLUDED_FILES = new Set([".env", ".DS_Store"]);
12
- export async function deploy() {
13
- assertProjectRoot();
14
- const apiKey = readApiKey();
15
- if (!apiKey) {
16
- console.error(chalk.red("Error: No TERSE_API_KEY found in .env"));
17
- console.error(chalk.dim("Run `terse init` to set up your project, or add TERSE_API_KEY to your .env file."));
18
- process.exit(1);
19
- }
20
- const registry = await loadJobRegistry();
9
+ import { resolveProvider } from "./providers/resolveProvider.js";
10
+ export async function deploy(provider = resolveProvider(), entryFile) {
11
+ const apiKey = readApiKeyOrBail({
12
+ title: "Error: No TERSE_API_KEY found in .env",
13
+ detail: "Run `terse init` to set up your project, or add TERSE_API_KEY to your .env file."
14
+ });
15
+ const registry = await loadJobRegistry(provider, entryFile);
21
16
  const jobs = [...registry.values()];
22
- const { sourceZipBase64, fileCount, zipSizeBytes } = buildZipPayload();
17
+ // If TERSE_REMOTE_SERVER_URL (or legacy TERSE_JOB_URL) is set in .env, deploy
18
+ // in URL mode (user infrastructure). No source code is zipped or uploaded.
19
+ const remoteServerUrl = readEnvVar("TERSE_REMOTE_SERVER_URL") ?? readEnvVar("TERSE_JOB_URL");
20
+ const isUrlMode = !!remoteServerUrl;
21
+ let sourceZipBase64;
22
+ let fileCount = 0;
23
+ let zipSizeBytes = 0;
24
+ if (!isUrlMode) {
25
+ const zipPayload = buildZipPayload(provider);
26
+ sourceZipBase64 = zipPayload.sourceZipBase64;
27
+ fileCount = zipPayload.fileCount;
28
+ zipSizeBytes = zipPayload.zipSizeBytes;
29
+ }
23
30
  const spinner = ora(`Deploying ${jobs.length} job${jobs.length === 1 ? "" : "s"}...`).start();
24
31
  try {
25
- const result = await fetchWithAuth(ApiRoutes.SDK.DEPLOY, apiKey, {
32
+ const body = sdkDeployRequestBodySchema.parse({
26
33
  jobs: jobs.map(job => ({
27
34
  jobName: job.name,
28
- triggers: job.triggers.map(serializeTrigger),
29
- webhookURL: job.webhookURL
35
+ triggers: job.triggers,
36
+ outputs: job.skills ?? [],
37
+ toolApprovals: job.toolApprovals ?? []
30
38
  })),
39
+ remoteServerUrl: isUrlMode ? remoteServerUrl : undefined,
31
40
  sourceZipBase64
32
- }, "POST");
41
+ });
42
+ const result = await fetchWithAuth(ApiRoutes.SDK.DEPLOY, apiKey, body, "POST");
33
43
  if (!result.success) {
34
44
  spinner.fail(chalk.red(`Deploy failed: ${result.error}`));
35
45
  if (result.details) {
@@ -41,9 +51,31 @@ export async function deploy() {
41
51
  for (const r of result.results) {
42
52
  const verb = r.isUpdate ? "Updated" : "Created";
43
53
  console.log(chalk.dim(` ${verb} "${r.jobName}" (${r.automationId})`));
54
+ if (r.triggers) {
55
+ for (const t of r.triggers) {
56
+ if (t.metadata?.webhookUrl) {
57
+ console.log(chalk.cyan(` Webhook URL: ${t.metadata.webhookUrl}`));
58
+ }
59
+ }
60
+ }
61
+ }
62
+ if (isUrlMode) {
63
+ console.log(chalk.dim(` Mode: user infrastructure`));
64
+ console.log(chalk.dim(` Server URL: ${remoteServerUrl}`));
65
+ const signingSecret = result.results.find(r => r.signingSecret)?.signingSecret;
66
+ if (signingSecret) {
67
+ const existingSecret = readEnvVar("TERSE_SIGNING_SECRET");
68
+ if (!existingSecret) {
69
+ console.log(`\n Add this to your ${chalk.bold(".env")} file:\n`);
70
+ console.log(`TERSE_SIGNING_SECRET=${signingSecret}`);
71
+ console.log("");
72
+ }
73
+ }
74
+ }
75
+ else {
76
+ console.log(chalk.dim(` Files: ${fileCount}`));
77
+ console.log(chalk.dim(` Zip size: ${(zipSizeBytes / 1024).toFixed(1)} KB`));
44
78
  }
45
- console.log(chalk.dim(` Files: ${fileCount}`));
46
- console.log(chalk.dim(` Zip size: ${(zipSizeBytes / 1024).toFixed(1)} KB`));
47
79
  if (result.removed.length > 0) {
48
80
  console.log(chalk.yellow(`\nRemoved ${result.removed.length} stale job${result.removed.length === 1 ? "" : "s"} no longer in project:`));
49
81
  for (const r of result.removed) {
@@ -56,17 +88,17 @@ export async function deploy() {
56
88
  process.exit(1);
57
89
  }
58
90
  }
59
- function collectFiles(dir, baseDir) {
91
+ function collectFiles(dir, baseDir, provider) {
60
92
  const entries = {};
61
93
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
62
- if (EXCLUDED_DIRS.has(entry.name))
94
+ if (provider.deployExclusions.dirs.has(entry.name))
63
95
  continue;
64
- if (EXCLUDED_FILES.has(entry.name))
96
+ if (provider.deployExclusions.files.has(entry.name))
65
97
  continue;
66
98
  const fullPath = path.join(dir, entry.name);
67
99
  const relativePath = path.relative(baseDir, fullPath);
68
100
  if (entry.isDirectory()) {
69
- Object.assign(entries, collectFiles(fullPath, baseDir));
101
+ Object.assign(entries, collectFiles(fullPath, baseDir, provider));
70
102
  }
71
103
  else if (entry.isFile()) {
72
104
  entries[relativePath] = new Uint8Array(fs.readFileSync(fullPath));
@@ -74,18 +106,9 @@ function collectFiles(dir, baseDir) {
74
106
  }
75
107
  return entries;
76
108
  }
77
- function serializeTrigger(config) {
78
- const { isComplete, formatForAgent, configType, integrationType, integrationId, ...rest } = config;
79
- return {
80
- configType,
81
- integrationType,
82
- integrationId,
83
- config: rest
84
- };
85
- }
86
- function buildZipPayload() {
109
+ function buildZipPayload(provider) {
87
110
  const cwd = process.cwd();
88
- const files = collectFiles(cwd, cwd);
111
+ const files = collectFiles(cwd, cwd, provider);
89
112
  const fileCount = Object.keys(files).length;
90
113
  if (fileCount === 0) {
91
114
  console.error(chalk.red("No files found to deploy"));
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGjD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;AAClF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;AAErD,MAAM,CAAC,KAAK,UAAU,MAAM;IACxB,iBAAiB,EAAE,CAAA;IAEnB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAA;QACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC,CAAA;QAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAA;IACxC,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACnC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,eAAe,EAAE,CAAA;IAEtE,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IAE7F,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAC9B,SAAS,CAAC,GAAG,CAAC,MAAM,EACpB,MAAM,EACN;YACI,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACnB,OAAO,EAAE,GAAG,CAAC,IAAI;gBACjB,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBAC5C,UAAU,EAAE,GAAG,CAAC,UAAU;aAC7B,CAAC,CAAC;YACH,eAAe;SAClB,EACD,MAAM,CACT,CAAA;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;YACzD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YACnD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAE9G,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;QAC1E,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC,CAAA;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAE5E,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,MAAM,CAAC,OAAO,CAAC,MAAM,aAAa,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAA;YACxI,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YACrD,CAAC;QACL,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAmB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,OAAe;IAC9C,MAAM,OAAO,GAA+B,EAAE,CAAA;IAE9C,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC/D,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC3C,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAQ;QAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAErD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxB,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAA;QACrE,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAW;IAMjC,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAA;IAClG,OAAO;QACH,UAAU;QACV,eAAe;QACf,aAAa;QACb,MAAM,EAAE,IAAI;KACf,CAAA;AACL,CAAC;AAED,SAAS,eAAe;IACpB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACpC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;IAE3C,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAA;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IAC5C,OAAO;QACH,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACxD,SAAS;QACT,YAAY,EAAE,OAAO,CAAC,MAAM;KAC/B,CAAA;AACL,CAAC"}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function mirrorSecretToLocalEnv(name: string, value: string, cwd?: string): void;
2
+ export declare function removeSecretFromLocalEnv(name: string, cwd?: string): void;
3
+ //# sourceMappingURL=envMirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envMirror.d.ts","sourceRoot":"","sources":["../src/envMirror.ts"],"names":[],"mappings":"AAUA,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,IAAI,CAUrG;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,IAAI,CAWxF"}
@@ -0,0 +1,121 @@
1
+ import chalk from "chalk";
2
+ import dotenv from "dotenv";
3
+ import { execFileSync } from "node:child_process";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { CliError } from "./cliError.js";
7
+ const ENV_FILENAME = ".env";
8
+ export function mirrorSecretToLocalEnv(name, value, cwd = process.cwd()) {
9
+ let outcome;
10
+ try {
11
+ outcome = upsertEnvEntry(cwd, name, value);
12
+ }
13
+ catch (error) {
14
+ warnMirrorFailed(`write ${name} to`, error);
15
+ return;
16
+ }
17
+ reportOutcome(name, outcome);
18
+ if (outcome !== "unchanged")
19
+ warnIfNotGitignored(cwd);
20
+ }
21
+ export function removeSecretFromLocalEnv(name, cwd = process.cwd()) {
22
+ let removed;
23
+ try {
24
+ removed = removeEnvEntry(cwd, name);
25
+ }
26
+ catch (error) {
27
+ warnMirrorFailed(`remove ${name} from`, error);
28
+ return;
29
+ }
30
+ if (removed) {
31
+ process.stdout.write(`Removed ${name} from ${ENV_FILENAME}.\n`);
32
+ }
33
+ }
34
+ function upsertEnvEntry(cwd, name, value) {
35
+ const filePath = path.join(cwd, ENV_FILENAME);
36
+ const entry = `${name}=${serializeEnvValue(name, value)}`;
37
+ if (!fs.existsSync(filePath)) {
38
+ fs.writeFileSync(filePath, `${entry}\n`, { mode: 0o600 });
39
+ return "created";
40
+ }
41
+ const raw = fs.readFileSync(filePath, "utf8");
42
+ if (dotenv.parse(raw)[name] === value)
43
+ return "unchanged";
44
+ const eol = raw.includes("\r\n") ? "\r\n" : "\n";
45
+ const lines = raw.split(/\r?\n/);
46
+ const [firstMatch, ...duplicateMatches] = lines.flatMap((line, index) => (envLineName(line) === name ? [index] : []));
47
+ if (firstMatch === undefined) {
48
+ const body = raw.length === 0 || raw.endsWith("\n") ? raw : `${raw}${eol}`;
49
+ fs.writeFileSync(filePath, `${body}${entry}${eol}`);
50
+ return "added";
51
+ }
52
+ const updatedLines = lines.map((line, index) => (index === firstMatch ? entry : line)).filter((_, index) => !duplicateMatches.includes(index));
53
+ fs.writeFileSync(filePath, updatedLines.join(eol));
54
+ return "updated";
55
+ }
56
+ function removeEnvEntry(cwd, name) {
57
+ const filePath = path.join(cwd, ENV_FILENAME);
58
+ if (!fs.existsSync(filePath))
59
+ return false;
60
+ const raw = fs.readFileSync(filePath, "utf8");
61
+ const eol = raw.includes("\r\n") ? "\r\n" : "\n";
62
+ const lines = raw.split(/\r?\n/);
63
+ const remaining = lines.filter(line => envLineName(line) !== name);
64
+ if (remaining.length === lines.length)
65
+ return false;
66
+ fs.writeFileSync(filePath, remaining.join(eol));
67
+ return true;
68
+ }
69
+ function serializeEnvValue(name, value) {
70
+ const candidates = [value, `'${value}'`, `"${value}"`, `"${value.replace(/\r/g, "\\r").replace(/\n/g, "\\n")}"`];
71
+ const usable = candidates.find(candidate => !/[\r\n]/.test(candidate) && dotenv.parse(`${name}=${candidate}`)[name] === value);
72
+ if (usable === undefined) {
73
+ throw new CliError("env_value_unwritable", `Could not represent the value of ${name} in ${ENV_FILENAME}.`);
74
+ }
75
+ return usable;
76
+ }
77
+ function envLineName(line) {
78
+ const separatorIndex = line.indexOf("=");
79
+ if (separatorIndex <= 0)
80
+ return null;
81
+ return line.slice(0, separatorIndex).trim();
82
+ }
83
+ function reportOutcome(name, outcome) {
84
+ switch (outcome) {
85
+ case "created":
86
+ process.stdout.write(`Created ${ENV_FILENAME} with ${name} for local runs.\n`);
87
+ return;
88
+ case "added":
89
+ process.stdout.write(`Added ${name} to ${ENV_FILENAME} for local runs.\n`);
90
+ return;
91
+ case "updated":
92
+ process.stdout.write(`Updated ${name} in ${ENV_FILENAME} (replaced a different local value).\n`);
93
+ return;
94
+ case "unchanged":
95
+ return;
96
+ default:
97
+ throw outcome;
98
+ }
99
+ }
100
+ function warnIfNotGitignored(cwd) {
101
+ if (isEnvGitignored(cwd) === false) {
102
+ process.stdout.write(chalk.yellow(`Warning: ${ENV_FILENAME} is not ignored by git. Add it to your .gitignore so secret values are not committed.\n`));
103
+ }
104
+ }
105
+ function isEnvGitignored(cwd) {
106
+ try {
107
+ execFileSync("git", ["check-ignore", "-q", ENV_FILENAME], { cwd, stdio: "ignore" });
108
+ return true;
109
+ }
110
+ catch (error) {
111
+ return isCheckIgnoreMiss(error) ? false : null;
112
+ }
113
+ }
114
+ function isCheckIgnoreMiss(error) {
115
+ return typeof error === "object" && error !== null && "status" in error && error.status === 1;
116
+ }
117
+ function warnMirrorFailed(action, error) {
118
+ const detail = error instanceof Error ? error.message : String(error);
119
+ process.stdout.write(chalk.yellow(`Warning: could not ${action} ${ENV_FILENAME} (${detail}). Update it manually so local runs stay in sync.\n`));
120
+ }
121
+ //# sourceMappingURL=envMirror.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envMirror.js","sourceRoot":"","sources":["../src/envMirror.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SerializedEvent } from "terse-types";
2
+ export declare function parseEventFixtureJson(raw: string, sourceLabel: string): SerializedEvent;
3
+ //# sourceMappingURL=eventFixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventFixture.d.ts","sourceRoot":"","sources":["../src/eventFixture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAKlD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CASvF"}
@@ -0,0 +1,36 @@
1
+ import { eventFixtureSchema, hydrateSerializedEvent } from "terse-types";
2
+ import { z } from "zod";
3
+ import { CliError } from "./cliError.js";
4
+ export function parseEventFixtureJson(raw, sourceLabel) {
5
+ const parsed = parseJson(raw, sourceLabel);
6
+ const result = eventFixtureSchema.safeParse(parsed);
7
+ if (result.success) {
8
+ return hydrateSerializedEvent(result.data);
9
+ }
10
+ throw new CliError("invalid_event_shape", `${sourceLabel} does not match the canonical Trigger schema.`, {
11
+ detail: `${z.prettifyError(result.error)}\n\n${EXPECTED_FIXTURE_HINT}`
12
+ });
13
+ }
14
+ function parseJson(raw, sourceLabel) {
15
+ try {
16
+ return JSON.parse(raw);
17
+ }
18
+ catch (err) {
19
+ throw new CliError("invalid_event_json", `${sourceLabel} must be valid JSON.`, {
20
+ detail: err instanceof Error ? err.message : String(err)
21
+ });
22
+ }
23
+ }
24
+ const EXPECTED_FIXTURE_HINT = [
25
+ "Expected a flat trigger fixture, e.g. for a webhook:",
26
+ "{",
27
+ ' "integrationType": "webhook",',
28
+ ' "eventType": "webhook",',
29
+ ' "method": "POST",',
30
+ ' "headers": { "content-type": "application/json" },',
31
+ ' "body": { "your": "payload" }',
32
+ "}",
33
+ 'Optional top-level "formattedContent" / "debugLog" strings override the derived prompt and log text.',
34
+ "Tip: `terse test show <id> --json` emits ready-to-use fixtures."
35
+ ].join("\n");
36
+ //# sourceMappingURL=eventFixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventFixture.js","sourceRoot":"","sources":["../src/eventFixture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAExE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,WAAmB;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,qBAAqB,EAAE,GAAG,WAAW,+CAA+C,EAAE;QACrG,MAAM,EAAE,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,qBAAqB,EAAE;KACzE,CAAC,CAAA;AACN,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,WAAmB;IAC/C,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,IAAI,QAAQ,CAAC,oBAAoB,EAAE,GAAG,WAAW,sBAAsB,EAAE;YAC3E,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC3D,CAAC,CAAA;IACN,CAAC;AACL,CAAC;AAED,MAAM,qBAAqB,GAAG;IAC1B,sDAAsD;IACtD,GAAG;IACH,iCAAiC;IACjC,2BAA2B;IAC3B,qBAAqB;IACrB,sDAAsD;IACtD,iCAAiC;IACjC,GAAG;IACH,sGAAsG;IACtG,iEAAiE;CACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA"}
@@ -1,2 +1,3 @@
1
- export declare function generate(): Promise<void>;
1
+ import type { LanguageProvider } from "./providers/LanguageProvider.js";
2
+ export declare function generate(provider?: LanguageProvider): Promise<void>;
2
3
  //# sourceMappingURL=generate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAwCA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAmQ9C"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAkBvE,wBAAsB,QAAQ,CAAC,QAAQ,GAAE,gBAAoC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoT5F"}
package/dist/generate.js CHANGED
@@ -1,23 +1,21 @@
1
+ import chalk from "chalk";
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
- import chalk from "chalk";
4
4
  import ora from "ora";
5
+ import { IntegrationType, isValidToolName } from "terse-types";
6
+ import { ApiRoutes, buildRoute } from "terse-types";
7
+ import { fetchWithAuth, readApiKeyOrBail } from "./api.js";
5
8
  import { assertProjectRoot } from "./assertProjectRoot.js";
6
- import { generateCode, } from "./codegen.js";
7
- import { IntegrationType } from "./shared/Integrations.js";
8
- import { ApiRoutes } from "./shared/ApiRoutes.js";
9
- import { fetchWithAuth, readApiKey } from "./api.js";
9
+ import { resolveProvider } from "./providers/resolveProvider.js";
10
10
  // ── Main ──────────────────────────────────────────────────────────────
11
- export async function generate() {
12
- assertProjectRoot();
11
+ export async function generate(provider = resolveProvider()) {
12
+ assertProjectRoot(provider, provider.detectionMarkers);
13
13
  const totalStart = performance.now();
14
14
  // 1. Read API key
15
- const apiKey = readApiKey();
16
- if (!apiKey) {
17
- console.error(chalk.red("\n Missing TERSE_API_KEY in .env\n") +
18
- chalk.dim(" Create a project with `terse init` or add TERSE_API_KEY to your .env file.\n"));
19
- process.exit(1);
20
- }
15
+ const apiKey = readApiKeyOrBail({
16
+ title: "\n Missing TERSE_API_KEY in .env\n",
17
+ detail: " Create a project with `terse init` or add TERSE_API_KEY to your .env file.\n"
18
+ });
21
19
  // 2. Fetch active integrations
22
20
  const spinner = ora("Fetching integrations...").start();
23
21
  let activeTypes;
@@ -33,8 +31,7 @@ export async function generate() {
33
31
  message.toLowerCase().includes("unauthorized") ||
34
32
  message.toLowerCase().includes("forbidden");
35
33
  if (isAuthError) {
36
- console.error(chalk.red("\n Authentication failed: your TERSE_API_KEY was rejected.\n") +
37
- chalk.dim(" Update TERSE_API_KEY in .env and try again.\n"));
34
+ console.error(chalk.red("\n Authentication failed: your TERSE_API_KEY was rejected.\n") + chalk.dim(" Update TERSE_API_KEY in .env and try again.\n"));
38
35
  }
39
36
  else {
40
37
  console.error(chalk.red(`\n ${message}\n`));
@@ -49,6 +46,11 @@ export async function generate() {
49
46
  // Filter to only tools whose integration matches an active integration type
50
47
  const activeSet = new Set(activeTypes);
51
48
  toolDefs = resp.tools.filter(t => activeSet.has(t.integration));
49
+ const skippedToolNames = [...new Set(toolDefs.filter(t => !isValidToolName(t.name)).map(t => t.name))].sort();
50
+ toolDefs = toolDefs.filter(t => isValidToolName(t.name));
51
+ if (skippedToolNames.length > 0) {
52
+ console.warn(chalk.yellow(`\n Skipped ${skippedToolNames.length} tool(s) absent from terse-types ToolDefinitions: ${skippedToolNames.join(", ")}\n`));
53
+ }
52
54
  }
53
55
  catch {
54
56
  // Non-fatal: proceed without tool definitions
@@ -56,11 +58,18 @@ export async function generate() {
56
58
  // 4. Fetch all integration instances + resources in parallel
57
59
  spinner.text = "Fetching integration details...";
58
60
  const input = {
59
- github: [], slack: [], gmail: [], figma: [],
60
- linear: [], atlassian: [], notion: [],
61
- posthog: [], datadog: [], launchdarkly: [],
62
- workos: [], attio: [],
63
- tools: toolDefs,
61
+ github: [],
62
+ slack: [],
63
+ gmail: [],
64
+ linear: [],
65
+ notion: [],
66
+ posthog: [],
67
+ datadog: [],
68
+ launchdarkly: [],
69
+ workos: [],
70
+ attio: [],
71
+ snowflake: [],
72
+ tools: toolDefs
64
73
  };
65
74
  const has = (t) => activeTypes.includes(t);
66
75
  const promises = [];
@@ -91,37 +100,18 @@ export async function generate() {
91
100
  }));
92
101
  }));
93
102
  }
94
- // ── Figma (no resources) ──
95
- if (has(IntegrationType.FIGMA)) {
96
- promises.push(safely(async () => {
97
- const instances = await fetchWithAuth(ApiRoutes.FIGMA.INTEGRATIONS, apiKey);
98
- input.figma = instances.map(inst => ({ id: inst.id, displayName: inst.handle || inst.id }));
99
- }));
100
- }
101
103
  // ── Linear (fetches teams per instance) ──
102
104
  if (has(IntegrationType.LINEAR)) {
103
105
  promises.push(safely(async () => {
104
106
  const instances = await fetchWithAuth(ApiRoutes.LINEAR.INTEGRATIONS, apiKey);
105
107
  input.linear = await Promise.all(instances.map(async (inst) => {
106
108
  const teams = await fetchWithAuth(`${ApiRoutes.LINEAR.TEAMS}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => []);
107
- return { id: inst.id, displayName: inst.workspaceName || inst.id, teams: Array.isArray(teams) ? teams : [] };
108
- }));
109
- }));
110
- }
111
- // ── Atlassian — fetches Jira projects + Confluence pages per instance ──
112
- if (has(IntegrationType.ATLASSIAN)) {
113
- promises.push(safely(async () => {
114
- const instances = await fetchWithAuth(ApiRoutes.ATLASSIAN.INTEGRATIONS, apiKey);
115
- input.atlassian = await Promise.all(instances.map(async (inst) => {
116
- const [jiraResp, confResp] = await Promise.all([
117
- fetchWithAuth(`${ApiRoutes.JIRA.RESOURCES}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => null),
118
- fetchWithAuth(`${ApiRoutes.CONFLUENCE.RESOURCES}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => null),
119
- ]);
109
+ const projects = await fetchWithAuth(`${ApiRoutes.LINEAR.PROJECTS}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => []);
120
110
  return {
121
111
  id: inst.id,
122
- displayName: inst.siteName || inst.email || inst.id,
123
- jiraProjects: jiraResp?.resources?.projects || [],
124
- confluencePages: confResp?.resources || [],
112
+ displayName: inst.workspaceName || inst.id,
113
+ teams: Array.isArray(teams) ? teams : [],
114
+ projects: Array.isArray(projects) ? projects : []
125
115
  };
126
116
  }));
127
117
  }));
@@ -137,7 +127,7 @@ export async function generate() {
137
127
  id: inst.id,
138
128
  displayName: inst.workspaceName || inst.id,
139
129
  databases: resources.filter(r => r.type === "database"),
140
- pages: resources.filter(r => r.type === "page"),
130
+ pages: resources.filter(r => r.type === "page")
141
131
  };
142
132
  }));
143
133
  }));
@@ -157,7 +147,9 @@ export async function generate() {
157
147
  promises.push(safely(async () => {
158
148
  const instances = await fetchWithAuth(ApiRoutes.DATADOG.INTEGRATIONS, apiKey);
159
149
  input.datadog = await Promise.all(instances.map(async (inst) => {
160
- const resp = await fetchWithAuth(`${ApiRoutes.DATADOG.INDEXES}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => ({ indexes: [] }));
150
+ const resp = await fetchWithAuth(`${ApiRoutes.DATADOG.INDEXES}?integrationId=${encodeURIComponent(inst.id)}`, apiKey).catch(() => ({
151
+ indexes: []
152
+ }));
161
153
  return { id: inst.id, displayName: inst.region || inst.id, indexes: resp.indexes || [] };
162
154
  }));
163
155
  }));
@@ -167,7 +159,7 @@ export async function generate() {
167
159
  promises.push(safely(async () => {
168
160
  const instances = await fetchWithAuth(ApiRoutes.LAUNCHDARKLY.INTEGRATIONS, apiKey);
169
161
  input.launchdarkly = await Promise.all(instances.map(async (inst) => {
170
- const resp = await fetchWithAuth(ApiRoutes.LAUNCHDARKLY.PROJECTS_BY_INTEGRATION_ID.build(inst.id), apiKey).catch(() => ({ projects: [] }));
162
+ const resp = await fetchWithAuth(buildRoute(ApiRoutes.LAUNCHDARKLY.PROJECTS_BY_INTEGRATION_ID, { integrationId: inst.id }), apiKey).catch(() => ({ projects: [] }));
171
163
  return { id: inst.id, displayName: inst.tokenName || inst.email || inst.id, projects: resp.projects || [] };
172
164
  }));
173
165
  }));
@@ -184,23 +176,35 @@ export async function generate() {
184
176
  promises.push(safely(async () => {
185
177
  const instances = await fetchWithAuth(ApiRoutes.ATTIO.INTEGRATIONS, apiKey);
186
178
  input.attio = await Promise.all(instances.map(async (inst) => {
187
- const objects = await fetchWithAuth(ApiRoutes.ATTIO.OBJECTS.build(inst.id), apiKey).catch(() => []);
179
+ const objects = await fetchWithAuth(buildRoute(ApiRoutes.ATTIO.OBJECTS, { integrationId: inst.id }), apiKey).catch(() => []);
188
180
  return { id: inst.id, displayName: inst.workspaceName || inst.id, objects: Array.isArray(objects) ? objects : [] };
189
181
  }));
190
182
  }));
191
183
  }
184
+ if (has(IntegrationType.SNOWFLAKE)) {
185
+ promises.push(safely(async () => {
186
+ const instances = await fetchWithAuth(ApiRoutes.SNOWFLAKE.INTEGRATIONS, apiKey);
187
+ input.snowflake = instances.map(inst => ({ id: inst.id, name: inst.accountIdentifier }));
188
+ }));
189
+ }
192
190
  await Promise.all(promises);
193
- const integrationCount = input.github.length + input.slack.length + input.gmail.length + input.figma.length +
194
- input.linear.length + input.atlassian.length + input.notion.length +
195
- input.posthog.length + input.datadog.length + input.launchdarkly.length +
196
- input.workos.length + input.attio.length;
191
+ const integrationCount = input.github.length +
192
+ input.slack.length +
193
+ input.gmail.length +
194
+ input.linear.length +
195
+ input.notion.length +
196
+ input.posthog.length +
197
+ input.datadog.length +
198
+ input.launchdarkly.length +
199
+ input.workos.length +
200
+ input.attio.length;
197
201
  spinner.succeed(`Fetched ${integrationCount} integration(s)`);
198
202
  // 5. Generate code
199
203
  const codegenStart = performance.now();
200
- const code = generateCode(input);
204
+ const code = provider.renderGeneratedCode(input);
201
205
  const codegenMs = performance.now() - codegenStart;
202
206
  // 6. Write output
203
- writeOutput(code);
207
+ writeOutput(code, provider);
204
208
  // 7. Summary
205
209
  const totalMs = performance.now() - totalStart;
206
210
  console.log("");
@@ -211,7 +215,7 @@ export async function generate() {
211
215
  console.log(` ${chalk.green("+")} Schedule trigger`);
212
216
  console.log(` ${chalk.green("+")} Terse skills (web search)`);
213
217
  console.log("");
214
- console.log(` ${chalk.green.bold("Generated")} src/terse.generated.ts`);
218
+ console.log(` ${chalk.green.bold("Generated")} ${path.relative(process.cwd(), provider.resolveGeneratedCodePath(process.cwd()))}`);
215
219
  console.log(` ${chalk.dim(`Codegen: ${codegenMs.toFixed(0)}ms | Total: ${totalMs.toFixed(0)}ms`)}`);
216
220
  console.log("");
217
221
  }
@@ -220,14 +224,17 @@ async function safely(fn) {
220
224
  try {
221
225
  await fn();
222
226
  }
223
- catch { /* skip failed integrations */ }
227
+ catch {
228
+ /* skip failed integrations */
229
+ }
224
230
  }
225
- function writeOutput(code) {
226
- const srcDir = path.resolve(process.cwd(), "src");
227
- if (!fs.existsSync(srcDir)) {
228
- fs.mkdirSync(srcDir, { recursive: true });
231
+ function writeOutput(code, provider) {
232
+ const outputPath = provider.resolveGeneratedCodePath(process.cwd());
233
+ const outputDir = path.dirname(outputPath);
234
+ if (!fs.existsSync(outputDir)) {
235
+ fs.mkdirSync(outputDir, { recursive: true });
229
236
  }
230
- fs.writeFileSync(path.join(srcDir, "terse.generated.ts"), code);
237
+ fs.writeFileSync(outputPath, code);
231
238
  }
232
239
  function printSummary(input) {
233
240
  const g = chalk.green("+");
@@ -243,19 +250,10 @@ function printSummary(input) {
243
250
  const n = inst.channels.length;
244
251
  console.log(` ${g} Slack (${inst.displayName}) — ${n} ${n === 1 ? "channel" : "channels"}`);
245
252
  }
246
- for (const inst of input.figma) {
247
- console.log(` ${g} Figma (${inst.displayName})`);
248
- }
249
253
  for (const inst of input.linear) {
250
254
  const n = inst.teams.length;
251
255
  console.log(` ${g} Linear (${inst.displayName}) — ${n} ${n === 1 ? "team" : "teams"}`);
252
256
  }
253
- for (const inst of input.atlassian) {
254
- const jp = inst.jiraProjects.length;
255
- const cp = inst.confluencePages.length;
256
- console.log(` ${g} Jira (${inst.displayName}) — ${jp} ${jp === 1 ? "project" : "projects"}`);
257
- console.log(` ${g} Confluence (${inst.displayName}) — ${cp} ${cp === 1 ? "page" : "pages"}`);
258
- }
259
257
  for (const inst of input.notion) {
260
258
  const d = inst.databases.length;
261
259
  const p = inst.pages.length;