@danypops/pi-packed 0.22.3 → 0.22.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/pi-packed",
3
- "version": "0.22.3",
3
+ "version": "0.22.4",
4
4
  "description": "Pi package lifecycle, validation, daemon, tools, profiles, and TUI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -146,6 +146,28 @@ export function detectVehicleDaemonService(
146
146
  for (const depDir of candidateDirs) {
147
147
  const dep = readPackageJson(depDir);
148
148
  if (!dep) continue;
149
+ // An explicit manifest on the dependency itself wins over convention detection here too --
150
+ // mirrors resolveDaemonServiceSpec's own explicit-manifest-first behavior for a directly
151
+ // installed package. Without this, a dependency's own correct, explicit
152
+ // handleFilename/name/etc. was silently discarded in favor of a guess whenever the daemon
153
+ // was discovered one level down instead of installed directly by name -- exactly the
154
+ // common case (a Pi extension like pi-papyrus has no daemon of its own). Confirmed live:
155
+ // papyrus's real handle file is "vehicle-handle.json", not the "daemon.json" convention
156
+ // guess, and papyrus is only ever discovered this way, never installed directly by name.
157
+ const depManifest = dep.packed?.daemonService;
158
+ if (depManifest && typeof depManifest.binPath === "string" && depManifest.binPath.length > 0 && dep.version) {
159
+ return {
160
+ binPath: join(depDir, depManifest.binPath),
161
+ args: depManifest.args,
162
+ name: depManifest.name ?? unscopedName(dep.name ?? depName),
163
+ displayName: depManifest.displayName,
164
+ handleFilename: depManifest.handleFilename,
165
+ workingDirectory: depManifest.workingDirectory,
166
+ restartOnFailure: depManifest.restartOnFailure,
167
+ restartSec: depManifest.restartSec,
168
+ version: dep.version,
169
+ };
170
+ }
149
171
  const depBin = firstBinPath(dep);
150
172
  if (depBin && dependsOnVehicle(dep) && dep.version) {
151
173
  return { binPath: join(depDir, depBin), args: ["serve"], name: unscopedName(dep.name ?? depName), version: dep.version };
@@ -185,6 +185,29 @@ describe("resolveDaemonServiceSpec", () => {
185
185
  expect(result.spec.name).toBe("papyrus");
186
186
  });
187
187
 
188
+ it("honors a nested dependency's own explicit packed.daemonService manifest, not just bin+dependency convention -- confirmed live: papyrus's real handle file is 'vehicle-handle.json', not the 'daemon.json' convention guess, and papyrus is only ever discovered this way (one level into pi-papyrus's own dependencies), never installed directly by name", () => {
189
+ const piHome = fakePiHome();
190
+ const extDir = join(piHome, "npm", "node_modules", "@danypops/pi-papyrus");
191
+ writeRawPackage(extDir, { name: "@danypops/pi-papyrus", version: "1.0.0", dependencies: { "@danypops/papyrus": "^0.54.0" } });
192
+ const depDir = join(extDir, "node_modules", "@danypops/papyrus");
193
+ writeRawPackage(depDir, {
194
+ name: "@danypops/papyrus",
195
+ version: "0.54.0",
196
+ bin: { papyrus: "src/cli.ts" },
197
+ dependencies: { "@danypops/vehicle-server": "^0.24.0" },
198
+ packed: { daemonService: { binPath: "src/cli.ts", args: ["serve"], handleFilename: "vehicle-handle.json", restartOnFailure: true, restartSec: 2 } },
199
+ });
200
+
201
+ const result = resolveDaemonServiceSpec(piHome, "npm:@danypops/pi-papyrus");
202
+ expect(result.ok).toBe(true);
203
+ if (!result.ok) throw new Error("expected ok");
204
+ expect(result.spec.binPath).toBe(join(depDir, "src/cli.ts"));
205
+ expect(result.spec.name).toBe("papyrus");
206
+ expect(result.spec.handlePath.endsWith("vehicle-handle.json")).toBe(true);
207
+ expect(result.spec.restartOnFailure).toBe(true);
208
+ expect(result.spec.restartSec).toBe(2);
209
+ });
210
+
188
211
  it("also detects the legacy @danypops/daemon-kit dependency name, not just vehicle-server", () => {
189
212
  const piHome = fakePiHome();
190
213
  const dir = join(piHome, "npm", "node_modules", "@danypops/web-spider-daemon");