@tailor-platform/sdk 1.48.0 → 1.50.0

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 (51) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +1 -1
  3. package/dist/{application-DUENhx4Y.mjs → application-CZMzt9jL.mjs} +3 -2
  4. package/dist/application-CZMzt9jL.mjs.map +1 -0
  5. package/dist/application-v_E2W-Fz.mjs +4 -0
  6. package/dist/brand-D-d15jx3.mjs.map +1 -1
  7. package/dist/cli/index.mjs +137 -25
  8. package/dist/cli/index.mjs.map +1 -1
  9. package/dist/cli/lib.d.mts +1409 -1373
  10. package/dist/cli/lib.mjs +4 -4
  11. package/dist/cli/lib.mjs.map +1 -1
  12. package/dist/cli/skills.mjs.map +1 -1
  13. package/dist/client-_kHh0Pip.mjs.map +1 -1
  14. package/dist/configure/index.mjs.map +1 -1
  15. package/dist/crashreport-CvmdFs4i.mjs.map +1 -1
  16. package/dist/enum-constants-C3KSpsYj.mjs.map +1 -1
  17. package/dist/errors-pMPXghkO.mjs.map +1 -1
  18. package/dist/field-DLSIuMTu.mjs.map +1 -1
  19. package/dist/file-utils-DjNi_3U_.mjs.map +1 -1
  20. package/dist/interceptor-DTNS0EtF.mjs.map +1 -1
  21. package/dist/job-M3Avv_SV.mjs.map +1 -1
  22. package/dist/kysely/index.mjs.map +1 -1
  23. package/dist/kysely-type-B8aRz_oC.mjs.map +1 -1
  24. package/dist/logger-DTNAMYGy.mjs.map +1 -1
  25. package/dist/mock-BfL09ULZ.mjs.map +1 -1
  26. package/dist/multiline-e3IpANmS.mjs.map +1 -1
  27. package/dist/package-json-6Px8bDpG.mjs.map +1 -1
  28. package/dist/plugin/index.mjs.map +1 -1
  29. package/dist/repl-editor-jZ493eQI.mjs.map +1 -1
  30. package/dist/{runtime-CNg0w27y.mjs → runtime-B2K6JW7V.mjs} +543 -164
  31. package/dist/runtime-B2K6JW7V.mjs.map +1 -0
  32. package/dist/schema-C5QjYEc-.mjs.map +1 -1
  33. package/dist/secret-file-BHpxGyNf.mjs.map +1 -1
  34. package/dist/seed/index.mjs.map +1 -1
  35. package/dist/seed-DjfAn0BC.mjs.map +1 -1
  36. package/dist/service-DCgJxdg1.mjs.map +1 -1
  37. package/dist/telemetry-C1Y56L5E.mjs.map +1 -1
  38. package/dist/types-sir9UPht.mjs.map +1 -1
  39. package/dist/utils/test/index.mjs.map +1 -1
  40. package/dist/vitest/environment.mjs.map +1 -1
  41. package/dist/vitest/index.mjs.map +1 -1
  42. package/dist/vitest/setup.mjs.map +1 -1
  43. package/docs/cli/tailordb.md +50 -0
  44. package/docs/cli/workspace.md +20 -17
  45. package/docs/cli-reference.md +1 -0
  46. package/docs/services/tailordb-migration.md +49 -31
  47. package/package.json +8 -8
  48. package/dist/application-BNkNt47b.mjs +0 -4
  49. package/dist/application-DUENhx4Y.mjs.map +0 -1
  50. package/dist/runtime-CNg0w27y.mjs.map +0 -1
  51. /package/{skills → agent-skills}/tailor-sdk/SKILL.md +0 -0
@@ -0,0 +1,4 @@
1
+
2
+ import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-CZMzt9jL.mjs";
3
+
4
+ export { defineApplication };
@@ -1 +1 @@
1
- {"version":3,"file":"brand-D-d15jx3.mjs","names":[],"sources":["../src/utils/brand.ts"],"sourcesContent":["// Symbol.for ensures the same symbol is returned across different ESM module instances,\n// avoiding identity mismatches when multiple copies of the SDK are loaded.\nexport const SDK_BRAND: unique symbol = Symbol.for(\"tailor-platform/sdk\");\n\nexport type SdkBrandKind =\n | \"tailordb-type\"\n | \"resolver\"\n | \"executor\"\n | \"workflow\"\n | \"workflow-job\"\n | \"wait-point\";\n\n/**\n * Adds a non-enumerable SDK brand symbol to the given object (in-place).\n * The brand stores the kind so service loaders can distinguish between\n * different SDK object types (e.g. a type loader skips executors).\n * @param value - The object to brand\n * @param kind - The kind of SDK object\n * @returns The same object with the brand applied\n */\nexport function brandValue<T extends object>(value: T, kind: SdkBrandKind): T {\n Object.defineProperty(value, SDK_BRAND, {\n value: kind,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return value;\n}\n\n/**\n * Checks whether the given value has been branded by the SDK.\n * When kind is specified, only returns true if the brand matches that kind.\n * Accepts a single kind or an array of kinds for multi-kind matching.\n * @param value - The value to check\n * @param kind - Optional kind or kinds to match against\n * @returns True if the value has the SDK brand symbol (and matches kind if specified)\n */\nexport function isSdkBranded(\n value: unknown,\n kind?: SdkBrandKind | readonly SdkBrandKind[],\n): boolean {\n if (value === null || typeof value !== \"object\" || !(SDK_BRAND in value)) return false;\n const stored = (value as Record<symbol, unknown>)[SDK_BRAND];\n // No kind filter → any brand matches. Legacy `true` brand → matches any kind.\n return (\n kind === undefined ||\n stored === true ||\n (Array.isArray(kind) ? kind.includes(stored as SdkBrandKind) : stored === kind)\n );\n}\n"],"mappings":";;AAEA,MAAa,YAA2B,OAAO,IAAI,sBAAsB;;;;;;;;;AAkBzE,SAAgB,WAA6B,OAAU,MAAuB;CAC5E,OAAO,eAAe,OAAO,WAAW;EACtC,OAAO;EACP,YAAY;EACZ,cAAc;EACd,UAAU;EACX,CAAC;CACF,OAAO;;;;;;;;;;AAWT,SAAgB,aACd,OACA,MACS;CACT,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,EAAE,aAAa,QAAQ,OAAO;CACjF,MAAM,SAAU,MAAkC;CAElD,OACE,SAAS,UACT,WAAW,SACV,MAAM,QAAQ,KAAK,GAAG,KAAK,SAAS,OAAuB,GAAG,WAAW"}
1
+ {"version":3,"file":"brand-D-d15jx3.mjs","names":[],"sources":["../src/utils/brand.ts"],"sourcesContent":["// Symbol.for ensures the same symbol is returned across different ESM module instances,\n// avoiding identity mismatches when multiple copies of the SDK are loaded.\nexport const SDK_BRAND: unique symbol = Symbol.for(\"tailor-platform/sdk\");\n\nexport type SdkBrandKind =\n | \"tailordb-type\"\n | \"resolver\"\n | \"executor\"\n | \"workflow\"\n | \"workflow-job\"\n | \"wait-point\";\n\n/**\n * Adds a non-enumerable SDK brand symbol to the given object (in-place).\n * The brand stores the kind so service loaders can distinguish between\n * different SDK object types (e.g. a type loader skips executors).\n * @param value - The object to brand\n * @param kind - The kind of SDK object\n * @returns The same object with the brand applied\n */\nexport function brandValue<T extends object>(value: T, kind: SdkBrandKind): T {\n Object.defineProperty(value, SDK_BRAND, {\n value: kind,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return value;\n}\n\n/**\n * Checks whether the given value has been branded by the SDK.\n * When kind is specified, only returns true if the brand matches that kind.\n * Accepts a single kind or an array of kinds for multi-kind matching.\n * @param value - The value to check\n * @param kind - Optional kind or kinds to match against\n * @returns True if the value has the SDK brand symbol (and matches kind if specified)\n */\nexport function isSdkBranded(\n value: unknown,\n kind?: SdkBrandKind | readonly SdkBrandKind[],\n): boolean {\n if (value === null || typeof value !== \"object\" || !(SDK_BRAND in value)) return false;\n const stored = (value as Record<symbol, unknown>)[SDK_BRAND];\n // No kind filter → any brand matches. Legacy `true` brand → matches any kind.\n return (\n kind === undefined ||\n stored === true ||\n (Array.isArray(kind) ? kind.includes(stored as SdkBrandKind) : stored === kind)\n );\n}\n"],"mappings":";;AAEA,MAAa,YAA2B,OAAO,IAAI,qBAAqB;;;;;;;;;AAkBxE,SAAgB,WAA6B,OAAU,MAAuB;CAC5E,OAAO,eAAe,OAAO,WAAW;EACtC,OAAO;EACP,YAAY;EACZ,cAAc;EACd,UAAU;CACZ,CAAC;CACD,OAAO;AACT;;;;;;;;;AAUA,SAAgB,aACd,OACA,MACS;CACT,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,EAAE,aAAa,QAAQ,OAAO;CACjF,MAAM,SAAU,MAAkC;CAElD,OACE,SAAS,UACT,WAAW,SACV,MAAM,QAAQ,IAAI,IAAI,KAAK,SAAS,MAAsB,IAAI,WAAW;AAE9E"}
@@ -2,8 +2,8 @@
2
2
 
3
3
  import { G as PATScope, R as AuthInvokerSchema, c as fetchUserInfo, d as initOperatorClient, h as userAgent, i as fetchAll, j as FunctionExecution_Type, n as closeConnectionPool, o as fetchPaged, s as fetchPlatformMachineUserToken, u as initOAuth2Client } from "../client-_kHh0Pip.mjs";
4
4
  import { n as logger, r as styles } from "../logger-DTNAMYGy.mjs";
5
- import { $ as deleteCommand$3, At as executionsCommand, C as listCommand$13, Cn as toPageDirection, Ct as jobsCommand, E as resumeCommand, Et as startCommand, F as showCommand, Ft as getCommand$1, G as getCommand$5, H as treeCommand, I as logBetaWarning, Lt as deploy, N as generateCommand$1, Nt as functionExecutionStatusToString, O as listCommand$12, Ot as getCommand$6, Pt as formatKeyValueTable, R as removeCommand$1, Rt as executeScript, Sn as paginationArgs, T as healthCommand, U as listCommand$11, Vt as parseMigrationLabelNumber, Y as listCommand$10, Z as getCommand$4, Zt as formatMigrationNumber, _n as commonArgs, _t as webhookCommand, at as getCommand$3, b as createCommand$4, bn as isVerbose, bt as listCommand$6, c as listCommand$14, ct as tokenCommand, dn as trnPrefix, dt as generate, en as getMigrationFilePath, f as restoreCommand, ft as listCommand$7, g as getCommand$7, gn as defineAppCommand, i as updateCommand$4, in as loadDiff, j as truncateCommand, ln as getNamespacesWithMigrations, lt as listCommand$8, m as listCommand$15, mn as apiCommand, mt as getCommand$2, o as removeCommand, pn as prompt, q as updateCommand$2, r as queryCommand, rn as isValidMigrationNumber, rt as listCommand$9, t as isNativeTypeScriptRuntime, tn as getMigrationFiles, tt as createCommand$3, u as inviteCommand, un as sdkNameLabelKey, v as deleteCommand$4, vn as confirmationArgs, vt as triggerCommand, wn as workspaceArgs, xn as pagedLogArgs, yn as deploymentArgs, z as updateCommand$3 } from "../runtime-CNg0w27y.mjs";
6
- import { D as saveUserTokens, E as resolveTokens, O as writePlatformConfig, S as loadAccessToken, T as readPlatformConfig, _ as getDistDir, a as WorkflowJobSchema, b as deleteUserTokens, c as ExecutorSchema, i as resolveInlineSourcemap, l as INVOKER_EXPR, o as ResolverSchema, w as loadWorkspaceId, x as fetchLatestToken, y as loadConfig } from "../application-DUENhx4Y.mjs";
5
+ import { $ as listCommand$10, An as workspaceArgs, At as startCommand, B as logBetaWarning, C as listCommand$13, Cn as configArg, Dn as pagedLogArgs, Dt as jobsCommand, E as resumeCommand, En as isVerbose, F as writeDbTypesFile, Gt as parseMigrationLabelNumber, H as removeCommand$1, Ht as executeScript, I as getConfiguredEditorCommand, K as treeCommand, L as openInConfiguredEditor, Lt as functionExecutionStatusToString, Mt as getCommand$6, N as generateCommand$1, O as listCommand$12, On as paginationArgs, P as generateMigrationScript, Pt as executionsCommand, Rt as formatKeyValueTable, Sn as commonArgs, St as triggerCommand, T as healthCommand, Tn as deploymentArgs, U as updateCommand$3, Vt as deploy, Y as getCommand$5, Yt as INITIAL_SCHEMA_NUMBER, Z as updateCommand$2, _n as prompt, an as getMigrationFiles, at as createCommand$3, b as createCommand$4, bn as assertWritable, c as listCommand$14, cn as loadDiff, f as restoreCommand, ft as tokenCommand, g as getCommand$7, gt as listCommand$7, hn as trnPrefix, ht as generate, i as updateCommand$4, in as getMigrationFilePath, j as truncateCommand, kn as toPageDirection, ln as reconstructSnapshotFromMigrations, lt as getCommand$3, m as listCommand$15, mn as sdkNameLabelKey, o as removeCommand, pn as getNamespacesWithMigrations, pt as listCommand$8, q as listCommand$11, r as queryCommand, rt as deleteCommand$3, sn as isValidMigrationNumber, st as listCommand$9, t as isNativeTypeScriptRuntime, tn as formatMigrationNumber, tt as getCommand$4, u as inviteCommand, v as deleteCommand$4, vn as apiCommand, vt as getCommand$2, wn as confirmationArgs, wt as listCommand$6, xn as defineAppCommand, xt as webhookCommand, z as showCommand, zt as getCommand$1 } from "../runtime-B2K6JW7V.mjs";
6
+ import { D as saveUserTokens, E as resolveTokens, O as writePlatformConfig, S as loadAccessToken, T as readPlatformConfig, _ as getDistDir, a as WorkflowJobSchema, b as deleteUserTokens, c as ExecutorSchema, i as resolveInlineSourcemap, l as INVOKER_EXPR, o as ResolverSchema, w as loadWorkspaceId, x as fetchLatestToken, y as loadConfig } from "../application-CZMzt9jL.mjs";
7
7
  import { t as multiline } from "../multiline-e3IpANmS.mjs";
8
8
  import { t as readPackageJson } from "../package-json-6Px8bDpG.mjs";
9
9
  import { n as isCLIError } from "../errors-pMPXghkO.mjs";
@@ -25,6 +25,7 @@ import * as crypto from "node:crypto";
25
25
  import * as http from "node:http";
26
26
  import open from "open";
27
27
  import * as rolldown from "rolldown";
28
+ import * as fsPromises from "node:fs/promises";
28
29
  import { TraceMap, generatedPositionFor, originalPositionFor } from "@jridgewell/trace-mapping";
29
30
  import { spawn, spawnSync } from "node:child_process";
30
31
  import * as fs from "fs";
@@ -70,6 +71,7 @@ const authorizeAuthConnectionCommand = defineAppCommand({
70
71
  "no-browser": z.boolean().optional().default(false).describe("Don't open browser automatically")
71
72
  }).strict(),
72
73
  run: async (args) => {
74
+ await assertWritable({ profile: args.profile });
73
75
  const client = await initOperatorClient(await loadAccessToken({
74
76
  useProfile: true,
75
77
  profile: args.profile
@@ -221,6 +223,7 @@ const revokeAuthConnectionCommand = defineAppCommand({
221
223
  ...confirmationArgs
222
224
  }).strict(),
223
225
  run: async (args) => {
226
+ await assertWritable({ profile: args.profile });
224
227
  const client = await initOperatorClient(await loadAccessToken({
225
228
  useProfile: true,
226
229
  profile: args.profile
@@ -388,6 +391,7 @@ const deployCommand$1 = defineAppCommand({
388
391
  "clean-cache": arg(z.boolean().optional(), { description: "Clean the bundle cache before building" })
389
392
  }).strict(),
390
393
  run: async (args) => {
394
+ await assertWritable({ profile: args.profile });
391
395
  const { initTelemetry } = await import("../telemetry-C13VIFpT.mjs");
392
396
  await initTelemetry();
393
397
  await deploy({
@@ -1864,7 +1868,8 @@ const createCommand$2 = defineAppCommand({
1864
1868
  "workspace-id": arg(z.string(), {
1865
1869
  alias: "w",
1866
1870
  description: "Workspace ID"
1867
- })
1871
+ }),
1872
+ permission: arg(z.enum(["write", "read"]).default("write"), { description: "Profile permission. 'read' blocks all write commands while the profile is active." })
1868
1873
  }).strict(),
1869
1874
  run: async (args) => {
1870
1875
  const config = await readPlatformConfig();
@@ -1879,14 +1884,16 @@ const createCommand$2 = defineAppCommand({
1879
1884
  })).find((ws) => ws.id === args["workspace-id"])) throw new Error(`Workspace "${args["workspace-id"]}" not found.`);
1880
1885
  config.profiles[args.name] = {
1881
1886
  user: args.user,
1882
- workspace_id: args["workspace-id"]
1887
+ workspace_id: args["workspace-id"],
1888
+ ...args.permission === "read" ? { readonly: true } : {}
1883
1889
  };
1884
1890
  writePlatformConfig(config);
1885
1891
  if (!args.json) logger.success(`Profile "${args.name}" created successfully.`);
1886
1892
  const profileInfo = {
1887
1893
  name: args.name,
1888
1894
  user: args.user,
1889
- workspaceId: args["workspace-id"]
1895
+ workspaceId: args["workspace-id"],
1896
+ permission: args.permission
1890
1897
  };
1891
1898
  logger.out(profileInfo);
1892
1899
  }
@@ -1929,7 +1936,8 @@ const listCommand$4 = defineAppCommand({
1929
1936
  const profileInfos = profiles.map(([name, profile]) => ({
1930
1937
  name,
1931
1938
  user: profile.user,
1932
- workspaceId: profile.workspace_id
1939
+ workspaceId: profile.workspace_id,
1940
+ permission: profile.readonly === true ? "read" : "write"
1933
1941
  }));
1934
1942
  logger.out(profileInfos);
1935
1943
  }
@@ -1952,33 +1960,39 @@ const updateCommand$1 = defineAppCommand({
1952
1960
  "workspace-id": arg(z.string().optional(), {
1953
1961
  alias: "w",
1954
1962
  description: "New workspace ID"
1955
- })
1963
+ }),
1964
+ permission: arg(z.enum(["write", "read"]).optional(), { description: "Profile permission. 'read' blocks all write commands; 'write' lifts the restriction." })
1956
1965
  }).strict(),
1957
1966
  run: async (args) => {
1958
1967
  const config = await readPlatformConfig();
1959
1968
  if (!config.profiles[args.name]) throw new Error(`Profile "${args.name}" not found.`);
1960
- if (!args.user && !args["workspace-id"]) throw new Error("Please provide at least one property to update.");
1969
+ if (!args.user && !args["workspace-id"] && args.permission === void 0) throw new Error("Please provide at least one property to update.");
1961
1970
  const profile = config.profiles[args.name];
1962
1971
  const oldUser = profile.user;
1963
1972
  const newUser = args.user || oldUser;
1964
1973
  const oldWorkspaceId = profile.workspace_id;
1965
1974
  const newWorkspaceId = args["workspace-id"] || oldWorkspaceId;
1966
- const client = await initOperatorClient(await fetchLatestToken(config, newUser));
1967
- if (!(await fetchAll(async (pageToken, maxPageSize) => {
1968
- const { workspaces, nextPageToken } = await client.listWorkspaces({
1969
- pageToken,
1970
- pageSize: maxPageSize
1971
- });
1972
- return [workspaces, nextPageToken];
1973
- })).find((ws) => ws.id === newWorkspaceId)) throw new Error(`Workspace "${newWorkspaceId}" not found.`);
1975
+ if (args.user !== void 0 || args["workspace-id"] !== void 0) {
1976
+ const client = await initOperatorClient(await fetchLatestToken(config, newUser));
1977
+ if (!(await fetchAll(async (pageToken, maxPageSize) => {
1978
+ const { workspaces, nextPageToken } = await client.listWorkspaces({
1979
+ pageToken,
1980
+ pageSize: maxPageSize
1981
+ });
1982
+ return [workspaces, nextPageToken];
1983
+ })).find((ws) => ws.id === newWorkspaceId)) throw new Error(`Workspace "${newWorkspaceId}" not found.`);
1984
+ }
1974
1985
  profile.user = newUser;
1975
1986
  profile.workspace_id = newWorkspaceId;
1987
+ if (args.permission === "read") profile.readonly = true;
1988
+ else if (args.permission === "write") delete profile.readonly;
1976
1989
  writePlatformConfig(config);
1977
1990
  if (!args.json) logger.success(`Profile "${args.name}" updated successfully`);
1978
1991
  const profileInfo = {
1979
1992
  name: args.name,
1980
1993
  user: newUser,
1981
- workspaceId: newWorkspaceId
1994
+ workspaceId: newWorkspaceId,
1995
+ permission: profile.readonly === true ? "read" : "write"
1982
1996
  };
1983
1997
  logger.out(profileInfo);
1984
1998
  }
@@ -2092,6 +2106,7 @@ const createSecretCommand = defineAppCommand({
2092
2106
  ...confirmationArgs
2093
2107
  }).strict(),
2094
2108
  run: async (args) => {
2109
+ await assertWritable({ profile: args.profile });
2095
2110
  const client = await initOperatorClient(await loadAccessToken({
2096
2111
  useProfile: true,
2097
2112
  profile: args.profile
@@ -2144,6 +2159,7 @@ const deleteSecretCommand = defineAppCommand({
2144
2159
  ...confirmationArgs
2145
2160
  }).strict(),
2146
2161
  run: async (args) => {
2162
+ await assertWritable({ profile: args.profile });
2147
2163
  const client = await initOperatorClient(await loadAccessToken({
2148
2164
  useProfile: true,
2149
2165
  profile: args.profile
@@ -2252,6 +2268,7 @@ const updateSecretCommand = defineAppCommand({
2252
2268
  ...confirmationArgs
2253
2269
  }).strict(),
2254
2270
  run: async (args) => {
2271
+ await assertWritable({ profile: args.profile });
2255
2272
  const client = await initOperatorClient(await loadAccessToken({
2256
2273
  useProfile: true,
2257
2274
  profile: args.profile
@@ -2307,6 +2324,7 @@ const createCommand$1 = defineAppCommand({
2307
2324
  ...nameArgs
2308
2325
  }).strict(),
2309
2326
  run: async (args) => {
2327
+ await assertWritable({ profile: args.profile });
2310
2328
  const client = await initOperatorClient(await loadAccessToken({
2311
2329
  useProfile: true,
2312
2330
  profile: args.profile
@@ -2339,6 +2357,7 @@ const deleteCommand$1 = defineAppCommand({
2339
2357
  ...confirmationArgs
2340
2358
  }).strict(),
2341
2359
  run: async (args) => {
2360
+ await assertWritable({ profile: args.profile });
2342
2361
  const client = await initOperatorClient(await loadAccessToken({
2343
2362
  useProfile: true,
2344
2363
  profile: args.profile
@@ -2466,15 +2485,15 @@ var setup_bun_default = "- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019
2466
2485
 
2467
2486
  //#endregion
2468
2487
  //#region src/cli/commands/setup/github/setup-npm.yml
2469
- var setup_npm_default = "- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n with:\n node-version-file: package.json\n cache: npm\n- run: npm ci\n";
2488
+ var setup_npm_default = "- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0\n with:\n node-version-file: package.json\n cache: npm\n- run: npm ci\n";
2470
2489
 
2471
2490
  //#endregion
2472
2491
  //#region src/cli/commands/setup/github/setup-pnpm.yml
2473
- var setup_pnpm_default = "- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8\n- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n with:\n node-version-file: package.json\n cache: pnpm\n- run: pnpm install --frozen-lockfile\n";
2492
+ var setup_pnpm_default = "- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8\n- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0\n with:\n node-version-file: package.json\n cache: pnpm\n- run: pnpm install --frozen-lockfile\n";
2474
2493
 
2475
2494
  //#endregion
2476
2495
  //#region src/cli/commands/setup/github/setup-yarn.yml
2477
- var setup_yarn_default = "- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n with:\n node-version-file: package.json\n cache: yarn\n- run: yarn install --frozen-lockfile\n";
2496
+ var setup_yarn_default = "- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0\n with:\n node-version-file: package.json\n cache: yarn\n- run: yarn install --frozen-lockfile\n";
2478
2497
 
2479
2498
  //#endregion
2480
2499
  //#region src/cli/commands/setup/github/template-deploy.ts
@@ -2698,7 +2717,7 @@ async function runSkillsInstaller(options) {
2698
2717
  //#endregion
2699
2718
  //#region src/cli/commands/skills/install.ts
2700
2719
  async function resolveBundledSkillsDir() {
2701
- return resolve(dirname(await resolvePackageJSON(import.meta.url)), "skills");
2720
+ return resolve(dirname(await resolvePackageJSON(import.meta.url)), "agent-skills");
2702
2721
  }
2703
2722
  const DEFAULT_AGENT = "claude-code";
2704
2723
  const installCommand = defineAppCommand({
@@ -2908,6 +2927,7 @@ const deployCommand = defineAppCommand({
2908
2927
  })
2909
2928
  }).strict(),
2910
2929
  run: async (args) => {
2930
+ await assertWritable({ profile: args.profile });
2911
2931
  logger.info(`Deploying static website "${args.name}" from directory: ${args.dir}`);
2912
2932
  const client = await initOperatorClient(await loadAccessToken({
2913
2933
  useProfile: true,
@@ -3445,6 +3465,7 @@ const erdDeployCommand = defineAppCommand({
3445
3465
  })
3446
3466
  }).strict(),
3447
3467
  run: async (args) => {
3468
+ await assertWritable({ profile: args.profile });
3448
3469
  const { client, workspaceId, config } = await initErdContext(args);
3449
3470
  const buildResults = await prepareErdBuilds({
3450
3471
  client,
@@ -3551,6 +3572,91 @@ const erdCommand = defineCommand({
3551
3572
  }
3552
3573
  });
3553
3574
 
3575
+ //#endregion
3576
+ //#region src/cli/commands/tailordb/migrate/script.ts
3577
+ /**
3578
+ * Script command for TailorDB migrations
3579
+ *
3580
+ * Adds a `migrate.ts` (and supporting `db.ts`) template to an existing
3581
+ * migration directory. Useful for warning-tier changes where users may
3582
+ * want to write a custom data migration even though the change does not
3583
+ * automatically require one.
3584
+ */
3585
+ /**
3586
+ * Add a migrate.ts template to an existing migration directory.
3587
+ * @param {ScriptOptions} options - Command options
3588
+ */
3589
+ async function script(options) {
3590
+ logBetaWarning("tailordb migration");
3591
+ let migrationNumber;
3592
+ if (isValidMigrationNumber(options.number)) migrationNumber = parseInt(options.number, 10);
3593
+ else if (/^[1-9]\d*$/.test(options.number)) {
3594
+ migrationNumber = parseInt(options.number, 10);
3595
+ if (migrationNumber > 9999) throw new Error(`Migration number ${options.number} is out of range. Expected 1-9999.`);
3596
+ } else throw new Error(`Invalid migration number format: ${options.number}. Expected 4-digit format (e.g., 0001) or integer 1-9999 (e.g., 1).`);
3597
+ if (migrationNumber === 0) throw new Error(`Migration ${options.number} is the initial schema snapshot and cannot have a migration script.`);
3598
+ const { config } = await loadConfig(options.configPath);
3599
+ const namespacesWithMigrations = getNamespacesWithMigrations(config, path.dirname(config.path));
3600
+ if (namespacesWithMigrations.length === 0) throw new Error("No TailorDB services with migrations configuration found");
3601
+ const targetNamespace = resolveTargetNamespace(namespacesWithMigrations, options.namespace);
3602
+ const { migrationsDir } = namespacesWithMigrations.find((ns) => ns.namespace === targetNamespace);
3603
+ const diffPath = getMigrationFilePath(migrationsDir, migrationNumber, "diff");
3604
+ if (!fs$1.existsSync(diffPath)) throw new Error(`Migration ${options.number} not found in ${migrationsDir}. Expected ${diffPath}.`);
3605
+ const migratePath = getMigrationFilePath(migrationsDir, migrationNumber, "migrate");
3606
+ if (fs$1.existsSync(migratePath)) throw new Error(`Migration script already exists at ${migratePath}.`);
3607
+ const diff = loadDiff(diffPath);
3608
+ const previousSnapshot = reconstructSnapshotFromMigrations(migrationsDir, migrationNumber - 1);
3609
+ if (!previousSnapshot) throw new Error(`Could not reconstruct previous schema for migration ${options.number}. Make sure migration ${0} exists.`);
3610
+ const scriptContent = generateMigrationScript(diff);
3611
+ await fsPromises.writeFile(migratePath, scriptContent);
3612
+ await writeDbTypesFile(previousSnapshot, migrationsDir, migrationNumber, diff);
3613
+ logger.success(`Added migration script for migration ${styles.bold(options.number)} in namespace ${styles.bold(targetNamespace)}`);
3614
+ logger.info(` Migration script: ${migratePath}`);
3615
+ logger.info(` DB types: ${getMigrationFilePath(migrationsDir, migrationNumber, "db")}`);
3616
+ logger.newline();
3617
+ logger.log("Edit the script to implement your data migration logic.");
3618
+ logger.log("It will be executed by 'tailor-sdk deploy' between Pre and Post phases.");
3619
+ const editor = getConfiguredEditorCommand();
3620
+ if (!editor) return;
3621
+ logger.newline();
3622
+ logger.info(`Opening ${path.basename(migratePath)} in ${editor}...`);
3623
+ try {
3624
+ await openInConfiguredEditor(migratePath);
3625
+ } catch {
3626
+ return;
3627
+ }
3628
+ }
3629
+ function resolveTargetNamespace(namespacesWithMigrations, requested) {
3630
+ if (requested) {
3631
+ if (!namespacesWithMigrations.some((ns) => ns.namespace === requested)) throw new Error(`Namespace "${requested}" not found or does not have migrations configured`);
3632
+ return requested;
3633
+ }
3634
+ if (namespacesWithMigrations.length === 1) return namespacesWithMigrations[0].namespace;
3635
+ throw new Error(`Multiple TailorDB services found. Please specify namespace with --namespace flag: ${namespacesWithMigrations.map((ns) => ns.namespace).join(", ")}`);
3636
+ }
3637
+ const scriptCommand = defineAppCommand({
3638
+ name: "script",
3639
+ description: "Add a migration script (migrate.ts) template to an existing migration directory.",
3640
+ args: z.object({
3641
+ ...configArg,
3642
+ number: arg(z.string(), {
3643
+ positional: true,
3644
+ description: "Migration number to add a script to (e.g., 0001 or 1)"
3645
+ }),
3646
+ namespace: arg(z.string().optional(), {
3647
+ alias: "n",
3648
+ description: "Target TailorDB namespace (required if multiple namespaces exist)"
3649
+ })
3650
+ }).strict(),
3651
+ run: async (args) => {
3652
+ await script({
3653
+ configPath: args.config,
3654
+ number: args.number,
3655
+ namespace: args.namespace
3656
+ });
3657
+ }
3658
+ });
3659
+
3554
3660
  //#endregion
3555
3661
  //#region src/cli/commands/tailordb/migrate/set.ts
3556
3662
  /**
@@ -3641,6 +3747,7 @@ const setCommand = defineAppCommand({
3641
3747
  })
3642
3748
  }).strict(),
3643
3749
  run: async (args) => {
3750
+ await assertWritable({ profile: args.profile });
3644
3751
  await set({
3645
3752
  configPath: args.config,
3646
3753
  number: args.number,
@@ -3729,14 +3836,16 @@ const statusCommand = defineAppCommand({
3729
3836
  *
3730
3837
  * Subcommands:
3731
3838
  * - generate: Generate migration files from schema differences
3732
- * - set: Set migration checkpoint to a specific number
3733
- * - status: Show migration status for TailorDB namespaces
3839
+ * - script: Add a migrate.ts template to an existing migration
3840
+ * - set: Set migration checkpoint to a specific number
3841
+ * - status: Show migration status for TailorDB namespaces
3734
3842
  */
3735
3843
  const migrationCommand = defineCommand({
3736
3844
  name: "migration",
3737
3845
  description: "Manage TailorDB schema migrations.",
3738
3846
  subCommands: {
3739
3847
  generate: generateCommand$1,
3848
+ script: scriptCommand,
3740
3849
  set: setCommand,
3741
3850
  status: statusCommand
3742
3851
  }
@@ -3901,6 +4010,7 @@ const createCommand = defineAppCommand({
3901
4010
  })
3902
4011
  }).strict(),
3903
4012
  run: async (args) => {
4013
+ await assertWritable();
3904
4014
  const config = await readPlatformConfig();
3905
4015
  if (!config.current_user) throw new Error(multiline`
3906
4016
  No user logged in.
@@ -3927,6 +4037,7 @@ const deleteCommand = defineAppCommand({
3927
4037
  description: "Token name"
3928
4038
  }) }).strict(),
3929
4039
  run: async (args) => {
4040
+ await assertWritable();
3930
4041
  const config = await readPlatformConfig();
3931
4042
  if (!config.current_user) throw new Error(multiline`
3932
4043
  No user logged in.
@@ -3997,6 +4108,7 @@ const updateCommand = defineAppCommand({
3997
4108
  })
3998
4109
  }).strict(),
3999
4110
  run: async (args) => {
4111
+ await assertWritable();
4000
4112
  const config = await readPlatformConfig();
4001
4113
  if (!config.current_user) throw new Error(multiline`
4002
4114
  No user logged in.
@@ -4136,8 +4248,8 @@ const workspaceCommand = defineCommand({
4136
4248
  //#endregion
4137
4249
  //#region src/cli/index.ts
4138
4250
  if (!isNativeTypeScriptRuntime()) {
4139
- const { register } = await import("node:module");
4140
- register("tsx", import.meta.url, { data: {} });
4251
+ const { register } = await import("tsx/esm/api");
4252
+ register();
4141
4253
  }
4142
4254
  initCrashReporting();
4143
4255
  const packageJson = await readPackageJson();