@mondaydotcomorg/z2h-cli 0.15.0 → 0.15.2-feat-eitantsh-z2h-admin-panel-package-388aad6

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 (115) hide show
  1. package/dist/commands/build.d.ts +0 -1
  2. package/dist/commands/build.d.ts.map +1 -1
  3. package/dist/commands/build.js +0 -3
  4. package/dist/commands/clean.d.ts +1 -4
  5. package/dist/commands/clean.d.ts.map +1 -1
  6. package/dist/commands/clean.js +1 -4
  7. package/dist/commands/create-workspace.d.ts +1 -4
  8. package/dist/commands/create-workspace.d.ts.map +1 -1
  9. package/dist/commands/create-workspace.js +1 -4
  10. package/dist/commands/create.d.ts +0 -1
  11. package/dist/commands/create.d.ts.map +1 -1
  12. package/dist/commands/create.js +0 -3
  13. package/dist/commands/delete.d.ts +0 -1
  14. package/dist/commands/delete.d.ts.map +1 -1
  15. package/dist/commands/delete.js +1 -4
  16. package/dist/commands/deploy.d.ts +0 -1
  17. package/dist/commands/deploy.d.ts.map +1 -1
  18. package/dist/commands/deploy.js +4 -7
  19. package/dist/commands/dev.d.ts +0 -1
  20. package/dist/commands/dev.d.ts.map +1 -1
  21. package/dist/commands/dev.js +0 -3
  22. package/dist/commands/doctor.d.ts +1 -4
  23. package/dist/commands/doctor.d.ts.map +1 -1
  24. package/dist/commands/doctor.js +2 -5
  25. package/dist/commands/edit.d.ts +1 -4
  26. package/dist/commands/edit.d.ts.map +1 -1
  27. package/dist/commands/edit.js +1 -4
  28. package/dist/commands/generate-z2h-token.d.ts +0 -1
  29. package/dist/commands/generate-z2h-token.d.ts.map +1 -1
  30. package/dist/commands/generate-z2h-token.js +0 -3
  31. package/dist/commands/grant.d.ts +1 -5
  32. package/dist/commands/grant.d.ts.map +1 -1
  33. package/dist/commands/grant.js +1 -10
  34. package/dist/commands/migrate.d.ts +0 -1
  35. package/dist/commands/migrate.d.ts.map +1 -1
  36. package/dist/commands/migrate.js +106 -4
  37. package/dist/commands/tag.d.ts +0 -1
  38. package/dist/commands/tag.d.ts.map +1 -1
  39. package/dist/commands/tag.js +1 -4
  40. package/dist/esm/commands/build.d.ts +0 -1
  41. package/dist/esm/commands/build.d.ts.map +1 -1
  42. package/dist/esm/commands/build.mjs +1 -4
  43. package/dist/esm/commands/clean.d.ts +1 -4
  44. package/dist/esm/commands/clean.d.ts.map +1 -1
  45. package/dist/esm/commands/clean.mjs +2 -5
  46. package/dist/esm/commands/create-workspace.d.ts +1 -4
  47. package/dist/esm/commands/create-workspace.d.ts.map +1 -1
  48. package/dist/esm/commands/create-workspace.mjs +2 -5
  49. package/dist/esm/commands/create.d.ts +0 -1
  50. package/dist/esm/commands/create.d.ts.map +1 -1
  51. package/dist/esm/commands/create.mjs +1 -4
  52. package/dist/esm/commands/delete.d.ts +0 -1
  53. package/dist/esm/commands/delete.d.ts.map +1 -1
  54. package/dist/esm/commands/delete.mjs +2 -5
  55. package/dist/esm/commands/deploy.d.ts +0 -1
  56. package/dist/esm/commands/deploy.d.ts.map +1 -1
  57. package/dist/esm/commands/deploy.mjs +5 -8
  58. package/dist/esm/commands/dev.d.ts +0 -1
  59. package/dist/esm/commands/dev.d.ts.map +1 -1
  60. package/dist/esm/commands/dev.mjs +1 -4
  61. package/dist/esm/commands/doctor.d.ts +1 -4
  62. package/dist/esm/commands/doctor.d.ts.map +1 -1
  63. package/dist/esm/commands/doctor.mjs +3 -6
  64. package/dist/esm/commands/edit.d.ts +1 -4
  65. package/dist/esm/commands/edit.d.ts.map +1 -1
  66. package/dist/esm/commands/edit.mjs +2 -5
  67. package/dist/esm/commands/generate-z2h-token.d.ts +0 -1
  68. package/dist/esm/commands/generate-z2h-token.d.ts.map +1 -1
  69. package/dist/esm/commands/generate-z2h-token.mjs +1 -4
  70. package/dist/esm/commands/grant.d.ts +1 -5
  71. package/dist/esm/commands/grant.d.ts.map +1 -1
  72. package/dist/esm/commands/grant.mjs +2 -11
  73. package/dist/esm/commands/migrate.d.ts +0 -1
  74. package/dist/esm/commands/migrate.d.ts.map +1 -1
  75. package/dist/esm/commands/migrate.mjs +101 -5
  76. package/dist/esm/commands/tag.d.ts +0 -1
  77. package/dist/esm/commands/tag.d.ts.map +1 -1
  78. package/dist/esm/commands/tag.mjs +2 -5
  79. package/dist/esm/index.mjs +20 -29
  80. package/dist/esm/util/tracker.d.ts.map +1 -1
  81. package/dist/esm/util/tracker.mjs +4 -1
  82. package/dist/esm/util/workspace.d.ts +3 -0
  83. package/dist/esm/util/workspace.d.ts.map +1 -1
  84. package/dist/esm/util/workspace.mjs +64 -2
  85. package/dist/index.js +19 -28
  86. package/dist/util/tracker.d.ts.map +1 -1
  87. package/dist/util/tracker.js +4 -1
  88. package/dist/util/workspace.d.ts +3 -0
  89. package/dist/util/workspace.d.ts.map +1 -1
  90. package/dist/util/workspace.js +65 -0
  91. package/package.json +1 -1
  92. package/src/commands/__tests__/doctor.test.ts +12 -5
  93. package/src/commands/build.ts +1 -6
  94. package/src/commands/clean.ts +2 -9
  95. package/src/commands/create-workspace.ts +2 -10
  96. package/src/commands/create.ts +1 -6
  97. package/src/commands/delete.ts +2 -7
  98. package/src/commands/deploy.ts +5 -10
  99. package/src/commands/dev.ts +1 -6
  100. package/src/commands/doctor.ts +3 -11
  101. package/src/commands/edit.ts +2 -10
  102. package/src/commands/generate-z2h-token.ts +1 -6
  103. package/src/commands/grant.ts +2 -16
  104. package/src/commands/migrate.ts +139 -6
  105. package/src/commands/tag.ts +2 -7
  106. package/src/index.ts +29 -41
  107. package/src/util/tracker.ts +6 -1
  108. package/src/util/workspace.ts +75 -1
  109. package/dist/esm/migrations/auto-migrate.d.ts +0 -2
  110. package/dist/esm/migrations/auto-migrate.d.ts.map +0 -1
  111. package/dist/esm/migrations/auto-migrate.mjs +0 -169
  112. package/dist/migrations/auto-migrate.d.ts +0 -2
  113. package/dist/migrations/auto-migrate.d.ts.map +0 -1
  114. package/dist/migrations/auto-migrate.js +0 -177
  115. package/src/migrations/auto-migrate.ts +0 -217
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKpH,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkG5F"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKpH,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA6BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8F5F"}
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { pathExists, ensureDir, writeFile, copy, readdir } from 'fs-extra';
4
- import { setOutputMode, info, warn, output } from '../util/logger.mjs';
4
+ import { info, warn, output } from '../util/logger.mjs';
5
5
  import { assertWorkspace } from '../util/workspace.mjs';
6
6
  import { APP_TEMPLATES, getTemplatesDir, renderTemplate } from '../util/templates.mjs';
7
7
  import { APP_NAME_PATTERN } from '../constants.mjs';
@@ -38,9 +38,6 @@ async function isDirEmpty(dir) {
38
38
  return entries.length === 0;
39
39
  }
40
40
  async function createCommand(appName, opts = {}) {
41
- if (opts.json) {
42
- setOutputMode('json');
43
- }
44
41
  // Validate workspace.
45
42
  const workspace = await assertWorkspace();
46
43
  // Validate app name.
@@ -1,6 +1,5 @@
1
1
  export interface DeleteOptions {
2
2
  yes?: boolean;
3
- json?: boolean;
4
3
  }
5
4
  export declare function deleteCommand(opts?: DeleteOptions): Promise<void>;
6
5
  //# sourceMappingURL=delete.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/delete.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAkBD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC3E"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/delete.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAkBD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B3E"}
@@ -1,5 +1,5 @@
1
1
  import { createInterface } from 'node:readline';
2
- import { setOutputMode, info, output } from '../util/logger.mjs';
2
+ import { getOutputMode, info, output } from '../util/logger.mjs';
3
3
  import { getCwdAppName, cleanAppName, mfAppName } from '../util/app-name.mjs';
4
4
  import { brokerBaseUrl, routingHeaders } from '../constants.mjs';
5
5
  import { readZthAuth } from '../util/auth/auth-store.mjs';
@@ -17,9 +17,6 @@ async function confirmByName(appSlug) {
17
17
  }
18
18
  // Should be run from the consumer app directory — uses process.cwd() to locate it.
19
19
  async function deleteCommand(opts = {}) {
20
- if (opts.json) {
21
- setOutputMode('json');
22
- }
23
20
  const cwdName = getCwdAppName();
24
21
  if (!cwdName) {
25
22
  throw new Error('Run this from inside a consumer app directory (the one with your package.json).');
@@ -28,7 +25,7 @@ async function deleteCommand(opts = {}) {
28
25
  const appName = mfAppName(cwdName); // canonical mf- bundle name the backend keys on
29
26
  // Confirmation. --json is always non-interactive, so it requires --yes.
30
27
  if (!opts.yes) {
31
- if (opts.json || !process.stdin.isTTY) {
28
+ if (getOutputMode() === 'json' || !process.stdin.isTTY) {
32
29
  throw new Error('Refusing to delete without confirmation — pass --yes to delete non-interactively.');
33
30
  }
34
31
  if (!(await confirmByName(appSlug))) {
@@ -1,7 +1,6 @@
1
1
  import { type RemoteType } from '../util/git/remote-options';
2
2
  export interface DeployOptions {
3
3
  dryRun?: boolean;
4
- json?: boolean;
5
4
  remote?: RemoteType;
6
5
  repoUrl?: string;
7
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKtG,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuJ3E"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,UAAU,EAA2C,MAAM,4BAA4B,CAAC;AAKtG,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJ3E"}
@@ -2,7 +2,7 @@ import path from 'node:path';
2
2
  import os from 'node:os';
3
3
  import { createInterface } from 'node:readline';
4
4
  import { readJson, pathExists } from 'fs-extra';
5
- import { setOutputMode, info, output, getOutputMode, warn } from '../util/logger.mjs';
5
+ import { info, output, getOutputMode, warn } from '../util/logger.mjs';
6
6
  import { resolveConsumerPaths } from '../shadow/paths.mjs';
7
7
  import { fetchAppTags, fetchTagCatalog, setAppTags } from '../util/tags.mjs';
8
8
  import { uploadDir } from '../util/s3/upload.mjs';
@@ -20,9 +20,6 @@ import { buildCommand } from './build.mjs';
20
20
 
21
21
  // Should be run from the consumer app directory — uses process.cwd() to locate it.
22
22
  async function deployCommand(opts = {}) {
23
- if (opts.json) {
24
- setOutputMode('json');
25
- }
26
23
  const paths = resolveConsumerPaths(process.cwd());
27
24
  const consumerPkg = (await readJson(paths.consumerPkg));
28
25
  if (!consumerPkg.name) {
@@ -70,7 +67,7 @@ async function deployCommand(opts = {}) {
70
67
  const keyPrefix = `${appName}/${nextVersion}`;
71
68
  const url = `${BUCKET_READ_DNS_URL}/${keyPrefix}`;
72
69
  info('building');
73
- await buildCommand({ json: opts.json, publicUrl: url });
70
+ await buildCommand({ publicUrl: url });
74
71
  if (!(await pathExists(paths.shadowBuild))) {
75
72
  throw new Error(`No build output at ${paths.shadowBuild} after build step.`);
76
73
  }
@@ -121,7 +118,7 @@ async function deployCommand(opts = {}) {
121
118
  // The two are separate endpoints, so the CLI picks based on the version it
122
119
  // was handed.
123
120
  if (nextVersion === 1) {
124
- const visibility = await resolveFirstDeployVisibility(appName, opts.json);
121
+ const visibility = await resolveFirstDeployVisibility(appName);
125
122
  info(`registering app "${appName}" → v${nextVersion} (${visibility})`);
126
123
  await registerApp(appName, token, nextVersion, entry, visibility, gitRemote);
127
124
  }
@@ -214,8 +211,8 @@ async function updateApp(appName, token, version, entry, gitRemote) {
214
211
  // First deploy only: decide whether the app is born public or private. The
215
212
  // choice is passed to the register endpoint (default private). Non-interactive
216
213
  // runs (--json or no TTY) always default to private.
217
- async function resolveFirstDeployVisibility(appName, json) {
218
- if (json || !process.stdout.isTTY) {
214
+ async function resolveFirstDeployVisibility(appName) {
215
+ if (getOutputMode() === 'json' || !process.stdout.isTTY) {
219
216
  return 'private';
220
217
  }
221
218
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -1,5 +1,4 @@
1
1
  export interface DevOptions {
2
- json?: boolean;
3
2
  open?: boolean;
4
3
  }
5
4
  export declare function devCommand(opts?: DevOptions): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ErE"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/commands/dev.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyErE"}
@@ -3,7 +3,7 @@ import fs from 'node:fs';
3
3
  import { writeFile, readJson } from 'fs-extra';
4
4
  import { watch } from 'chokidar';
5
5
  import { execa } from 'execa';
6
- import { setOutputMode, info, output, warn, errorLog } from '../util/logger.mjs';
6
+ import { info, output, warn, errorLog } from '../util/logger.mjs';
7
7
  import { prepareShadow } from '../shadow/prepare.mjs';
8
8
  import { ensureConsumerPkg } from '../shadow/consumer-pkg.mjs';
9
9
  import { syncShadow } from '../shadow/sync.mjs';
@@ -12,9 +12,6 @@ import { openInBrowser } from '../util/open-browser.mjs';
12
12
  const TRIDENT_READY_PATTERN = /Server started at/i;
13
13
  // Should be run from the consumer app directory — uses process.cwd() to locate it.
14
14
  async function devCommand(opts = {}) {
15
- if (opts.json) {
16
- setOutputMode('json');
17
- }
18
15
  const ctx = await prepareShadow();
19
16
  const { port } = ctx;
20
17
  const url = `https://bigbrain.me/bigbrain-vibe/${ctx.appName}?zth_local=${port}`;
@@ -1,5 +1,2 @@
1
- export interface DoctorOptions {
2
- json?: boolean;
3
- }
4
- export declare function doctorCommand(opts?: DoctorOptions): Promise<void>;
1
+ export declare function doctorCommand(): Promise<void>;
5
2
  //# sourceMappingURL=doctor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAiSD,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyE3E"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor.ts"],"names":[],"mappings":"AA2TA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqEnD"}
@@ -6,7 +6,7 @@ import { execa } from 'execa';
6
6
  import semver from 'semver';
7
7
  import { pathExists, readJson } from 'fs-extra';
8
8
  import pc from 'picocolors';
9
- import { setOutputMode, output } from '../util/logger.mjs';
9
+ import { getOutputMode, output } from '../util/logger.mjs';
10
10
  import { getWorkspaceHome, isZ2hWorkspace } from '../util/workspace.mjs';
11
11
  import { tryReadAuthTokenSync, Z2H_AUTH_FILE } from '../util/auth/auth-store.mjs';
12
12
  import { brokerNpmRegistryUrl, routingHeaders } from '../constants.mjs';
@@ -253,10 +253,7 @@ function renderCheck(c) {
253
253
  process.stdout.write(` ${icon} ${label}${detail}\n`);
254
254
  }
255
255
  // ── command ───────────────────────────────────────────────────────────────────
256
- async function doctorCommand(opts = {}) {
257
- if (opts.json) {
258
- setOutputMode('json');
259
- }
256
+ async function doctorCommand() {
260
257
  let pluginsJson = null;
261
258
  try {
262
259
  if (await pathExists(CLAUDE_PLUGINS_JSON)) {
@@ -282,7 +279,7 @@ async function doctorCommand(opts = {}) {
282
279
  ];
283
280
  const allChecks = sections.flatMap(s => s.checks);
284
281
  const issues = allChecks.filter(c => c.status !== 'ok');
285
- if (opts.json) {
282
+ if (getOutputMode() === 'json') {
286
283
  output('', {
287
284
  ok: issues.filter(c => c.status === 'fail').length === 0,
288
285
  checks: allChecks,
@@ -1,5 +1,2 @@
1
- export interface EditOptions {
2
- json?: boolean;
3
- }
4
- export declare function editCommand(appName: string, opts?: EditOptions): Promise<void>;
1
+ export declare function editCommand(appName: string): Promise<void>;
5
2
  //# sourceMappingURL=edit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/commands/edit.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CxF"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/commands/edit.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ChE"}
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import { pathExists } from 'fs-extra';
3
- import { setOutputMode, output, info, warn } from '../util/logger.mjs';
3
+ import { output, info, warn } from '../util/logger.mjs';
4
4
  import { assertWorkspace } from '../util/workspace.mjs';
5
5
  import { mfAppName } from '../util/app-name.mjs';
6
6
  import { fetchApp } from '../util/broker/app.mjs';
@@ -9,10 +9,7 @@ import { cloneRepo, pullAndResolve } from '../util/git/repo.mjs';
9
9
  import { runYarnInstall } from '../util/npm/install.mjs';
10
10
  import { prepareShadow } from '../shadow/prepare.mjs';
11
11
 
12
- async function editCommand(appName, opts = {}) {
13
- if (opts.json) {
14
- setOutputMode('json');
15
- }
12
+ async function editCommand(appName) {
16
13
  const workspace = await assertWorkspace();
17
14
  const mfName = mfAppName(appName);
18
15
  const app = await fetchApp(mfName);
@@ -10,7 +10,6 @@ export interface GenerateZ2HTokenOptions {
10
10
  noBrowser?: boolean;
11
11
  /** Override the page URL — useful when pointing at staging. */
12
12
  url?: string;
13
- json?: boolean;
14
13
  }
15
14
  export declare function generateZ2HTokenCommand(opts?: GenerateZ2HTokenOptions): Promise<void>;
16
15
  //# sourceMappingURL=generate-z2h-token.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-z2h-token.d.ts","sourceRoot":"","sources":["../../../src/commands/generate-z2h-token.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,yDAAyD,CAAC;AAC7F,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAwDD,wBAAsB,uBAAuB,CAAC,IAAI,GAAE,uBAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F"}
1
+ {"version":3,"file":"generate-z2h-token.d.ts","sourceRoot":"","sources":["../../../src/commands/generate-z2h-token.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,yDAAyD,CAAC;AAC7F,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAwDD,wBAAsB,uBAAuB,CAAC,IAAI,GAAE,uBAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B/F"}
@@ -1,6 +1,6 @@
1
1
  import readline from 'node:readline/promises';
2
2
  import { stdin, stdout } from 'node:process';
3
- import { setOutputMode, warn, output, info } from '../util/logger.mjs';
3
+ import { warn, output, info } from '../util/logger.mjs';
4
4
  import { validateJwtPattern, writeZthAuth } from '../util/auth/write-auth.mjs';
5
5
  import { startLoopbackServer } from '../util/auth/loopback-server.mjs';
6
6
  import { openInBrowser } from '../util/open-browser.mjs';
@@ -56,9 +56,6 @@ async function runLoopbackFlow(pageUrl) {
56
56
  }
57
57
  }
58
58
  async function generateZ2HTokenCommand(opts = {}) {
59
- if (opts.json) {
60
- setOutputMode('json');
61
- }
62
59
  const pageUrl = opts.url ?? process.env.Z2H_TOKEN_PAGE_URL ?? DEFAULT_TOKEN_PAGE_URL;
63
60
  // --no-browser bypasses both auto-open and the loopback round-trip — the
64
61
  // user opens the URL themselves and pastes the token. Useful when the
@@ -1,12 +1,8 @@
1
1
  export interface GrantOptions {
2
2
  public?: boolean;
3
3
  level?: 'owner' | 'editor' | 'viewer';
4
- json?: boolean;
5
4
  }
6
5
  export declare function grantCommand(email: string | undefined, opts: GrantOptions): Promise<void>;
7
6
  export declare function revokeCommand(email: string | undefined, opts: GrantOptions): Promise<void>;
8
- export interface TransferOwnerOptions {
9
- json?: boolean;
10
- }
11
- export declare function transferOwnerCommand(email: string | undefined, opts: TransferOwnerOptions): Promise<void>;
7
+ export declare function transferOwnerCommand(email: string | undefined): Promise<void>;
12
8
  //# sourceMappingURL=grant.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/commands/grant.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAkBD,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhG;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB/G"}
1
+ {"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/commands/grant.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACvC;AAkBD,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B/F;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhG;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnF"}
@@ -1,4 +1,4 @@
1
- import { setOutputMode, output } from '../util/logger.mjs';
1
+ import { output } from '../util/logger.mjs';
2
2
  import { mfAppName, getCwdAppName } from '../util/app-name.mjs';
3
3
  import { brokerBaseUrl, routingHeaders } from '../constants.mjs';
4
4
  import { readZthAuth } from '../util/auth/auth-store.mjs';
@@ -15,9 +15,6 @@ async function postGrant(appName, token, body) {
15
15
  }
16
16
  }
17
17
  async function grantCommand(email, opts) {
18
- if (opts.json) {
19
- setOutputMode('json');
20
- }
21
18
  if (!opts.public && !email) {
22
19
  throw new Error('Specify what to grant — e.g. --public or provide an email');
23
20
  }
@@ -43,9 +40,6 @@ async function grantCommand(email, opts) {
43
40
  output(`[z2h-cli] "${appName}" granted to: ${parts.join(', ')}`, { ok: true, appName, granted: parts });
44
41
  }
45
42
  async function revokeCommand(email, opts) {
46
- if (opts.json) {
47
- setOutputMode('json');
48
- }
49
43
  if (!opts.public && !email) {
50
44
  throw new Error('Specify what to revoke — e.g. --public or provide an email');
51
45
  }
@@ -66,10 +60,7 @@ async function revokeCommand(email, opts) {
66
60
  : `[z2h-cli] "${appName}" is now private (owners/admins only)`;
67
61
  output(msg, { ok: true, appName, revoked });
68
62
  }
69
- async function transferOwnerCommand(email, opts) {
70
- if (opts.json) {
71
- setOutputMode('json');
72
- }
63
+ async function transferOwnerCommand(email) {
73
64
  if (!email) {
74
65
  throw new Error('Specify the new owner — e.g. z2h-cli transfer-owner someone@monday.com');
75
66
  }
@@ -1,6 +1,5 @@
1
1
  export interface MigrateOptions {
2
2
  dryRun?: boolean;
3
- json?: boolean;
4
3
  }
5
4
  export declare function migrateCommand(cliVersion: string, opts?: MigrateOptions): Promise<void>;
6
5
  //# sourceMappingURL=migrate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjG"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate.ts"],"names":[],"mappings":"AA6CA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGjG"}
@@ -1,11 +1,107 @@
1
- import { setOutputMode } from '../util/logger.mjs';
2
- import { autoMigrate } from '../migrations/auto-migrate.mjs';
1
+ import { createRequire } from 'node:module';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { pathExists, readJson, writeJson } from 'fs-extra';
5
+ import semver from 'semver';
6
+ import { warn, info, errorLog } from '../util/logger.mjs';
7
+ import { getWorkspaceHome, isZ2hWorkspace, ensureWorkspaceNx, runYarnInstall } from '../util/workspace.mjs';
3
8
 
9
+ const STATE_FILE = '.z2h-migrations-state.json';
10
+ // ─── Helpers ───
11
+ async function readMigrationState(workspaceHome) {
12
+ const statePath = path.join(workspaceHome, STATE_FILE);
13
+ if (!(await pathExists(statePath))) {
14
+ return null;
15
+ }
16
+ try {
17
+ return (await readJson(statePath));
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ async function writeMigrationState(workspaceHome, state) {
24
+ const statePath = path.join(workspaceHome, STATE_FILE);
25
+ await writeJson(statePath, state, { spaces: 2 });
26
+ }
4
27
  async function migrateCommand(cliVersion, opts = {}) {
5
- if (opts.json) {
6
- setOutputMode('json');
28
+ const workspaceHome = getWorkspaceHome();
29
+ if (!(await isZ2hWorkspace(workspaceHome))) {
30
+ warn('no Z2H workspace found');
31
+ return;
32
+ }
33
+ const state = await readMigrationState(workspaceHome);
34
+ const lastVersion = state?.lastMigratedVersion ?? '0.0.0';
35
+ if (!semver.gt(cliVersion, lastVersion)) {
36
+ info('workspace is up to date — no migrations pending');
37
+ return;
38
+ }
39
+ info(`migrating workspace from v${lastVersion} → v${cliVersion}...`);
40
+ // migrations.json is at the package root — two dirs up from dist/migrations/
41
+ const thisDir = path.dirname(fileURLToPath(import.meta.url));
42
+ const migrationsJsonPath = path.resolve(thisDir, '..', '..', 'migrations.json');
43
+ if (!(await pathExists(migrationsJsonPath))) {
44
+ warn('migrations.json not found — skipping migrations');
45
+ return;
46
+ }
47
+ const migrationsJson = (await readJson(migrationsJsonPath));
48
+ // Filter to pending migrations (version > lastVersion AND <= cliVersion).
49
+ // CONVENTION: a migration's `version` field must equal the CLI release it
50
+ // ships with (not the feature branch version). This ensures the `gt` check
51
+ // always catches a migration on the exact upgrade that introduces it.
52
+ const pending = Object.entries(migrationsJson.migrations)
53
+ .filter(([, entry]) => semver.gt(entry.version, lastVersion) && semver.lte(entry.version, cliVersion))
54
+ .sort(([, a], [, b]) => semver.compare(a.version, b.version));
55
+ if (opts.dryRun) {
56
+ info(`${pending.length} pending migration(s) (dry-run — no changes will be applied):`);
57
+ for (const [, entry] of pending) {
58
+ info(` - ${entry.description} (v${entry.version})`);
59
+ }
60
+ return;
61
+ }
62
+ if (pending.length === 0) {
63
+ await writeMigrationState(workspaceHome, { lastMigratedVersion: cliVersion });
64
+ return;
65
+ }
66
+ const nxReady = await ensureWorkspaceNx(workspaceHome);
67
+ if (!nxReady) {
68
+ return;
69
+ }
70
+ info(`applying ${pending.length} workspace migration(s)...`);
71
+ // Resolve NX from the workspace's node_modules (not from CLI's own deps)
72
+ const wsRequire = createRequire(path.join(workspaceHome, 'package.json'));
73
+ const { FsTree, flushChanges } = wsRequire('nx/src/generators/tree');
74
+ let needsInstall = false;
75
+ for (const [name, entry] of pending) {
76
+ const tree = new FsTree(workspaceHome, false);
77
+ try {
78
+ const factoryPath = path.resolve(path.dirname(migrationsJsonPath), entry.migrate);
79
+ const mod = require(factoryPath);
80
+ const fn = mod.default || mod;
81
+ fn(tree);
82
+ const changes = tree.listChanges();
83
+ if (changes.length > 0) {
84
+ if (changes.some(c => c.path.endsWith('package.json'))) {
85
+ needsInstall = true;
86
+ }
87
+ flushChanges(workspaceHome, changes);
88
+ info(` ✓ ${entry.description}`);
89
+ }
90
+ else {
91
+ info(` ○ ${entry.description} (no changes needed)`);
92
+ }
93
+ }
94
+ catch (err) {
95
+ const errorMessage = `migration "${name}" failed: ${err.message}`;
96
+ errorLog(`${errorMessage}\nSkipping remaining migrations — run "z2h-cli migrate" to retry.`);
97
+ throw new Error(errorMessage);
98
+ }
99
+ }
100
+ if (needsInstall) {
101
+ await runYarnInstall(workspaceHome, 'package.json changed');
7
102
  }
8
- await autoMigrate(cliVersion, opts.dryRun);
103
+ await writeMigrationState(workspaceHome, { lastMigratedVersion: cliVersion });
104
+ info('workspace migrations complete.');
9
105
  }
10
106
 
11
107
  export { migrateCommand };
@@ -2,7 +2,6 @@ import { type AppTag, type CatalogEntry } from '../util/tags';
2
2
  export interface TagOptions {
3
3
  /** Repeatable `--tag` — sets the full tag set non-interactively. */
4
4
  tag?: string[];
5
- json?: boolean;
6
5
  }
7
6
  /**
8
7
  * Closed-list prompt: one numbered pick per dimension (app type, team). Enter
@@ -1 +1 @@
1
- {"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../src/commands/tag.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA0ClH;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC5F"}
1
+ {"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../src/commands/tag.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA0ClH;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B5F"}
@@ -3,7 +3,7 @@ import { stdin, stdout } from 'node:process';
3
3
  import { readJson } from 'fs-extra';
4
4
  import { resolveConsumerPaths } from '../shadow/paths.mjs';
5
5
  import { mfAppName } from '../util/app-name.mjs';
6
- import { info, setOutputMode, output } from '../util/logger.mjs';
6
+ import { info, output, getOutputMode } from '../util/logger.mjs';
7
7
  import { TAG_TYPES, TAG_TYPE_LABELS, setAppTags, fetchTagCatalog, fetchAppTags } from '../util/tags.mjs';
8
8
 
9
9
  /** Render an app's tags as `name (Type), ...` — or `(none)`. */
@@ -81,9 +81,6 @@ async function promptForTags(appSlug, catalog, current) {
81
81
  }
82
82
  }
83
83
  async function tagCommand(appArg, opts) {
84
- if (opts.json) {
85
- setOutputMode('json');
86
- }
87
84
  const appSlug = await resolveAppSlug(appArg);
88
85
  // Non-interactive write: `--tag` flags set the full set directly.
89
86
  if (opts.tag && opts.tag.length > 0) {
@@ -95,7 +92,7 @@ async function tagCommand(appArg, opts) {
95
92
  // Read-only listing: agents (`--json`) and any non-TTY caller get the catalog
96
93
  // + current tags without a prompt — then they set tags via `--tag`. This also
97
94
  // avoids hanging on `readline` when no human is attached to stdin.
98
- if (opts.json || !process.stdin.isTTY) {
95
+ if (getOutputMode() === 'json' || !process.stdin.isTTY) {
99
96
  output(`[z2h-cli] "${appSlug}"\n catalog: ${catalog.map(t => `${t.name} (${TAG_TYPE_LABELS[t.type]})`).join(', ') || '(none)'}\n current: ${formatTags(current)}`, { ok: true, appName: appSlug, catalog, current });
100
97
  return;
101
98
  }