@wipcomputer/wip-ldm-os 0.4.67 → 0.4.69
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/SKILL.md +1 -1
- package/lib/deploy.mjs +58 -7
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ license: MIT
|
|
|
9
9
|
compatibility: Requires git, npm, node. Node.js 18+.
|
|
10
10
|
metadata:
|
|
11
11
|
display-name: "LDM OS"
|
|
12
|
-
version: "0.4.
|
|
12
|
+
version: "0.4.69"
|
|
13
13
|
homepage: "https://github.com/wipcomputer/wip-ldm-os"
|
|
14
14
|
author: "Parker Todd Brooks"
|
|
15
15
|
category: infrastructure
|
package/lib/deploy.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { execSync } from 'node:child_process';
|
|
|
12
12
|
import {
|
|
13
13
|
existsSync, readFileSync, writeFileSync, copyFileSync, cpSync, mkdirSync,
|
|
14
14
|
lstatSync, readlinkSync, unlinkSync, chmodSync, readdirSync,
|
|
15
|
-
renameSync, rmSync, statSync,
|
|
15
|
+
renameSync, rmSync, statSync, symlinkSync,
|
|
16
16
|
} from 'node:fs';
|
|
17
17
|
import { join, basename, resolve, dirname } from 'node:path';
|
|
18
18
|
import { tmpdir } from 'node:os';
|
|
@@ -221,6 +221,46 @@ function findExistingInstalls(toolName, pkg, ocPluginConfig) {
|
|
|
221
221
|
return matches;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
// ── Local dependency resolution ──
|
|
225
|
+
// Repos with file: dependencies (e.g. memory-crystal -> dream-weaver-protocol)
|
|
226
|
+
// fail to build in a clone context where the sibling directory doesn't exist.
|
|
227
|
+
// This function resolves those deps from the local LDM installation. No internet needed.
|
|
228
|
+
|
|
229
|
+
function resolveLocalDeps(repoPath) {
|
|
230
|
+
const pkg = readJSON(join(repoPath, 'package.json'));
|
|
231
|
+
if (!pkg) return;
|
|
232
|
+
|
|
233
|
+
const allDeps = { ...pkg.dependencies, ...pkg.optionalDependencies };
|
|
234
|
+
let resolved = 0;
|
|
235
|
+
|
|
236
|
+
for (const [name, spec] of Object.entries(allDeps)) {
|
|
237
|
+
if (typeof spec !== 'string' || !spec.startsWith('file:')) continue;
|
|
238
|
+
|
|
239
|
+
// This is a file: dependency that won't resolve in a clone
|
|
240
|
+
const extDir = join(LDM_EXTENSIONS, name);
|
|
241
|
+
if (existsSync(extDir)) {
|
|
242
|
+
const targetModules = join(repoPath, 'node_modules', name);
|
|
243
|
+
if (!existsSync(targetModules)) {
|
|
244
|
+
mkdirSync(join(repoPath, 'node_modules'), { recursive: true });
|
|
245
|
+
// Handle scoped packages (e.g. @scope/name)
|
|
246
|
+
const scopeDir = dirname(targetModules);
|
|
247
|
+
if (scopeDir !== join(repoPath, 'node_modules')) {
|
|
248
|
+
mkdirSync(scopeDir, { recursive: true });
|
|
249
|
+
}
|
|
250
|
+
symlinkSync(extDir, targetModules);
|
|
251
|
+
log(`Linked local dep: ${name} -> ${extDir}`);
|
|
252
|
+
resolved++;
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
log(`Dep ${name} not installed at ${extDir}, build may fail for this feature`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (resolved > 0) {
|
|
260
|
+
ok(`Resolved ${resolved} file: dep(s) from local LDM installation`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
224
264
|
// ── Build step (fix #6) ──
|
|
225
265
|
|
|
226
266
|
function runBuildIfNeeded(repoPath) {
|
|
@@ -228,17 +268,28 @@ function runBuildIfNeeded(repoPath) {
|
|
|
228
268
|
if (!pkg) return true;
|
|
229
269
|
|
|
230
270
|
const hasBuildScript = !!pkg.scripts?.build;
|
|
231
|
-
const
|
|
232
|
-
const
|
|
271
|
+
const distDir = join(repoPath, 'dist');
|
|
272
|
+
const hasPopulatedDist = existsSync(distDir) && readdirSync(distDir).length > 0;
|
|
233
273
|
|
|
234
|
-
//
|
|
235
|
-
if (
|
|
274
|
+
// Skip build if dist/ already has files (pre-built from npm or GitHub clone).
|
|
275
|
+
if (hasPopulatedDist) {
|
|
276
|
+
log(`Skipping build: dist/ already exists with ${readdirSync(distDir).length} files`);
|
|
277
|
+
} else if (hasBuildScript) {
|
|
236
278
|
log(`Building ${pkg.name || basename(repoPath)}...`);
|
|
237
279
|
try {
|
|
238
|
-
// Install deps first
|
|
280
|
+
// 1. Install deps first (gets devDependencies like tsup).
|
|
281
|
+
// npm may warn about unresolvable file: deps but still installs the rest.
|
|
239
282
|
if (!existsSync(join(repoPath, 'node_modules'))) {
|
|
240
283
|
execSync('npm install', { cwd: repoPath, stdio: 'pipe' });
|
|
241
284
|
}
|
|
285
|
+
|
|
286
|
+
// 2. Resolve file: deps from local LDM extensions AFTER npm install.
|
|
287
|
+
// npm install can remove or overwrite symlinks, so this must run second.
|
|
288
|
+
// Without this, repos like memory-crystal that depend on
|
|
289
|
+
// file:../dream-weaver-protocol-private fail to build (sibling doesn't exist in clones).
|
|
290
|
+
resolveLocalDeps(repoPath);
|
|
291
|
+
|
|
292
|
+
// 3. Build.
|
|
242
293
|
execSync('npm run build', { cwd: repoPath, stdio: 'pipe' });
|
|
243
294
|
ok(`Build complete`);
|
|
244
295
|
} catch (e) {
|
|
@@ -1089,4 +1140,4 @@ export function disableExtension(name) {
|
|
|
1089
1140
|
|
|
1090
1141
|
// ── Exports for ldm CLI ──
|
|
1091
1142
|
|
|
1092
|
-
export { loadRegistry, saveRegistry, updateRegistry, readJSON, writeJSON, runBuildIfNeeded, CORE_EXTENSIONS };
|
|
1143
|
+
export { loadRegistry, saveRegistry, updateRegistry, readJSON, writeJSON, runBuildIfNeeded, resolveLocalDeps, CORE_EXTENSIONS };
|