@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 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.67"
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 hasTsConfig = existsSync(join(repoPath, 'tsconfig.json'));
232
- const hasDist = existsSync(join(repoPath, 'dist'));
271
+ const distDir = join(repoPath, 'dist');
272
+ const hasPopulatedDist = existsSync(distDir) && readdirSync(distDir).length > 0;
233
273
 
234
- // Build if: has a build script AND (no dist/ or tsconfig exists implying TS)
235
- if (hasBuildScript && (!hasDist || hasTsConfig)) {
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 if node_modules is missing
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ldm-os",
3
- "version": "0.4.67",
3
+ "version": "0.4.69",
4
4
  "type": "module",
5
5
  "description": "LDM OS: identity, memory, and sovereignty infrastructure for AI agents",
6
6
  "engines": {