@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,98 @@
1
+ import path from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { pathExists, ensureDir, writeFile, copy, readdir } from 'fs-extra';
4
+ import { execa } from 'execa';
5
+ import { setOutputMode, info, output } from '../util/logger.mjs';
6
+ import { assertWorkspace } from '../util/workspace.mjs';
7
+ import { APP_TEMPLATES, getTemplatesDir, renderTemplate } from '../util/templates.mjs';
8
+ import { readManifest } from '../util/manifest.mjs';
9
+ import { mfAppName } from '../util/app-name.mjs';
10
+
11
+ const APP_NAME_RE = /^[a-z][a-z0-9-]{1,49}$/;
12
+ /**
13
+ * Convert kebab-case to PascalCase. `demo-app` → `DemoApp`.
14
+ */
15
+ function pascalCase(input) {
16
+ return input
17
+ .split('-')
18
+ .filter(Boolean)
19
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
20
+ .join('');
21
+ }
22
+ /**
23
+ * Returns true iff `dir` either does not exist or is an empty directory.
24
+ */
25
+ async function isDirEmpty(dir) {
26
+ if (!(await pathExists(dir))) {
27
+ return true;
28
+ }
29
+ const entries = await readdir(dir);
30
+ return entries.length === 0;
31
+ }
32
+ async function createCommand(appName, opts) {
33
+ if (opts.json) {
34
+ setOutputMode('json');
35
+ }
36
+ // Validate workspace.
37
+ const workspace = await assertWorkspace();
38
+ // Validate app name.
39
+ if (!APP_NAME_RE.test(appName)) {
40
+ throw new Error(`App name "${appName}" is invalid. Use lowercase kebab-case (a-z, 0-9, -), ` +
41
+ `2-50 chars, starting with a letter.`);
42
+ }
43
+ // Resolve template.
44
+ // `--html-file` implies `--template html-embed` unless the user already picked one.
45
+ const template = (opts.template ?? (opts.htmlFile ? 'html-embed' : 'default'));
46
+ if (!APP_TEMPLATES.includes(template)) {
47
+ throw new Error(`Unknown template "${template}". Available: ${APP_TEMPLATES.join(', ')}.`);
48
+ }
49
+ if (opts.htmlFile && !(await pathExists(opts.htmlFile))) {
50
+ throw new Error(`HTML file does not exist: ${opts.htmlFile}`);
51
+ }
52
+ // Validate target dir.
53
+ const appDir = path.join(workspace, appName);
54
+ if (!(await isDirEmpty(appDir))) {
55
+ throw new Error(`${appDir} is non-empty. Pick a different name or wipe it first.`);
56
+ }
57
+ // Check for manifest collision (network call — after all local checks).
58
+ const manifest = await readManifest();
59
+ if (manifest[mfAppName(appName)]) {
60
+ throw new Error(`An app named "${appName}" already exists in the Z2H registry. Pick a different name.`);
61
+ }
62
+ // Compute substitutions.
63
+ const vars = {
64
+ __APP_NAME__: appName,
65
+ __APP_COMPONENT__: pascalCase(appName),
66
+ };
67
+ const appTemplatesDir = path.join(getTemplatesDir(), 'app');
68
+ await ensureDir(path.join(appDir, 'src'));
69
+ await ensureDir(path.join(appDir, '.claude'));
70
+ // package.json (templated).
71
+ const pkgRaw = await readFile(path.join(appTemplatesDir, 'package.json.tmpl'), 'utf8');
72
+ await writeFile(path.join(appDir, 'package.json'), renderTemplate(pkgRaw, vars));
73
+ // src/index.tsx (templated; choice driven by template).
74
+ const indexTemplate = template === 'html-embed' ? 'html-index.tsx.tmpl' : 'default-index.tsx.tmpl';
75
+ const indexRaw = await readFile(path.join(appTemplatesDir, indexTemplate), 'utf8');
76
+ await writeFile(path.join(appDir, 'src', 'index.tsx'), renderTemplate(indexRaw, vars));
77
+ // Copy verbatim files.
78
+ await copy(path.join(appTemplatesDir, 'gitignore'), path.join(appDir, '.gitignore'));
79
+ await copy(path.join(appTemplatesDir, 'claude-settings.json'), path.join(appDir, '.claude', 'settings.json'));
80
+ await copy(path.join(appTemplatesDir, 'CLAUDE.md'), path.join(appDir, 'CLAUDE.md'));
81
+ // html-embed: also copy the source HTML.
82
+ if (template === 'html-embed' && opts.htmlFile) {
83
+ await copy(opts.htmlFile, path.join(appDir, 'src', 'page.html'));
84
+ }
85
+ info(`installing into workspace at ${workspace}`);
86
+ await execa('yarn', ['install'], {
87
+ cwd: workspace,
88
+ stdio: 'inherit',
89
+ });
90
+ output(`[z2h-cli] app ready at ${appDir}`, {
91
+ ok: true,
92
+ appDir,
93
+ appName,
94
+ template,
95
+ });
96
+ }
97
+
98
+ export { 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,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import os from 'node:os';
2
3
  import { readJson, pathExists } from 'fs-extra';
3
4
  import 'execa';
4
5
  import { setOutputMode, info, output, warn } from '../util/logger.mjs';
@@ -22,14 +23,19 @@ async function deployCommand(opts) {
22
23
  }
23
24
  info('checking S3 bucket');
24
25
  await assertBucketExists();
25
- info('building');
26
- await buildCommand({ json: opts.json });
27
26
  const paths = resolveConsumerPaths(process.cwd());
28
27
  const consumerPkg = (await readJson(paths.consumerPkg));
29
28
  if (!consumerPkg.name) {
30
29
  throw new Error('Consumer package.json must have a "name" field');
31
30
  }
32
31
  const appName = mfAppName(consumerPkg.name);
32
+ info('reading current Z2H manifest');
33
+ const manifest = await readManifest();
34
+ const version = nextVersion(manifest, appName);
35
+ const keyPrefix = `${appName}/${version}`;
36
+ const url = `${BUCKET_READ_DNS_URL}/${keyPrefix}`;
37
+ info('building');
38
+ await buildCommand({ json: opts.json, publicUrl: url });
33
39
  if (!(await pathExists(paths.shadowBuild))) {
34
40
  throw new Error(`No build output at ${paths.shadowBuild} after build step.`);
35
41
  }
@@ -39,11 +45,6 @@ async function deployCommand(opts) {
39
45
  throw new Error(`Missing asset-manifest.json at ${assetManifestPath}.`);
40
46
  }
41
47
  const assetManifest = (await readJson(assetManifestPath));
42
- info('reading current Z2H manifest');
43
- const manifest = await readManifest();
44
- const version = nextVersion(manifest, appName);
45
- const keyPrefix = `${appName}/${version}`;
46
- const url = `${BUCKET_READ_DNS_URL}/${keyPrefix}`;
47
48
  if (opts.dryRun) {
48
49
  output(`[z2h-cli] dry-run: would upload to s3://${BUCKET_WRITE_NAME}/${keyPrefix}/ as v${version}`, {
49
50
  ok: true,
@@ -58,13 +59,15 @@ async function deployCommand(opts) {
58
59
  return;
59
60
  }
60
61
  await requestAponoAccess();
61
- info(`uploading build → s3://${BUCKET_WRITE_NAME}/${keyPrefix}/`);
62
- await uploadDir(paths.shadowBuild, keyPrefix);
62
+ const deployedBy = os.userInfo().username;
63
63
  const entry = {
64
64
  ...assetManifest,
65
65
  version,
66
66
  url,
67
+ deployedBy,
67
68
  };
69
+ info(`uploading build → s3://${BUCKET_WRITE_NAME}/${keyPrefix}/`);
70
+ await uploadDir(paths.shadowBuild, keyPrefix);
68
71
  info(`updating manifest entry "${appName}" → v${version}`);
69
72
  await writeManifest(upsertEntry(manifest, appName, entry));
70
73
  // 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,4 +1,6 @@
1
- import { readJson } from 'fs-extra';
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { writeFile, readJson } from 'fs-extra';
2
4
  import { watch } from 'chokidar';
3
5
  import { execa } from 'execa';
4
6
  import { setOutputMode, info, output, warn, errorLog } from '../util/logger.mjs';
@@ -22,6 +24,28 @@ async function devCommand(opts) {
22
24
  cwd: ctx.paths.shadowDir,
23
25
  stdio: ['inherit', 'pipe', 'inherit'],
24
26
  });
27
+ const pidFile = path.join(ctx.paths.shadowDir, 'dev.pid');
28
+ if (server.pid) {
29
+ await writeFile(pidFile, String(server.pid));
30
+ }
31
+ const cleanupPid = () => {
32
+ try {
33
+ fs.unlinkSync(pidFile);
34
+ }
35
+ catch (_) {
36
+ // file already gone — ignore
37
+ }
38
+ };
39
+ server.on('exit', cleanupPid);
40
+ process.on('exit', cleanupPid);
41
+ process.on('SIGINT', () => {
42
+ server.kill();
43
+ process.exit(0);
44
+ });
45
+ process.on('SIGTERM', () => {
46
+ server.kill();
47
+ process.exit(0);
48
+ });
25
49
  let readyPrinted = false;
26
50
  server.stdout?.on('data', (chunk) => {
27
51
  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"}
@@ -4,41 +4,20 @@
4
4
  */
5
5
  // ─────────── Shadow dir layout ───────────
6
6
  const SHADOW_DIR_NAME = '.zth';
7
- // ─────────── Consumer pkg enforcement ──────
8
- /**
9
- * Protected runtime deps that MUST resolve to a single instance across the
10
- * wrapper (.zth) and the consumer's src. Declared as peerDependencies in
11
- * the shadow pkg so yarn hoists them from the workspace root — which is
12
- * why we enforce their presence in the consumer's own package.json.
13
- */
14
- const PROTECTED_DEPS = {
15
- react: '^18.2.0',
16
- 'react-dom': '^18.2.0',
17
- 'react-error-boundary': '^3.1.3',
18
- '@mondaydotcomorg/trident-runtime': '^1.24.1',
19
- '@vibe/core': '^4.0.1',
20
- };
21
- /**
22
- * Protected dev deps. Same idempotent treatment as PROTECTED_DEPS but live
23
- * in the consumer's `devDependencies`. These give the LLM-authored consumer
24
- * code access to monday.com platform types out of the box.
25
- */
26
- const PROTECTED_DEV_DEPS = {
27
- '@mondaydotcomorg/mf-api-types': '^0.1.1',
28
- '@mondaydotcomorg/bigbrain-types': '^0.3.3',
29
- };
30
- // ─────────── Shadow pkg template ───────────
31
- // TODO — Add trident mf-types / bigbrain-types opt-in.
32
- const WORKSPACE_DEV_DEPS = {
33
- '@mondaydotcomorg/trident-toolkit': '^2.9.25',
34
- '@types/react': '^18.0.14',
35
- '@types/react-dom': '^18.0.5',
36
- typescript: '^5.7.2',
37
- };
7
+ // ─────────── Shadow scripts ───────
38
8
  const SHADOW_SCRIPTS = {
39
9
  start: 'trident start',
40
10
  build: 'trident build',
41
11
  };
12
+ // ─────────── Shadow dev deps ───────
13
+ // Yarn berry only wires a workspace member's `node_modules/.bin/` PATH
14
+ // for packages that member explicitly declares. The shadow's scripts
15
+ // invoke `trident`, so trident-toolkit must be declared here for the
16
+ // bin to resolve. `*` is fine — yarn workspaces resolve the actual
17
+ // version from the workspace root's pinned entry.
18
+ const SHADOW_DEV_DEPS = {
19
+ '@mondaydotcomorg/trident-toolkit': '*',
20
+ };
42
21
  // ─────────── Auto-allocated dev port range ────
43
22
  // High enough to dodge common dev defaults (3000 Next, 5173 Vite, 8080).
44
23
  // Collisions within the 7k-port pool are rare for POC; if trident can't
@@ -54,4 +33,4 @@ const YARNRC_LINES = [
54
33
  "npmRegistryServer: 'https://registry.npmjs.org/'",
55
34
  ];
56
35
 
57
- export { GITIGNORE_ENTRIES, MAX_PORT, MIN_PORT, PROTECTED_DEPS, PROTECTED_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, WORKSPACE_DEV_DEPS, YARNRC_LINES };
36
+ export { GITIGNORE_ENTRIES, MAX_PORT, MIN_PORT, SHADOW_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, YARNRC_LINES };
@@ -3,6 +3,8 @@ import { devCommand } from './commands/dev.mjs';
3
3
  import { buildCommand } from './commands/build.mjs';
4
4
  import { cleanCommand } from './commands/clean.mjs';
5
5
  import { deployCommand } from './commands/deploy.mjs';
6
+ import { createWorkspaceCommand } from './commands/create-workspace.mjs';
7
+ import { createCommand } from './commands/create.mjs';
6
8
  import { errorLog, fail } from './util/logger.mjs';
7
9
 
8
10
  async function main() {
@@ -74,6 +76,32 @@ async function main() {
74
76
  fail(`deploy failed: ${err.message}`, { command: 'deploy' }, 2);
75
77
  }
76
78
  });
79
+ program
80
+ .command('create-workspace')
81
+ .description('Bootstrap the ~/zth-projects/ yarn workspace (one-time setup)')
82
+ .option('--json', 'emit structured JSON on stdout')
83
+ .action(async (opts) => {
84
+ try {
85
+ await createWorkspaceCommand(opts);
86
+ }
87
+ catch (err) {
88
+ fail(`create-workspace failed: ${err.message}`, { command: 'create-workspace' }, 1);
89
+ }
90
+ });
91
+ program
92
+ .command('create <app-name>')
93
+ .description('Scaffold a new Z2H consumer app inside ~/zth-projects/')
94
+ .option('--template <name>', 'Template name (default | html-embed)')
95
+ .option('--html-file <path>', 'Path to an HTML file to embed (implies --template html-embed)')
96
+ .option('--json', 'emit structured JSON on stdout')
97
+ .action(async (appName, opts) => {
98
+ try {
99
+ await createCommand(appName, opts);
100
+ }
101
+ catch (err) {
102
+ fail(`create failed: ${err.message}`, { command: 'create' }, 1);
103
+ }
104
+ });
77
105
  await program.parseAsync(process.argv);
78
106
  }
79
107
  void main()
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=consumer-pkg.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consumer-pkg.test.d.ts","sourceRoot":"","sources":["../../../../src/shadow/__tests__/consumer-pkg.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=merge-package-json.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-package-json.test.d.ts","sourceRoot":"","sources":["../../../../src/shadow/__tests__/merge-package-json.test.ts"],"names":[],"mappings":""}
@@ -1,21 +1,11 @@
1
1
  import type { ConsumerPkg } from '../types';
2
2
  /**
3
- * Return the consumer's `workspaces` field extended with `.zth`. Handles
4
- * all three shapes: missing, array form, or object form (`{ packages }`).
5
- * Always extends — never replaces the user's existing entries.
6
- */
7
- export declare function ensureConsumerWorkspaces(pkg: ConsumerPkg): {
8
- changed: boolean;
9
- workspaces: ConsumerPkg['workspaces'];
10
- };
11
- /**
12
- * Idempotently reshape the consumer's package.json so that:
13
- * - it is marked `"private": true`
14
- * - `.zth` is declared as a yarn workspace member (yarn will hoist)
15
- * - the protected runtime deps are present at compatible versions
16
- * - the protected dev deps are present at compatible versions
3
+ * The consumer pkg is a thin manifest. Z2H apps live inside a yarn
4
+ * workspace at `~/zth-projects/`; runtime and dev deps come from the
5
+ * workspace root, hoisted into a single `node_modules/`.
17
6
  *
18
- * Always extends — never overrides existing fields.
7
+ * The only thing this file enforces today is `private: true` — apps must
8
+ * never accidentally publish to npm.
19
9
  */
20
10
  export declare function ensureConsumerPkg(pkgPath: string, pkg: ConsumerPkg): Promise<{
21
11
  changed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"consumer-pkg.d.ts","sourceRoot":"","sources":["../../../src/shadow/consumer-pkg.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,WAAW,GAAG;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CACvC,CAsBA;AAqBD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,WAAW,CAAA;CAAE,CAAC,CAgCjD"}
1
+ {"version":3,"file":"consumer-pkg.d.ts","sourceRoot":"","sources":["../../../src/shadow/consumer-pkg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,WAAW,CAAA;CAAE,CAAC,CAOjD"}
@@ -1,81 +1,20 @@
1
1
  import { writeJson } from 'fs-extra';
2
- import { SHADOW_DIR_NAME, PROTECTED_DEPS, PROTECTED_DEV_DEPS } from '../constants.mjs';
3
2
 
4
3
  /**
5
- * Return the consumer's `workspaces` field extended with `.zth`. Handles
6
- * all three shapes: missing, array form, or object form (`{ packages }`).
7
- * Always extends — never replaces the user's existing entries.
8
- */
9
- function ensureConsumerWorkspaces(pkg) {
10
- const { workspaces } = pkg;
11
- if (Array.isArray(workspaces)) {
12
- if (workspaces.includes(SHADOW_DIR_NAME)) {
13
- return { changed: false, workspaces };
14
- }
15
- return { changed: true, workspaces: [...workspaces, SHADOW_DIR_NAME] };
16
- }
17
- if (workspaces && typeof workspaces === 'object') {
18
- const pkgs = workspaces.packages ?? [];
19
- if (pkgs.includes(SHADOW_DIR_NAME)) {
20
- return { changed: false, workspaces };
21
- }
22
- return {
23
- changed: true,
24
- workspaces: { ...workspaces, packages: [...pkgs, SHADOW_DIR_NAME] },
25
- };
26
- }
27
- return { changed: true, workspaces: [SHADOW_DIR_NAME] };
28
- }
29
- /**
30
- * Extend a deps map with the protected entries; only fills in missing ones,
31
- * never overrides versions the consumer already pinned.
32
- */
33
- function applyProtected(current, protectedMap) {
34
- const next = { ...(current ?? {}) };
35
- let changed = false;
36
- for (const [name, version] of Object.entries(protectedMap)) {
37
- if (!next[name]) {
38
- next[name] = version;
39
- changed = true;
40
- }
41
- }
42
- return { changed, next };
43
- }
44
- /**
45
- * Idempotently reshape the consumer's package.json so that:
46
- * - it is marked `"private": true`
47
- * - `.zth` is declared as a yarn workspace member (yarn will hoist)
48
- * - the protected runtime deps are present at compatible versions
49
- * - the protected dev deps are present at compatible versions
4
+ * The consumer pkg is a thin manifest. Z2H apps live inside a yarn
5
+ * workspace at `~/zth-projects/`; runtime and dev deps come from the
6
+ * workspace root, hoisted into a single `node_modules/`.
50
7
  *
51
- * Always extends — never overrides existing fields.
8
+ * The only thing this file enforces today is `private: true` — apps must
9
+ * never accidentally publish to npm.
52
10
  */
53
11
  async function ensureConsumerPkg(pkgPath, pkg) {
54
- let changed = false;
55
- const next = { ...pkg };
56
- if (next.private !== true) {
57
- next.private = true;
58
- changed = true;
59
- }
60
- const ws = ensureConsumerWorkspaces(next);
61
- if (ws.changed) {
62
- next.workspaces = ws.workspaces;
63
- changed = true;
64
- }
65
- const deps = applyProtected(next.dependencies, PROTECTED_DEPS);
66
- if (deps.changed) {
67
- next.dependencies = deps.next;
68
- changed = true;
69
- }
70
- const devDeps = applyProtected(next.devDependencies, PROTECTED_DEV_DEPS);
71
- if (devDeps.changed) {
72
- next.devDependencies = devDeps.next;
73
- changed = true;
74
- }
75
- if (changed) {
76
- await writeJson(pkgPath, next, { spaces: 2 });
12
+ if (pkg.private === true) {
13
+ return { changed: false, pkg };
77
14
  }
78
- return { changed, pkg: next };
15
+ const next = { ...pkg, private: true };
16
+ await writeJson(pkgPath, next, { spaces: 2 });
17
+ return { changed: true, pkg: next };
79
18
  }
80
19
 
81
- export { ensureConsumerPkg, ensureConsumerWorkspaces };
20
+ export { ensureConsumerPkg };
@@ -1,9 +1,15 @@
1
1
  import type { ConsumerPkg, ShadowPkg } from '../types';
2
2
  /**
3
- * Build the shadow package.json. Declares the shared runtime deps as
4
- * peerDependencies — yarn resolves them from the workspace root (the
5
- * consumer's package.json), guaranteeing a single React instance across
6
- * the wrapper and consumer src.
3
+ * Build the shadow package.json.
4
+ *
5
+ * Runtime deps live at the workspace root (`~/zth-projects/`) and are
6
+ * hoisted in via yarn workspaces — no need to mirror them here. The shadow
7
+ * only declares the toolchain it directly executes (`trident-toolkit`) so
8
+ * yarn berry wires the `trident` bin into the shadow's script PATH.
9
+ *
10
+ * The `@trident/` scope is preserved so trident-toolkit strips it and the
11
+ * emitted bundle becomes `MF-mf-<appName>`, matching the URL the host MF
12
+ * routes to.
7
13
  */
8
14
  export declare function buildShadowPkg(consumerPkg: ConsumerPkg): ShadowPkg;
9
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"merge-package-json.d.ts","sourceRoot":"","sources":["../../../src/shadow/merge-package-json.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAalE;AAgBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAW9D;AAED,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5F"}
1
+ {"version":3,"file":"merge-package-json.d.ts","sourceRoot":"","sources":["../../../src/shadow/merge-package-json.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAQlE;AAgBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAW9D;AAED,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5F"}
@@ -1,26 +1,27 @@
1
1
  import crypto from 'node:crypto';
2
2
  import { writeJson } from 'fs-extra';
3
- import { SHADOW_SCRIPTS, PROTECTED_DEPS, WORKSPACE_DEV_DEPS } from '../constants.mjs';
3
+ import { SHADOW_SCRIPTS, SHADOW_DEV_DEPS } from '../constants.mjs';
4
4
  import { mfAppName } from '../util/app-name.mjs';
5
5
 
6
6
  /**
7
- * Build the shadow package.json. Declares the shared runtime deps as
8
- * peerDependencies — yarn resolves them from the workspace root (the
9
- * consumer's package.json), guaranteeing a single React instance across
10
- * the wrapper and consumer src.
7
+ * Build the shadow package.json.
8
+ *
9
+ * Runtime deps live at the workspace root (`~/zth-projects/`) and are
10
+ * hoisted in via yarn workspaces — no need to mirror them here. The shadow
11
+ * only declares the toolchain it directly executes (`trident-toolkit`) so
12
+ * yarn berry wires the `trident` bin into the shadow's script PATH.
13
+ *
14
+ * The `@trident/` scope is preserved so trident-toolkit strips it and the
15
+ * emitted bundle becomes `MF-mf-<appName>`, matching the URL the host MF
16
+ * routes to.
11
17
  */
12
18
  function buildShadowPkg(consumerPkg) {
13
- // Use the `@trident/` scope so trident-toolkit strips it and the emitted
14
- // bundle becomes `MF-mf-<appName>`, matching the URL the host MF routes to.
15
- // The scope also keeps the shadow's name distinct from the consumer's
16
- // package.json name (same workspace, different identifiers).
17
19
  return {
18
20
  name: `@trident/${mfAppName(consumerPkg.name)}`,
19
21
  version: '0.0.1',
20
22
  private: true,
21
23
  scripts: SHADOW_SCRIPTS,
22
- peerDependencies: { ...PROTECTED_DEPS },
23
- devDependencies: WORKSPACE_DEV_DEPS,
24
+ devDependencies: { ...SHADOW_DEV_DEPS },
24
25
  };
25
26
  }
26
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/shadow/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqG9C;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvG"}
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/shadow/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0G9C;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvG"}
@@ -73,6 +73,11 @@ declare module '*.wasm' {
73
73
  const e: string;
74
74
  export default e;
75
75
  }
76
+
77
+ declare module '*.html?url' {
78
+ const src: string;
79
+ export default src;
80
+ }
76
81
  `;
77
82
  const TSCONFIG_TEMPLATE = {
78
83
  compilerOptions: {
@@ -16,8 +16,8 @@ async function syncShadow(paths, consumerPkg) {
16
16
  const oldHash = (await pathExists(paths.shadowDepsHash)) ? await readFile(paths.shadowDepsHash, 'utf8') : null;
17
17
  if (oldHash !== newHash) {
18
18
  info(oldHash ? 'consumer deps changed — yarn install' : 'first run — yarn install');
19
- // Yarn 4 is cache-first and non-interactive by default
20
- // in non-TTY contexts, so no flags are needed
19
+ // Yarn 4 is cache-first and non-interactive by default in non-TTY
20
+ // contexts, so plain `yarn install` is all we need.
21
21
  await execa('yarn', ['install'], {
22
22
  cwd: paths.consumerDir,
23
23
  stdio: 'inherit',
@@ -0,0 +1,23 @@
1
+ var permissions = {
2
+ allow: [
3
+ "Skill(z2h:*)"
4
+ ]
5
+ };
6
+ var hooks = {
7
+ Stop: [
8
+ {
9
+ hooks: [
10
+ {
11
+ type: "command",
12
+ command: "if [ -f .zth/dev.pid ]; then kill $(cat .zth/dev.pid) 2>/dev/null; rm .zth/dev.pid; fi"
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ };
18
+ const claudeSettings = {
19
+ permissions: permissions,
20
+ hooks: hooks
21
+ };
22
+
23
+ export { claudeSettings as default, hooks, permissions };
@@ -20,7 +20,6 @@ export interface ShadowPkg {
20
20
  version: string;
21
21
  private: true;
22
22
  scripts: Record<string, string>;
23
- peerDependencies: Record<string, string>;
24
23
  devDependencies: Record<string, string>;
25
24
  }
26
25
  export interface ShadowMetadata {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAGD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAGD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAOD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAGD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=templates.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.test.d.ts","sourceRoot":"","sources":["../../../../src/util/__tests__/templates.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workspace-templates-shipped.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-templates-shipped.test.d.ts","sourceRoot":"","sources":["../../../../src/util/__tests__/workspace-templates-shipped.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workspace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.test.d.ts","sourceRoot":"","sources":["../../../../src/util/__tests__/workspace.test.ts"],"names":[],"mappings":""}