@dreamboard-games/cli 0.1.30-alpha.2 → 0.1.30-alpha.4

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 (103) hide show
  1. package/dist/agent-verifier/agent-workspace-verifier.mjs +227 -0
  2. package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -0
  3. package/dist/agent-verifier/chunk-27EEIZCI.mjs +185 -0
  4. package/dist/agent-verifier/chunk-27EEIZCI.mjs.map +1 -0
  5. package/dist/agent-verifier/chunk-5NYBTZB4.mjs +226 -0
  6. package/dist/agent-verifier/chunk-5NYBTZB4.mjs.map +1 -0
  7. package/dist/agent-verifier/chunk-776W3UGV.mjs +167 -0
  8. package/dist/agent-verifier/chunk-776W3UGV.mjs.map +1 -0
  9. package/dist/agent-verifier/chunk-C3VW3DTA.mjs +2909 -0
  10. package/dist/agent-verifier/chunk-C3VW3DTA.mjs.map +1 -0
  11. package/dist/agent-verifier/chunk-F2DIOJJZ.mjs +302 -0
  12. package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +1 -0
  13. package/dist/agent-verifier/chunk-G42BGGG2.mjs +70 -0
  14. package/dist/agent-verifier/chunk-G42BGGG2.mjs.map +1 -0
  15. package/dist/agent-verifier/chunk-H6XDQJ3N.mjs +11 -0
  16. package/dist/agent-verifier/chunk-H76MT5UR.mjs +57 -0
  17. package/dist/agent-verifier/chunk-H76MT5UR.mjs.map +1 -0
  18. package/dist/agent-verifier/chunk-IAYRNVUC.mjs +49 -0
  19. package/dist/agent-verifier/chunk-IAYRNVUC.mjs.map +1 -0
  20. package/dist/agent-verifier/chunk-IDVQXGAO.mjs +222 -0
  21. package/dist/agent-verifier/chunk-IDVQXGAO.mjs.map +1 -0
  22. package/dist/agent-verifier/chunk-JO5AMVZU.mjs +1744 -0
  23. package/dist/agent-verifier/chunk-JO5AMVZU.mjs.map +1 -0
  24. package/dist/agent-verifier/chunk-JZTH3EMV.mjs +14523 -0
  25. package/dist/agent-verifier/chunk-JZTH3EMV.mjs.map +1 -0
  26. package/dist/agent-verifier/chunk-KDBSVLCF.mjs +624 -0
  27. package/dist/agent-verifier/chunk-KDBSVLCF.mjs.map +1 -0
  28. package/dist/agent-verifier/chunk-MW2QIWWA.mjs +729 -0
  29. package/dist/agent-verifier/chunk-MW2QIWWA.mjs.map +1 -0
  30. package/dist/agent-verifier/chunk-NAK77WXW.mjs +767 -0
  31. package/dist/agent-verifier/chunk-NAK77WXW.mjs.map +1 -0
  32. package/dist/agent-verifier/chunk-ON62IGWK.mjs +3137 -0
  33. package/dist/agent-verifier/chunk-ON62IGWK.mjs.map +1 -0
  34. package/dist/agent-verifier/chunk-QBAF7EYR.mjs +214 -0
  35. package/dist/agent-verifier/chunk-QBAF7EYR.mjs.map +1 -0
  36. package/dist/agent-verifier/chunk-QZH6IEZS.mjs +39 -0
  37. package/dist/agent-verifier/chunk-QZH6IEZS.mjs.map +1 -0
  38. package/dist/agent-verifier/chunk-TAEQKBJB.mjs +107 -0
  39. package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +1 -0
  40. package/dist/agent-verifier/chunk-UIOLGH4A.mjs +150 -0
  41. package/dist/agent-verifier/chunk-UIOLGH4A.mjs.map +1 -0
  42. package/dist/agent-verifier/chunk-XKCJBIRY.mjs +75 -0
  43. package/dist/agent-verifier/chunk-XKCJBIRY.mjs.map +1 -0
  44. package/dist/agent-verifier/chunk-XQXDOBYB.mjs +382 -0
  45. package/dist/agent-verifier/chunk-XQXDOBYB.mjs.map +1 -0
  46. package/dist/agent-verifier/chunk-YDIOW2BO.mjs +45 -0
  47. package/dist/agent-verifier/chunk-YDIOW2BO.mjs.map +1 -0
  48. package/dist/agent-verifier/chunk-YE7UAO3T.mjs +129 -0
  49. package/dist/agent-verifier/chunk-YE7UAO3T.mjs.map +1 -0
  50. package/dist/agent-verifier/chunk-Z6OZWUIZ.mjs +261 -0
  51. package/dist/agent-verifier/chunk-Z6OZWUIZ.mjs.map +1 -0
  52. package/dist/agent-verifier/chunk-ZEELHSY3.mjs +20 -0
  53. package/dist/agent-verifier/chunk-ZEELHSY3.mjs.map +1 -0
  54. package/dist/agent-verifier/compile-576O7TYP.mjs +312 -0
  55. package/dist/agent-verifier/compile-576O7TYP.mjs.map +1 -0
  56. package/dist/agent-verifier/global-config-NYCSCAUI.mjs +18 -0
  57. package/dist/agent-verifier/keychain-backend-A3MRWLPF.mjs +135 -0
  58. package/dist/agent-verifier/keychain-backend-A3MRWLPF.mjs.map +1 -0
  59. package/dist/agent-verifier/local-files-QVJ2H3MH.mjs +45 -0
  60. package/dist/agent-verifier/local-files-QVJ2H3MH.mjs.map +1 -0
  61. package/dist/agent-verifier/local-typecheck-2JWG5IGL.mjs +10 -0
  62. package/dist/agent-verifier/local-typecheck-2JWG5IGL.mjs.map +1 -0
  63. package/dist/agent-verifier/materialize-workspace-OZKOQCSQ.mjs +89 -0
  64. package/dist/agent-verifier/materialize-workspace-OZKOQCSQ.mjs.map +1 -0
  65. package/dist/agent-verifier/project-state-XKUSCFSV.mjs +33 -0
  66. package/dist/agent-verifier/project-state-XKUSCFSV.mjs.map +1 -0
  67. package/dist/agent-verifier/prompt-VKHMCQT6.mjs +756 -0
  68. package/dist/agent-verifier/prompt-VKHMCQT6.mjs.map +1 -0
  69. package/dist/agent-verifier/reducer-bundle-preflight-7NYZF5ZT.mjs +20 -0
  70. package/dist/agent-verifier/reducer-bundle-preflight-7NYZF5ZT.mjs.map +1 -0
  71. package/dist/agent-verifier/reducer-contract-preflight-COD2CO22.mjs +11 -0
  72. package/dist/agent-verifier/reducer-contract-preflight-COD2CO22.mjs.map +1 -0
  73. package/dist/agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs +50 -0
  74. package/dist/agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs.map +1 -0
  75. package/dist/agent-verifier/static-scaffold-JBUE3ROP.mjs +27 -0
  76. package/dist/agent-verifier/static-scaffold-JBUE3ROP.mjs.map +1 -0
  77. package/dist/agent-verifier/sync-C6S3OGCD.mjs +588 -0
  78. package/dist/agent-verifier/sync-C6S3OGCD.mjs.map +1 -0
  79. package/dist/agent-verifier/test-Y5UGQV7J.mjs +353 -0
  80. package/dist/agent-verifier/test-Y5UGQV7J.mjs.map +1 -0
  81. package/dist/agent-verifier/workspace-codegen-WPZHMATU.mjs +10 -0
  82. package/dist/agent-verifier/workspace-codegen-WPZHMATU.mjs.map +1 -0
  83. package/dist/agent-verifier/workspace-dependencies-B6A2ZX55.mjs +15 -0
  84. package/dist/agent-verifier/workspace-dependencies-B6A2ZX55.mjs.map +1 -0
  85. package/dist/chunk-2H7UOFLK.js +11 -0
  86. package/dist/chunk-2H7UOFLK.js.map +1 -0
  87. package/dist/{chunk-N7XPNNUI.js → chunk-3NRROR4P.js} +3 -3
  88. package/dist/{chunk-TAQKH67O.js → chunk-M4SCKH5M.js} +8 -2224
  89. package/dist/chunk-M4SCKH5M.js.map +1 -0
  90. package/dist/{global-config-S4ZIPECE.js → global-config-YBFEGJQG.js} +3 -3
  91. package/dist/global-config-YBFEGJQG.js.map +1 -0
  92. package/dist/index.js +4 -4
  93. package/dist/internal.js +3 -3
  94. package/dist/{keychain-backend-HDF4TZDL.js → keychain-backend-JHTXAKWC.js} +2 -2
  95. package/dist/{prompt-NDV3AE5L.js → prompt-GMZABCJC.js} +2 -2
  96. package/package.json +3 -2
  97. package/dist/chunk-SEGVTWSK.js +0 -44
  98. package/dist/chunk-TAQKH67O.js.map +0 -1
  99. /package/dist/{chunk-SEGVTWSK.js.map → agent-verifier/chunk-H6XDQJ3N.mjs.map} +0 -0
  100. /package/dist/{global-config-S4ZIPECE.js.map → agent-verifier/global-config-NYCSCAUI.mjs.map} +0 -0
  101. /package/dist/{chunk-N7XPNNUI.js.map → chunk-3NRROR4P.js.map} +0 -0
  102. /package/dist/{keychain-backend-HDF4TZDL.js.map → keychain-backend-JHTXAKWC.js.map} +0 -0
  103. /package/dist/{prompt-NDV3AE5L.js.map → prompt-GMZABCJC.js.map} +0 -0
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/utils/repo-root.ts
4
+ import { existsSync } from "fs";
5
+ import path from "path";
6
+ import { fileURLToPath } from "url";
7
+ function isRepoRoot(candidate) {
8
+ return existsSync(path.join(candidate, "pnpm-workspace.yaml")) && existsSync(path.join(candidate, "apps", "dreamboard-cli", "package.json"));
9
+ }
10
+ function resolveCliRepoRoot(importMetaUrl = import.meta.url) {
11
+ let current = path.dirname(fileURLToPath(importMetaUrl));
12
+ while (true) {
13
+ if (isRepoRoot(current)) {
14
+ return current;
15
+ }
16
+ const parent = path.dirname(current);
17
+ if (parent === current) {
18
+ break;
19
+ }
20
+ current = parent;
21
+ }
22
+ throw new Error(
23
+ `Could not resolve Dreamboard CLI repo root from ${importMetaUrl}.`
24
+ );
25
+ }
26
+
27
+ // src/utils/repo-local-package-resolution.ts
28
+ import { existsSync as existsSync2, readdirSync, readFileSync } from "fs";
29
+ import { createRequire } from "module";
30
+ import path2 from "path";
31
+ var PACKAGE_INFO_CACHE = /* @__PURE__ */ new Map();
32
+ function normalizeRepoRoot(options) {
33
+ return options?.repoRoot ?? resolveCliRepoRoot(import.meta.url);
34
+ }
35
+ function readPackageInfos(repoRoot) {
36
+ const cached = PACKAGE_INFO_CACHE.get(repoRoot);
37
+ if (cached) {
38
+ return cached;
39
+ }
40
+ const packageInfos = /* @__PURE__ */ new Map();
41
+ const addPackageInfo = (packageRoot) => {
42
+ const packageJsonPath = path2.join(packageRoot, "package.json");
43
+ if (!existsSync2(packageJsonPath)) {
44
+ return;
45
+ }
46
+ const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
47
+ if (!parsed.name || !parsed.name.startsWith("@dreamboard/") && !parsed.name.startsWith("@dreamboard-games/") || parsed.exports === void 0) {
48
+ return;
49
+ }
50
+ packageInfos.set(parsed.name, {
51
+ rootDir: packageRoot,
52
+ exports: parsed.exports
53
+ });
54
+ };
55
+ for (const workspaceDirName of ["packages", "apps"]) {
56
+ const workspaceRoot = path2.join(repoRoot, workspaceDirName);
57
+ if (!existsSync2(workspaceRoot)) {
58
+ continue;
59
+ }
60
+ for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {
61
+ if (!entry.isDirectory()) {
62
+ continue;
63
+ }
64
+ addPackageInfo(path2.join(workspaceRoot, entry.name));
65
+ }
66
+ }
67
+ for (const nodeModulesRoot of [
68
+ path2.join(repoRoot, "node_modules"),
69
+ path2.join(repoRoot, "apps", "dreamboard-cli", "node_modules")
70
+ ]) {
71
+ for (const scopeName of ["@dreamboard", "@dreamboard-games"]) {
72
+ const scopeRoot = path2.join(nodeModulesRoot, scopeName);
73
+ if (!existsSync2(scopeRoot)) {
74
+ continue;
75
+ }
76
+ for (const entry of readdirSync(scopeRoot, { withFileTypes: true })) {
77
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) {
78
+ continue;
79
+ }
80
+ addPackageInfo(path2.join(scopeRoot, entry.name));
81
+ }
82
+ }
83
+ }
84
+ PACKAGE_INFO_CACHE.set(repoRoot, packageInfos);
85
+ return packageInfos;
86
+ }
87
+ function parseDreamboardPackageSpecifier(specifier) {
88
+ if (!specifier.startsWith("@dreamboard/") && !specifier.startsWith("@dreamboard-games/")) {
89
+ return null;
90
+ }
91
+ const segments = specifier.split("/");
92
+ if (segments.length < 2) {
93
+ return null;
94
+ }
95
+ const packageName = `${segments[0]}/${segments[1]}`;
96
+ const subpath = segments.length === 2 ? "." : `./${segments.slice(2).join("/")}`;
97
+ return { packageName, subpath };
98
+ }
99
+ function resolveSourceTarget(exportEntry) {
100
+ if (typeof exportEntry === "string") {
101
+ return exportEntry;
102
+ }
103
+ if (typeof exportEntry === "object" && exportEntry !== null && "dreamboard-source" in exportEntry && typeof exportEntry["dreamboard-source"] === "string") {
104
+ return exportEntry["dreamboard-source"];
105
+ }
106
+ if (typeof exportEntry === "object" && exportEntry !== null && "bun" in exportEntry && typeof exportEntry.bun === "string") {
107
+ return exportEntry.bun;
108
+ }
109
+ if (typeof exportEntry === "object" && exportEntry !== null && "import" in exportEntry && typeof exportEntry.import === "string") {
110
+ return exportEntry.import;
111
+ }
112
+ return null;
113
+ }
114
+ function resolveSourceTargetForSubpath(options) {
115
+ if (typeof options.exportsField !== "object" || options.exportsField === null || Array.isArray(options.exportsField)) {
116
+ return options.subpath === "." ? resolveSourceTarget(options.exportsField) : null;
117
+ }
118
+ const exportsMap = options.exportsField;
119
+ if (options.subpath === ".") {
120
+ return resolveSourceTarget(exportsMap["."]) ?? resolveSourceTarget(exportsMap);
121
+ }
122
+ const exactTarget = resolveSourceTarget(exportsMap[options.subpath]);
123
+ if (exactTarget) {
124
+ return exactTarget;
125
+ }
126
+ const wildcardEntries = Object.entries(exportsMap).filter(([key]) => key.includes("*")).sort(([left], [right]) => right.length - left.length);
127
+ for (const [pattern, exportEntry] of wildcardEntries) {
128
+ const starIndex = pattern.indexOf("*");
129
+ const prefix = pattern.slice(0, starIndex);
130
+ const suffix = pattern.slice(starIndex + 1);
131
+ if (!options.subpath.startsWith(prefix) || !options.subpath.endsWith(suffix)) {
132
+ continue;
133
+ }
134
+ const wildcardValue = options.subpath.slice(
135
+ prefix.length,
136
+ options.subpath.length - suffix.length
137
+ );
138
+ const targetPattern = resolveSourceTarget(exportEntry);
139
+ if (!targetPattern) {
140
+ continue;
141
+ }
142
+ return targetPattern.replace("*", wildcardValue);
143
+ }
144
+ return null;
145
+ }
146
+ function resolveRepoLocalPackageSource(specifier, options) {
147
+ const parsedSpecifier = parseDreamboardPackageSpecifier(specifier);
148
+ if (!parsedSpecifier) {
149
+ return null;
150
+ }
151
+ let repoRoot;
152
+ try {
153
+ repoRoot = normalizeRepoRoot(options);
154
+ } catch {
155
+ return null;
156
+ }
157
+ const packageInfo = readPackageInfos(repoRoot).get(
158
+ parsedSpecifier.packageName
159
+ );
160
+ if (!packageInfo) {
161
+ return null;
162
+ }
163
+ const sourceTarget = resolveSourceTargetForSubpath({
164
+ exportsField: packageInfo.exports,
165
+ subpath: parsedSpecifier.subpath
166
+ });
167
+ if (!sourceTarget) {
168
+ return null;
169
+ }
170
+ return path2.join(packageInfo.rootDir, sourceTarget);
171
+ }
172
+ var cliPackageRequire = createRequire(import.meta.url);
173
+ function resolvableFromDirectory(specifier, directory) {
174
+ try {
175
+ createRequire(path2.join(directory, "noop.js")).resolve(specifier);
176
+ return true;
177
+ } catch {
178
+ return false;
179
+ }
180
+ }
181
+ function resolveCliBundledPackage(specifier) {
182
+ try {
183
+ return cliPackageRequire.resolve(specifier);
184
+ } catch {
185
+ return null;
186
+ }
187
+ }
188
+ function createRepoLocalPackageResolutionPlugin(options) {
189
+ return {
190
+ name: "dreamboard-repo-local-package-resolution",
191
+ setup(build) {
192
+ build.onResolve({ filter: /^@dreamboard(?:-games)?\// }, (args) => {
193
+ const resolvedPath = resolveRepoLocalPackageSource(args.path, options);
194
+ if (resolvedPath) {
195
+ return { path: resolvedPath };
196
+ }
197
+ if (resolvableFromDirectory(args.path, args.resolveDir)) {
198
+ return null;
199
+ }
200
+ const bundledPath = resolveCliBundledPackage(args.path);
201
+ if (bundledPath) {
202
+ return { path: bundledPath };
203
+ }
204
+ return null;
205
+ });
206
+ }
207
+ };
208
+ }
209
+
210
+ export {
211
+ resolveCliRepoRoot,
212
+ createRepoLocalPackageResolutionPlugin
213
+ };
214
+ //# sourceMappingURL=chunk-QBAF7EYR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/repo-root.ts","../../src/utils/repo-local-package-resolution.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction isRepoRoot(candidate: string): boolean {\n return (\n existsSync(path.join(candidate, \"pnpm-workspace.yaml\")) &&\n existsSync(path.join(candidate, \"apps\", \"dreamboard-cli\", \"package.json\"))\n );\n}\n\nexport function resolveCliRepoRoot(importMetaUrl: string = import.meta.url) {\n let current = path.dirname(fileURLToPath(importMetaUrl));\n\n while (true) {\n if (isRepoRoot(current)) {\n return current;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n throw new Error(\n `Could not resolve Dreamboard CLI repo root from ${importMetaUrl}.`,\n );\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport type { Plugin } from \"esbuild\";\nimport { resolveCliRepoRoot } from \"./repo-root.js\";\n\ntype RepoLocalPackageInfo = {\n rootDir: string;\n exports: unknown;\n};\n\ntype RepoLocalPackageResolutionOptions = {\n repoRoot?: string;\n};\n\nconst PACKAGE_INFO_CACHE = new Map<string, Map<string, RepoLocalPackageInfo>>();\n\nfunction normalizeRepoRoot(\n options?: RepoLocalPackageResolutionOptions,\n): string {\n return options?.repoRoot ?? resolveCliRepoRoot(import.meta.url);\n}\n\nfunction readPackageInfos(repoRoot: string): Map<string, RepoLocalPackageInfo> {\n const cached = PACKAGE_INFO_CACHE.get(repoRoot);\n if (cached) {\n return cached;\n }\n\n const packageInfos = new Map<string, RepoLocalPackageInfo>();\n const addPackageInfo = (packageRoot: string): void => {\n const packageJsonPath = path.join(packageRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n return;\n }\n\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n name?: string;\n exports?: unknown;\n };\n if (\n !parsed.name ||\n (!parsed.name.startsWith(\"@dreamboard/\") &&\n !parsed.name.startsWith(\"@dreamboard-games/\")) ||\n parsed.exports === undefined\n ) {\n return;\n }\n\n packageInfos.set(parsed.name, {\n rootDir: packageRoot,\n exports: parsed.exports,\n });\n };\n\n for (const workspaceDirName of [\"packages\", \"apps\"]) {\n const workspaceRoot = path.join(repoRoot, workspaceDirName);\n if (!existsSync(workspaceRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue;\n }\n addPackageInfo(path.join(workspaceRoot, entry.name));\n }\n }\n\n for (const nodeModulesRoot of [\n path.join(repoRoot, \"node_modules\"),\n path.join(repoRoot, \"apps\", \"dreamboard-cli\", \"node_modules\"),\n ]) {\n for (const scopeName of [\"@dreamboard\", \"@dreamboard-games\"]) {\n const scopeRoot = path.join(nodeModulesRoot, scopeName);\n if (!existsSync(scopeRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(scopeRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) {\n continue;\n }\n addPackageInfo(path.join(scopeRoot, entry.name));\n }\n }\n }\n\n PACKAGE_INFO_CACHE.set(repoRoot, packageInfos);\n return packageInfos;\n}\n\nfunction parseDreamboardPackageSpecifier(specifier: string): {\n packageName: string;\n subpath: string;\n} | null {\n if (\n !specifier.startsWith(\"@dreamboard/\") &&\n !specifier.startsWith(\"@dreamboard-games/\")\n ) {\n return null;\n }\n\n const segments = specifier.split(\"/\");\n if (segments.length < 2) {\n return null;\n }\n\n const packageName = `${segments[0]}/${segments[1]}`;\n const subpath =\n segments.length === 2 ? \".\" : `./${segments.slice(2).join(\"/\")}`;\n return { packageName, subpath };\n}\n\nfunction resolveSourceTarget(exportEntry: unknown): string | null {\n if (typeof exportEntry === \"string\") {\n return exportEntry;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"dreamboard-source\" in exportEntry &&\n typeof (exportEntry as { \"dreamboard-source\"?: unknown })[\n \"dreamboard-source\"\n ] === \"string\"\n ) {\n return (exportEntry as { \"dreamboard-source\": string })[\n \"dreamboard-source\"\n ];\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"bun\" in exportEntry &&\n typeof (exportEntry as { bun?: unknown }).bun === \"string\"\n ) {\n return (exportEntry as { bun: string }).bun;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"import\" in exportEntry &&\n typeof (exportEntry as { import?: unknown }).import === \"string\"\n ) {\n return (exportEntry as { import: string }).import;\n }\n return null;\n}\n\nfunction resolveSourceTargetForSubpath(options: {\n exportsField: unknown;\n subpath: string;\n}): string | null {\n if (\n typeof options.exportsField !== \"object\" ||\n options.exportsField === null ||\n Array.isArray(options.exportsField)\n ) {\n return options.subpath === \".\"\n ? resolveSourceTarget(options.exportsField)\n : null;\n }\n\n const exportsMap = options.exportsField as Record<string, unknown>;\n if (options.subpath === \".\") {\n return (\n resolveSourceTarget(exportsMap[\".\"]) ?? resolveSourceTarget(exportsMap)\n );\n }\n const exactTarget = resolveSourceTarget(exportsMap[options.subpath]);\n if (exactTarget) {\n return exactTarget;\n }\n\n const wildcardEntries = Object.entries(exportsMap)\n .filter(([key]) => key.includes(\"*\"))\n .sort(([left], [right]) => right.length - left.length);\n for (const [pattern, exportEntry] of wildcardEntries) {\n const starIndex = pattern.indexOf(\"*\");\n const prefix = pattern.slice(0, starIndex);\n const suffix = pattern.slice(starIndex + 1);\n if (\n !options.subpath.startsWith(prefix) ||\n !options.subpath.endsWith(suffix)\n ) {\n continue;\n }\n\n const wildcardValue = options.subpath.slice(\n prefix.length,\n options.subpath.length - suffix.length,\n );\n const targetPattern = resolveSourceTarget(exportEntry);\n if (!targetPattern) {\n continue;\n }\n return targetPattern.replace(\"*\", wildcardValue);\n }\n\n return null;\n}\n\nexport function resolveRepoLocalPackageSource(\n specifier: string,\n options?: RepoLocalPackageResolutionOptions,\n): string | null {\n const parsedSpecifier = parseDreamboardPackageSpecifier(specifier);\n if (!parsedSpecifier) {\n return null;\n }\n\n let repoRoot: string;\n try {\n repoRoot = normalizeRepoRoot(options);\n } catch {\n return null;\n }\n\n const packageInfo = readPackageInfos(repoRoot).get(\n parsedSpecifier.packageName,\n );\n if (!packageInfo) {\n return null;\n }\n\n const sourceTarget = resolveSourceTargetForSubpath({\n exportsField: packageInfo.exports,\n subpath: parsedSpecifier.subpath,\n });\n if (!sourceTarget) {\n return null;\n }\n\n return path.join(packageInfo.rootDir, sourceTarget);\n}\n\nconst cliPackageRequire = createRequire(import.meta.url);\n\nfunction resolvableFromDirectory(\n specifier: string,\n directory: string,\n): boolean {\n try {\n createRequire(path.join(directory, \"noop.js\")).resolve(specifier);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a `@dreamboard-games/*` specifier against the CLI package's own\n * dependency tree. This keeps manifest evaluation working in workspaces that\n * have not installed their dependencies yet (for example right after\n * `dreamboard clone`), where the installed CLI's pinned SDK is the only\n * available copy.\n */\nfunction resolveCliBundledPackage(specifier: string): string | null {\n try {\n return cliPackageRequire.resolve(specifier);\n } catch {\n return null;\n }\n}\n\nexport function createRepoLocalPackageResolutionPlugin(\n options?: RepoLocalPackageResolutionOptions,\n): Plugin {\n return {\n name: \"dreamboard-repo-local-package-resolution\",\n setup(build) {\n build.onResolve({ filter: /^@dreamboard(?:-games)?\\// }, (args) => {\n const resolvedPath = resolveRepoLocalPackageSource(args.path, options);\n if (resolvedPath) {\n return { path: resolvedPath };\n }\n // Prefer the workspace's own installed copy when present; returning\n // null lets esbuild perform its normal node_modules resolution.\n if (resolvableFromDirectory(args.path, args.resolveDir)) {\n return null;\n }\n const bundledPath = resolveCliBundledPackage(args.path);\n if (bundledPath) {\n return { path: bundledPath };\n }\n return null;\n });\n },\n };\n}\n"],"mappings":"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","names":["existsSync","path","path","existsSync"]}
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ensureProjectSdk,
4
+ loadRemoteProjectIdentity
5
+ } from "./chunk-KDBSVLCF.mjs";
6
+ import {
7
+ updateProjectState
8
+ } from "./chunk-776W3UGV.mjs";
9
+
10
+ // src/services/project/remote-project.ts
11
+ async function resolveRemoteProject(options) {
12
+ const identity = await loadRemoteProjectIdentity();
13
+ const project = await ensureProjectSdk({
14
+ projectId: options.projectConfig.projectId,
15
+ slug: options.projectConfig.slug,
16
+ updateAlias: options.updateAlias
17
+ });
18
+ const nextProjectConfig = {
19
+ ...options.projectConfig,
20
+ slug: project.slug,
21
+ deploymentId: identity.deploymentId,
22
+ ownerScopeId: identity.ownerScopeId,
23
+ bindingKey: identity.bindingKey,
24
+ remoteHeadDigest: project.head?.revisionDigest,
25
+ apiBaseUrl: options.config.apiBaseUrl,
26
+ webBaseUrl: options.config.webBaseUrl
27
+ };
28
+ await updateProjectState(options.projectRoot, nextProjectConfig);
29
+ return {
30
+ identity,
31
+ project,
32
+ projectConfig: nextProjectConfig
33
+ };
34
+ }
35
+
36
+ export {
37
+ resolveRemoteProject
38
+ };
39
+ //# sourceMappingURL=chunk-QZH6IEZS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/project/remote-project.ts"],"sourcesContent":["import type { Project } from \"@dreamboard-games/api-client\";\nimport { updateProjectState } from \"../../config/project-config.js\";\nimport type { ProjectConfig, ResolvedConfig } from \"../../types.js\";\nimport {\n ensureProjectSdk,\n loadRemoteProjectIdentity,\n type RemoteProjectIdentity,\n} from \"../api/index.js\";\n\nexport type ResolvedRemoteProject = {\n identity: RemoteProjectIdentity;\n project: Project;\n projectConfig: ProjectConfig;\n};\n\nexport async function resolveRemoteProject(options: {\n projectRoot: string;\n projectConfig: ProjectConfig;\n config: Pick<ResolvedConfig, \"apiBaseUrl\" | \"webBaseUrl\">;\n updateAlias?: boolean;\n}): Promise<ResolvedRemoteProject> {\n const identity = await loadRemoteProjectIdentity();\n const project = await ensureProjectSdk({\n projectId: options.projectConfig.projectId,\n slug: options.projectConfig.slug,\n updateAlias: options.updateAlias,\n });\n const nextProjectConfig: ProjectConfig = {\n ...options.projectConfig,\n slug: project.slug,\n deploymentId: identity.deploymentId,\n ownerScopeId: identity.ownerScopeId,\n bindingKey: identity.bindingKey,\n remoteHeadDigest: project.head?.revisionDigest,\n apiBaseUrl: options.config.apiBaseUrl,\n webBaseUrl: options.config.webBaseUrl,\n };\n\n await updateProjectState(options.projectRoot, nextProjectConfig);\n\n return {\n identity,\n project,\n projectConfig: nextProjectConfig,\n };\n}\n"],"mappings":";;;;;;;;;;AAeA,eAAsB,qBAAqB,SAKR;AACjC,QAAM,WAAW,MAAM,0BAA0B;AACjD,QAAM,UAAU,MAAM,iBAAiB;AAAA,IACrC,WAAW,QAAQ,cAAc;AAAA,IACjC,MAAM,QAAQ,cAAc;AAAA,IAC5B,aAAa,QAAQ;AAAA,EACvB,CAAC;AACD,QAAM,oBAAmC;AAAA,IACvC,GAAG,QAAQ;AAAA,IACX,MAAM,QAAQ;AAAA,IACd,cAAc,SAAS;AAAA,IACvB,cAAc,SAAS;AAAA,IACvB,YAAY,SAAS;AAAA,IACrB,kBAAkB,QAAQ,MAAM;AAAA,IAChC,YAAY,QAAQ,OAAO;AAAA,IAC3B,YAAY,QAAQ,OAAO;AAAA,EAC7B;AAEA,QAAM,mBAAmB,QAAQ,aAAa,iBAAiB;AAE/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB;AACF;","names":[]}
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/utils/atomic-file.ts
4
+ import { constants as fsConstants, promises as fs } from "fs";
5
+ import path from "path";
6
+ import crypto from "crypto";
7
+ async function atomicWriteFile(targetPath, contents, options = {}) {
8
+ if (contents.length === 0) {
9
+ throw new Error(
10
+ `Refusing to atomicWriteFile an empty payload to ${targetPath}`
11
+ );
12
+ }
13
+ const mode = options.mode ?? 384;
14
+ const shouldFsync = options.fsync ?? true;
15
+ const dir = path.dirname(targetPath);
16
+ await fs.mkdir(dir, { recursive: true });
17
+ const suffix = crypto.randomBytes(6).toString("hex");
18
+ const tmpPath = `${targetPath}.tmp-${process.pid}-${suffix}`;
19
+ const fh = await fs.open(
20
+ tmpPath,
21
+ fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,
22
+ mode
23
+ );
24
+ try {
25
+ await fh.writeFile(contents, "utf8");
26
+ try {
27
+ await fh.chmod(mode);
28
+ } catch {
29
+ }
30
+ if (shouldFsync) {
31
+ try {
32
+ await fh.sync();
33
+ } catch {
34
+ }
35
+ }
36
+ } finally {
37
+ await fh.close();
38
+ }
39
+ try {
40
+ await fs.rename(tmpPath, targetPath);
41
+ } catch (err) {
42
+ await fs.unlink(tmpPath).catch(() => void 0);
43
+ throw err;
44
+ }
45
+ }
46
+ async function withFileLock(lockPath, fn, options = {}) {
47
+ const retries = options.retries ?? 100;
48
+ const minDelayMs = options.minDelayMs ?? 20;
49
+ const maxDelayMs = options.maxDelayMs ?? 200;
50
+ const staleMs = options.staleMs ?? 3e4;
51
+ await fs.mkdir(path.dirname(lockPath), { recursive: true });
52
+ let attempt = 0;
53
+ let acquired = false;
54
+ while (!acquired) {
55
+ try {
56
+ const fh = await fs.open(
57
+ lockPath,
58
+ fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,
59
+ 384
60
+ );
61
+ await fh.writeFile(`${process.pid}
62
+ `, "utf8");
63
+ await fh.close();
64
+ acquired = true;
65
+ break;
66
+ } catch (err) {
67
+ const code = err.code;
68
+ if (code !== "EEXIST") {
69
+ throw err;
70
+ }
71
+ }
72
+ let stat = null;
73
+ try {
74
+ stat = await fs.stat(lockPath);
75
+ } catch {
76
+ continue;
77
+ }
78
+ if (stat !== null) {
79
+ const ageMs = Date.now() - stat.mtimeMs;
80
+ if (ageMs > staleMs) {
81
+ await fs.unlink(lockPath).catch(() => void 0);
82
+ continue;
83
+ }
84
+ }
85
+ attempt += 1;
86
+ if (attempt >= retries) {
87
+ throw new Error(
88
+ `Timed out acquiring file lock at ${lockPath} after ${retries} attempts.`
89
+ );
90
+ }
91
+ const jitter = Math.floor(
92
+ Math.random() * Math.max(1, maxDelayMs - minDelayMs)
93
+ );
94
+ await new Promise((resolve) => setTimeout(resolve, minDelayMs + jitter));
95
+ }
96
+ try {
97
+ return await fn();
98
+ } finally {
99
+ await fs.unlink(lockPath).catch(() => void 0);
100
+ }
101
+ }
102
+
103
+ export {
104
+ atomicWriteFile,
105
+ withFileLock
106
+ };
107
+ //# sourceMappingURL=chunk-TAEQKBJB.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/atomic-file.ts"],"sourcesContent":["/**\n * Primitives for safely mutating local state files owned by the CLI.\n *\n * Two guarantees:\n * - Writes are atomic-ish: we stage the payload in a sibling temp file with\n * the target permissions, fsync the contents, then `rename` over the target.\n * On POSIX `rename` within the same directory is atomic; on Windows it is\n * atomic within the same volume which is always the case for files we write\n * inside `~/.dreamboard`.\n * - We refuse to clobber a file with an empty payload. The original bug that\n * wiped refresh tokens on a failing `sync`/`compile` hinged on `undefined`\n * JSON values being persisted and reloaded as `{}`. Forbidding empty\n * writes here removes that entire failure mode at the primitive level.\n *\n * Additionally, `withFileLock` provides a cross-process advisory lock built on\n * `O_CREAT | O_EXCL` so that parallel CLI invocations (e.g. `dreamboard sync`\n * running while `dreamboard compile` is in flight) serialize around mutations\n * of the same credential state.\n */\n\nimport { constants as fsConstants, promises as fs, type Stats } from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\n\nexport type AtomicWriteOptions = {\n /** File mode applied to the written file (default: 0o600). */\n mode?: number;\n /** Call `fsync` on the temp file before renaming. Default: true. */\n fsync?: boolean;\n};\n\nexport async function atomicWriteFile(\n targetPath: string,\n contents: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n if (contents.length === 0) {\n throw new Error(\n `Refusing to atomicWriteFile an empty payload to ${targetPath}`,\n );\n }\n const mode = options.mode ?? 0o600;\n const shouldFsync = options.fsync ?? true;\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n\n const suffix = crypto.randomBytes(6).toString(\"hex\");\n const tmpPath = `${targetPath}.tmp-${process.pid}-${suffix}`;\n\n const fh = await fs.open(\n tmpPath,\n fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,\n mode,\n );\n try {\n await fh.writeFile(contents, \"utf8\");\n try {\n await fh.chmod(mode);\n } catch {\n // Some filesystems (e.g. network volumes, Windows) refuse chmod.\n // Ignoring here is safe: the `open` call above already created the\n // file with the requested mode on systems that honor it.\n }\n if (shouldFsync) {\n try {\n await fh.sync();\n } catch {\n // Best-effort. Not all backends (tmpfs on some platforms) support fsync.\n }\n }\n } finally {\n await fh.close();\n }\n\n try {\n await fs.rename(tmpPath, targetPath);\n } catch (err) {\n await fs.unlink(tmpPath).catch(() => undefined);\n throw err;\n }\n}\n\nexport type FileLockOptions = {\n /** Max number of acquisition attempts before giving up. Default: 100. */\n retries?: number;\n /** Minimum backoff between retries in ms. Default: 20. */\n minDelayMs?: number;\n /** Maximum backoff between retries in ms. Default: 200. */\n maxDelayMs?: number;\n /**\n * A lockfile older than this is considered stale and forcibly removed.\n * Guards against crashed processes leaving a permanent lock. Default: 30s.\n */\n staleMs?: number;\n};\n\nexport async function withFileLock<T>(\n lockPath: string,\n fn: () => Promise<T>,\n options: FileLockOptions = {},\n): Promise<T> {\n const retries = options.retries ?? 100;\n const minDelayMs = options.minDelayMs ?? 20;\n const maxDelayMs = options.maxDelayMs ?? 200;\n const staleMs = options.staleMs ?? 30_000;\n\n await fs.mkdir(path.dirname(lockPath), { recursive: true });\n\n let attempt = 0;\n let acquired = false;\n while (!acquired) {\n try {\n const fh = await fs.open(\n lockPath,\n fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,\n 0o600,\n );\n await fh.writeFile(`${process.pid}\\n`, \"utf8\");\n await fh.close();\n acquired = true;\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n throw err;\n }\n }\n\n let stat: Stats | null = null;\n try {\n stat = await fs.stat(lockPath);\n } catch {\n continue;\n }\n if (stat !== null) {\n const ageMs = Date.now() - stat.mtimeMs;\n if (ageMs > staleMs) {\n await fs.unlink(lockPath).catch(() => undefined);\n continue;\n }\n }\n\n attempt += 1;\n if (attempt >= retries) {\n throw new Error(\n `Timed out acquiring file lock at ${lockPath} after ${retries} attempts.`,\n );\n }\n const jitter = Math.floor(\n Math.random() * Math.max(1, maxDelayMs - minDelayMs),\n );\n await new Promise((resolve) => setTimeout(resolve, minDelayMs + jitter));\n }\n\n try {\n return await fn();\n } finally {\n await fs.unlink(lockPath).catch(() => undefined);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MANIFEST_TYPECHECK_CONFIG_FILE
4
+ } from "./chunk-H76MT5UR.mjs";
5
+
6
+ // src/services/project/local-typecheck.ts
7
+ import { spawn } from "child_process";
8
+ import { lstat } from "fs/promises";
9
+ import { createRequire } from "module";
10
+ import path from "path";
11
+ var TYPESCRIPT_BIN_PATH_SEGMENTS = [
12
+ "node_modules",
13
+ "typescript",
14
+ "bin",
15
+ "tsc"
16
+ ];
17
+ var CLI_PACKAGE_TYPESCRIPT_CLI = resolveCliPackageTypescriptCli();
18
+ function resolveCliPackageTypescriptCli() {
19
+ try {
20
+ const require2 = createRequire(import.meta.url);
21
+ return require2.resolve("typescript/bin/tsc");
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+ function getProjectNodeModules(projectRoot) {
27
+ return path.join(projectRoot, "node_modules");
28
+ }
29
+ function getProjectTypescriptCli(projectRoot) {
30
+ return path.join(projectRoot, ...TYPESCRIPT_BIN_PATH_SEGMENTS);
31
+ }
32
+ async function pathExists(targetPath) {
33
+ try {
34
+ await lstat(targetPath);
35
+ return true;
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+ async function ensureTypecheckDependencies(projectRoot) {
41
+ if (await pathExists(getProjectNodeModules(projectRoot))) {
42
+ return null;
43
+ }
44
+ return `Skipping local typecheck: workspace dependencies are not installed at ${getProjectNodeModules(projectRoot)}. Run \`dreamboard sync\` to reconcile workspace dependencies first.`;
45
+ }
46
+ async function resolveTypecheckRunner(projectRoot) {
47
+ const localTypescriptCli = getProjectTypescriptCli(projectRoot);
48
+ if (await pathExists(localTypescriptCli)) {
49
+ return {
50
+ command: process.execPath,
51
+ argsPrefix: [localTypescriptCli]
52
+ };
53
+ }
54
+ if (CLI_PACKAGE_TYPESCRIPT_CLI && await pathExists(CLI_PACKAGE_TYPESCRIPT_CLI)) {
55
+ return {
56
+ command: process.execPath,
57
+ argsPrefix: [CLI_PACKAGE_TYPESCRIPT_CLI]
58
+ };
59
+ }
60
+ const globalTscAvailable = await new Promise((resolve) => {
61
+ const child = spawn("tsc", ["--version"], {
62
+ env: process.env,
63
+ stdio: "ignore"
64
+ });
65
+ child.on("error", () => {
66
+ resolve(false);
67
+ });
68
+ child.on("close", (code) => {
69
+ resolve(code === 0);
70
+ });
71
+ });
72
+ if (!globalTscAvailable) {
73
+ return null;
74
+ }
75
+ return {
76
+ command: "tsc",
77
+ argsPrefix: []
78
+ };
79
+ }
80
+ async function runTypecheckProject(runner, projectRoot, projectPath) {
81
+ return new Promise((resolve, reject) => {
82
+ const child = spawn(
83
+ runner.command,
84
+ [...runner.argsPrefix, "--noEmit", "-p", projectPath],
85
+ {
86
+ cwd: projectRoot,
87
+ env: process.env,
88
+ stdio: ["ignore", "pipe", "pipe"]
89
+ }
90
+ );
91
+ let stdout = "";
92
+ let stderr = "";
93
+ child.stdout.on("data", (chunk) => {
94
+ stdout += chunk.toString();
95
+ });
96
+ child.stderr.on("data", (chunk) => {
97
+ stderr += chunk.toString();
98
+ });
99
+ child.on("error", (error) => {
100
+ reject(new Error(`Failed to start local typecheck. ${error.message}`));
101
+ });
102
+ child.on("close", (code) => {
103
+ const output = [stdout, stderr].filter(Boolean).join("\n").trim();
104
+ resolve({
105
+ success: code === 0,
106
+ output
107
+ });
108
+ });
109
+ });
110
+ }
111
+ async function runLocalTypecheck(projectRoot) {
112
+ const dependencySkipReason = await ensureTypecheckDependencies(projectRoot);
113
+ if (dependencySkipReason) {
114
+ return {
115
+ success: true,
116
+ skipped: true,
117
+ output: dependencySkipReason
118
+ };
119
+ }
120
+ const runner = await resolveTypecheckRunner(projectRoot);
121
+ if (!runner) {
122
+ return {
123
+ success: true,
124
+ skipped: true,
125
+ output: "Skipping local typecheck: TypeScript CLI was not found in workspace dependencies or on PATH."
126
+ };
127
+ }
128
+ const results = await Promise.all(
129
+ [
130
+ MANIFEST_TYPECHECK_CONFIG_FILE,
131
+ "app/tsconfig.json",
132
+ "ui/tsconfig.json"
133
+ ].map(
134
+ (projectPath) => runTypecheckProject(runner, projectRoot, projectPath)
135
+ )
136
+ );
137
+ const firstFailure = results.find((result) => !result.success);
138
+ if (firstFailure) {
139
+ return firstFailure;
140
+ }
141
+ return {
142
+ success: true,
143
+ output: ""
144
+ };
145
+ }
146
+
147
+ export {
148
+ runLocalTypecheck
149
+ };
150
+ //# sourceMappingURL=chunk-UIOLGH4A.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/project/local-typecheck.ts"],"sourcesContent":["import { MANIFEST_TYPECHECK_CONFIG_FILE } from \"../../constants.js\";\nimport { spawn } from \"node:child_process\";\nimport { lstat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\n\nexport type LocalTypecheckResult = {\n success: boolean;\n output: string;\n skipped?: boolean;\n};\n\ntype TypecheckRunner = {\n command: string;\n argsPrefix: string[];\n};\n\nconst TYPESCRIPT_BIN_PATH_SEGMENTS = [\n \"node_modules\",\n \"typescript\",\n \"bin\",\n \"tsc\",\n];\n\n// TypeScript shipped with the CLI package itself; used as a fallback when the\n// user's workspace does not provide its own `typescript` install.\nconst CLI_PACKAGE_TYPESCRIPT_CLI = resolveCliPackageTypescriptCli();\n\nfunction resolveCliPackageTypescriptCli(): string | null {\n try {\n const require = createRequire(import.meta.url);\n return require.resolve(\"typescript/bin/tsc\");\n } catch {\n return null;\n }\n}\n\nfunction getProjectNodeModules(projectRoot: string): string {\n return path.join(projectRoot, \"node_modules\");\n}\n\nfunction getProjectTypescriptCli(projectRoot: string): string {\n return path.join(projectRoot, ...TYPESCRIPT_BIN_PATH_SEGMENTS);\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await lstat(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function ensureTypecheckDependencies(\n projectRoot: string,\n): Promise<string | null> {\n if (await pathExists(getProjectNodeModules(projectRoot))) {\n return null;\n }\n\n return `Skipping local typecheck: workspace dependencies are not installed at ${getProjectNodeModules(projectRoot)}. Run \\`dreamboard sync\\` to reconcile workspace dependencies first.`;\n}\n\nasync function resolveTypecheckRunner(\n projectRoot: string,\n): Promise<TypecheckRunner | null> {\n const localTypescriptCli = getProjectTypescriptCli(projectRoot);\n if (await pathExists(localTypescriptCli)) {\n return {\n command: process.execPath,\n argsPrefix: [localTypescriptCli],\n };\n }\n\n if (\n CLI_PACKAGE_TYPESCRIPT_CLI &&\n (await pathExists(CLI_PACKAGE_TYPESCRIPT_CLI))\n ) {\n return {\n command: process.execPath,\n argsPrefix: [CLI_PACKAGE_TYPESCRIPT_CLI],\n };\n }\n\n const globalTscAvailable = await new Promise<boolean>((resolve) => {\n const child = spawn(\"tsc\", [\"--version\"], {\n env: process.env,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", () => {\n resolve(false);\n });\n child.on(\"close\", (code) => {\n resolve(code === 0);\n });\n });\n\n if (!globalTscAvailable) {\n return null;\n }\n\n return {\n command: \"tsc\",\n argsPrefix: [],\n };\n}\n\nasync function runTypecheckProject(\n runner: TypecheckRunner,\n projectRoot: string,\n projectPath: string,\n): Promise<LocalTypecheckResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\n runner.command,\n [...runner.argsPrefix, \"--noEmit\", \"-p\", projectPath],\n {\n cwd: projectRoot,\n env: process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n },\n );\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n child.on(\"error\", (error) => {\n reject(new Error(`Failed to start local typecheck. ${error.message}`));\n });\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n resolve({\n success: code === 0,\n output,\n });\n });\n });\n}\n\nexport async function runLocalTypecheck(\n projectRoot: string,\n): Promise<LocalTypecheckResult> {\n const dependencySkipReason = await ensureTypecheckDependencies(projectRoot);\n if (dependencySkipReason) {\n return {\n success: true,\n skipped: true,\n output: dependencySkipReason,\n };\n }\n\n const runner = await resolveTypecheckRunner(projectRoot);\n if (!runner) {\n return {\n success: true,\n skipped: true,\n output:\n \"Skipping local typecheck: TypeScript CLI was not found in workspace dependencies or on PATH.\",\n };\n }\n\n // The three projects are independent (no cross-project references), so\n // checking them in parallel roughly halves wall-clock time without changing\n // correctness. The slowest project (typically `ui/tsconfig.json`) bounds the\n // total cost.\n const results = await Promise.all(\n [\n MANIFEST_TYPECHECK_CONFIG_FILE,\n \"app/tsconfig.json\",\n \"ui/tsconfig.json\",\n ].map((projectPath) =>\n runTypecheckProject(runner, projectRoot, projectPath),\n ),\n );\n\n const firstFailure = results.find((result) => !result.success);\n if (firstFailure) {\n return firstFailure;\n }\n\n return {\n success: true,\n output: \"\",\n };\n}\n"],"mappings":"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","names":["require"]}
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createRepoLocalPackageResolutionPlugin,
4
+ resolveCliRepoRoot
5
+ } from "./chunk-QBAF7EYR.mjs";
6
+
7
+ // src/utils/ts-module-loader.ts
8
+ import { mkdtemp, rm, writeFile } from "fs/promises";
9
+ import { tmpdir } from "os";
10
+ import path from "path";
11
+ import { pathToFileURL } from "url";
12
+ import { build } from "esbuild";
13
+ var ESBUILD_EXTERNALS = [
14
+ "playwright",
15
+ "playwright-core",
16
+ "chromium-bidi",
17
+ "electron"
18
+ ];
19
+ function resolveSourceCheckoutBuildContext() {
20
+ try {
21
+ const repoRoot = resolveCliRepoRoot(import.meta.url);
22
+ return {
23
+ nodePaths: [
24
+ path.join(repoRoot, "apps", "dreamboard-cli", "node_modules"),
25
+ path.join(repoRoot, "node_modules")
26
+ ],
27
+ plugins: [createRepoLocalPackageResolutionPlugin({ repoRoot })]
28
+ };
29
+ } catch {
30
+ return {
31
+ nodePaths: [path.join(process.cwd(), "node_modules")],
32
+ plugins: []
33
+ };
34
+ }
35
+ }
36
+ async function bundleTypeScriptModuleText(entryPath, options = {}) {
37
+ const sourceCheckoutContext = resolveSourceCheckoutBuildContext();
38
+ const result = await build({
39
+ entryPoints: [entryPath],
40
+ bundle: true,
41
+ format: "esm",
42
+ platform: "node",
43
+ target: "node24",
44
+ sourcemap: "inline",
45
+ external: [...ESBUILD_EXTERNALS, ...options.external ?? []],
46
+ nodePaths: sourceCheckoutContext.nodePaths,
47
+ plugins: sourceCheckoutContext.plugins,
48
+ write: false
49
+ });
50
+ const output = result.outputFiles?.[0];
51
+ if (!output) {
52
+ throw new Error(`Failed to bundle TypeScript module '${entryPath}'.`);
53
+ }
54
+ return output.text;
55
+ }
56
+ async function importTypeScriptModule(entryPath) {
57
+ const tempDir = await mkdtemp(path.join(tmpdir(), "dreamboard-ts-module-"));
58
+ const outfile = path.join(
59
+ tempDir,
60
+ `${path.basename(entryPath).replace(/\.[^.]+$/u, "")}.mjs`
61
+ );
62
+ try {
63
+ const bundledText = await bundleTypeScriptModuleText(entryPath);
64
+ await writeFile(outfile, bundledText);
65
+ return await import(pathToFileURL(outfile).href);
66
+ } finally {
67
+ await rm(tempDir, { recursive: true, force: true });
68
+ }
69
+ }
70
+
71
+ export {
72
+ bundleTypeScriptModuleText,
73
+ importTypeScriptModule
74
+ };
75
+ //# sourceMappingURL=chunk-XKCJBIRY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/ts-module-loader.ts"],"sourcesContent":["import { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { build } from \"esbuild\";\nimport { resolveCliRepoRoot } from \"./repo-root.js\";\nimport { createRepoLocalPackageResolutionPlugin } from \"./repo-local-package-resolution.js\";\n\nconst ESBUILD_EXTERNALS = [\n \"playwright\",\n \"playwright-core\",\n \"chromium-bidi\",\n \"electron\",\n];\n\nfunction resolveSourceCheckoutBuildContext(): {\n nodePaths: string[];\n plugins: ReturnType<typeof createRepoLocalPackageResolutionPlugin>[];\n} {\n try {\n const repoRoot = resolveCliRepoRoot(import.meta.url);\n return {\n nodePaths: [\n path.join(repoRoot, \"apps\", \"dreamboard-cli\", \"node_modules\"),\n path.join(repoRoot, \"node_modules\"),\n ],\n plugins: [createRepoLocalPackageResolutionPlugin({ repoRoot })],\n };\n } catch {\n return {\n nodePaths: [path.join(process.cwd(), \"node_modules\")],\n plugins: [],\n };\n }\n}\n\nexport async function bundleTypeScriptModuleText(\n entryPath: string,\n options: { external?: readonly string[] } = {},\n): Promise<string> {\n const sourceCheckoutContext = resolveSourceCheckoutBuildContext();\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node24\",\n sourcemap: \"inline\",\n external: [...ESBUILD_EXTERNALS, ...(options.external ?? [])],\n nodePaths: sourceCheckoutContext.nodePaths,\n plugins: sourceCheckoutContext.plugins,\n write: false,\n });\n\n const output = result.outputFiles?.[0];\n if (!output) {\n throw new Error(`Failed to bundle TypeScript module '${entryPath}'.`);\n }\n return output.text;\n}\n\nexport async function importTypeScriptModule<T>(entryPath: string): Promise<T> {\n const tempDir = await mkdtemp(path.join(tmpdir(), \"dreamboard-ts-module-\"));\n const outfile = path.join(\n tempDir,\n `${path.basename(entryPath).replace(/\\.[^.]+$/u, \"\")}.mjs`,\n );\n\n try {\n const bundledText = await bundleTypeScriptModuleText(entryPath);\n await writeFile(outfile, bundledText);\n\n return (await import(pathToFileURL(outfile).href)) as T;\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n}\n"],"mappings":";;;;;;;AAAA,SAAS,SAAS,IAAI,iBAAiB;AACvC,SAAS,cAAc;AACvB,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AAItB,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,oCAGP;AACA,MAAI;AACF,UAAM,WAAW,mBAAmB,YAAY,GAAG;AACnD,WAAO;AAAA,MACL,WAAW;AAAA,QACT,KAAK,KAAK,UAAU,QAAQ,kBAAkB,cAAc;AAAA,QAC5D,KAAK,KAAK,UAAU,cAAc;AAAA,MACpC;AAAA,MACA,SAAS,CAAC,uCAAuC,EAAE,SAAS,CAAC,CAAC;AAAA,IAChE;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,WAAW,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,cAAc,CAAC;AAAA,MACpD,SAAS,CAAC;AAAA,IACZ;AAAA,EACF;AACF;AAEA,eAAsB,2BACpB,WACA,UAA4C,CAAC,GAC5B;AACjB,QAAM,wBAAwB,kCAAkC;AAChE,QAAM,SAAS,MAAM,MAAM;AAAA,IACzB,aAAa,CAAC,SAAS;AAAA,IACvB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU,CAAC,GAAG,mBAAmB,GAAI,QAAQ,YAAY,CAAC,CAAE;AAAA,IAC5D,WAAW,sBAAsB;AAAA,IACjC,SAAS,sBAAsB;AAAA,IAC/B,OAAO;AAAA,EACT,CAAC;AAED,QAAM,SAAS,OAAO,cAAc,CAAC;AACrC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,uCAAuC,SAAS,IAAI;AAAA,EACtE;AACA,SAAO,OAAO;AAChB;AAEA,eAAsB,uBAA0B,WAA+B;AAC7E,QAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,OAAO,GAAG,uBAAuB,CAAC;AAC1E,QAAM,UAAU,KAAK;AAAA,IACnB;AAAA,IACA,GAAG,KAAK,SAAS,SAAS,EAAE,QAAQ,aAAa,EAAE,CAAC;AAAA,EACtD;AAEA,MAAI;AACF,UAAM,cAAc,MAAM,2BAA2B,SAAS;AAC9D,UAAM,UAAU,SAAS,WAAW;AAEpC,WAAQ,MAAM,OAAO,cAAc,OAAO,EAAE;AAAA,EAC9C,UAAE;AACA,UAAM,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACpD;AACF;","names":[]}