@dreamboard-games/cli 0.1.30-alpha.2 → 0.1.30-alpha.21
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 +25 -107
- package/dist/agent-verifier/agent-workspace-verifier.mjs +1682 -0
- package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -0
- package/dist/agent-verifier/chunk-22U6RMWO.mjs +722 -0
- package/dist/agent-verifier/chunk-22U6RMWO.mjs.map +1 -0
- package/dist/agent-verifier/chunk-4I2WWAPK.mjs +399 -0
- package/dist/agent-verifier/chunk-4I2WWAPK.mjs.map +1 -0
- package/dist/agent-verifier/chunk-BWBN2TDJ.mjs +2811 -0
- package/dist/agent-verifier/chunk-BWBN2TDJ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-DQUYBIGQ.mjs +353 -0
- package/dist/agent-verifier/chunk-DQUYBIGQ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-F2DIOJJZ.mjs +302 -0
- package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-GWRZRWCF.mjs +107 -0
- package/dist/agent-verifier/chunk-GWRZRWCF.mjs.map +1 -0
- package/dist/agent-verifier/chunk-H6XDQJ3N.mjs +11 -0
- package/dist/agent-verifier/chunk-HUBV22JQ.mjs +89 -0
- package/dist/agent-verifier/chunk-HUBV22JQ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-IWB4L2HV.mjs +273 -0
- package/dist/agent-verifier/chunk-IWB4L2HV.mjs.map +1 -0
- package/dist/agent-verifier/chunk-JZTH3EMV.mjs +14523 -0
- package/dist/agent-verifier/chunk-JZTH3EMV.mjs.map +1 -0
- package/dist/agent-verifier/chunk-KDAQ4CZY.mjs +192 -0
- package/dist/agent-verifier/chunk-KDAQ4CZY.mjs.map +1 -0
- package/dist/agent-verifier/chunk-M7UVBANQ.mjs +58 -0
- package/dist/agent-verifier/chunk-M7UVBANQ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-MYMVXTZT.mjs +766 -0
- package/dist/agent-verifier/chunk-MYMVXTZT.mjs.map +1 -0
- package/dist/agent-verifier/chunk-OJFZVGEL.mjs +492 -0
- package/dist/agent-verifier/chunk-OJFZVGEL.mjs.map +1 -0
- package/dist/agent-verifier/chunk-QD4SQNUP.mjs +75 -0
- package/dist/agent-verifier/chunk-QD4SQNUP.mjs.map +1 -0
- package/dist/agent-verifier/chunk-RDYXWXXC.mjs +47 -0
- package/dist/agent-verifier/chunk-RDYXWXXC.mjs.map +1 -0
- package/dist/agent-verifier/chunk-TIDX3YLW.mjs +158 -0
- package/dist/agent-verifier/chunk-TIDX3YLW.mjs.map +1 -0
- package/dist/agent-verifier/chunk-TTB7AIHZ.mjs +214 -0
- package/dist/agent-verifier/chunk-TTB7AIHZ.mjs.map +1 -0
- package/dist/agent-verifier/chunk-UXGTT25Q.mjs +59 -0
- package/dist/agent-verifier/chunk-UXGTT25Q.mjs.map +1 -0
- package/dist/agent-verifier/chunk-YE7UAO3T.mjs +129 -0
- package/dist/agent-verifier/chunk-YE7UAO3T.mjs.map +1 -0
- package/dist/agent-verifier/chunk-ZEELHSY3.mjs +20 -0
- package/dist/agent-verifier/chunk-ZEELHSY3.mjs.map +1 -0
- package/dist/agent-verifier/global-config-IXZLY4BS.mjs +19 -0
- package/dist/agent-verifier/keychain-backend-UF3Z26JM.mjs +140 -0
- package/dist/agent-verifier/keychain-backend-UF3Z26JM.mjs.map +1 -0
- package/dist/agent-verifier/local-files-OF4QFISU.mjs +45 -0
- package/dist/agent-verifier/local-files-OF4QFISU.mjs.map +1 -0
- package/dist/agent-verifier/local-typecheck-DHVLM37Z.mjs +150 -0
- package/dist/agent-verifier/local-typecheck-DHVLM37Z.mjs.map +1 -0
- package/dist/agent-verifier/materialize-workspace-7DFE45ZH.mjs +90 -0
- package/dist/agent-verifier/materialize-workspace-7DFE45ZH.mjs.map +1 -0
- package/dist/agent-verifier/project-state-XKUSCFSV.mjs +33 -0
- package/dist/agent-verifier/project-state-XKUSCFSV.mjs.map +1 -0
- package/dist/agent-verifier/prompt-VKHMCQT6.mjs +756 -0
- package/dist/agent-verifier/prompt-VKHMCQT6.mjs.map +1 -0
- package/dist/agent-verifier/reducer-bundle-preflight-GLUJKTWU.mjs +312 -0
- package/dist/agent-verifier/reducer-bundle-preflight-GLUJKTWU.mjs.map +1 -0
- package/dist/agent-verifier/reducer-contract-preflight-WVQQPW5F.mjs +46 -0
- package/dist/agent-verifier/reducer-contract-preflight-WVQQPW5F.mjs.map +1 -0
- package/dist/agent-verifier/reducer-native-test-harness-H6G6RBRY.mjs +3436 -0
- package/dist/agent-verifier/reducer-native-test-harness-H6G6RBRY.mjs.map +1 -0
- package/dist/agent-verifier/static-scaffold-CC4KL6K7.mjs +24 -0
- package/dist/agent-verifier/static-scaffold-CC4KL6K7.mjs.map +1 -0
- package/dist/agent-verifier/workspace-codegen-SPPVHURX.mjs +10 -0
- package/dist/agent-verifier/workspace-codegen-SPPVHURX.mjs.map +1 -0
- package/dist/agent-verifier/workspace-dependencies-5HEEKZFP.mjs +17 -0
- package/dist/agent-verifier/workspace-dependencies-5HEEKZFP.mjs.map +1 -0
- package/dist/authoring-compatibility-internal.js +12 -0
- package/dist/authoring-compatibility-internal.js.map +1 -0
- package/dist/chunk-2H7UOFLK.js +11 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/{chunk-TAQKH67O.js → chunk-2Z65YI7P.js} +2702 -7338
- package/dist/chunk-2Z65YI7P.js.map +1 -0
- package/dist/chunk-EQNBQVIW.js +204 -0
- package/dist/chunk-EQNBQVIW.js.map +1 -0
- package/dist/chunk-GQ3ZEAEG.js +4281 -0
- package/dist/chunk-GQ3ZEAEG.js.map +1 -0
- package/dist/chunk-UI7NWSYA.js +334 -0
- package/dist/chunk-UI7NWSYA.js.map +1 -0
- package/dist/{global-config-S4ZIPECE.js → global-config-GK2UC2X6.js} +4 -3
- package/dist/global-config-GK2UC2X6.js.map +1 -0
- package/dist/index.js +3421 -6435
- package/dist/index.js.map +1 -1
- package/dist/internal.js +15 -9
- package/dist/{keychain-backend-HDF4TZDL.js → keychain-backend-GO34KGTG.js} +12 -7
- package/dist/keychain-backend-GO34KGTG.js.map +1 -0
- package/dist/{prompt-NDV3AE5L.js → prompt-GMZABCJC.js} +2 -2
- package/package.json +11 -20
- package/release/authoring-release-set.json +38 -0
- package/skills/dreamboard/SKILL.md +30 -28
- package/skills/dreamboard/references/building-your-first-game.md +15 -15
- package/skills/dreamboard/references/cli.md +48 -47
- package/skills/dreamboard/references/manifest-authoring.md +11 -3
- package/skills/dreamboard/references/quickstart.md +16 -13
- package/skills/dreamboard/references/testing.md +10 -10
- package/dist/chunk-N7XPNNUI.js +0 -432
- package/dist/chunk-N7XPNNUI.js.map +0 -1
- package/dist/chunk-SEGVTWSK.js +0 -44
- package/dist/chunk-TAQKH67O.js.map +0 -1
- package/dist/dev-host/components/drawer.tsx +0 -132
- package/dist/dev-host/components/input.tsx +0 -21
- package/dist/dev-host/dev-api-proxy-plugin.ts +0 -328
- package/dist/dev-host/dev-author-dom-warnings.ts +0 -100
- package/dist/dev-host/dev-diagnostics.ts +0 -62
- package/dist/dev-host/dev-fallback-stylesheet.ts +0 -53
- package/dist/dev-host/dev-hmr-guard-plugin.ts +0 -47
- package/dist/dev-host/dev-host-controller.ts +0 -674
- package/dist/dev-host/dev-host-player-query.ts +0 -17
- package/dist/dev-host/dev-host-session-transport.ts +0 -52
- package/dist/dev-host/dev-host-storage.ts +0 -56
- package/dist/dev-host/dev-log-relay-plugin.ts +0 -510
- package/dist/dev-host/dev-runtime-config.ts +0 -14
- package/dist/dev-host/dev-runtime-platform.ts +0 -335
- package/dist/dev-host/dev-virtual-modules-plugin.ts +0 -64
- package/dist/dev-host/host-main.css +0 -224
- package/dist/dev-host/host-main.tsx +0 -948
- package/dist/dev-host/index.html +0 -56
- package/dist/dev-host/lib/utils.ts +0 -6
- package/dist/dev-host/plugin-main.ts +0 -61
- package/dist/dev-host/plugin.html +0 -24
- package/dist/dev-host/shared-styles.css +0 -144
- package/dist/dev-host/start-dev-server.ts +0 -140
- package/dist/dev-host/virtual-modules.d.ts +0 -27
- package/dist/keychain-backend-HDF4TZDL.js.map +0 -1
- package/skills/dreamboard/scripts/events-extract.mjs +0 -218
- /package/dist/{chunk-SEGVTWSK.js.map → agent-verifier/chunk-H6XDQJ3N.mjs.map} +0 -0
- /package/dist/{global-config-S4ZIPECE.js.map → agent-verifier/global-config-IXZLY4BS.mjs.map} +0 -0
- /package/dist/{prompt-NDV3AE5L.js.map → prompt-GMZABCJC.js.map} +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.framework.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/index.tsx +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/style.css +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.framework.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.json +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
atomicWriteFile
|
|
4
|
+
} from "./chunk-GWRZRWCF.mjs";
|
|
5
|
+
import {
|
|
6
|
+
hashContent,
|
|
7
|
+
isAllowedGamePath,
|
|
8
|
+
isDynamicGeneratedPath,
|
|
9
|
+
isLibraryPath,
|
|
10
|
+
materializeManifest,
|
|
11
|
+
writeManifestSource
|
|
12
|
+
} from "./chunk-BWBN2TDJ.mjs";
|
|
13
|
+
import {
|
|
14
|
+
readWorkspaceTextFile,
|
|
15
|
+
readWorkspaceTextFileIfExists,
|
|
16
|
+
resolveWorkspacePath,
|
|
17
|
+
unlinkWorkspaceFile,
|
|
18
|
+
writeWorkspaceTextFile
|
|
19
|
+
} from "./chunk-OJFZVGEL.mjs";
|
|
20
|
+
import {
|
|
21
|
+
LOCAL_IGNORE_DIRS,
|
|
22
|
+
MANIFEST_FILE,
|
|
23
|
+
PROJECT_DIR_NAME,
|
|
24
|
+
RULE_FILE,
|
|
25
|
+
SNAPSHOT_FILE
|
|
26
|
+
} from "./chunk-M7UVBANQ.mjs";
|
|
27
|
+
|
|
28
|
+
// src/services/project/local-files.ts
|
|
29
|
+
import { readdir } from "fs/promises";
|
|
30
|
+
import path from "path";
|
|
31
|
+
function isAllowedGamePath2(filePath) {
|
|
32
|
+
return isAllowedGamePath(filePath);
|
|
33
|
+
}
|
|
34
|
+
function isLibraryPath2(filePath) {
|
|
35
|
+
return isLibraryPath(filePath);
|
|
36
|
+
}
|
|
37
|
+
function shouldWriteScaffoldFile(filePath, existingContent) {
|
|
38
|
+
if (isLibraryPath2(filePath)) return "write";
|
|
39
|
+
const hasContent = existingContent !== null && existingContent.trim().length > 0;
|
|
40
|
+
return hasContent ? "skip" : "write";
|
|
41
|
+
}
|
|
42
|
+
async function writeSourceFiles(rootDir, files) {
|
|
43
|
+
for (const [relativePath, content] of Object.entries(files)) {
|
|
44
|
+
if (content === null || content === void 0) continue;
|
|
45
|
+
await writeWorkspaceTextFile(rootDir, relativePath, content);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function writeScaffoldFiles(rootDir, files) {
|
|
49
|
+
const written = [];
|
|
50
|
+
const skipped = [];
|
|
51
|
+
for (const [relativePath, content] of Object.entries(files)) {
|
|
52
|
+
if (content === null || content === void 0) continue;
|
|
53
|
+
const existingContent = await readWorkspaceTextFileIfExists(
|
|
54
|
+
rootDir,
|
|
55
|
+
relativePath
|
|
56
|
+
);
|
|
57
|
+
const decision = shouldWriteScaffoldFile(relativePath, existingContent);
|
|
58
|
+
if (decision === "skip") {
|
|
59
|
+
skipped.push(relativePath);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
await writeWorkspaceTextFile(rootDir, relativePath, content);
|
|
63
|
+
if (existingContent !== content) {
|
|
64
|
+
written.push(relativePath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
written.sort();
|
|
68
|
+
skipped.sort();
|
|
69
|
+
return { written, skipped };
|
|
70
|
+
}
|
|
71
|
+
async function removeExtraneousFiles(rootDir, keep) {
|
|
72
|
+
const localFiles = await collectLocalFiles(rootDir);
|
|
73
|
+
for (const filePath of Object.keys(localFiles)) {
|
|
74
|
+
if (filePath === MANIFEST_FILE || filePath === RULE_FILE) continue;
|
|
75
|
+
if (!keep.has(filePath)) {
|
|
76
|
+
await unlinkWorkspaceFile(rootDir, filePath);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function collectLocalFiles(rootDir) {
|
|
81
|
+
const result = {};
|
|
82
|
+
await walkDir(rootDir, rootDir, result);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
async function walkDir(rootDir, currentDir, result) {
|
|
86
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (entry.isDirectory()) {
|
|
89
|
+
if (LOCAL_IGNORE_DIRS.has(entry.name)) continue;
|
|
90
|
+
await walkDir(rootDir, path.join(currentDir, entry.name), result);
|
|
91
|
+
} else if (entry.isFile()) {
|
|
92
|
+
const filePath = path.join(currentDir, entry.name);
|
|
93
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
94
|
+
result[relativePath] = await readWorkspaceTextFile(rootDir, relativePath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function writeManifest(rootDir, manifest) {
|
|
99
|
+
await writeManifestSource(rootDir, manifest);
|
|
100
|
+
}
|
|
101
|
+
async function writeRule(rootDir, ruleText) {
|
|
102
|
+
await writeWorkspaceTextFile(rootDir, RULE_FILE, ruleText);
|
|
103
|
+
}
|
|
104
|
+
async function loadManifest(rootDir) {
|
|
105
|
+
return materializeManifest(rootDir);
|
|
106
|
+
}
|
|
107
|
+
async function loadRule(rootDir) {
|
|
108
|
+
return readWorkspaceTextFile(rootDir, RULE_FILE);
|
|
109
|
+
}
|
|
110
|
+
async function writeSnapshot(rootDir) {
|
|
111
|
+
const files = await collectLocalFiles(rootDir);
|
|
112
|
+
await writeSnapshotFromFiles(rootDir, files);
|
|
113
|
+
}
|
|
114
|
+
async function writeSnapshotFromFiles(rootDir, files) {
|
|
115
|
+
const snapshot = {
|
|
116
|
+
files: {}
|
|
117
|
+
};
|
|
118
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
119
|
+
if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;
|
|
120
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
121
|
+
snapshot.files[filePath] = hashContent(content);
|
|
122
|
+
}
|
|
123
|
+
const snapshotPath = resolveWorkspacePath(
|
|
124
|
+
rootDir,
|
|
125
|
+
`${PROJECT_DIR_NAME}/${SNAPSHOT_FILE}`
|
|
126
|
+
);
|
|
127
|
+
await atomicWriteFile(
|
|
128
|
+
snapshotPath,
|
|
129
|
+
`${JSON.stringify(snapshot, null, 2)}
|
|
130
|
+
`,
|
|
131
|
+
{
|
|
132
|
+
mode: 420
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function isIgnorableLocalDiffPath(filePath) {
|
|
137
|
+
return filePath.startsWith("test/generated/") || filePath.startsWith(".playwright-cli/");
|
|
138
|
+
}
|
|
139
|
+
async function getLocalDiff(rootDir) {
|
|
140
|
+
const snapshot = await readWorkspaceTextFile(
|
|
141
|
+
rootDir,
|
|
142
|
+
`${PROJECT_DIR_NAME}/${SNAPSHOT_FILE}`
|
|
143
|
+
).then((text) => JSON.parse(text)).catch(() => null);
|
|
144
|
+
if (!snapshot) {
|
|
145
|
+
return { modified: [], added: [], deleted: [] };
|
|
146
|
+
}
|
|
147
|
+
const files = await collectLocalFiles(rootDir);
|
|
148
|
+
const currentHashes = {};
|
|
149
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
150
|
+
if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;
|
|
151
|
+
if (isIgnorableLocalDiffPath(filePath)) continue;
|
|
152
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
153
|
+
currentHashes[filePath] = hashContent(content);
|
|
154
|
+
}
|
|
155
|
+
const modified = [];
|
|
156
|
+
const added = [];
|
|
157
|
+
const deleted = [];
|
|
158
|
+
for (const [filePath, hash] of Object.entries(currentHashes)) {
|
|
159
|
+
const prevHash = snapshot.files[filePath];
|
|
160
|
+
if (!prevHash) {
|
|
161
|
+
added.push(filePath);
|
|
162
|
+
} else if (prevHash !== hash) {
|
|
163
|
+
modified.push(filePath);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const filePath of Object.keys(snapshot.files)) {
|
|
167
|
+
if (isIgnorableLocalDiffPath(filePath)) continue;
|
|
168
|
+
if (isDynamicGeneratedPath(filePath)) continue;
|
|
169
|
+
if (!currentHashes[filePath]) {
|
|
170
|
+
deleted.push(filePath);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return { modified, added, deleted };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export {
|
|
177
|
+
isAllowedGamePath2 as isAllowedGamePath,
|
|
178
|
+
isLibraryPath2 as isLibraryPath,
|
|
179
|
+
writeSourceFiles,
|
|
180
|
+
writeScaffoldFiles,
|
|
181
|
+
removeExtraneousFiles,
|
|
182
|
+
collectLocalFiles,
|
|
183
|
+
walkDir,
|
|
184
|
+
writeManifest,
|
|
185
|
+
writeRule,
|
|
186
|
+
loadManifest,
|
|
187
|
+
loadRule,
|
|
188
|
+
writeSnapshot,
|
|
189
|
+
writeSnapshotFromFiles,
|
|
190
|
+
getLocalDiff
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=chunk-KDAQ4CZY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/project/local-files.ts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { GameTopologyManifest } from \"@dreamboard-games/sdk/types\";\nimport {\n PROJECT_DIR_NAME,\n MANIFEST_FILE,\n RULE_FILE,\n SNAPSHOT_FILE,\n LOCAL_IGNORE_DIRS,\n} from \"../../constants.js\";\nimport type { Snapshot } from \"../../types.js\";\nimport { atomicWriteFile } from \"../../utils/atomic-file.js\";\nimport { hashContent } from \"../../utils/crypto.js\";\nimport {\n computeManifestHash,\n materializeManifest,\n writeManifestSource,\n} from \"./manifest-authoring.js\";\nimport {\n isAllowedGamePath as isAllowedPathFromOwnership,\n isDynamicGeneratedPath,\n isLibraryPath as isLibraryPathFromOwnership,\n} from \"./scaffold-ownership.js\";\nimport {\n readWorkspaceTextFile,\n readWorkspaceTextFileIfExists,\n resolveWorkspacePath,\n unlinkWorkspaceFile,\n writeWorkspaceTextFile,\n} from \"./workspace-path.js\";\n\n/**\n * Returns true when a path is inside the canonical game project structure.\n * Anything outside app/, ui/, shared/, or the known root files is rejected.\n */\nexport function isAllowedGamePath(filePath: string): boolean {\n return isAllowedPathFromOwnership(filePath);\n}\n\nexport function isLibraryPath(filePath: string): boolean {\n return isLibraryPathFromOwnership(filePath);\n}\n\ntype WriteDecision = \"write\" | \"skip\";\n\n/**\n * Decide whether a file from the scaffold response should be written to disk.\n *\n * - Library files → always overwrite (they are fully generated).\n * - Everything else → only write if the file does not yet exist or is empty\n * locally (first-time seeding; preserves user edits).\n */\nfunction shouldWriteScaffoldFile(\n filePath: string,\n existingContent: string | null,\n): WriteDecision {\n if (isLibraryPath(filePath)) return \"write\";\n const hasContent =\n existingContent !== null && existingContent.trim().length > 0;\n return hasContent ? \"skip\" : \"write\";\n}\n\nexport async function writeSourceFiles(\n rootDir: string,\n files: Record<string, string | null>,\n): Promise<void> {\n for (const [relativePath, content] of Object.entries(files)) {\n if (content === null || content === undefined) continue;\n await writeWorkspaceTextFile(rootDir, relativePath, content);\n }\n}\n\nexport interface ScaffoldWriteResult {\n written: string[];\n skipped: string[];\n}\n\n/**\n * Write scaffold files using local-merge logic.\n *\n * - Library files are always overwritten.\n * - User-owned files (phases, components, etc.) are only written when the\n * local file does not exist or is empty. Files with content are skipped\n * so user edits are never lost.\n *\n * Returns lists of files that were written (and actually changed) and files\n * that were skipped because a non-empty local copy already exists.\n */\nexport async function writeScaffoldFiles(\n rootDir: string,\n files: Record<string, string | null>,\n): Promise<ScaffoldWriteResult> {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const [relativePath, content] of Object.entries(files)) {\n if (content === null || content === undefined) continue;\n\n const existingContent = await readWorkspaceTextFileIfExists(\n rootDir,\n relativePath,\n );\n\n const decision = shouldWriteScaffoldFile(relativePath, existingContent);\n\n if (decision === \"skip\") {\n skipped.push(relativePath);\n continue;\n }\n\n await writeWorkspaceTextFile(rootDir, relativePath, content);\n\n if (existingContent !== content) {\n written.push(relativePath);\n }\n }\n\n written.sort();\n skipped.sort();\n return { written, skipped };\n}\n\nexport async function removeExtraneousFiles(\n rootDir: string,\n keep: Set<string>,\n): Promise<void> {\n const localFiles = await collectLocalFiles(rootDir);\n for (const filePath of Object.keys(localFiles)) {\n if (filePath === MANIFEST_FILE || filePath === RULE_FILE) continue;\n if (!keep.has(filePath)) {\n await unlinkWorkspaceFile(rootDir, filePath);\n }\n }\n}\n\nexport async function collectLocalFiles(\n rootDir: string,\n): Promise<Record<string, string>> {\n const result: Record<string, string> = {};\n await walkDir(rootDir, rootDir, result);\n return result;\n}\n\nexport async function walkDir(\n rootDir: string,\n currentDir: string,\n result: Record<string, string>,\n): Promise<void> {\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (LOCAL_IGNORE_DIRS.has(entry.name)) continue;\n await walkDir(rootDir, path.join(currentDir, entry.name), result);\n } else if (entry.isFile()) {\n const filePath = path.join(currentDir, entry.name);\n const relativePath = path.relative(rootDir, filePath);\n result[relativePath] = await readWorkspaceTextFile(rootDir, relativePath);\n }\n }\n}\n\nexport async function writeManifest(\n rootDir: string,\n manifest: GameTopologyManifest,\n): Promise<void> {\n await writeManifestSource(rootDir, manifest);\n}\n\nexport async function writeRule(\n rootDir: string,\n ruleText: string,\n): Promise<void> {\n await writeWorkspaceTextFile(rootDir, RULE_FILE, ruleText);\n}\n\nexport async function loadManifest(\n rootDir: string,\n): Promise<GameTopologyManifest> {\n return materializeManifest(rootDir);\n}\n\nexport { computeManifestHash };\n\nexport async function loadRule(rootDir: string): Promise<string> {\n return readWorkspaceTextFile(rootDir, RULE_FILE);\n}\n\nexport async function writeSnapshot(rootDir: string): Promise<void> {\n const files = await collectLocalFiles(rootDir);\n await writeSnapshotFromFiles(rootDir, files);\n}\n\nexport async function writeSnapshotFromFiles(\n rootDir: string,\n files: Record<string, string>,\n): Promise<void> {\n const snapshot: Snapshot = {\n files: {},\n };\n\n for (const [filePath, content] of Object.entries(files)) {\n if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n snapshot.files[filePath] = hashContent(content);\n }\n\n // Atomic write: a crash mid-snapshot (e.g. user kills a long `dreamboard\n // sync`) must not leave `.dreamboard/snapshot.json` truncated, or\n // `getLocalDiff` will silently report everything as \"added\" on the\n // next run and force a full re-sync.\n const snapshotPath = resolveWorkspacePath(\n rootDir,\n `${PROJECT_DIR_NAME}/${SNAPSHOT_FILE}`,\n );\n await atomicWriteFile(\n snapshotPath,\n `${JSON.stringify(snapshot, null, 2)}\\n`,\n {\n mode: 0o644,\n },\n );\n}\n\nfunction isIgnorableLocalDiffPath(filePath: string): boolean {\n return (\n filePath.startsWith(\"test/generated/\") ||\n filePath.startsWith(\".playwright-cli/\")\n );\n}\n\nexport async function getLocalDiff(rootDir: string): Promise<{\n modified: string[];\n added: string[];\n deleted: string[];\n}> {\n const snapshot = await readWorkspaceTextFile(\n rootDir,\n `${PROJECT_DIR_NAME}/${SNAPSHOT_FILE}`,\n )\n .then((text) => JSON.parse(text) as Snapshot)\n .catch(() => null);\n if (!snapshot) {\n return { modified: [], added: [], deleted: [] };\n }\n\n const files = await collectLocalFiles(rootDir);\n const currentHashes: Record<string, string> = {};\n\n for (const [filePath, content] of Object.entries(files)) {\n if (filePath.startsWith(`${PROJECT_DIR_NAME}/`)) continue;\n if (isIgnorableLocalDiffPath(filePath)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n currentHashes[filePath] = hashContent(content);\n }\n\n const modified: string[] = [];\n const added: string[] = [];\n const deleted: string[] = [];\n\n for (const [filePath, hash] of Object.entries(currentHashes)) {\n const prevHash = snapshot.files[filePath];\n if (!prevHash) {\n added.push(filePath);\n } else if (prevHash !== hash) {\n modified.push(filePath);\n }\n }\n\n for (const filePath of Object.keys(snapshot.files)) {\n if (isIgnorableLocalDiffPath(filePath)) continue;\n if (isDynamicGeneratedPath(filePath)) continue;\n if (!currentHashes[filePath]) {\n deleted.push(filePath);\n }\n }\n\n return { modified, added, deleted };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AACxB,OAAO,UAAU;AAkCV,SAASA,mBAAkB,UAA2B;AAC3D,SAAO,kBAA2B,QAAQ;AAC5C;AAEO,SAASC,eAAc,UAA2B;AACvD,SAAO,cAA2B,QAAQ;AAC5C;AAWA,SAAS,wBACP,UACA,iBACe;AACf,MAAIA,eAAc,QAAQ,EAAG,QAAO;AACpC,QAAM,aACJ,oBAAoB,QAAQ,gBAAgB,KAAK,EAAE,SAAS;AAC9D,SAAO,aAAa,SAAS;AAC/B;AAEA,eAAsB,iBACpB,SACA,OACe;AACf,aAAW,CAAC,cAAc,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC3D,QAAI,YAAY,QAAQ,YAAY,OAAW;AAC/C,UAAM,uBAAuB,SAAS,cAAc,OAAO;AAAA,EAC7D;AACF;AAkBA,eAAsB,mBACpB,SACA,OAC8B;AAC9B,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAE3B,aAAW,CAAC,cAAc,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC3D,QAAI,YAAY,QAAQ,YAAY,OAAW;AAE/C,UAAM,kBAAkB,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAEA,UAAM,WAAW,wBAAwB,cAAc,eAAe;AAEtE,QAAI,aAAa,QAAQ;AACvB,cAAQ,KAAK,YAAY;AACzB;AAAA,IACF;AAEA,UAAM,uBAAuB,SAAS,cAAc,OAAO;AAE3D,QAAI,oBAAoB,SAAS;AAC/B,cAAQ,KAAK,YAAY;AAAA,IAC3B;AAAA,EACF;AAEA,UAAQ,KAAK;AACb,UAAQ,KAAK;AACb,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAEA,eAAsB,sBACpB,SACA,MACe;AACf,QAAM,aAAa,MAAM,kBAAkB,OAAO;AAClD,aAAW,YAAY,OAAO,KAAK,UAAU,GAAG;AAC9C,QAAI,aAAa,iBAAiB,aAAa,UAAW;AAC1D,QAAI,CAAC,KAAK,IAAI,QAAQ,GAAG;AACvB,YAAM,oBAAoB,SAAS,QAAQ;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,eAAsB,kBACpB,SACiC;AACjC,QAAM,SAAiC,CAAC;AACxC,QAAM,QAAQ,SAAS,SAAS,MAAM;AACtC,SAAO;AACT;AAEA,eAAsB,QACpB,SACA,YACA,QACe;AACf,QAAM,UAAU,MAAM,QAAQ,YAAY,EAAE,eAAe,KAAK,CAAC;AACjE,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,YAAY,GAAG;AACvB,UAAI,kBAAkB,IAAI,MAAM,IAAI,EAAG;AACvC,YAAM,QAAQ,SAAS,KAAK,KAAK,YAAY,MAAM,IAAI,GAAG,MAAM;AAAA,IAClE,WAAW,MAAM,OAAO,GAAG;AACzB,YAAM,WAAW,KAAK,KAAK,YAAY,MAAM,IAAI;AACjD,YAAM,eAAe,KAAK,SAAS,SAAS,QAAQ;AACpD,aAAO,YAAY,IAAI,MAAM,sBAAsB,SAAS,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;AAEA,eAAsB,cACpB,SACA,UACe;AACf,QAAM,oBAAoB,SAAS,QAAQ;AAC7C;AAEA,eAAsB,UACpB,SACA,UACe;AACf,QAAM,uBAAuB,SAAS,WAAW,QAAQ;AAC3D;AAEA,eAAsB,aACpB,SAC+B;AAC/B,SAAO,oBAAoB,OAAO;AACpC;AAIA,eAAsB,SAAS,SAAkC;AAC/D,SAAO,sBAAsB,SAAS,SAAS;AACjD;AAEA,eAAsB,cAAc,SAAgC;AAClE,QAAM,QAAQ,MAAM,kBAAkB,OAAO;AAC7C,QAAM,uBAAuB,SAAS,KAAK;AAC7C;AAEA,eAAsB,uBACpB,SACA,OACe;AACf,QAAM,WAAqB;AAAA,IACzB,OAAO,CAAC;AAAA,EACV;AAEA,aAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACvD,QAAI,SAAS,WAAW,GAAG,gBAAgB,GAAG,EAAG;AACjD,QAAI,uBAAuB,QAAQ,EAAG;AACtC,aAAS,MAAM,QAAQ,IAAI,YAAY,OAAO;AAAA,EAChD;AAMA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,GAAG,gBAAgB,IAAI,aAAa;AAAA,EACtC;AACA,QAAM;AAAA,IACJ;AAAA,IACA,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA;AAAA,IACpC;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,UAA2B;AAC3D,SACE,SAAS,WAAW,iBAAiB,KACrC,SAAS,WAAW,kBAAkB;AAE1C;AAEA,eAAsB,aAAa,SAIhC;AACD,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA,GAAG,gBAAgB,IAAI,aAAa;AAAA,EACtC,EACG,KAAK,CAAC,SAAS,KAAK,MAAM,IAAI,CAAa,EAC3C,MAAM,MAAM,IAAI;AACnB,MAAI,CAAC,UAAU;AACb,WAAO,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,EAChD;AAEA,QAAM,QAAQ,MAAM,kBAAkB,OAAO;AAC7C,QAAM,gBAAwC,CAAC;AAE/C,aAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACvD,QAAI,SAAS,WAAW,GAAG,gBAAgB,GAAG,EAAG;AACjD,QAAI,yBAAyB,QAAQ,EAAG;AACxC,QAAI,uBAAuB,QAAQ,EAAG;AACtC,kBAAc,QAAQ,IAAI,YAAY,OAAO;AAAA,EAC/C;AAEA,QAAM,WAAqB,CAAC;AAC5B,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAE3B,aAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC5D,UAAM,WAAW,SAAS,MAAM,QAAQ;AACxC,QAAI,CAAC,UAAU;AACb,YAAM,KAAK,QAAQ;AAAA,IACrB,WAAW,aAAa,MAAM;AAC5B,eAAS,KAAK,QAAQ;AAAA,IACxB;AAAA,EACF;AAEA,aAAW,YAAY,OAAO,KAAK,SAAS,KAAK,GAAG;AAClD,QAAI,yBAAyB,QAAQ,EAAG;AACxC,QAAI,uBAAuB,QAAQ,EAAG;AACtC,QAAI,CAAC,cAAc,QAAQ,GAAG;AAC5B,cAAQ,KAAK,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,OAAO,QAAQ;AACpC;","names":["isAllowedGamePath","isLibraryPath"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/constants.ts
|
|
4
|
+
var DEFAULT_API_BASE_URL = "https://api.dreamboard.games";
|
|
5
|
+
var DEFAULT_WEB_BASE_URL = "https://dreamboard.games";
|
|
6
|
+
var PROJECT_DIR_NAME = ".dreamboard";
|
|
7
|
+
var DEFAULT_CLERK_OAUTH_SCOPE = "openid profile email offline_access";
|
|
8
|
+
var ENVIRONMENT_CONFIGS = {
|
|
9
|
+
local: {
|
|
10
|
+
apiBaseUrl: "http://localhost:8080",
|
|
11
|
+
webBaseUrl: "http://localhost:5173",
|
|
12
|
+
clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE
|
|
13
|
+
},
|
|
14
|
+
staging: {
|
|
15
|
+
apiBaseUrl: "https://api-staging.dreamboard.games",
|
|
16
|
+
webBaseUrl: "https://staging.dreamboard.games",
|
|
17
|
+
clerkOAuthIssuer: "https://happy-caribou-19.clerk.accounts.dev",
|
|
18
|
+
clerkOAuthClientId: "wkjMF92OFsKbSaGI",
|
|
19
|
+
clerkOAuthTokenUrl: "https://happy-caribou-19.clerk.accounts.dev/oauth/token",
|
|
20
|
+
clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE
|
|
21
|
+
},
|
|
22
|
+
prod: {
|
|
23
|
+
apiBaseUrl: "https://api.dreamboard.games",
|
|
24
|
+
webBaseUrl: "https://dreamboard.games",
|
|
25
|
+
clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var PROJECT_CONFIG_FILE = "project.json";
|
|
29
|
+
var PROJECT_STATE_FILE = "state.json";
|
|
30
|
+
var SNAPSHOT_FILE = "snapshot.json";
|
|
31
|
+
var MANIFEST_FILE = "manifest.ts";
|
|
32
|
+
var GENERATED_DIR_NAME = "generated";
|
|
33
|
+
var MATERIALIZED_MANIFEST_FILE = `${PROJECT_DIR_NAME}/${GENERATED_DIR_NAME}/manifest.json`;
|
|
34
|
+
var MANIFEST_TYPECHECK_CONFIG_FILE = "manifest.tsconfig.json";
|
|
35
|
+
var RULE_FILE = "rule.md";
|
|
36
|
+
var DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
37
|
+
var LOCAL_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
38
|
+
".dreamboard",
|
|
39
|
+
".git",
|
|
40
|
+
"node_modules",
|
|
41
|
+
"dist"
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
DEFAULT_API_BASE_URL,
|
|
46
|
+
DEFAULT_WEB_BASE_URL,
|
|
47
|
+
PROJECT_DIR_NAME,
|
|
48
|
+
ENVIRONMENT_CONFIGS,
|
|
49
|
+
PROJECT_CONFIG_FILE,
|
|
50
|
+
PROJECT_STATE_FILE,
|
|
51
|
+
SNAPSHOT_FILE,
|
|
52
|
+
MANIFEST_FILE,
|
|
53
|
+
MATERIALIZED_MANIFEST_FILE,
|
|
54
|
+
MANIFEST_TYPECHECK_CONFIG_FILE,
|
|
55
|
+
RULE_FILE,
|
|
56
|
+
LOCAL_IGNORE_DIRS
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=chunk-M7UVBANQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants.ts"],"sourcesContent":["import type { EnvironmentConfig } from \"./types.js\";\n\nexport const DEFAULT_API_BASE_URL = \"https://api.dreamboard.games\";\nexport const DEFAULT_WEB_BASE_URL = \"https://dreamboard.games\";\n\nexport const PROJECT_DIR_NAME = \".dreamboard\";\nexport const DEFAULT_CLERK_OAUTH_SCOPE =\n \"openid profile email offline_access\";\n\n// Predefined environment configurations. These are intentionally static:\n// process/env overrides are applied in config resolution so the CLI does not\n// depend on a shell-sourced env file just to know first-party environments.\nexport const ENVIRONMENT_CONFIGS: Record<string, EnvironmentConfig> = {\n local: {\n apiBaseUrl: \"http://localhost:8080\",\n webBaseUrl: \"http://localhost:5173\",\n clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE,\n },\n staging: {\n apiBaseUrl: \"https://api-staging.dreamboard.games\",\n webBaseUrl: \"https://staging.dreamboard.games\",\n clerkOAuthIssuer: \"https://happy-caribou-19.clerk.accounts.dev\",\n clerkOAuthClientId: \"wkjMF92OFsKbSaGI\",\n clerkOAuthTokenUrl:\n \"https://happy-caribou-19.clerk.accounts.dev/oauth/token\",\n clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE,\n },\n prod: {\n apiBaseUrl: \"https://api.dreamboard.games\",\n webBaseUrl: \"https://dreamboard.games\",\n clerkOAuthScope: DEFAULT_CLERK_OAUTH_SCOPE,\n },\n};\nexport const PROJECT_CONFIG_FILE = \"project.json\";\nexport const PROJECT_STATE_FILE = \"state.json\";\nexport const SNAPSHOT_FILE = \"snapshot.json\";\nexport const MANIFEST_FILE = \"manifest.ts\";\nexport const GENERATED_DIR_NAME = \"generated\";\nexport const MATERIALIZED_MANIFEST_FILE = `${PROJECT_DIR_NAME}/${GENERATED_DIR_NAME}/manifest.json`;\nexport const MANIFEST_TYPECHECK_CONFIG_FILE = \"manifest.tsconfig.json\";\nexport const RULE_FILE = \"rule.md\";\nexport const DEFAULT_LOGIN_TIMEOUT_MS = 5 * 60 * 1000;\nexport const DEFAULT_TURN_DELAY_MS = 250;\n\nexport const LOCAL_IGNORE_DIRS = new Set([\n \".dreamboard\",\n \".git\",\n \"node_modules\",\n \"dist\",\n]);\n"],"mappings":";;;AAEO,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAE7B,IAAM,mBAAmB;AACzB,IAAM,4BACX;AAKK,IAAM,sBAAyD;AAAA,EACpE,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,EACnB;AAAA,EACA,SAAS;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,oBACE;AAAA,IACF,iBAAiB;AAAA,EACnB;AAAA,EACA,MAAM;AAAA,IACJ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB;AAAA,EACnB;AACF;AACO,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB;AAC3B,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAC3B,IAAM,6BAA6B,GAAG,gBAAgB,IAAI,kBAAkB;AAC5E,IAAM,iCAAiC;AACvC,IAAM,YAAY;AAClB,IAAM,2BAA2B,IAAI,KAAK;AAG1C,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;","names":[]}
|