@mondaydotcomorg/z2h-cli 0.1.0 → 0.2.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 (142) hide show
  1. package/dist/commands/__tests__/create-workspace.test.d.ts +2 -0
  2. package/dist/commands/__tests__/create-workspace.test.d.ts.map +1 -0
  3. package/dist/commands/__tests__/create.test.d.ts +2 -0
  4. package/dist/commands/__tests__/create.test.d.ts.map +1 -0
  5. package/dist/commands/build.d.ts +1 -0
  6. package/dist/commands/build.d.ts.map +1 -1
  7. package/dist/commands/build.js +5 -1
  8. package/dist/commands/create-workspace.d.ts +5 -0
  9. package/dist/commands/create-workspace.d.ts.map +1 -0
  10. package/dist/commands/create-workspace.js +81 -0
  11. package/dist/commands/create.d.ts +7 -0
  12. package/dist/commands/create.d.ts.map +1 -0
  13. package/dist/commands/create.js +104 -0
  14. package/dist/commands/deploy.d.ts.map +1 -1
  15. package/dist/commands/deploy.js +13 -9
  16. package/dist/commands/dev.d.ts.map +1 -1
  17. package/dist/commands/dev.js +29 -0
  18. package/dist/constants.d.ts +1 -14
  19. package/dist/constants.d.ts.map +1 -1
  20. package/dist/constants.js +11 -34
  21. package/dist/esm/commands/__tests__/create-workspace.test.d.ts +2 -0
  22. package/dist/esm/commands/__tests__/create-workspace.test.d.ts.map +1 -0
  23. package/dist/esm/commands/__tests__/create.test.d.ts +2 -0
  24. package/dist/esm/commands/__tests__/create.test.d.ts.map +1 -0
  25. package/dist/esm/commands/build.d.ts +1 -0
  26. package/dist/esm/commands/build.d.ts.map +1 -1
  27. package/dist/esm/commands/build.mjs +5 -1
  28. package/dist/esm/commands/create-workspace.d.ts +5 -0
  29. package/dist/esm/commands/create-workspace.d.ts.map +1 -0
  30. package/dist/esm/commands/create-workspace.mjs +75 -0
  31. package/dist/esm/commands/create.d.ts +7 -0
  32. package/dist/esm/commands/create.d.ts.map +1 -0
  33. package/dist/esm/commands/create.mjs +98 -0
  34. package/dist/esm/commands/deploy.d.ts.map +1 -1
  35. package/dist/esm/commands/deploy.mjs +12 -9
  36. package/dist/esm/commands/dev.d.ts.map +1 -1
  37. package/dist/esm/commands/dev.mjs +25 -1
  38. package/dist/esm/constants.d.ts +1 -14
  39. package/dist/esm/constants.d.ts.map +1 -1
  40. package/dist/esm/constants.mjs +11 -32
  41. package/dist/esm/index.mjs +28 -0
  42. package/dist/esm/shadow/__tests__/consumer-pkg.test.d.ts +2 -0
  43. package/dist/esm/shadow/__tests__/consumer-pkg.test.d.ts.map +1 -0
  44. package/dist/esm/shadow/__tests__/merge-package-json.test.d.ts +2 -0
  45. package/dist/esm/shadow/__tests__/merge-package-json.test.d.ts.map +1 -0
  46. package/dist/esm/shadow/consumer-pkg.d.ts +5 -15
  47. package/dist/esm/shadow/consumer-pkg.d.ts.map +1 -1
  48. package/dist/esm/shadow/consumer-pkg.mjs +11 -72
  49. package/dist/esm/shadow/merge-package-json.d.ts +10 -4
  50. package/dist/esm/shadow/merge-package-json.d.ts.map +1 -1
  51. package/dist/esm/shadow/merge-package-json.mjs +12 -11
  52. package/dist/esm/shadow/scaffold.d.ts.map +1 -1
  53. package/dist/esm/shadow/scaffold.mjs +5 -0
  54. package/dist/esm/shadow/sync.mjs +2 -2
  55. package/dist/esm/templates/app/claude-settings.mjs +23 -0
  56. package/dist/esm/types.d.ts +0 -1
  57. package/dist/esm/types.d.ts.map +1 -1
  58. package/dist/esm/util/__tests__/templates.test.d.ts +2 -0
  59. package/dist/esm/util/__tests__/templates.test.d.ts.map +1 -0
  60. package/dist/esm/util/__tests__/workspace-templates-shipped.test.d.ts +2 -0
  61. package/dist/esm/util/__tests__/workspace-templates-shipped.test.d.ts.map +1 -0
  62. package/dist/esm/util/__tests__/workspace.test.d.ts +2 -0
  63. package/dist/esm/util/__tests__/workspace.test.d.ts.map +1 -0
  64. package/dist/esm/util/manifest.d.ts +1 -0
  65. package/dist/esm/util/manifest.d.ts.map +1 -1
  66. package/dist/esm/util/s3/upload.mjs +1 -1
  67. package/dist/esm/util/templates.d.ts +22 -0
  68. package/dist/esm/util/templates.d.ts.map +1 -0
  69. package/dist/esm/util/templates.mjs +36 -0
  70. package/dist/esm/util/workspace.d.ts +20 -0
  71. package/dist/esm/util/workspace.d.ts.map +1 -0
  72. package/dist/esm/util/workspace.mjs +46 -0
  73. package/dist/index.js +28 -0
  74. package/dist/shadow/__tests__/consumer-pkg.test.d.ts +2 -0
  75. package/dist/shadow/__tests__/consumer-pkg.test.d.ts.map +1 -0
  76. package/dist/shadow/__tests__/merge-package-json.test.d.ts +2 -0
  77. package/dist/shadow/__tests__/merge-package-json.test.d.ts.map +1 -0
  78. package/dist/shadow/consumer-pkg.d.ts +5 -15
  79. package/dist/shadow/consumer-pkg.d.ts.map +1 -1
  80. package/dist/shadow/consumer-pkg.js +10 -72
  81. package/dist/shadow/merge-package-json.d.ts +10 -4
  82. package/dist/shadow/merge-package-json.d.ts.map +1 -1
  83. package/dist/shadow/merge-package-json.js +11 -10
  84. package/dist/shadow/scaffold.d.ts.map +1 -1
  85. package/dist/shadow/scaffold.js +5 -0
  86. package/dist/shadow/sync.js +2 -2
  87. package/dist/templates/app/claude-settings.js +27 -0
  88. package/dist/types.d.ts +0 -1
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/util/__tests__/templates.test.d.ts +2 -0
  91. package/dist/util/__tests__/templates.test.d.ts.map +1 -0
  92. package/dist/util/__tests__/workspace-templates-shipped.test.d.ts +2 -0
  93. package/dist/util/__tests__/workspace-templates-shipped.test.d.ts.map +1 -0
  94. package/dist/util/__tests__/workspace.test.d.ts +2 -0
  95. package/dist/util/__tests__/workspace.test.d.ts.map +1 -0
  96. package/dist/util/manifest.d.ts +1 -0
  97. package/dist/util/manifest.d.ts.map +1 -1
  98. package/dist/util/s3/upload.js +1 -1
  99. package/dist/util/templates.d.ts +22 -0
  100. package/dist/util/templates.d.ts.map +1 -0
  101. package/dist/util/templates.js +45 -0
  102. package/dist/util/workspace.d.ts +20 -0
  103. package/dist/util/workspace.d.ts.map +1 -0
  104. package/dist/util/workspace.js +57 -0
  105. package/package.json +5 -3
  106. package/src/commands/__tests__/create-workspace.test.ts +78 -0
  107. package/src/commands/__tests__/create.test.ts +114 -0
  108. package/src/commands/build.ts +6 -1
  109. package/src/commands/create-workspace.ts +86 -0
  110. package/src/commands/create.ts +121 -0
  111. package/src/commands/deploy.ts +15 -11
  112. package/src/commands/dev.ts +26 -1
  113. package/src/constants.ts +11 -34
  114. package/src/index.ts +28 -0
  115. package/src/shadow/__tests__/consumer-pkg.test.ts +56 -0
  116. package/src/shadow/__tests__/merge-package-json.test.ts +44 -0
  117. package/src/shadow/consumer-pkg.ts +10 -88
  118. package/src/shadow/merge-package-json.ts +12 -11
  119. package/src/shadow/scaffold.ts +5 -0
  120. package/src/shadow/sync.ts +2 -2
  121. package/src/templates/app/CLAUDE.md +72 -0
  122. package/src/templates/app/claude-settings.json +19 -0
  123. package/src/templates/app/default-index.tsx.tmpl +21 -0
  124. package/src/templates/app/gitignore +4 -0
  125. package/src/templates/app/html-index.tsx.tmpl +21 -0
  126. package/src/templates/app/package.json.tmpl +13 -0
  127. package/src/templates/workspace/README.md +39 -0
  128. package/src/templates/workspace/gitignore +23 -0
  129. package/src/templates/workspace/npmrc +3 -0
  130. package/src/templates/workspace/nvmrc +1 -0
  131. package/src/templates/workspace/package.json.tmpl +23 -0
  132. package/src/templates/workspace/yarn-releases/yarn-4.5.1.cjs +934 -0
  133. package/src/templates/workspace/yarnlock +0 -0
  134. package/src/templates/workspace/yarnrc.yml +7 -0
  135. package/src/types.ts +4 -1
  136. package/src/util/__tests__/templates.test.ts +27 -0
  137. package/src/util/__tests__/workspace-templates-shipped.test.ts +35 -0
  138. package/src/util/__tests__/workspace.test.ts +65 -0
  139. package/src/util/manifest.ts +1 -0
  140. package/src/util/s3/upload.ts +1 -1
  141. package/src/util/templates.ts +37 -0
  142. package/src/util/workspace.ts +52 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create-workspace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-workspace.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/create-workspace.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/create.test.ts"],"names":[],"mappings":""}
@@ -1,5 +1,6 @@
1
1
  export interface BuildOptions {
2
2
  json?: boolean;
3
+ publicUrl?: string;
3
4
  }
4
5
  export declare function buildCommand(opts: BuildOptions): Promise<void>;
5
6
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCpE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpE"}
@@ -22,7 +22,11 @@ async function buildCommand(opts) {
22
22
  stdio: 'inherit',
23
23
  });
24
24
  util_logger.info(`building "${ctx.appName}" via trident`);
25
- await execa.execa('yarn', ['build'], { cwd: ctx.paths.shadowDir, stdio: 'inherit' });
25
+ await execa.execa('yarn', ['build'], {
26
+ cwd: ctx.paths.shadowDir,
27
+ stdio: 'inherit',
28
+ env: { ...process.env, ...(opts.publicUrl ? { PUBLIC_URL: opts.publicUrl } : {}) },
29
+ });
26
30
  if (!(await fsExtra.pathExists(ctx.paths.shadowBuild))) {
27
31
  throw new Error(`Expected build output at ${ctx.paths.shadowBuild} — not found.`);
28
32
  }
@@ -0,0 +1,5 @@
1
+ export interface CreateWorkspaceOptions {
2
+ json?: boolean;
3
+ }
4
+ export declare function createWorkspaceCommand(opts: CreateWorkspaceOptions): Promise<void>;
5
+ //# sourceMappingURL=create-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAiBD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DxF"}
@@ -0,0 +1,81 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const path = require('node:path');
4
+ const promises = require('node:fs/promises');
5
+ const fsExtra = require('fs-extra');
6
+ const execa = require('execa');
7
+ const util_logger = require('../util/logger.js');
8
+ const util_workspace = require('../util/workspace.js');
9
+ const util_templates = require('../util/templates.js');
10
+
11
+ const _interopDefault = e => e && e.__esModule ? e : { default: e };
12
+
13
+ const path__default = /*#__PURE__*/_interopDefault(path);
14
+
15
+ /**
16
+ * Read the current z2h-cli version from its own package.json — the version
17
+ * that gets pinned into the workspace's devDependencies. That way the
18
+ * workspace's `@mondaydotcomorg/z2h-cli` always matches the version that
19
+ * bootstrapped it.
20
+ */
21
+ async function readCurrentCliVersion() {
22
+ // util/templates.ts already locates `<package-root>/src/templates`. The
23
+ // package's own package.json sits two levels above templates/.
24
+ const templatesDir = util_templates.getTemplatesDir();
25
+ const pkgPath = path__default.default.resolve(templatesDir, '..', '..', 'package.json');
26
+ const pkg = (await fsExtra.readJson(pkgPath));
27
+ return `^${pkg.version}`;
28
+ }
29
+ async function createWorkspaceCommand(opts) {
30
+ if (opts.json) {
31
+ util_logger.setOutputMode('json');
32
+ }
33
+ const home = util_workspace.getWorkspaceHome();
34
+ const templatesDir = util_templates.getTemplatesDir();
35
+ const wsTemplatesDir = path__default.default.join(templatesDir, 'workspace');
36
+ // Refuse non-empty target.
37
+ if (await fsExtra.pathExists(home)) {
38
+ const entries = await fsExtra.readdir(home);
39
+ if (entries.length > 0) {
40
+ throw new Error(`${home} is non-empty. Wipe it before running create-workspace.`);
41
+ }
42
+ }
43
+ else {
44
+ await fsExtra.ensureDir(home);
45
+ }
46
+ const [cliVersion, pkgRaw] = await Promise.all([
47
+ readCurrentCliVersion(),
48
+ promises.readFile(path__default.default.join(wsTemplatesDir, 'package.json.tmpl'), 'utf8'),
49
+ ]);
50
+ // Sources have plain names (gitignore, yarnrc.yml, nvmrc, npmrc) so they
51
+ // aren't interpreted as the active config files of *this* package; we
52
+ // rename to dotfiles at the destination.
53
+ //
54
+ // Yarn berry ships inline at .yarn/releases/. The workspace's .yarnrc.yml
55
+ // sets `yarnPath` to point here, so any `yarn` invocation (system classic
56
+ // or otherwise) reads the rc, delegates to this binary, and runs as 4.5.1
57
+ // — no corepack, no global pin needed. Mirrors how bigbrain-z2h ships its
58
+ // own yarn release.
59
+ await Promise.all([
60
+ fsExtra.writeFile(path__default.default.join(home, 'package.json'), util_templates.renderTemplate(pkgRaw, { __Z2H_CLI_VERSION__: cliVersion })),
61
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'gitignore'), path__default.default.join(home, '.gitignore')),
62
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarnrc.yml'), path__default.default.join(home, '.yarnrc.yml')),
63
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarnlock'), path__default.default.join(home, 'yarn.lock')),
64
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'nvmrc'), path__default.default.join(home, '.nvmrc')),
65
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'npmrc'), path__default.default.join(home, '.npmrc')),
66
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'README.md'), path__default.default.join(home, 'README.md')),
67
+ fsExtra.copy(path__default.default.join(wsTemplatesDir, 'yarn-releases', 'yarn-4.5.1.cjs'), path__default.default.join(home, '.yarn', 'releases', 'yarn-4.5.1.cjs')),
68
+ ]);
69
+ util_logger.info(`bootstrapping workspace at ${home}`);
70
+ await execa.execa('yarn', ['install'], {
71
+ cwd: home,
72
+ stdio: 'inherit',
73
+ });
74
+ util_logger.output(`[z2h-cli] workspace ready at ${home}`, {
75
+ ok: true,
76
+ workspace: home,
77
+ z2hCliVersion: cliVersion,
78
+ });
79
+ }
80
+
81
+ exports.createWorkspaceCommand = createWorkspaceCommand;
@@ -0,0 +1,7 @@
1
+ export interface CreateOptions {
2
+ template?: string;
3
+ htmlFile?: string;
4
+ json?: boolean;
5
+ }
6
+ export declare function createCommand(appName: string, opts: CreateOptions): Promise<void>;
7
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA0BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFvF"}
@@ -0,0 +1,104 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const path = require('node:path');
4
+ const promises = require('node:fs/promises');
5
+ const fsExtra = require('fs-extra');
6
+ const execa = require('execa');
7
+ const util_logger = require('../util/logger.js');
8
+ const util_workspace = require('../util/workspace.js');
9
+ const util_templates = require('../util/templates.js');
10
+ const util_manifest = require('../util/manifest.js');
11
+ const util_appName = require('../util/app-name.js');
12
+
13
+ const _interopDefault = e => e && e.__esModule ? e : { default: e };
14
+
15
+ const path__default = /*#__PURE__*/_interopDefault(path);
16
+
17
+ const APP_NAME_RE = /^[a-z][a-z0-9-]{1,49}$/;
18
+ /**
19
+ * Convert kebab-case to PascalCase. `demo-app` → `DemoApp`.
20
+ */
21
+ function pascalCase(input) {
22
+ return input
23
+ .split('-')
24
+ .filter(Boolean)
25
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
26
+ .join('');
27
+ }
28
+ /**
29
+ * Returns true iff `dir` either does not exist or is an empty directory.
30
+ */
31
+ async function isDirEmpty(dir) {
32
+ if (!(await fsExtra.pathExists(dir))) {
33
+ return true;
34
+ }
35
+ const entries = await fsExtra.readdir(dir);
36
+ return entries.length === 0;
37
+ }
38
+ async function createCommand(appName, opts) {
39
+ if (opts.json) {
40
+ util_logger.setOutputMode('json');
41
+ }
42
+ // Validate workspace.
43
+ const workspace = await util_workspace.assertWorkspace();
44
+ // Validate app name.
45
+ if (!APP_NAME_RE.test(appName)) {
46
+ throw new Error(`App name "${appName}" is invalid. Use lowercase kebab-case (a-z, 0-9, -), ` +
47
+ `2-50 chars, starting with a letter.`);
48
+ }
49
+ // Resolve template.
50
+ // `--html-file` implies `--template html-embed` unless the user already picked one.
51
+ const template = (opts.template ?? (opts.htmlFile ? 'html-embed' : 'default'));
52
+ if (!util_templates.APP_TEMPLATES.includes(template)) {
53
+ throw new Error(`Unknown template "${template}". Available: ${util_templates.APP_TEMPLATES.join(', ')}.`);
54
+ }
55
+ if (opts.htmlFile && !(await fsExtra.pathExists(opts.htmlFile))) {
56
+ throw new Error(`HTML file does not exist: ${opts.htmlFile}`);
57
+ }
58
+ // Validate target dir.
59
+ const appDir = path__default.default.join(workspace, appName);
60
+ if (!(await isDirEmpty(appDir))) {
61
+ throw new Error(`${appDir} is non-empty. Pick a different name or wipe it first.`);
62
+ }
63
+ // Check for manifest collision (network call — after all local checks).
64
+ const manifest = await util_manifest.readManifest();
65
+ if (manifest[util_appName.mfAppName(appName)]) {
66
+ throw new Error(`An app named "${appName}" already exists in the Z2H registry. Pick a different name.`);
67
+ }
68
+ // Compute substitutions.
69
+ const vars = {
70
+ __APP_NAME__: appName,
71
+ __APP_COMPONENT__: pascalCase(appName),
72
+ };
73
+ const appTemplatesDir = path__default.default.join(util_templates.getTemplatesDir(), 'app');
74
+ await fsExtra.ensureDir(path__default.default.join(appDir, 'src'));
75
+ await fsExtra.ensureDir(path__default.default.join(appDir, '.claude'));
76
+ // package.json (templated).
77
+ const pkgRaw = await promises.readFile(path__default.default.join(appTemplatesDir, 'package.json.tmpl'), 'utf8');
78
+ await fsExtra.writeFile(path__default.default.join(appDir, 'package.json'), util_templates.renderTemplate(pkgRaw, vars));
79
+ // src/index.tsx (templated; choice driven by template).
80
+ const indexTemplate = template === 'html-embed' ? 'html-index.tsx.tmpl' : 'default-index.tsx.tmpl';
81
+ const indexRaw = await promises.readFile(path__default.default.join(appTemplatesDir, indexTemplate), 'utf8');
82
+ await fsExtra.writeFile(path__default.default.join(appDir, 'src', 'index.tsx'), util_templates.renderTemplate(indexRaw, vars));
83
+ // Copy verbatim files.
84
+ await fsExtra.copy(path__default.default.join(appTemplatesDir, 'gitignore'), path__default.default.join(appDir, '.gitignore'));
85
+ await fsExtra.copy(path__default.default.join(appTemplatesDir, 'claude-settings.json'), path__default.default.join(appDir, '.claude', 'settings.json'));
86
+ await fsExtra.copy(path__default.default.join(appTemplatesDir, 'CLAUDE.md'), path__default.default.join(appDir, 'CLAUDE.md'));
87
+ // html-embed: also copy the source HTML.
88
+ if (template === 'html-embed' && opts.htmlFile) {
89
+ await fsExtra.copy(opts.htmlFile, path__default.default.join(appDir, 'src', 'page.html'));
90
+ }
91
+ util_logger.info(`installing into workspace at ${workspace}`);
92
+ await execa.execa('yarn', ['install'], {
93
+ cwd: workspace,
94
+ stdio: 'inherit',
95
+ });
96
+ util_logger.output(`[z2h-cli] app ready at ${appDir}`, {
97
+ ok: true,
98
+ appDir,
99
+ appName,
100
+ template,
101
+ });
102
+ }
103
+
104
+ exports.createCommand = createCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAaD,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6EtE"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAaD,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFtE"}
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const path = require('node:path');
4
+ const os = require('node:os');
4
5
  const fsExtra = require('fs-extra');
5
6
  require('execa');
6
7
  const util_logger = require('../util/logger.js');
@@ -14,6 +15,7 @@ const commands_build = require('./build.js');
14
15
  const _interopDefault = e => e && e.__esModule ? e : { default: e };
15
16
 
16
17
  const path__default = /*#__PURE__*/_interopDefault(path);
18
+ const os__default = /*#__PURE__*/_interopDefault(os);
17
19
 
18
20
  const APONO_BUNDLE = '<APONO_BUNDLE_NAME>'; // TODO: replace with actual bundle name once infra setup is complete
19
21
  async function requestAponoAccess() {
@@ -28,14 +30,19 @@ async function deployCommand(opts) {
28
30
  }
29
31
  util_logger.info('checking S3 bucket');
30
32
  await util_s3_client.assertBucketExists();
31
- util_logger.info('building');
32
- await commands_build.buildCommand({ json: opts.json });
33
33
  const paths = shadow_paths.resolveConsumerPaths(process.cwd());
34
34
  const consumerPkg = (await fsExtra.readJson(paths.consumerPkg));
35
35
  if (!consumerPkg.name) {
36
36
  throw new Error('Consumer package.json must have a "name" field');
37
37
  }
38
38
  const appName = util_appName.mfAppName(consumerPkg.name);
39
+ util_logger.info('reading current Z2H manifest');
40
+ const manifest = await util_manifest.readManifest();
41
+ const version = util_manifest.nextVersion(manifest, appName);
42
+ const keyPrefix = `${appName}/${version}`;
43
+ const url = `${util_s3_client.BUCKET_READ_DNS_URL}/${keyPrefix}`;
44
+ util_logger.info('building');
45
+ await commands_build.buildCommand({ json: opts.json, publicUrl: url });
39
46
  if (!(await fsExtra.pathExists(paths.shadowBuild))) {
40
47
  throw new Error(`No build output at ${paths.shadowBuild} after build step.`);
41
48
  }
@@ -45,11 +52,6 @@ async function deployCommand(opts) {
45
52
  throw new Error(`Missing asset-manifest.json at ${assetManifestPath}.`);
46
53
  }
47
54
  const assetManifest = (await fsExtra.readJson(assetManifestPath));
48
- util_logger.info('reading current Z2H manifest');
49
- const manifest = await util_manifest.readManifest();
50
- const version = util_manifest.nextVersion(manifest, appName);
51
- const keyPrefix = `${appName}/${version}`;
52
- const url = `${util_s3_client.BUCKET_READ_DNS_URL}/${keyPrefix}`;
53
55
  if (opts.dryRun) {
54
56
  util_logger.output(`[z2h-cli] dry-run: would upload to s3://${util_s3_client.BUCKET_WRITE_NAME}/${keyPrefix}/ as v${version}`, {
55
57
  ok: true,
@@ -64,13 +66,15 @@ async function deployCommand(opts) {
64
66
  return;
65
67
  }
66
68
  await requestAponoAccess();
67
- util_logger.info(`uploading build → s3://${util_s3_client.BUCKET_WRITE_NAME}/${keyPrefix}/`);
68
- await util_s3_upload.uploadDir(paths.shadowBuild, keyPrefix);
69
+ const deployedBy = os__default.default.userInfo().username;
69
70
  const entry = {
70
71
  ...assetManifest,
71
72
  version,
72
73
  url,
74
+ deployedBy,
73
75
  };
76
+ util_logger.info(`uploading build → s3://${util_s3_client.BUCKET_WRITE_NAME}/${keyPrefix}/`);
77
+ await util_s3_upload.uploadDir(paths.shadowBuild, keyPrefix);
74
78
  util_logger.info(`updating manifest entry "${appName}" → v${version}`);
75
79
  await util_manifest.writeManifest(util_manifest.upsertEntry(manifest, appName, entry));
76
80
  // The host MF parses the app name from the URL and prepends `mf-` itself
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAID,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDhE"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAID,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEhE"}
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const path = require('node:path');
4
+ const fs = require('node:fs');
3
5
  const fsExtra = require('fs-extra');
4
6
  const chokidar = require('chokidar');
5
7
  const execa = require('execa');
@@ -8,6 +10,11 @@ const shadow_prepare = require('../shadow/prepare.js');
8
10
  const shadow_consumerPkg = require('../shadow/consumer-pkg.js');
9
11
  const shadow_sync = require('../shadow/sync.js');
10
12
 
13
+ const _interopDefault = e => e && e.__esModule ? e : { default: e };
14
+
15
+ const path__default = /*#__PURE__*/_interopDefault(path);
16
+ const fs__default = /*#__PURE__*/_interopDefault(fs);
17
+
11
18
  const TRIDENT_READY_PATTERN = /Server started at/i;
12
19
  async function devCommand(opts) {
13
20
  if (opts.json) {
@@ -24,6 +31,28 @@ async function devCommand(opts) {
24
31
  cwd: ctx.paths.shadowDir,
25
32
  stdio: ['inherit', 'pipe', 'inherit'],
26
33
  });
34
+ const pidFile = path__default.default.join(ctx.paths.shadowDir, 'dev.pid');
35
+ if (server.pid) {
36
+ await fsExtra.writeFile(pidFile, String(server.pid));
37
+ }
38
+ const cleanupPid = () => {
39
+ try {
40
+ fs__default.default.unlinkSync(pidFile);
41
+ }
42
+ catch (_) {
43
+ // file already gone — ignore
44
+ }
45
+ };
46
+ server.on('exit', cleanupPid);
47
+ process.on('exit', cleanupPid);
48
+ process.on('SIGINT', () => {
49
+ server.kill();
50
+ process.exit(0);
51
+ });
52
+ process.on('SIGTERM', () => {
53
+ server.kill();
54
+ process.exit(0);
55
+ });
27
56
  let readyPrinted = false;
28
57
  server.stdout?.on('data', (chunk) => {
29
58
  process.stdout.write(chunk);
@@ -3,21 +3,8 @@
3
3
  * one place) stay local to their file to keep this index small.
4
4
  */
5
5
  export declare const SHADOW_DIR_NAME = ".zth";
6
- /**
7
- * Protected runtime deps that MUST resolve to a single instance across the
8
- * wrapper (.zth) and the consumer's src. Declared as peerDependencies in
9
- * the shadow pkg so yarn hoists them from the workspace root — which is
10
- * why we enforce their presence in the consumer's own package.json.
11
- */
12
- export declare const PROTECTED_DEPS: Record<string, string>;
13
- /**
14
- * Protected dev deps. Same idempotent treatment as PROTECTED_DEPS but live
15
- * in the consumer's `devDependencies`. These give the LLM-authored consumer
16
- * code access to monday.com platform types out of the box.
17
- */
18
- export declare const PROTECTED_DEV_DEPS: Record<string, string>;
19
- export declare const WORKSPACE_DEV_DEPS: Record<string, string>;
20
6
  export declare const SHADOW_SCRIPTS: Record<string, string>;
7
+ export declare const SHADOW_DEV_DEPS: Record<string, string>;
21
8
  export declare const MIN_PORT = 13000;
22
9
  export declare const MAX_PORT = 19999;
23
10
  export declare const GITIGNORE_ENTRIES: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGrD,CAAC;AAIF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAG3C,eAAO,MAAM,YAAY,UAIxB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAQF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAElD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAG3C,eAAO,MAAM,YAAY,UAIxB,CAAC"}
package/dist/constants.js CHANGED
@@ -6,41 +6,20 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6
6
  */
7
7
  // ─────────── Shadow dir layout ───────────
8
8
  const SHADOW_DIR_NAME = '.zth';
9
- // ─────────── Consumer pkg enforcement ──────
10
- /**
11
- * Protected runtime deps that MUST resolve to a single instance across the
12
- * wrapper (.zth) and the consumer's src. Declared as peerDependencies in
13
- * the shadow pkg so yarn hoists them from the workspace root — which is
14
- * why we enforce their presence in the consumer's own package.json.
15
- */
16
- const PROTECTED_DEPS = {
17
- react: '^18.2.0',
18
- 'react-dom': '^18.2.0',
19
- 'react-error-boundary': '^3.1.3',
20
- '@mondaydotcomorg/trident-runtime': '^1.24.1',
21
- '@vibe/core': '^4.0.1',
22
- };
23
- /**
24
- * Protected dev deps. Same idempotent treatment as PROTECTED_DEPS but live
25
- * in the consumer's `devDependencies`. These give the LLM-authored consumer
26
- * code access to monday.com platform types out of the box.
27
- */
28
- const PROTECTED_DEV_DEPS = {
29
- '@mondaydotcomorg/mf-api-types': '^0.1.1',
30
- '@mondaydotcomorg/bigbrain-types': '^0.3.3',
31
- };
32
- // ─────────── Shadow pkg template ───────────
33
- // TODO — Add trident mf-types / bigbrain-types opt-in.
34
- const WORKSPACE_DEV_DEPS = {
35
- '@mondaydotcomorg/trident-toolkit': '^2.9.25',
36
- '@types/react': '^18.0.14',
37
- '@types/react-dom': '^18.0.5',
38
- typescript: '^5.7.2',
39
- };
9
+ // ─────────── Shadow scripts ───────
40
10
  const SHADOW_SCRIPTS = {
41
11
  start: 'trident start',
42
12
  build: 'trident build',
43
13
  };
14
+ // ─────────── Shadow dev deps ───────
15
+ // Yarn berry only wires a workspace member's `node_modules/.bin/` PATH
16
+ // for packages that member explicitly declares. The shadow's scripts
17
+ // invoke `trident`, so trident-toolkit must be declared here for the
18
+ // bin to resolve. `*` is fine — yarn workspaces resolve the actual
19
+ // version from the workspace root's pinned entry.
20
+ const SHADOW_DEV_DEPS = {
21
+ '@mondaydotcomorg/trident-toolkit': '*',
22
+ };
44
23
  // ─────────── Auto-allocated dev port range ────
45
24
  // High enough to dodge common dev defaults (3000 Next, 5173 Vite, 8080).
46
25
  // Collisions within the 7k-port pool are rare for POC; if trident can't
@@ -59,9 +38,7 @@ const YARNRC_LINES = [
59
38
  exports.GITIGNORE_ENTRIES = GITIGNORE_ENTRIES;
60
39
  exports.MAX_PORT = MAX_PORT;
61
40
  exports.MIN_PORT = MIN_PORT;
62
- exports.PROTECTED_DEPS = PROTECTED_DEPS;
63
- exports.PROTECTED_DEV_DEPS = PROTECTED_DEV_DEPS;
41
+ exports.SHADOW_DEV_DEPS = SHADOW_DEV_DEPS;
64
42
  exports.SHADOW_DIR_NAME = SHADOW_DIR_NAME;
65
43
  exports.SHADOW_SCRIPTS = SHADOW_SCRIPTS;
66
- exports.WORKSPACE_DEV_DEPS = WORKSPACE_DEV_DEPS;
67
44
  exports.YARNRC_LINES = YARNRC_LINES;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create-workspace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-workspace.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/create-workspace.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/create.test.ts"],"names":[],"mappings":""}
@@ -1,5 +1,6 @@
1
1
  export interface BuildOptions {
2
2
  json?: boolean;
3
+ publicUrl?: string;
3
4
  }
4
5
  export declare function buildCommand(opts: BuildOptions): Promise<void>;
5
6
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCpE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/build.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpE"}
@@ -20,7 +20,11 @@ async function buildCommand(opts) {
20
20
  stdio: 'inherit',
21
21
  });
22
22
  info(`building "${ctx.appName}" via trident`);
23
- await execa('yarn', ['build'], { cwd: ctx.paths.shadowDir, stdio: 'inherit' });
23
+ await execa('yarn', ['build'], {
24
+ cwd: ctx.paths.shadowDir,
25
+ stdio: 'inherit',
26
+ env: { ...process.env, ...(opts.publicUrl ? { PUBLIC_URL: opts.publicUrl } : {}) },
27
+ });
24
28
  if (!(await pathExists(ctx.paths.shadowBuild))) {
25
29
  throw new Error(`Expected build output at ${ctx.paths.shadowBuild} — not found.`);
26
30
  }
@@ -0,0 +1,5 @@
1
+ export interface CreateWorkspaceOptions {
2
+ json?: boolean;
3
+ }
4
+ export declare function createWorkspaceCommand(opts: CreateWorkspaceOptions): Promise<void>;
5
+ //# sourceMappingURL=create-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/create-workspace.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAiBD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DxF"}
@@ -0,0 +1,75 @@
1
+ import path from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { pathExists, readdir, ensureDir, writeFile, copy, readJson } from 'fs-extra';
4
+ import { execa } from 'execa';
5
+ import { setOutputMode, info, output } from '../util/logger.mjs';
6
+ import { getWorkspaceHome } from '../util/workspace.mjs';
7
+ import { getTemplatesDir, renderTemplate } from '../util/templates.mjs';
8
+
9
+ /**
10
+ * Read the current z2h-cli version from its own package.json — the version
11
+ * that gets pinned into the workspace's devDependencies. That way the
12
+ * workspace's `@mondaydotcomorg/z2h-cli` always matches the version that
13
+ * bootstrapped it.
14
+ */
15
+ async function readCurrentCliVersion() {
16
+ // util/templates.ts already locates `<package-root>/src/templates`. The
17
+ // package's own package.json sits two levels above templates/.
18
+ const templatesDir = getTemplatesDir();
19
+ const pkgPath = path.resolve(templatesDir, '..', '..', 'package.json');
20
+ const pkg = (await readJson(pkgPath));
21
+ return `^${pkg.version}`;
22
+ }
23
+ async function createWorkspaceCommand(opts) {
24
+ if (opts.json) {
25
+ setOutputMode('json');
26
+ }
27
+ const home = getWorkspaceHome();
28
+ const templatesDir = getTemplatesDir();
29
+ const wsTemplatesDir = path.join(templatesDir, 'workspace');
30
+ // Refuse non-empty target.
31
+ if (await pathExists(home)) {
32
+ const entries = await readdir(home);
33
+ if (entries.length > 0) {
34
+ throw new Error(`${home} is non-empty. Wipe it before running create-workspace.`);
35
+ }
36
+ }
37
+ else {
38
+ await ensureDir(home);
39
+ }
40
+ const [cliVersion, pkgRaw] = await Promise.all([
41
+ readCurrentCliVersion(),
42
+ readFile(path.join(wsTemplatesDir, 'package.json.tmpl'), 'utf8'),
43
+ ]);
44
+ // Sources have plain names (gitignore, yarnrc.yml, nvmrc, npmrc) so they
45
+ // aren't interpreted as the active config files of *this* package; we
46
+ // rename to dotfiles at the destination.
47
+ //
48
+ // Yarn berry ships inline at .yarn/releases/. The workspace's .yarnrc.yml
49
+ // sets `yarnPath` to point here, so any `yarn` invocation (system classic
50
+ // or otherwise) reads the rc, delegates to this binary, and runs as 4.5.1
51
+ // — no corepack, no global pin needed. Mirrors how bigbrain-z2h ships its
52
+ // own yarn release.
53
+ await Promise.all([
54
+ writeFile(path.join(home, 'package.json'), renderTemplate(pkgRaw, { __Z2H_CLI_VERSION__: cliVersion })),
55
+ copy(path.join(wsTemplatesDir, 'gitignore'), path.join(home, '.gitignore')),
56
+ copy(path.join(wsTemplatesDir, 'yarnrc.yml'), path.join(home, '.yarnrc.yml')),
57
+ copy(path.join(wsTemplatesDir, 'yarnlock'), path.join(home, 'yarn.lock')),
58
+ copy(path.join(wsTemplatesDir, 'nvmrc'), path.join(home, '.nvmrc')),
59
+ copy(path.join(wsTemplatesDir, 'npmrc'), path.join(home, '.npmrc')),
60
+ copy(path.join(wsTemplatesDir, 'README.md'), path.join(home, 'README.md')),
61
+ copy(path.join(wsTemplatesDir, 'yarn-releases', 'yarn-4.5.1.cjs'), path.join(home, '.yarn', 'releases', 'yarn-4.5.1.cjs')),
62
+ ]);
63
+ info(`bootstrapping workspace at ${home}`);
64
+ await execa('yarn', ['install'], {
65
+ cwd: home,
66
+ stdio: 'inherit',
67
+ });
68
+ output(`[z2h-cli] workspace ready at ${home}`, {
69
+ ok: true,
70
+ workspace: home,
71
+ z2hCliVersion: cliVersion,
72
+ });
73
+ }
74
+
75
+ export { createWorkspaceCommand };
@@ -0,0 +1,7 @@
1
+ export interface CreateOptions {
2
+ template?: string;
3
+ htmlFile?: string;
4
+ json?: boolean;
5
+ }
6
+ export declare function createCommand(appName: string, opts: CreateOptions): Promise<void>;
7
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/create.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA0BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFvF"}