@adhdev/daemon-core 0.9.82-rc.142 → 0.9.82-rc.144

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 (91) hide show
  1. package/dist/boot/process-hardening.d.ts +50 -0
  2. package/dist/cli-adapters/cli-script-runner.d.ts +73 -1
  3. package/dist/cli-adapters/provider-cli-adapter.d.ts +17 -0
  4. package/dist/cli-adapters/provider-cli-shared.d.ts +6 -0
  5. package/dist/commands/handler.d.ts +66 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +2876 -403
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +2890 -424
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/ipc/local-ipc-server.d.ts +91 -0
  12. package/dist/providers/contracts.d.ts +8 -0
  13. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  14. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  15. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  16. package/dist/providers/native-history/index.d.ts +11 -0
  17. package/dist/providers/provider-loader.d.ts +19 -1
  18. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  19. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
  20. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  21. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +64 -0
  22. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +82 -0
  23. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  24. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  25. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  26. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  27. package/dist/providers/sdk/v1/index.d.ts +30 -0
  28. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  29. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  30. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  31. package/dist/providers/sdk/v1/types/cli/index.d.ts +268 -0
  32. package/dist/providers/sdk/v1/types/common/index.d.ts +169 -0
  33. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  34. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  35. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  36. package/package.json +4 -2
  37. package/src/boot/daemon-lifecycle.ts +14 -10
  38. package/src/boot/process-hardening.ts +89 -0
  39. package/src/cli-adapters/cli-script-runner.ts +289 -13
  40. package/src/cli-adapters/cli-state-engine.ts +8 -5
  41. package/src/cli-adapters/provider-cli-adapter.ts +36 -2
  42. package/src/cli-adapters/provider-cli-shared.ts +6 -0
  43. package/src/commands/chat-commands.ts +22 -1
  44. package/src/commands/cli-manager.ts +39 -0
  45. package/src/commands/handler.ts +539 -1
  46. package/src/commands/router.ts +1 -0
  47. package/src/index.ts +27 -0
  48. package/src/ipc/local-ipc-server.ts +278 -0
  49. package/src/providers/cli-provider-instance.ts +15 -0
  50. package/src/providers/contracts.ts +8 -0
  51. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  52. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  53. package/src/providers/native-history/codex-cli-transcript.ts +419 -0
  54. package/src/providers/native-history/index.ts +23 -0
  55. package/src/providers/provider-loader.ts +258 -17
  56. package/src/providers/provider-schema.ts +3 -0
  57. package/src/providers/sdk/README.md +49 -0
  58. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  59. package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
  60. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  61. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +245 -0
  62. package/src/providers/sdk/v1/builders/cli/parse-session.ts +247 -0
  63. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  64. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  65. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  66. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  67. package/src/providers/sdk/v1/index.ts +151 -0
  68. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  69. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  70. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  71. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +428 -0
  72. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  73. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  74. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  75. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  76. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  77. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  78. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  79. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  80. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +119 -0
  81. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  82. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  83. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  84. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  85. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  86. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  87. package/src/providers/sdk/v1/types/cli/index.ts +355 -0
  88. package/src/providers/sdk/v1/types/common/index.ts +210 -0
  89. package/src/providers/sdk/v1/validators/index.ts +19 -0
  90. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  91. package/src/providers/sdk/v1/validators/taint.ts +309 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Process-level hardening — boot-time mitigations against provider scripts.
3
+ *
4
+ * Provider scripts run in-process (see providers/sdk/v1/sandbox/README-design.ts).
5
+ * The require() whitelist (sandbox/require-whitelist.ts) blocks the obvious
6
+ * attack surfaces (no `child_process.exec`, no `fs.writeFile`, no `net`, etc.)
7
+ * but a malicious or buggy script can still:
8
+ *
9
+ * 1. Pollute Object.prototype to influence the daemon's downstream consumers
10
+ * (e.g. `Object.prototype.toString = () => '...'` makes every untagged
11
+ * object stringify to that value across the whole process).
12
+ * 2. Mutate Array/Function/String prototypes for similar effect.
13
+ * 3. Call `process.exit()` / `process.kill()` to kill the daemon.
14
+ *
15
+ * Sandbox isolation (isolated-vm) is the proper fix but has a real perf cost
16
+ * and a real marshalling-complexity cost. As a cheaper layer we just freeze
17
+ * the built-in prototypes at boot, which is irreversible and catches every
18
+ * prototype-pollution variant for the lifetime of the process.
19
+ *
20
+ * `applyProcessHardening()` is idempotent — calling it twice is a no-op the
21
+ * second time. The function intentionally swallows any "cannot redefine
22
+ * property" errors that would arise if some upstream code already froze
23
+ * the same prototype: the post-condition (prototype is frozen) is satisfied
24
+ * either way.
25
+ *
26
+ * Trade-offs:
27
+ * - Read-only access to prototype methods (`Object.prototype.hasOwnProperty.call`,
28
+ * `Array.prototype.slice.call`, etc.) is unaffected — only writes throw.
29
+ * - Some older npm libraries patch Array.prototype or Function.prototype at
30
+ * import time. If a daemon-core dep does this, the import will throw. The
31
+ * daemon-core vitest suite is the canonical regression check for this.
32
+ * - We deliberately do NOT freeze RegExp.prototype, Error.prototype, Map/Set
33
+ * prototypes, or Date.prototype because at least one of those tends to be
34
+ * mutated by mainstream test/runtime libs and the value of freezing them
35
+ * is low (no useful prototype-pollution attack surface).
36
+ */
37
+ /**
38
+ * Freeze the canonical built-in prototypes so provider scripts (and anything
39
+ * else running in this process) cannot mutate them. Idempotent.
40
+ *
41
+ * Returns the list of prototype names that were newly frozen — primarily for
42
+ * tests / observability. Already-frozen prototypes are not re-reported.
43
+ */
44
+ export declare function applyProcessHardening(): string[];
45
+ /** For tests only — clears the internal "already hardened" flag. The
46
+ * prototypes themselves cannot be un-frozen, so this is mostly useful for
47
+ * testing the idempotency guard. */
48
+ export declare function _resetProcessHardeningForTest(): void;
49
+ /** For tests only — peek at the hardened state. */
50
+ export declare function _isProcessHardened(): boolean;
@@ -10,13 +10,76 @@
10
10
  * remain a pure transport layer without embedding parsing logic.
11
11
  */
12
12
  import { type CliApprovalInput, type CliScripts, type CliScriptInput, type CliScreenSnapshot, type CliStatusInput, type ParsedSession } from './provider-cli-shared.js';
13
+ /**
14
+ * One entry per script invocation, kept in a ring buffer so debug
15
+ * tooling can answer "what did the script see, and what did it return?"
16
+ * without having to re-run the daemon with custom logs. This is the
17
+ * trace that would have answered the codex-cli #102 regression in one
18
+ * pass instead of a dozen guesses.
19
+ *
20
+ * Body fields are bounded: input is reduced to a small summary (sizes
21
+ * + a salted hash + the first few normalized chars of screenText), and
22
+ * result is JSON-serialized then capped. Full PTY frames are NOT
23
+ * captured here — they live in CliBufferSnapshot and are exposed by
24
+ * the chat debug bundle separately.
25
+ */
26
+ export interface CliScriptInvocationTrace {
27
+ at: number;
28
+ scriptName: string;
29
+ arity: number;
30
+ inputSummary: {
31
+ screenTextLen: number;
32
+ rawBufferLen: number;
33
+ tailLen: number;
34
+ isWaitingForResponse?: boolean;
35
+ screenTextHead?: string;
36
+ };
37
+ ok: boolean;
38
+ elapsedUs: number;
39
+ resultSummary?: string;
40
+ error?: string;
41
+ /**
42
+ * True when the invocation's elapsed time exceeded the runner's
43
+ * `scriptCallBudgetMs`. The script is NOT aborted (Node CJS can't
44
+ * interrupt sync code without a worker thread) — this flag plus the
45
+ * trace ring lets an operator identify which provider is hanging the
46
+ * settle loop. A throttled WARN is emitted alongside.
47
+ */
48
+ timedOut?: boolean;
49
+ }
13
50
  export declare class CliScriptRunner {
14
51
  private scripts;
15
52
  private scriptState;
16
53
  private _parseErrorMessage;
17
54
  private readonly cliType;
55
+ private sdk;
56
+ private invocationTrace;
57
+ /** Per-invocation wall-clock budget (ms). Configurable via setScriptCallBudget. */
58
+ private scriptCallBudgetMs;
59
+ /** Last WARN emit time per scriptName, used to throttle repeated budget violations. */
60
+ private lastBudgetWarnAt;
18
61
  constructor(cliType: string);
19
- setScripts(scripts: CliScripts): void;
62
+ /** Returns the most-recent script invocation traces (oldest → newest). */
63
+ getInvocationTrace(): CliScriptInvocationTrace[];
64
+ /** Clear the trace ring — used by tests and after PTY reset. */
65
+ clearInvocationTrace(): void;
66
+ /**
67
+ * Configure the wall-clock budget (ms) applied to every script invocation.
68
+ *
69
+ * Out-of-range or non-finite values are clamped to [1, 5000] and the
70
+ * default (50ms) is used as a fallback. The budget is enforced per-call,
71
+ * not aggregated — it does not abort a runaway script (Node CJS cannot
72
+ * interrupt synchronous code without a worker thread). Instead, an
73
+ * exceeded budget flags the trace entry with `timedOut: true` and emits
74
+ * a throttled WARN naming the script and elapsed time so an operator
75
+ * can identify which provider is hanging the settle loop.
76
+ */
77
+ setScriptCallBudget(ms: number): void;
78
+ /** Test/debug accessor — current effective budget in ms. */
79
+ getScriptCallBudgetMs(): number;
80
+ private recordTrace;
81
+ setScripts(scripts: CliScripts, providerTui?: Record<string, unknown> | undefined): void;
82
+ private buildSdk;
20
83
  /** Reset per-session state — called when the PTY process exits. */
21
84
  resetSessionState(): void;
22
85
  /** Returns the live scripts object. Direct property assignment on this object
@@ -42,4 +105,13 @@ export declare class CliScriptRunner {
42
105
  */
43
106
  invokeByName(name: string, input: any): any;
44
107
  private invoke;
108
+ /**
109
+ * Returns true when `elapsedUs` exceeded the configured budget. On the
110
+ * first violation per script (or after the throttle window expires) we
111
+ * emit a single WARN so the operator learns which provider is slow.
112
+ *
113
+ * We deliberately throttle per-scriptName so a chronically-slow
114
+ * detectStatus doesn't spam the log on every PTY frame settle.
115
+ */
116
+ private checkBudget;
45
117
  }
@@ -65,6 +65,23 @@ export declare class ProviderCliAdapter implements CliAdapter {
65
65
  private readonly runner;
66
66
  /** @deprecated use runner.cliScripts for direct script access */
67
67
  get cliScripts(): CliScripts;
68
+ /**
69
+ * Recent script invocations (oldest → newest). Exposed via the
70
+ * `get_chat_debug_bundle` daemon command so anyone debugging a
71
+ * stuck-status regression can read what each detectStatus /
72
+ * parseSession call actually saw and returned, instead of having
73
+ * to instrument the daemon.
74
+ */
75
+ getScriptInvocationTrace(): import("./cli-script-runner.js").CliScriptInvocationTrace[];
76
+ /**
77
+ * Returns the full raw PTY byte stream captured since adapter start.
78
+ * Used by the `record_provider_pty` IPC command to produce fixtures.
79
+ * Bounded by MAX_ACCUMULATED_BUFFER; older bytes may have been dropped.
80
+ */
81
+ getAccumulatedRawBuffer(): {
82
+ text: string;
83
+ droppedChars: number;
84
+ };
68
85
  set cliScripts(scripts: CliScripts);
69
86
  private runtimeSettings;
70
87
  /** Full accumulated rendered PTY transcript for parser/readback use */
@@ -175,6 +175,10 @@ export interface CliProviderModule {
175
175
  binary: string;
176
176
  approvalKeys?: Record<number, string>;
177
177
  sendDelayMs?: number;
178
+ /** Wall-clock budget (ms) for a single provider script invocation. Default 50. Range 1..5000.
179
+ * Exceeding the budget records `timedOut: true` on the invocation trace and emits a
180
+ * throttled WARN — it does NOT abort the script (Node CJS can't interrupt sync code). */
181
+ scriptCallBudgetMs?: number;
178
182
  sendKey?: string;
179
183
  submitStrategy?: 'wait_for_echo' | 'immediate';
180
184
  /** Require the typed prompt to be visible on the PTY screen before sending Enter. */
@@ -189,6 +193,8 @@ export interface CliProviderModule {
189
193
  transcriptAuthority?: 'provider' | 'daemon';
190
194
  /** Full context lets provider-owned parsers canonicalize retained history instead of daemon prefix stitching. */
191
195
  transcriptContext?: 'full' | 'tail';
196
+ /** v1 declarative tui block — used by CliScriptRunner to synthesize SDK helpers (declarativeDetectStatus, declarativeParseApproval). */
197
+ tui?: Record<string, unknown>;
192
198
  scripts?: CliScripts;
193
199
  spawn: {
194
200
  command: string;
@@ -104,7 +104,73 @@ export declare class DaemonCommandHandler implements CommandHelpers {
104
104
  setAgentStreamManager(manager: DaemonAgentStreamManager): void;
105
105
  handle(cmd: string, args: any): Promise<CommandResult>;
106
106
  private dispatch;
107
+ /**
108
+ * Reload providers from disk. Does NOT pull from the registry — the user
109
+ * controls installs explicitly via install_provider_manifest. To upgrade
110
+ * an installed provider, call install_provider_manifest again with the
111
+ * desired version (or with no version to pick up the latest from
112
+ * registry), or use check_provider_updates to see what is out of date.
113
+ */
107
114
  private handleRefreshScripts;
115
+ /**
116
+ * Return per-provider availability so a Marketplace UI can show
117
+ * "Installed" badges. Reuses the existing detection state from
118
+ * ProviderLoader.getMachineProviderStatus() — no probing is triggered.
119
+ */
120
+ private handleListProviderAvailability;
121
+ /**
122
+ * Compute the *Marketplace install root*. This is always
123
+ * `~/.adhdev/marketplace/` regardless of how ProviderLoader resolved its
124
+ * userDir (which can point to a sibling adhdev-providers git checkout in
125
+ * dev). Marketplace-installed manifests must never overwrite files in a
126
+ * developer checkout, and they should be isolated from upstream/registry
127
+ * sync so they survive `refresh_scripts`.
128
+ */
129
+ private getMarketplaceInstallRoot;
130
+ /**
131
+ * Download a single provider manifest from the registry and write it to
132
+ * ~/.adhdev/marketplace/{category}/{type}/provider.json.
133
+ *
134
+ * Used by the Marketplace UI's Install button. Verifies SHA-256 checksum
135
+ * against the registry meta before persisting. Refuses to write outside
136
+ * the marketplace root.
137
+ *
138
+ * Args: { type: string, category?: string, version?: string }
139
+ * If category/version are omitted, looks up the latest from the registry.
140
+ */
141
+ private handleInstallProviderManifest;
142
+ /**
143
+ * If `manifest.source = { type:'github', repo, ref, subdir? }` is set,
144
+ * walk each script directory the manifest references and download every
145
+ * file from the public GitHub raw endpoint. Returns a small summary so
146
+ * the caller can report what was fetched.
147
+ *
148
+ * Best-effort: failures don't reject the install — the manifest itself is
149
+ * usable for declarative-only providers, and the user still gets a clear
150
+ * error string back if a needed script is missing.
151
+ */
152
+ private fetchProviderSources;
153
+ /**
154
+ * Remove a provider manifest from the marketplace install root
155
+ * (~/.adhdev/marketplace/{category}/{type}/). Refuses to touch anything
156
+ * outside that root.
157
+ */
158
+ private handleUninstallProviderManifest;
159
+ /**
160
+ * Return everything currently installed in ~/.adhdev/marketplace/ with its
161
+ * version. This is the "what does this daemon have" answer used both by
162
+ * the UI and by the update checker.
163
+ */
164
+ private handleListInstalledProviders;
165
+ /**
166
+ * For each installed provider, ask the registry for its current latest
167
+ * version and report whether an update is available. The user can then
168
+ * call install_provider_manifest to upgrade (it overwrites the file).
169
+ *
170
+ * Returns { providers: [{ type, category, installedVersion, latestVersion,
171
+ * updateAvailable, error? }] }
172
+ */
173
+ private handleCheckProviderUpdates;
108
174
  private proxyDevServerPost;
109
175
  private proxyDevServerGet;
110
176
  private proxyDevServerScaffold;
package/dist/index.d.ts CHANGED
@@ -134,3 +134,5 @@ export { getAIExtensions, installExtensions, launchIDE, isExtensionInstalled } f
134
134
  export type { ExtensionInfo as InstallerExtensionInfo } from './installer.js';
135
135
  export { initDaemonComponents, startDaemonDevSupport, shutdownDaemonComponents } from './boot/daemon-lifecycle.js';
136
136
  export type { DaemonInitConfig, DaemonComponents, DaemonDevSupportOptions } from './boot/daemon-lifecycle.js';
137
+ export { startLocalIpcServer, buildIpcStatusHttpResponse, type LocalIpcServerOptions, type LocalIpcServerHandle, type IpcCommandContext, type IpcCommandResult, type IpcStatusPayload, } from './ipc/local-ipc-server.js';
138
+ export { validateCliProviderManifest, formatManifestValidationIssues, type ManifestValidationIssue, type ManifestValidationResult, V1_CONTRACT_VERSION, V1_PRIMITIVE_CATALOG, V1_ALL_PRIMITIVES, } from './providers/sdk/v1/index.js';