@dreamboard-games/cli 0.1.30-alpha.0 → 0.1.30-alpha.2
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.
- package/README.md +179 -22
- package/dist/{chunk-TSJVWTJO.js → chunk-N7XPNNUI.js} +14 -12
- package/dist/chunk-N7XPNNUI.js.map +1 -0
- package/dist/chunk-SEGVTWSK.js +44 -0
- package/dist/{chunk-3XNJT3RK.js → chunk-TAQKH67O.js} +21279 -35845
- package/dist/chunk-TAQKH67O.js.map +1 -0
- package/dist/{global-config-UKSWNDTX.js → global-config-S4ZIPECE.js} +3 -3
- package/dist/index.js +955 -230
- package/dist/index.js.map +1 -1
- package/dist/internal.js +3 -4
- package/dist/{agent-verifier/keychain-backend-TNOPQV3Z.mjs → keychain-backend-HDF4TZDL.js} +2 -1
- package/dist/{agent-verifier/prompt-3BAINGAQ.mjs → prompt-NDV3AE5L.js} +2 -1
- package/package.json +6 -6
- package/skills/dreamboard/references/building-your-first-game.md +510 -0
- package/skills/dreamboard/references/cli.md +104 -0
- package/skills/dreamboard/references/game-interface.md +548 -0
- package/skills/dreamboard/references/manifest-authoring.md +597 -0
- package/skills/dreamboard/references/quickstart.md +66 -0
- package/skills/dreamboard/references/reducer.md +864 -0
- package/skills/dreamboard/references/rule-authoring.md +147 -0
- package/skills/dreamboard/references/testing.md +249 -0
- package/skills/dreamboard/scripts/events-extract.mjs +218 -0
- package/dist/agent-verifier/agent-workspace-verifier.mjs +0 -227
- package/dist/agent-verifier/chunk-2E5P5NWG.mjs +0 -835
- package/dist/agent-verifier/chunk-2GBBP27W.mjs +0 -301
- package/dist/agent-verifier/chunk-2NZNKIND.mjs +0 -166
- package/dist/agent-verifier/chunk-2QMNAVV4.mjs +0 -14522
- package/dist/agent-verifier/chunk-2SZHMP6F.mjs +0 -264
- package/dist/agent-verifier/chunk-54TAYXUD.mjs +0 -12
- package/dist/agent-verifier/chunk-6A5HRJMQ.mjs +0 -3174
- package/dist/agent-verifier/chunk-6UUJEYDV.mjs +0 -213
- package/dist/agent-verifier/chunk-7653FPGJ.mjs +0 -381
- package/dist/agent-verifier/chunk-BVVNBJM4.mjs +0 -221
- package/dist/agent-verifier/chunk-CEDUHGNH.mjs +0 -74
- package/dist/agent-verifier/chunk-CEQ2VJWN.mjs +0 -149
- package/dist/agent-verifier/chunk-CFU5EWIC.mjs +0 -69
- package/dist/agent-verifier/chunk-DTMJCPS4.mjs +0 -730
- package/dist/agent-verifier/chunk-EIQWDQWJ.mjs +0 -186
- package/dist/agent-verifier/chunk-EOQIV6PS.mjs +0 -649
- package/dist/agent-verifier/chunk-HBNDKQT5.mjs +0 -8381
- package/dist/agent-verifier/chunk-HJFQDSTU.mjs +0 -225
- package/dist/agent-verifier/chunk-LI3ZR3BI.mjs +0 -41
- package/dist/agent-verifier/chunk-LM3OZLZG.mjs +0 -48
- package/dist/agent-verifier/chunk-MINCYHXN.mjs +0 -106
- package/dist/agent-verifier/chunk-MRCUP5SW.mjs +0 -128
- package/dist/agent-verifier/chunk-PM3SVG6R.mjs +0 -38
- package/dist/agent-verifier/chunk-RBDDIIPM.mjs +0 -19
- package/dist/agent-verifier/chunk-RJBLBYHX.mjs +0 -1681
- package/dist/agent-verifier/chunk-SHUMAVAP.mjs +0 -59
- package/dist/agent-verifier/chunk-SYPLYRGB.mjs +0 -2812
- package/dist/agent-verifier/chunk-U6OJN7XS.mjs +0 -8092
- package/dist/agent-verifier/chunk-VYJTHSYR.mjs +0 -44
- package/dist/agent-verifier/chunk-XYDL7GY6.mjs +0 -10
- package/dist/agent-verifier/compile-WNCQQVOF.mjs +0 -313
- package/dist/agent-verifier/global-config-WX3ZZIVU.mjs +0 -17
- package/dist/agent-verifier/local-files-MTPLP62S.mjs +0 -46
- package/dist/agent-verifier/local-typecheck-QFYYAZOK.mjs +0 -9
- package/dist/agent-verifier/materialize-workspace-EWGZIVOY.mjs +0 -90
- package/dist/agent-verifier/project-state-7GR6BQTQ.mjs +0 -32
- package/dist/agent-verifier/reducer-bundle-preflight-C73LEXI2.mjs +0 -23
- package/dist/agent-verifier/reducer-contract-preflight-22X7DSZW.mjs +0 -10
- package/dist/agent-verifier/reducer-native-test-harness-GMWBUISX.mjs +0 -53
- package/dist/agent-verifier/static-scaffold-4YEQME5N.mjs +0 -28
- package/dist/agent-verifier/sync-LOQAH4RC.mjs +0 -594
- package/dist/agent-verifier/test-YOJERVHN.mjs +0 -356
- package/dist/agent-verifier/testing-5K2BJYF2.mjs +0 -674
- package/dist/agent-verifier/workspace-codegen-JDZJRSDV.mjs +0 -11
- package/dist/agent-verifier/workspace-dependencies-HZ6VVS4G.mjs +0 -14
- package/dist/chunk-2H7UOFLK.js +0 -11
- package/dist/chunk-3XNJT3RK.js.map +0 -1
- package/dist/chunk-7FOO4AJI.js +0 -50
- package/dist/chunk-7FOO4AJI.js.map +0 -1
- package/dist/chunk-TSJVWTJO.js.map +0 -1
- package/dist/internal.d.ts +0 -311
- package/dist/keychain-backend-JHTXAKWC.js +0 -135
- package/dist/prompt-GMZABCJC.js +0 -756
- package/dist/runtime-packages/ui-host-runtime/src/actor-principal.ts +0 -71
- package/dist/runtime-packages/ui-host-runtime/src/browser-interaction.ts +0 -139
- package/dist/runtime-packages/ui-host-runtime/src/components/host-controls.tsx +0 -374
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback-toaster.tsx +0 -266
- package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback.tsx +0 -212
- package/dist/runtime-packages/ui-host-runtime/src/components/host-primitives.tsx +0 -271
- package/dist/runtime-packages/ui-host-runtime/src/components/host-session-metadata.tsx +0 -135
- package/dist/runtime-packages/ui-host-runtime/src/components/index.ts +0 -5
- package/dist/runtime-packages/ui-host-runtime/src/components/perf-overlay.tsx +0 -194
- package/dist/runtime-packages/ui-host-runtime/src/gameplay-authority-transport.ts +0 -626
- package/dist/runtime-packages/ui-host-runtime/src/host-controls.tsx +0 -1
- package/dist/runtime-packages/ui-host-runtime/src/host-feedback.tsx +0 -1
- package/dist/runtime-packages/ui-host-runtime/src/host-session-transport.ts +0 -294
- package/dist/runtime-packages/ui-host-runtime/src/index.ts +0 -3
- package/dist/runtime-packages/ui-host-runtime/src/logger.ts +0 -11
- package/dist/runtime-packages/ui-host-runtime/src/perf.ts +0 -324
- package/dist/runtime-packages/ui-host-runtime/src/plugin-bridge.ts +0 -195
- package/dist/runtime-packages/ui-host-runtime/src/plugin-health-check.ts +0 -138
- package/dist/runtime-packages/ui-host-runtime/src/plugin-messages.ts +0 -159
- package/dist/runtime-packages/ui-host-runtime/src/plugin-session-gateway.ts +0 -551
- package/dist/runtime-packages/ui-host-runtime/src/runtime/index.ts +0 -13
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/projection-to-snapshot.ts +0 -122
- package/dist/runtime-packages/ui-host-runtime/src/screenshot/static-store-api.ts +0 -26
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress-controller.ts +0 -583
- package/dist/runtime-packages/ui-host-runtime/src/session-ingress.ts +0 -219
- package/dist/runtime-packages/ui-host-runtime/src/session-live-runtime.ts +0 -117
- package/dist/runtime-packages/ui-host-runtime/src/session-model.ts +0 -431
- package/dist/runtime-packages/ui-host-runtime/src/session-projection.ts +0 -211
- package/dist/runtime-packages/ui-host-runtime/src/session-recovery.ts +0 -80
- package/dist/runtime-packages/ui-host-runtime/src/session-state-reducer.ts +0 -1034
- package/dist/runtime-packages/ui-host-runtime/src/sse-manager.ts +0 -416
- package/dist/runtime-packages/ui-host-runtime/src/unified-session-store.ts +0 -184
- package/dist/testing-KLSV6CPJ.js +0 -674
- package/dist/testing-KLSV6CPJ.js.map +0 -1
- /package/dist/{chunk-2H7UOFLK.js.map → chunk-SEGVTWSK.js.map} +0 -0
- /package/dist/{global-config-UKSWNDTX.js.map → global-config-S4ZIPECE.js.map} +0 -0
- /package/dist/{keychain-backend-JHTXAKWC.js.map → keychain-backend-HDF4TZDL.js.map} +0 -0
- /package/dist/{prompt-GMZABCJC.js.map → prompt-NDV3AE5L.js.map} +0 -0
|
@@ -1,213 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
FRAMEWORK_PNPM_OVERRIDES
|
|
4
|
-
} from "./chunk-RBDDIIPM.mjs";
|
|
5
|
-
import {
|
|
6
|
-
DEFAULT_WEB_BASE_URL
|
|
7
|
-
} from "./chunk-SHUMAVAP.mjs";
|
|
8
|
-
|
|
9
|
-
// src/services/project/workspace-dependencies.ts
|
|
10
|
-
import crypto from "crypto";
|
|
11
|
-
import { spawn } from "child_process";
|
|
12
|
-
import "events";
|
|
13
|
-
import { existsSync } from "fs";
|
|
14
|
-
import { mkdir, lstat, readFile, rm, writeFile } from "fs/promises";
|
|
15
|
-
import path from "path";
|
|
16
|
-
import { fileURLToPath } from "url";
|
|
17
|
-
|
|
18
|
-
// src/services/project/dependency-tooling-messages.ts
|
|
19
|
-
var DEPENDENCY_SETUP_DOCS_PATH = "/docs/reference/dependency-setup";
|
|
20
|
-
var DEPENDENCY_SETUP_DOCS_URL = `${DEFAULT_WEB_BASE_URL}${DEPENDENCY_SETUP_DOCS_PATH}`;
|
|
21
|
-
function buildMissingDependencyToolingMessage() {
|
|
22
|
-
return [
|
|
23
|
-
"Dreamboard needs dependency tooling to finish `dreamboard sync`.",
|
|
24
|
-
"Use Node 24+ with Corepack enabled, then run `dreamboard sync` again.",
|
|
25
|
-
"If Corepack is unavailable on this machine, install pnpm globally with `npm install -g pnpm`.",
|
|
26
|
-
`Help: ${DEPENDENCY_SETUP_DOCS_URL}`
|
|
27
|
-
].join("\n");
|
|
28
|
-
}
|
|
29
|
-
function buildPackageLockConflictMessage() {
|
|
30
|
-
return [
|
|
31
|
-
"Dreamboard manages workspace dependencies during `dreamboard sync`.",
|
|
32
|
-
"This workspace has an npm lockfile that conflicts with Dreamboard-managed dependencies.",
|
|
33
|
-
"Remove `package-lock.json` and run `dreamboard sync` again.",
|
|
34
|
-
`Help: ${DEPENDENCY_SETUP_DOCS_URL}`
|
|
35
|
-
].join("\n");
|
|
36
|
-
}
|
|
37
|
-
function buildMissingGeneratedLockfileMessage() {
|
|
38
|
-
return [
|
|
39
|
-
"Dreamboard could not finish preparing workspace dependencies during `dreamboard sync`.",
|
|
40
|
-
"Diagnostic: `pnpm-lock.yaml` was not created.",
|
|
41
|
-
`Help: ${DEPENDENCY_SETUP_DOCS_URL}`
|
|
42
|
-
].join("\n");
|
|
43
|
-
}
|
|
44
|
-
function buildDependencyPreparationFailureMessage(options) {
|
|
45
|
-
const details = options.output?.trim();
|
|
46
|
-
return [
|
|
47
|
-
`Dreamboard could not finish preparing workspace dependencies during \`dreamboard sync\`${options.exitCode != null ? ` (exit code ${options.exitCode})` : ""}.`,
|
|
48
|
-
details ? `Diagnostic output:
|
|
49
|
-
${details}` : null,
|
|
50
|
-
`Help: ${DEPENDENCY_SETUP_DOCS_URL}`
|
|
51
|
-
].filter(Boolean).join("\n");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/services/project/workspace-dependencies.ts
|
|
55
|
-
var MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
56
|
-
var CLI_ROOT = path.resolve(MODULE_DIR, "../../..");
|
|
57
|
-
var REPO_ROOT = path.resolve(CLI_ROOT, "../..");
|
|
58
|
-
var REPO_PACKAGE_JSON_PATH = path.join(REPO_ROOT, "package.json");
|
|
59
|
-
var DEFAULT_PACKAGE_MANAGER = "pnpm@10.4.1";
|
|
60
|
-
var SDK_PACKAGE_NAME = "@dreamboard-games/sdk";
|
|
61
|
-
var SDK_REQUIRED_DIST_FILES = [
|
|
62
|
-
"dist/index.d.ts",
|
|
63
|
-
"dist/index.js",
|
|
64
|
-
"dist/types.d.ts",
|
|
65
|
-
"dist/types.js",
|
|
66
|
-
"dist/ui.d.ts",
|
|
67
|
-
"dist/ui.js",
|
|
68
|
-
"dist/runtime.d.ts",
|
|
69
|
-
"dist/runtime.js"
|
|
70
|
-
];
|
|
71
|
-
var DEPENDENCY_INSTALL_METADATA_PATH_SEGMENTS = [
|
|
72
|
-
".dreamboard",
|
|
73
|
-
"dependency-install.json"
|
|
74
|
-
];
|
|
75
|
-
var LockfileGenerationError = class extends Error {
|
|
76
|
-
constructor(binary, details) {
|
|
77
|
-
super(buildLockfileGenerationErrorMessage(binary, details), {
|
|
78
|
-
cause: details.cause
|
|
79
|
-
});
|
|
80
|
-
this.binary = binary;
|
|
81
|
-
this.details = details;
|
|
82
|
-
this.name = "LockfileGenerationError";
|
|
83
|
-
}
|
|
84
|
-
binary;
|
|
85
|
-
details;
|
|
86
|
-
};
|
|
87
|
-
async function generatePnpmLockfile(projectRoot, _options = {}) {
|
|
88
|
-
await ensurePackageManagerNormalized(projectRoot);
|
|
89
|
-
await assertNoNpmLockfileConflict(projectRoot);
|
|
90
|
-
await runPackageManagerCommand(projectRoot, {
|
|
91
|
-
args: [
|
|
92
|
-
"install",
|
|
93
|
-
"--ignore-workspace",
|
|
94
|
-
"--lockfile-only",
|
|
95
|
-
"--config.shared-workspace-lockfile=false"
|
|
96
|
-
]
|
|
97
|
-
});
|
|
98
|
-
await assertPnpmLockfilePresent(projectRoot);
|
|
99
|
-
return true;
|
|
100
|
-
}
|
|
101
|
-
async function installWorkspaceDependencies(projectRoot, _options = {}) {
|
|
102
|
-
const result = await reconcileWorkspaceDependencies(projectRoot);
|
|
103
|
-
return result.required;
|
|
104
|
-
}
|
|
105
|
-
async function reconcileWorkspaceDependencies(projectRoot) {
|
|
106
|
-
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
107
|
-
if (!await pathExists(packageJsonPath)) {
|
|
108
|
-
return {
|
|
109
|
-
required: false,
|
|
110
|
-
installed: false,
|
|
111
|
-
lockfileGenerated: false,
|
|
112
|
-
packageManagerNormalized: false,
|
|
113
|
-
fingerprint: null
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
await assertNoNpmLockfileConflict(projectRoot);
|
|
117
|
-
const packageManagerNormalized = await ensurePackageManagerNormalized(projectRoot);
|
|
118
|
-
const pnpmLockfilePath = path.join(projectRoot, "pnpm-lock.yaml");
|
|
119
|
-
const nodeModulesPath = path.join(projectRoot, "node_modules");
|
|
120
|
-
const metadataPath = path.join(
|
|
121
|
-
projectRoot,
|
|
122
|
-
...DEPENDENCY_INSTALL_METADATA_PATH_SEGMENTS
|
|
123
|
-
);
|
|
124
|
-
let lockfileGenerated = false;
|
|
125
|
-
let installed = false;
|
|
126
|
-
const metadata = await readJsonFile(metadataPath);
|
|
127
|
-
const lockfileExists = await pathExists(pnpmLockfilePath);
|
|
128
|
-
if (!lockfileExists) {
|
|
129
|
-
await runPackageManagerCommand(projectRoot, {
|
|
130
|
-
args: [
|
|
131
|
-
"install",
|
|
132
|
-
"--ignore-workspace",
|
|
133
|
-
"--config.shared-workspace-lockfile=false"
|
|
134
|
-
]
|
|
135
|
-
});
|
|
136
|
-
lockfileGenerated = true;
|
|
137
|
-
installed = true;
|
|
138
|
-
}
|
|
139
|
-
await assertPnpmLockfilePresent(projectRoot);
|
|
140
|
-
let fingerprint = await fingerprintInstallManifest({
|
|
141
|
-
packageJsonPath,
|
|
142
|
-
lockfilePath: pnpmLockfilePath
|
|
143
|
-
});
|
|
144
|
-
const hasValidInstalledDeps = await pathExists(nodeModulesPath) && await hasValidInstalledDependencies({
|
|
145
|
-
packageJsonPath,
|
|
146
|
-
nodeModulesPath
|
|
147
|
-
});
|
|
148
|
-
const shouldInstall = !installed && (metadata?.dependencyFingerprint !== fingerprint || !hasValidInstalledDeps);
|
|
149
|
-
if (shouldInstall) {
|
|
150
|
-
await rm(nodeModulesPath, { recursive: true, force: true });
|
|
151
|
-
await runPackageManagerCommand(projectRoot, {
|
|
152
|
-
args: [
|
|
153
|
-
"install",
|
|
154
|
-
"--ignore-workspace",
|
|
155
|
-
"--config.shared-workspace-lockfile=false"
|
|
156
|
-
]
|
|
157
|
-
});
|
|
158
|
-
installed = true;
|
|
159
|
-
fingerprint = await fingerprintInstallManifest({
|
|
160
|
-
packageJsonPath,
|
|
161
|
-
lockfilePath: pnpmLockfilePath
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
if (installed || packageManagerNormalized || !metadata) {
|
|
165
|
-
await mkdir(path.dirname(metadataPath), { recursive: true });
|
|
166
|
-
await writeJsonFile(metadataPath, {
|
|
167
|
-
dependencyFingerprint: fingerprint,
|
|
168
|
-
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
169
|
-
packageManager: await readRepoPackageManager()
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
required: true,
|
|
174
|
-
installed,
|
|
175
|
-
lockfileGenerated,
|
|
176
|
-
packageManagerNormalized,
|
|
177
|
-
fingerprint
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
async function assertNoNpmLockfileConflict(projectRoot) {
|
|
181
|
-
const packageLockPath = path.join(projectRoot, "package-lock.json");
|
|
182
|
-
const pnpmLockPath = path.join(projectRoot, "pnpm-lock.yaml");
|
|
183
|
-
if (await pathExists(packageLockPath) && !await pathExists(pnpmLockPath)) {
|
|
184
|
-
throw new Error(buildPackageLockConflictMessage());
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
async function assertPnpmLockfilePresent(projectRoot) {
|
|
188
|
-
const pnpmLockfilePath = path.join(projectRoot, "pnpm-lock.yaml");
|
|
189
|
-
if (!await pathExists(pnpmLockfilePath)) {
|
|
190
|
-
throw new Error(buildMissingGeneratedLockfileMessage());
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
async function ensurePackageManagerNormalized(projectRoot) {
|
|
194
|
-
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
195
|
-
const packageJsonContent = await readFile(packageJsonPath, "utf8");
|
|
196
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
197
|
-
const packageManager = await readRepoPackageManager();
|
|
198
|
-
const nextPackageJson = {
|
|
199
|
-
...packageJson,
|
|
200
|
-
packageManager,
|
|
201
|
-
pnpm: mergePnpmConfig(packageJson.pnpm)
|
|
202
|
-
};
|
|
203
|
-
const normalizedPackageJson = `${JSON.stringify(nextPackageJson, null, 2)}
|
|
204
|
-
`;
|
|
205
|
-
if (normalizedPackageJson === packageJsonContent) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
await writeFile(packageJsonPath, normalizedPackageJson, "utf8");
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
function mergePnpmConfig(existingPnpm) {
|
|
212
|
-
const existingOverrides = existingPnpm?.overrides && typeof existingPnpm.overrides === "object" && !Array.isArray(existingPnpm.overrides) ? existingPnpm.overrides : {};
|
|
213
|
-
return {
|
|
214
|
-
...existingPnpm ?? {},
|
|
215
|
-
overrides: {
|
|
216
|
-
...existingOverrides,
|
|
217
|
-
...FRAMEWORK_PNPM_OVERRIDES
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
async function fingerprintInstallManifest(options) {
|
|
222
|
-
const packageJson = await readFile(options.packageJsonPath, "utf8");
|
|
223
|
-
const lockfile = await readFile(options.lockfilePath, "utf8");
|
|
224
|
-
const packageManager = await readRepoPackageManager();
|
|
225
|
-
return fingerprintContent([
|
|
226
|
-
packageJson,
|
|
227
|
-
lockfile,
|
|
228
|
-
`packageManager:${packageManager}`
|
|
229
|
-
]);
|
|
230
|
-
}
|
|
231
|
-
async function hasValidInstalledDependencies(options) {
|
|
232
|
-
const packageJson = await readJsonFile(
|
|
233
|
-
options.packageJsonPath
|
|
234
|
-
);
|
|
235
|
-
if (!packageJson) {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
const directDependencyNames = /* @__PURE__ */ new Set();
|
|
239
|
-
for (const field of [
|
|
240
|
-
"dependencies",
|
|
241
|
-
"devDependencies",
|
|
242
|
-
"optionalDependencies"
|
|
243
|
-
]) {
|
|
244
|
-
for (const packageName of Object.keys(packageJson[field] ?? {})) {
|
|
245
|
-
directDependencyNames.add(packageName);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (directDependencyNames.size === 0) {
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
for (const packageName of directDependencyNames) {
|
|
252
|
-
const packageRoot = path.join(
|
|
253
|
-
options.nodeModulesPath,
|
|
254
|
-
...packageName.split("/")
|
|
255
|
-
);
|
|
256
|
-
if (!await pathExists(path.join(packageRoot, "package.json"))) {
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
|
-
if (packageName === SDK_PACKAGE_NAME && !await hasInstalledSdkDistFiles(packageRoot)) {
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
async function hasInstalledSdkDistFiles(packageRoot) {
|
|
266
|
-
for (const relativePath of SDK_REQUIRED_DIST_FILES) {
|
|
267
|
-
if (!await pathExists(path.join(packageRoot, relativePath))) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
function hasExactPnpmVersion(value) {
|
|
274
|
-
return /^pnpm@\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(value ?? "");
|
|
275
|
-
}
|
|
276
|
-
async function readRepoPackageManager() {
|
|
277
|
-
const packageJson = await readJsonFile(
|
|
278
|
-
REPO_PACKAGE_JSON_PATH
|
|
279
|
-
);
|
|
280
|
-
const packageManager = packageJson?.packageManager?.trim();
|
|
281
|
-
return hasExactPnpmVersion(packageManager) ? packageManager : DEFAULT_PACKAGE_MANAGER;
|
|
282
|
-
}
|
|
283
|
-
function fingerprintContent(parts) {
|
|
284
|
-
return crypto.createHash("sha256").update(parts.join("\n---\n")).digest("hex");
|
|
285
|
-
}
|
|
286
|
-
function resolvePnpmInstallInvocation(installArgs) {
|
|
287
|
-
const corepackPath = path.join(path.dirname(process.execPath), "corepack");
|
|
288
|
-
if (existsSync(corepackPath)) {
|
|
289
|
-
return { command: corepackPath, args: ["pnpm", ...installArgs] };
|
|
290
|
-
}
|
|
291
|
-
return { command: "pnpm", args: [...installArgs] };
|
|
292
|
-
}
|
|
293
|
-
async function runPackageManagerCommand(projectRoot, command) {
|
|
294
|
-
const invocation = resolvePnpmInstallInvocation(command.args);
|
|
295
|
-
await runLockfileCommand(projectRoot, {
|
|
296
|
-
binary: invocation.command,
|
|
297
|
-
args: invocation.args
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
async function runLockfileCommand(projectRoot, command) {
|
|
301
|
-
await new Promise((resolve, reject) => {
|
|
302
|
-
const child = spawn(command.binary, command.args, {
|
|
303
|
-
cwd: projectRoot,
|
|
304
|
-
env: process.env,
|
|
305
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
306
|
-
});
|
|
307
|
-
let stdout = "";
|
|
308
|
-
let stderr = "";
|
|
309
|
-
bindStream(child.stdout, (chunk) => {
|
|
310
|
-
stdout += chunk.toString();
|
|
311
|
-
});
|
|
312
|
-
bindStream(child.stderr, (chunk) => {
|
|
313
|
-
stderr += chunk.toString();
|
|
314
|
-
});
|
|
315
|
-
child.on("error", (cause) => {
|
|
316
|
-
reject(
|
|
317
|
-
new LockfileGenerationError(command.binary, {
|
|
318
|
-
stdout,
|
|
319
|
-
stderr,
|
|
320
|
-
cause
|
|
321
|
-
})
|
|
322
|
-
);
|
|
323
|
-
});
|
|
324
|
-
child.on("close", (code) => {
|
|
325
|
-
if (code === 0) {
|
|
326
|
-
resolve();
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
reject(
|
|
330
|
-
new LockfileGenerationError(command.binary, {
|
|
331
|
-
code,
|
|
332
|
-
stdout,
|
|
333
|
-
stderr
|
|
334
|
-
})
|
|
335
|
-
);
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
function buildLockfileGenerationErrorMessage(binary, details) {
|
|
340
|
-
if (details.cause) {
|
|
341
|
-
const errnoError = details.cause;
|
|
342
|
-
const binaryName = path.basename(binary).toLowerCase();
|
|
343
|
-
if (errnoError.code === "ENOENT" && (binaryName === "pnpm" || binaryName === "pnpm.cmd" || binaryName === "corepack" || binaryName === "corepack.exe")) {
|
|
344
|
-
return buildMissingDependencyToolingMessage();
|
|
345
|
-
}
|
|
346
|
-
return `Failed to start ${binary} for Dreamboard dependency reconciliation. ${details.cause.message}`;
|
|
347
|
-
}
|
|
348
|
-
const output = [details.stdout.trim(), details.stderr.trim()].filter((chunk) => chunk.length > 0).join("\n");
|
|
349
|
-
return buildDependencyPreparationFailureMessage({
|
|
350
|
-
exitCode: details.code,
|
|
351
|
-
output
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
async function pathExists(targetPath) {
|
|
355
|
-
try {
|
|
356
|
-
await lstat(targetPath);
|
|
357
|
-
return true;
|
|
358
|
-
} catch {
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
async function readJsonFile(filePath) {
|
|
363
|
-
try {
|
|
364
|
-
return JSON.parse(await readFile(filePath, "utf8"));
|
|
365
|
-
} catch {
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
async function writeJsonFile(filePath, value) {
|
|
370
|
-
await writeFile(filePath, `${JSON.stringify(value, null, 2)}
|
|
371
|
-
`, "utf8");
|
|
372
|
-
}
|
|
373
|
-
function bindStream(stream, onData) {
|
|
374
|
-
stream?.on("data", onData);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
export {
|
|
378
|
-
generatePnpmLockfile,
|
|
379
|
-
installWorkspaceDependencies,
|
|
380
|
-
reconcileWorkspaceDependencies
|
|
381
|
-
};
|