@agfpd/iapeer 0.2.65 → 0.2.67

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": "@agfpd/iapeer",
3
- "version": "0.2.65",
3
+ "version": "0.2.67",
4
4
  "description": "Foundation core for the iapeer multi-agent ecosystem: identity, registry, storage, codec.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -66,7 +66,25 @@ export interface StartDaemonResult {
66
66
  detail?: string
67
67
  }
68
68
 
69
- const selfArgv = (): string[] => [process.execPath, fileURLToPath(import.meta.url)]
69
+ /**
70
+ * Re-invoke THIS module as the detached daemon (spawn-flip Ф1 serving-wiring). From SOURCE (bun) the
71
+ * module is a real file on disk → run it directly (`bun <self> daemon …` → import.meta.main →
72
+ * runSupervisorCli). In a `bun build --compile` STANDALONE the module is EMBEDDED at a `/$bunfs`
73
+ * virtual path that is NOT on disk; a bare `<binary> <bunfs-path> daemon …` invocation mis-routes
74
+ * through the CLI (the path becomes an unknown verb → usage, daemon never comes up — and a hosted
75
+ * launch then silently falls back to tmux). Detect that (the resolved self path is absent on disk) and
76
+ * re-invoke the installed binary through its `supervisor` verb instead. The caller appends
77
+ * `daemon <session> <runtime> --run-dir <dir>`, so runSupervisorCli is reached either way.
78
+ */
79
+ export function resolveDaemonSelfArgv(execPath: string, selfPath: string): string[] {
80
+ // A `bun build --compile` standalone embeds this module at a `/$bunfs/root/…` virtual path
81
+ // (verified: import.meta.url → file:///$bunfs/root/…). `existsSync` is NO discriminator — Bun
82
+ // intercepts bunfs reads so it is true for BOTH src and compiled. The `$bunfs` marker in the self
83
+ // path IS the discriminator: compiled → re-invoke the installed binary through its `supervisor` verb
84
+ // (the caller appends `daemon …`); source → a real on-disk file, run it directly via the runtime.
85
+ return selfPath.includes('$bunfs') ? [execPath, 'supervisor'] : [execPath, selfPath]
86
+ }
87
+ const selfArgv = (): string[] => resolveDaemonSelfArgv(process.execPath, fileURLToPath(import.meta.url))
70
88
 
71
89
  /** Start a detached supervisor daemon and wait until its socket is live. Idempotent. */
72
90
  export function startSupervisorDaemon(opts: StartDaemonOptions): StartDaemonResult {
@@ -0,0 +1,22 @@
1
+ // Spawn-flip Ф1 serving-wiring — resolveDaemonSelfArgv picks the right re-invocation for the detached
2
+ // supervisor daemon: a real on-disk module (bun/source) runs directly; an EMBEDDED module (a compiled
3
+ // `bun build --compile` standalone, whose self path is NOT on disk) re-invokes the installed binary
4
+ // through its `supervisor` verb. The bug this guards: a bare bunfs-path invocation mis-routes through
5
+ // the CLI (unknown verb → usage), the daemon never comes up, and a hosted launch falls back to tmux.
6
+ import { describe, expect, test } from 'bun:test'
7
+ import { resolveDaemonSelfArgv } from './index.ts'
8
+
9
+ describe('resolveDaemonSelfArgv', () => {
10
+ // Paths are the EMPIRICALLY-verified shapes: bun → real /private/... file; compiled → /$bunfs/root/...
11
+ test('source (real on-disk module) → re-run the module directly via the runtime (bun)', () => {
12
+ expect(resolveDaemonSelfArgv('/Users/x/.bun/bin/bun', '/Users/x/iapeer/src/supervisor/index.ts'))
13
+ .toEqual(['/Users/x/.bun/bin/bun', '/Users/x/iapeer/src/supervisor/index.ts'])
14
+ })
15
+
16
+ test('compiled standalone (embedded /$bunfs path) → installed binary + `supervisor` verb', () => {
17
+ expect(resolveDaemonSelfArgv('/Users/x/.local/bin/iapeer', '/$bunfs/root/src/supervisor/index.ts'))
18
+ .toEqual(['/Users/x/.local/bin/iapeer', 'supervisor'])
19
+ // The caller appends `daemon <session> <runtime> --run-dir <dir>` → `iapeer supervisor daemon …`,
20
+ // which the CLI routes to runSupervisorCli('daemon', …). NOT a bare bunfs-path (→ usage dump).
21
+ })
22
+ })