@crouter/api 0.3.387 → 0.3.388

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.
Files changed (130) hide show
  1. package/dist/api/__tests__/integration/client.test.js +97 -0
  2. package/dist/api/client.d.ts +7 -0
  3. package/dist/api/client.js +40 -21
  4. package/dist/core/asset-root.d.ts +7 -0
  5. package/dist/core/asset-root.js +18 -0
  6. package/dist/core/canvas/boot-id.d.ts +6 -0
  7. package/dist/core/canvas/boot-id.js +26 -0
  8. package/dist/core/canvas/paths.d.ts +72 -0
  9. package/dist/core/canvas/paths.js +163 -0
  10. package/dist/core/canvas/pid.d.ts +391 -0
  11. package/dist/core/canvas/pid.js +948 -0
  12. package/dist/core/command-plugins/bundle.d.ts +149 -0
  13. package/dist/core/command-plugins/bundle.js +588 -0
  14. package/dist/core/command-plugins/endpoint.d.ts +24 -0
  15. package/dist/core/command-plugins/endpoint.js +51 -0
  16. package/dist/core/config.d.ts +233 -0
  17. package/dist/core/config.js +1120 -0
  18. package/dist/core/env-name.d.ts +6 -0
  19. package/dist/core/env-name.js +9 -0
  20. package/dist/core/errors.d.ts +38 -0
  21. package/dist/core/errors.js +90 -0
  22. package/dist/core/events/emit.d.ts +6 -0
  23. package/dist/core/events/emit.js +42 -0
  24. package/dist/core/events/envelope.d.ts +2 -0
  25. package/dist/core/events/envelope.js +84 -0
  26. package/dist/core/events/errors.d.ts +4 -0
  27. package/dist/core/events/errors.js +69 -0
  28. package/dist/core/events/operation-id.d.ts +4 -0
  29. package/dist/core/events/operation-id.js +24 -0
  30. package/dist/core/events/serialize.d.ts +4 -0
  31. package/dist/core/events/serialize.js +199 -0
  32. package/dist/core/events/source.d.ts +16 -0
  33. package/dist/core/events/source.js +31 -0
  34. package/dist/core/events/types.d.ts +68 -0
  35. package/dist/core/events/types.js +11 -0
  36. package/dist/core/exclusive-lock.d.ts +34 -0
  37. package/dist/core/exclusive-lock.js +197 -0
  38. package/dist/core/fs-utils.d.ts +44 -0
  39. package/dist/core/fs-utils.js +208 -0
  40. package/dist/core/help.d.ts +309 -0
  41. package/dist/core/help.js +406 -0
  42. package/dist/core/human/page-catalog.d.ts +57 -0
  43. package/dist/core/human/page-catalog.js +172 -0
  44. package/dist/core/installed-plugins.d.ts +2 -0
  45. package/dist/core/installed-plugins.js +79 -0
  46. package/dist/core/io.d.ts +122 -0
  47. package/dist/core/io.js +373 -0
  48. package/dist/core/keybindings/attach-control.d.ts +49 -0
  49. package/dist/core/keybindings/attach-control.js +42 -0
  50. package/dist/core/keybindings/catalog.d.ts +18 -0
  51. package/dist/core/keybindings/catalog.js +257 -0
  52. package/dist/core/keybindings/types.d.ts +42 -0
  53. package/dist/core/keybindings/types.js +1 -0
  54. package/dist/core/layout.d.ts +26 -0
  55. package/dist/core/layout.js +94 -0
  56. package/dist/core/locked-file.d.ts +27 -0
  57. package/dist/core/locked-file.js +118 -0
  58. package/dist/core/log.d.ts +9 -0
  59. package/dist/core/log.js +89 -0
  60. package/dist/core/manifest.d.ts +5 -0
  61. package/dist/core/manifest.js +15 -0
  62. package/dist/core/plugin-env.d.ts +8 -0
  63. package/dist/core/plugin-env.js +31 -0
  64. package/dist/core/plugin-extensions.d.ts +29 -0
  65. package/dist/core/plugin-extensions.js +191 -0
  66. package/dist/core/plugin-swap-lock.d.ts +9 -0
  67. package/dist/core/plugin-swap-lock.js +31 -0
  68. package/dist/core/preview-result-path.d.ts +4 -0
  69. package/dist/core/preview-result-path.js +26 -0
  70. package/dist/core/profiles/env-store.d.ts +22 -0
  71. package/dist/core/profiles/env-store.js +163 -0
  72. package/dist/core/profiles/fuzzy-match.d.ts +19 -0
  73. package/dist/core/profiles/fuzzy-match.js +92 -0
  74. package/dist/core/profiles/manifest.d.ts +120 -0
  75. package/dist/core/profiles/manifest.js +529 -0
  76. package/dist/core/rate-limit-scope.d.ts +25 -0
  77. package/dist/core/rate-limit-scope.js +64 -0
  78. package/dist/core/render.d.ts +12 -0
  79. package/dist/core/render.js +138 -0
  80. package/dist/core/resolver.d.ts +14 -0
  81. package/dist/core/resolver.js +111 -0
  82. package/dist/core/runtime/branded-host.d.ts +25 -0
  83. package/dist/core/runtime/branded-host.js +264 -0
  84. package/dist/core/runtime/broker/daemon-ops.d.ts +65 -0
  85. package/dist/core/runtime/broker/daemon-ops.js +177 -0
  86. package/dist/core/runtime/broker/signal-stream.d.ts +30 -0
  87. package/dist/core/runtime/broker/signal-stream.js +149 -0
  88. package/dist/core/scope.d.ts +32 -0
  89. package/dist/core/scope.js +184 -0
  90. package/dist/core/scoped-state/db.d.ts +17 -0
  91. package/dist/core/scoped-state/db.js +247 -0
  92. package/dist/core/scoped-state/migrate.d.ts +8 -0
  93. package/dist/core/scoped-state/migrate.js +187 -0
  94. package/dist/core/scoped-state/paths.d.ts +9 -0
  95. package/dist/core/scoped-state/paths.js +27 -0
  96. package/dist/core/scoped-state/profiles.d.ts +27 -0
  97. package/dist/core/scoped-state/profiles.js +93 -0
  98. package/dist/core/scoped-state/providers.d.ts +24 -0
  99. package/dist/core/scoped-state/providers.js +19 -0
  100. package/dist/core/scoped-state/schema.d.ts +6 -0
  101. package/dist/core/scoped-state/schema.js +43 -0
  102. package/dist/core/scoped-state/settings.d.ts +28 -0
  103. package/dist/core/scoped-state/settings.js +83 -0
  104. package/dist/core/spaces/open-beneath.d.ts +71 -0
  105. package/dist/core/spaces/open-beneath.js +581 -0
  106. package/dist/core/sqlite-statements.d.ts +4 -0
  107. package/dist/core/sqlite-statements.js +17 -0
  108. package/dist/core/subscription-state.d.ts +121 -0
  109. package/dist/core/subscription-state.js +287 -0
  110. package/dist/core/user-settings.d.ts +377 -0
  111. package/dist/core/user-settings.js +458 -0
  112. package/dist/daemon/broker-signals/bus.d.ts +30 -0
  113. package/dist/daemon/broker-signals/bus.js +87 -0
  114. package/dist/daemon/manage.d.ts +176 -0
  115. package/dist/daemon/manage.js +664 -0
  116. package/dist/daemon/pidfile.d.ts +8 -0
  117. package/dist/daemon/pidfile.js +37 -0
  118. package/dist/daemon/startup-policy.d.ts +1 -0
  119. package/dist/daemon/startup-policy.js +1 -0
  120. package/dist/native/linux.d.ts +29 -0
  121. package/dist/native/linux.js +20 -0
  122. package/dist/shared/env.d.ts +116 -0
  123. package/dist/shared/env.js +271 -0
  124. package/dist/shared/inbox-entry-body.d.ts +22 -0
  125. package/dist/shared/inbox-entry-body.js +116 -0
  126. package/dist/shared/working-activity.d.ts +9 -0
  127. package/dist/shared/working-activity.js +27 -0
  128. package/dist/types.d.ts +562 -0
  129. package/dist/types.js +186 -0
  130. package/package.json +1 -1
@@ -0,0 +1,176 @@
1
+ import { type HealthDTO, type StartupPhaseDTO } from '../api/index.js';
2
+ /** Env keys that must NEVER reach the daemon process. Restarting crtrd is
3
+ * overwhelmingly done from inside an agent node's own bash tool (`crtr sys
4
+ * daemon stop && start`), which inherits that node's FULL env — its identity
5
+ * (`CRTR_NODE_ID`/`CRTR_KIND`/…, the `nodeEnv()` shape in `core/runtime/
6
+ * nodes.ts`), its front-door recursion-guard flag, and any pi-engine
7
+ * resolution seam a prior test/dev session left exported. The daemon is a
8
+ * singleton supervisor, never "a node" itself, so none of this belongs in its
9
+ * env regardless of whether today's code happens to read it — and at least one
10
+ * of these IS actively read: `host.ts`'s broker-engine resolution falls back to
11
+ * `envBrokerEngine()`'s raw `CRTR_BROKER_ENGINE` read verbatim (nodeEnv() never
12
+ * sets that key, so nothing overrides it per child launch), so a daemon that inherits a
13
+ * stale/dev override throws inside `headlessBrokerHost.launch()` on EVERY
14
+ * relaunch it ever attempts, for its whole lifetime — the 2026-07-06 diagnosis
15
+ * root cause behind 19 nodes killed with "failed to relaunch and is now dead". */
16
+ export declare const DAEMON_ENV_STRIP_KEYS: readonly string[];
17
+ /** A copy of `process.env` with every `DAEMON_ENV_STRIP_KEYS` entry removed.
18
+ * Deliberate global config the user actually wants the daemon to see —
19
+ * `CRTR_HOME`, `CRTR_SUBTREE`, `CRTR_LOG`, `CRTR_DEBUG`, etc. — passes through
20
+ * untouched; only the node-identity/engine-poisoning surface is stripped. */
21
+ export declare function sanitizedDaemonEnv(): NodeJS.ProcessEnv;
22
+ /** A crtrd declares its owning canvas in argv, so ownership is an exact match
23
+ * on this process's canvas home. Untagged daemons retain their own
24
+ * supervision and are never counted or killed here. */
25
+ export declare function daemonCommandDeclaresCanvasHome(command: string, home: string): boolean;
26
+ /** Every crtrd process on this host that declares ownership of this process's
27
+ * canvas home, by pid. The `daemon/crtrd` argv segment distinguishes daemons
28
+ * from brokers. `ps` is best-effort: failures return no matches, and the
29
+ * current process is always excluded. */
30
+ export declare function findDaemonPids(): number[];
31
+ /** SIGTERM (then SIGKILL after a short grace) every crtrd daemon process EXCEPT
32
+ * `keepPid`. This is the backstop the pidfile alone cannot provide: a daemon
33
+ * that survived a prior stop (ignored SIGTERM, or released its ownership lock
34
+ * without exiting) keeps running a supervise loop — reviving brokers and
35
+ * contending for canvas state — while never appearing in the pidfile again, so
36
+ * `stop`'s single recorded-pid signal can never reach it. Returns the pids it
37
+ * reaped. Best-effort throughout: a pid that dies between enumeration and signal
38
+ * just no-ops. */
39
+ export declare function sweepStrayDaemons(keepPid: number | null): number[];
40
+ /** Replace PID 1 with the selected daemon generation. Docker keeps a container
41
+ * alive only while PID 1 lives, so a handover there must preserve its pid. */
42
+ export declare function execDaemon(): Promise<never>;
43
+ export interface SpawnDaemonOptions {
44
+ /** The phase that proves a daemon launched by this call is available. */
45
+ targetPhase?: 'ready' | 'prepared';
46
+ }
47
+ export interface SpawnDaemonResult {
48
+ /** True when a new daemon process was spawned. */
49
+ started: boolean;
50
+ /** PID of the newly spawned process, if started. */
51
+ pid?: number;
52
+ /** PID of the already-running daemon, if it was already up. */
53
+ existing_pid?: number;
54
+ /** Present only when a live pidfile owner does not answer `/healthz`. */
55
+ running?: true;
56
+ /** Present with `running:true` when the Unix API socket is not serving. */
57
+ serving?: false;
58
+ /** The final `/healthz` probe failure when a live owner misses readiness. */
59
+ probe_error?: string;
60
+ /** The observed phase when the daemon was available. */
61
+ startup_phase?: StartupPhaseDTO;
62
+ }
63
+ /** Make one `/healthz` observation without client-side recovery. The caller owns the availability window, so this probe cannot extend it. */
64
+ export declare function probeDaemonHealth(timeoutMs?: number): Promise<HealthDTO>;
65
+ export declare function probeErrorMessage(error: unknown): string;
66
+ /** True only when one mandatory Unix API socket probe answers the existing ready health contract. */
67
+ export declare function probeDaemonServing(timeoutMs?: number): Promise<void>;
68
+ /** True only when one mandatory Unix API socket probe answers `/healthz`.
69
+ * A pidfile identifies an owner; it is never readiness. */
70
+ export declare function isDaemonServing(): Promise<boolean>;
71
+ export interface DaemonWaitDeps {
72
+ readPidfile?: () => number | null;
73
+ isPidAlive?: (pid: number) => boolean;
74
+ sleepMs?: (ms: number) => Promise<void> | void;
75
+ now?: () => number;
76
+ }
77
+ export interface DaemonStartupDeps extends DaemonWaitDeps {
78
+ childExited?: () => {
79
+ code: number | null;
80
+ signal: NodeJS.Signals | null;
81
+ } | null;
82
+ /** What the exited child wrote to its error log, attached to the typed exit error. */
83
+ childStderrTail?: () => string;
84
+ isDaemonServing?: () => Promise<boolean>;
85
+ probeDaemonServing?: (timeoutMs: number) => Promise<void>;
86
+ probeDaemonHealth?: (timeoutMs: number) => Promise<HealthDTO>;
87
+ }
88
+ /** The spawned daemon process died before it ever became ready — a startup
89
+ * failure, not a progressing migration (a live daemon never raises this).
90
+ * `stderrTail` is what that run wrote to crtrd.err, so the CLI can say why. */
91
+ export declare class DaemonExitedBeforeReadyError extends Error {
92
+ readonly stderrTail: string;
93
+ constructor(message: string, stderrTail: string);
94
+ }
95
+ /** A live daemon has bound its repair socket but cannot serve normal work
96
+ * until its corpus migration succeeds. */
97
+ export declare class DaemonStartupBlockedError extends Error {
98
+ constructor(pid: number, message: string);
99
+ }
100
+ /** A preparation request cannot succeed unless the live daemon explicitly reports prepared. */
101
+ export declare class DaemonNotPreparedError extends Error {
102
+ constructor(pid: number, startupPhase: StartupPhaseDTO | undefined);
103
+ }
104
+ /** Tiny bounded post-spawn guard: wait for the daemon pidfile and live pid to
105
+ * appear before reporting success. This catches the "started:true but not yet
106
+ * plausibly alive" race without turning startup into a retry loop.
107
+ *
108
+ * One deadline, owner-first polling. A signal or non-zero child exit fails
109
+ * immediately. A clean code-0 exit is treated only as a possible ownership-
110
+ * claim loser (never readiness on its own): polling continues on the SAME
111
+ * deadline for a different live pidfile owner — the winner may publish its
112
+ * pidfile deliberately late — and fails at that deadline if none appears. No
113
+ * deadline extension and no retry spawn.
114
+ *
115
+ * Returns null when the spawned pid owns the pidfile; returns a different live
116
+ * daemon pid when startup lost the race to an already-running daemon. */
117
+ export declare function verifyDaemonStartup(pid: number, timeoutMs?: number, deps?: DaemonStartupDeps, targetPhase?: 'ready' | 'prepared'): Promise<number | null>;
118
+ /** Wait until a signaled daemon has exited and relinquished its pidfile. This
119
+ * makes a following start safe to claim the singleton rather than racing its
120
+ * previous owner. */
121
+ export declare function waitForDaemonExit(pid: number, timeoutMs?: number, deps?: DaemonWaitDeps): Promise<void>;
122
+ /** Stop the RECORDED daemon: SIGTERM, and if it does not exit within the wait
123
+ * window, escalate to SIGKILL exactly as `sweepStrayDaemons` does for a stray.
124
+ *
125
+ * The escalation is the point. Without it — SIGTERM, wait, throw on timeout,
126
+ * never reaching the stray sweep — the one daemon `stop` is actually aimed at
127
+ * would be the only crtrd process exempt from the SIGKILL backstop, and a
128
+ * daemon whose shutdown hangs (or outruns the window) becomes permanently
129
+ * unstoppable from the CLI: every retry re-sends a SIGTERM it is already
130
+ * ignoring, and `start` keeps refusing as "already running".
131
+ *
132
+ * A SIGKILL'd daemon runs no exit handler, so it leaves its pidfile behind
133
+ * pointing at a dead pid. That is a stale record, not an owner: `readPidfile`
134
+ * callers gate on `isPidAlive`, and the next `start` overwrites it. So this
135
+ * waits on process death alone after a kill, never on pidfile release.
136
+ *
137
+ * Returns how the daemon went down, for a truthful report. */
138
+ export declare function stopDaemonProcess(pid: number, timeoutMs?: number, deps?: DaemonWaitDeps): Promise<'terminated' | 'killed'>;
139
+ /** Spawn crtrd detached. Returns immediately; the child outlives this process.
140
+ *
141
+ * If the daemon is already running, returns {started:false, existing_pid}.
142
+ * If spawning fails (e.g. missing dist — run `npm run build` first), throws. */
143
+ export declare function spawnDaemon(opts?: SpawnDaemonOptions): Promise<SpawnDaemonResult>;
144
+ /** Whether autostart is suppressed for this invocation. `--no-autostart` or
145
+ * `CRTR_NO_DAEMON_AUTOSTART=1` forces fail-loud on a cold socket (spec §7.1) —
146
+ * for environments that manage crtrd externally and want the diagnostic, and
147
+ * for test lanes, which point `CRTR_HOME` at a throwaway directory: an
148
+ * autostarted daemon there is detached and resident, so it outlives both the
149
+ * test process and the deleted temp home with nothing left to stop it.
150
+ *
151
+ * This is the ONE gate. `ensureDaemon` below is the only path that spawns a
152
+ * daemon implicitly, so the check belongs here rather than at each caller —
153
+ * `cliClient()` reads it too, but the in-process spawn/recycle/promote callers
154
+ * reach `ensureDaemon` without going through the CLI client at all. An
155
+ * explicit `crtr sys daemon start` calls `spawnDaemon` directly and is
156
+ * deliberately unaffected. */
157
+ export declare function autostartDisabled(): boolean;
158
+ /** Reset in-process spawn backoff after a daemon is observed alive. */
159
+ export declare function resetDaemonAutostart(): void;
160
+ export interface EnsureDaemonDeps {
161
+ isDaemonRunning?: () => boolean;
162
+ spawnDaemon?: () => Promise<SpawnDaemonResult>;
163
+ now?: () => number;
164
+ }
165
+ /** Why the daemon this process autostarted died before becoming ready, or
166
+ * undefined while it is starting, running, or exited cleanly (a clean exit may
167
+ * be a lost singleton race, so only a non-zero/signal exit counts). A client
168
+ * waiting for that daemon polls this so a startup failure ends the wait now
169
+ * rather than at the end of the startup window. */
170
+ export declare function daemonAutostartStartupFailure(): string | undefined;
171
+ /** Start the daemon if it is not already running. No-op if already up, if
172
+ * autostart is suppressed for this invocation, while an attempt is in flight,
173
+ * or while backing off from a recent failure.
174
+ * Silently swallows spawn errors (the canvas still works without the daemon;
175
+ * nodes just won't be auto-revived). */
176
+ export declare function ensureDaemon(deps?: EnsureDaemonDeps): void;