@agfpd/iapeer 0.2.65 → 0.2.66

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.66",
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,23 @@ 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, selfOnDisk: boolean): string[] {
80
+ return selfOnDisk ? [execPath, selfPath] : [execPath, 'supervisor']
81
+ }
82
+ const selfArgv = (): string[] => {
83
+ const self = fileURLToPath(import.meta.url)
84
+ return resolveDaemonSelfArgv(process.execPath, self, existsSync(self))
85
+ }
70
86
 
71
87
  /** Start a detached supervisor daemon and wait until its socket is live. Idempotent. */
72
88
  export function startSupervisorDaemon(opts: StartDaemonOptions): StartDaemonResult {
@@ -0,0 +1,21 @@
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
+ test('source (self on disk) → re-run the module directly with the runtime (bun)', () => {
11
+ expect(resolveDaemonSelfArgv('/opt/homebrew/bin/bun', '/Users/x/iapeer/src/supervisor/index.ts', true))
12
+ .toEqual(['/opt/homebrew/bin/bun', '/Users/x/iapeer/src/supervisor/index.ts'])
13
+ })
14
+
15
+ test('compiled standalone (self NOT on disk = embedded /$bunfs) → installed binary + `supervisor` verb', () => {
16
+ expect(resolveDaemonSelfArgv('/Users/x/.local/bin/iapeer', '/$bunfs/root/src/supervisor/index.ts', false))
17
+ .toEqual(['/Users/x/.local/bin/iapeer', 'supervisor'])
18
+ // The caller appends `daemon <session> <runtime> --run-dir <dir>` → `iapeer supervisor daemon …`,
19
+ // which the CLI routes to runSupervisorCli('daemon', …). NOT a bare bunfs-path (→ usage).
20
+ })
21
+ })