@phux/opencode 0.2.1

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/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # @phux/opencode
2
+
3
+ OpenCode V2 plugin for operating shared terminals through an external local
4
+ phux server and appending cache-preserving fleet context. Installation,
5
+ configuration, tool behavior, target precedence,
6
+ lifecycle gaps, and safety boundaries live in the canonical
7
+ [OpenCode integration guide](../../docs/consumers/opencode.md).
8
+
9
+ ## Package development
10
+
11
+ Install locked dependencies and run the deterministic, no-LLM gates from this
12
+ directory:
13
+
14
+ ```sh
15
+ npm ci
16
+ npm run gates
17
+ npm run smoke:opencode
18
+ ```
19
+
20
+ `smoke:opencode` starts an isolated OpenCode V2 server and verifies that its
21
+ resolved config accepts the built plugin URL. Plugin setup, registration,
22
+ cleanup, and tool behavior are covered by `npm run gates`. The smoke requires
23
+ an `opencode2` executable; set `OPENCODE_BIN` to choose it.
24
+
25
+ The real packed-plugin smoke is opt-in and requires `phux >= 0.1.0`:
26
+
27
+ ```sh
28
+ PHUX_OPENCODE_REAL_SMOKE=1 npm run smoke:real
29
+ ```
30
+
31
+ It packs and installs the artifact in a temporary consumer, starts a private
32
+ phux server on a temporary socket, invokes public create/run/snapshot tool
33
+ definitions without an LLM, prints safe human attach argv, and tears down the
34
+ server on normal exit, `SIGINT`, or `SIGTERM`. It never uses the default phux
35
+ socket.
@@ -0,0 +1,535 @@
1
+ import { Plugin } from '@opencode-ai/plugin';
2
+
3
+ interface RunRequest {
4
+ readonly executable: string;
5
+ readonly args: readonly string[];
6
+ readonly cwd?: string;
7
+ readonly env?: NodeJS.ProcessEnv;
8
+ readonly signal?: AbortSignal;
9
+ readonly timeoutMs?: number;
10
+ readonly maxStdoutBytes?: number;
11
+ readonly maxStderrBytes?: number;
12
+ }
13
+ type OutputLimitStream = "stdout" | "stderr";
14
+ interface ProcessResultBase {
15
+ readonly exitCode: number | null;
16
+ readonly stdout: string;
17
+ readonly stderr: string;
18
+ }
19
+ type ProcessResult = (ProcessResultBase & {
20
+ readonly termination: "completed" | "aborted" | "timed_out";
21
+ readonly outputLimit?: never;
22
+ }) | (ProcessResultBase & {
23
+ readonly termination: "output_limit";
24
+ readonly outputLimit: OutputLimitStream;
25
+ });
26
+ type ProcessRunner = (request: RunRequest) => Promise<ProcessResult>;
27
+
28
+ interface SessionSummary {
29
+ readonly name: string;
30
+ readonly windows: number;
31
+ readonly attached: boolean;
32
+ }
33
+ interface SessionList {
34
+ readonly schema_version: 1 | 2;
35
+ readonly sessions: readonly SessionSummary[];
36
+ /** Canonical selectors for every addressable terminal (v2; empty for v1). */
37
+ readonly terminals: readonly string[];
38
+ }
39
+ interface CursorState {
40
+ readonly x: number;
41
+ readonly y: number;
42
+ readonly visible: boolean;
43
+ }
44
+ type CellColor = {
45
+ readonly kind: "default";
46
+ } | {
47
+ readonly kind: "palette";
48
+ readonly index: number;
49
+ } | {
50
+ readonly kind: "rgb";
51
+ readonly r: number;
52
+ readonly g: number;
53
+ readonly b: number;
54
+ };
55
+ interface CellStyle {
56
+ readonly bold: boolean;
57
+ readonly faint: boolean;
58
+ readonly italic: boolean;
59
+ readonly underline: boolean;
60
+ readonly blink: boolean;
61
+ readonly inverse: boolean;
62
+ readonly invisible: boolean;
63
+ readonly strikethrough: boolean;
64
+ readonly overline: boolean;
65
+ readonly fg: CellColor;
66
+ readonly bg: CellColor;
67
+ }
68
+ interface CellInfo {
69
+ readonly col: number;
70
+ readonly row: number;
71
+ readonly semantic?: "output" | "input" | "prompt";
72
+ readonly style: CellStyle;
73
+ }
74
+ interface ScreenState {
75
+ readonly schema_version: 1 | 2 | 3;
76
+ readonly pane: number;
77
+ readonly cols: number;
78
+ readonly rows: number;
79
+ readonly cursor: CursorState | null;
80
+ readonly lines: readonly string[];
81
+ readonly scrollback: readonly string[];
82
+ readonly cells?: readonly CellInfo[];
83
+ }
84
+ interface RunResult {
85
+ readonly command: string;
86
+ readonly exit_code: number;
87
+ readonly output: string;
88
+ readonly duration_ms: number;
89
+ readonly truncated: boolean;
90
+ }
91
+ interface CreateResult {
92
+ readonly session: string;
93
+ readonly terminal_id: number;
94
+ }
95
+ interface SpawnResult {
96
+ readonly terminal_id: number;
97
+ readonly satellite: string | null;
98
+ }
99
+ interface LaunchResult {
100
+ readonly schema_version: 1;
101
+ readonly terminal_id: number;
102
+ readonly integration: string;
103
+ readonly plugin: string;
104
+ /** Validated because it is part of the CLI response, but never rendered to the model. */
105
+ readonly argv: readonly string[];
106
+ }
107
+ type SpatialDirection = "horizontal" | "vertical";
108
+ interface InsertPaneResult {
109
+ readonly schema_version: 1;
110
+ readonly operation: "insert-pane";
111
+ readonly session_id: number;
112
+ readonly target_terminal_id: number;
113
+ readonly new_terminal_id: number;
114
+ readonly direction: SpatialDirection;
115
+ readonly ratio: number;
116
+ }
117
+ interface MovePaneResult {
118
+ readonly schema_version: 1;
119
+ readonly operation: "move-pane";
120
+ readonly session_id: number;
121
+ readonly source_terminal_id: number;
122
+ readonly target_terminal_id: number;
123
+ readonly direction: SpatialDirection;
124
+ readonly ratio: number;
125
+ }
126
+ interface SwapPaneResult {
127
+ readonly schema_version: 1;
128
+ readonly operation: "swap-pane";
129
+ readonly session_id: number;
130
+ readonly first_terminal_id: number;
131
+ readonly second_terminal_id: number;
132
+ }
133
+ interface AskedEvent {
134
+ readonly event: "asked";
135
+ readonly terminal: string;
136
+ readonly id: string;
137
+ readonly question: string;
138
+ readonly suggestions: readonly string[];
139
+ readonly elapsed_seconds: number | null;
140
+ }
141
+ type WatchEvent = {
142
+ readonly event: "title_changed";
143
+ readonly terminal?: string;
144
+ readonly title: string;
145
+ } | {
146
+ readonly event: "command_started" | "bell" | "pane_spawned" | "dirty" | "idle";
147
+ readonly terminal?: string;
148
+ } | {
149
+ readonly event: "command_finished";
150
+ readonly terminal?: string;
151
+ readonly exit_code: number | null;
152
+ } | {
153
+ readonly event: "pane_closed";
154
+ readonly terminal?: string;
155
+ readonly exit_status: number | null;
156
+ } | ({
157
+ readonly event: "asked";
158
+ readonly terminal?: string;
159
+ } & Omit<AskedEvent, "event" | "terminal">) | {
160
+ readonly event: "unknown";
161
+ readonly terminal?: string;
162
+ readonly tag: number;
163
+ };
164
+ interface RenderedCell {
165
+ readonly grapheme: string;
166
+ readonly style: CellStyle;
167
+ }
168
+ interface RenderedFrame {
169
+ readonly schema_version: 1;
170
+ readonly cols: number;
171
+ readonly rows: number;
172
+ readonly cursor: CursorState | null;
173
+ readonly cells: readonly RenderedCell[];
174
+ }
175
+ interface TagRow {
176
+ readonly terminal: string;
177
+ /** Opaque human confirmation text; the current CLI has no tag JSON shape. */
178
+ readonly tagsText: string;
179
+ }
180
+ type AgentKind = "codex" | "claude" | "plugin" | "declared" | "unknown";
181
+ type AgentState = "unknown" | "idle" | "working" | "blocked" | "done";
182
+ type AgentAttention = "none" | "low" | "normal" | "high";
183
+ interface AgentIdentity {
184
+ readonly id: string;
185
+ readonly label: string;
186
+ readonly kind: AgentKind;
187
+ }
188
+ interface AgentSource {
189
+ readonly kind: string;
190
+ readonly signal: string;
191
+ readonly confidence: number;
192
+ readonly observed: string;
193
+ }
194
+ interface AgentPane {
195
+ /** Canonical phux pane selector, for example @3 or host/@3. */
196
+ readonly terminal: string;
197
+ readonly session: string;
198
+ readonly window: string;
199
+ readonly agent: AgentIdentity;
200
+ readonly state: AgentState;
201
+ readonly confidence: number;
202
+ readonly attention: AgentAttention;
203
+ readonly title: string | null;
204
+ readonly cwd: string | null;
205
+ readonly sources: readonly AgentSource[];
206
+ readonly explanation: string;
207
+ }
208
+ interface AgentStateList {
209
+ readonly schema_version: 1;
210
+ readonly agents: readonly AgentPane[];
211
+ }
212
+ /**
213
+ * The declared `phux.agent/v1` record written by `phux agent set`.
214
+ *
215
+ * `state` and `attention` are OPTIONAL, per `docs/spec/L3.md` §3.7 where only
216
+ * `name` is required. Declaring a `state` outranks the server's derivation for
217
+ * the record's whole lifetime (ADR-0046 point 8), so an integration that can
218
+ * let the server derive should omit it and write identity alone.
219
+ */
220
+ interface AgentRecord {
221
+ readonly name: string;
222
+ readonly kind: string;
223
+ readonly state?: AgentState;
224
+ readonly attention?: AgentAttention;
225
+ readonly session: string;
226
+ }
227
+
228
+ interface PhuxCliOptions {
229
+ readonly executable?: string;
230
+ readonly socket?: string;
231
+ readonly cwd?: string;
232
+ readonly env?: NodeJS.ProcessEnv;
233
+ readonly runner?: ProcessRunner;
234
+ readonly maxStdoutBytes?: number;
235
+ readonly maxStderrBytes?: number;
236
+ }
237
+ interface ExecutionOptions {
238
+ /** Abort this local subprocess invocation. */
239
+ readonly signal?: AbortSignal;
240
+ /** Kill this local subprocess if it has not exited within this many ms. */
241
+ readonly timeoutMs?: number;
242
+ }
243
+ interface SnapshotOptions extends ExecutionOptions {
244
+ readonly target?: string;
245
+ /** true or zero means all retained history; a positive number bounds it. */
246
+ readonly scrollback?: boolean | number;
247
+ readonly cells?: boolean;
248
+ }
249
+ interface WaitOptions extends ExecutionOptions {
250
+ readonly target?: string;
251
+ readonly until?: string;
252
+ readonly idleMs?: number;
253
+ /** phux's own wait deadline, in seconds (distinct from local timeoutMs). */
254
+ readonly phuxTimeoutSeconds?: number;
255
+ }
256
+ type WaitOutcome = {
257
+ readonly outcome: "satisfied";
258
+ readonly screen: ScreenState;
259
+ } | {
260
+ readonly outcome: "timed_out";
261
+ readonly screen: ScreenState;
262
+ };
263
+ interface CreateOptions extends ExecutionOptions {
264
+ readonly cwd?: string;
265
+ readonly command?: readonly string[];
266
+ }
267
+ interface RunOptions extends ExecutionOptions {
268
+ /** phux's own sentinel deadline, in seconds (distinct from local timeoutMs). */
269
+ readonly phuxTimeoutSeconds?: number;
270
+ }
271
+ interface AgentTargetOptions extends ExecutionOptions {
272
+ readonly target: string;
273
+ }
274
+ type SplitDirection = "horizontal" | "vertical";
275
+ interface PlacementOptions {
276
+ readonly target?: string;
277
+ readonly split?: SplitDirection;
278
+ readonly ratio?: number;
279
+ }
280
+ interface SpawnOptions extends ExecutionOptions, PlacementOptions {
281
+ readonly satellite?: string;
282
+ readonly cwd?: string;
283
+ readonly command?: readonly string[];
284
+ }
285
+ interface LaunchOptions extends ExecutionOptions, PlacementOptions {
286
+ readonly cwd?: string;
287
+ readonly extra?: readonly string[];
288
+ }
289
+ interface SpatialOptions extends ExecutionOptions {
290
+ readonly direction?: SplitDirection;
291
+ readonly ratio?: number;
292
+ }
293
+ interface RenderedSnapshotOptions extends ExecutionOptions {
294
+ readonly session?: string;
295
+ readonly cols: number;
296
+ readonly rows: number;
297
+ }
298
+ interface AskOptions extends ExecutionOptions {
299
+ readonly id?: string;
300
+ readonly suggestions?: readonly string[];
301
+ readonly elapsedSeconds?: number;
302
+ }
303
+ type TerminalSignal = "interrupt" | "freeze" | "resume" | "terminate" | "kill";
304
+ type TagAction = "ls" | "add" | "rm";
305
+ interface WatchOptions extends ExecutionOptions {
306
+ readonly target: string;
307
+ /** Required collection window. The streaming CLI is always stopped after this bound. */
308
+ readonly durationMs: number;
309
+ readonly maxEvents: number;
310
+ }
311
+ interface WatchCollection {
312
+ readonly events: readonly WatchEvent[];
313
+ readonly truncated: boolean;
314
+ readonly ended: boolean;
315
+ }
316
+ interface PhuxProbe {
317
+ readonly available: boolean;
318
+ readonly version?: string;
319
+ readonly rawVersion?: string;
320
+ readonly reason?: string;
321
+ }
322
+ declare class PhuxCli {
323
+ readonly executable: string;
324
+ readonly socket: string | undefined;
325
+ private readonly cwd;
326
+ private readonly env;
327
+ private readonly runner;
328
+ private readonly maxStdoutBytes;
329
+ private readonly maxStderrBytes;
330
+ constructor(options?: PhuxCliOptions);
331
+ probe(options?: ExecutionOptions): Promise<PhuxProbe>;
332
+ ls(options?: ExecutionOptions): Promise<SessionList>;
333
+ /** Inventory panes and their owning session through the documented agent CLI projection. */
334
+ agentList(options?: ExecutionOptions): Promise<AgentStateList>;
335
+ create(name: string, options?: CreateOptions): Promise<CreateResult>;
336
+ spawn(options?: SpawnOptions): Promise<SpawnResult>;
337
+ launch(integration: string, options?: LaunchOptions): Promise<LaunchResult>;
338
+ insertPane(target: string, newPane: string, options?: SpatialOptions): Promise<InsertPaneResult>;
339
+ movePane(source: string, target: string, options?: SpatialOptions): Promise<MovePaneResult>;
340
+ swapPane(first: string, second: string, options?: ExecutionOptions): Promise<SwapPaneResult>;
341
+ /** Read one pane's public projection, including declared-record provenance. */
342
+ agentShow(options: AgentTargetOptions): Promise<AgentStateList>;
343
+ /** Write and parse the CLI's confirmed whole-record response. */
344
+ agentSet(target: string, record: AgentRecord, options?: ExecutionOptions): Promise<AgentRecord>;
345
+ /** Clear a declaration and require the CLI's confirmed tombstone response. */
346
+ agentClear(target: string, options?: ExecutionOptions): Promise<void>;
347
+ renderedSnapshot(options: RenderedSnapshotOptions): Promise<RenderedFrame>;
348
+ snapshot(options?: SnapshotOptions): Promise<ScreenState>;
349
+ wait(options?: WaitOptions): Promise<WaitOutcome>;
350
+ run(target: string, command: readonly string[], options?: RunOptions): Promise<RunResult>;
351
+ sendKeys(target: string, keys: readonly string[], options?: ExecutionOptions): Promise<void>;
352
+ kill(target: string, options?: ExecutionOptions): Promise<void>;
353
+ signal(target: string, signal: TerminalSignal, options?: ExecutionOptions): Promise<void>;
354
+ tag(action: TagAction, target: string, tags?: readonly string[], options?: ExecutionOptions): Promise<readonly TagRow[]>;
355
+ ask(target: string, question: string, options?: AskOptions): Promise<AskedEvent>;
356
+ watch(options: WatchOptions): Promise<WatchCollection>;
357
+ private jsonCommand;
358
+ private completed;
359
+ private execute;
360
+ private throwTermination;
361
+ private withSocket;
362
+ private pushSocket;
363
+ }
364
+
365
+ declare const PHUX_CONTEXT_VERSION: 1;
366
+ interface PhuxAwarenessAdapter {
367
+ agentList(options?: ExecutionOptions): Promise<AgentStateList>;
368
+ }
369
+ interface PhuxContextIdentity {
370
+ readonly self?: string;
371
+ readonly selected?: string;
372
+ }
373
+ interface PhuxContextAwarenessOptions {
374
+ readonly enabled?: boolean;
375
+ readonly timeoutMs?: number;
376
+ readonly maxBytes?: number;
377
+ readonly maxPanes?: number;
378
+ readonly checkpointInterval?: number;
379
+ }
380
+ type PhuxContextKind = "checkpoint" | "delta";
381
+ interface PhuxContextEmission {
382
+ readonly version: typeof PHUX_CONTEXT_VERSION;
383
+ readonly kind: PhuxContextKind;
384
+ readonly seq: number;
385
+ readonly text: string;
386
+ }
387
+ /**
388
+ * Per-host-session fleet projection. It emits one full checkpoint, then only
389
+ * changed suffix messages so provider prompt prefixes remain reusable.
390
+ */
391
+ declare class PhuxContextAwareness {
392
+ private readonly adapter;
393
+ private readonly enabled;
394
+ private readonly timeoutMs;
395
+ private readonly maxBytes;
396
+ private readonly maxPanes;
397
+ private readonly checkpointInterval;
398
+ private readonly streams;
399
+ private readonly tails;
400
+ constructor(adapter: PhuxAwarenessAdapter, options?: PhuxContextAwarenessOptions);
401
+ next(streamId: string, identity?: PhuxContextIdentity, signal?: AbortSignal): Promise<PhuxContextEmission | null>;
402
+ /**
403
+ * Produce a compactor-only checkpoint. The next normal turn is forced to
404
+ * persist another checkpoint whether compaction succeeds or fails.
405
+ */
406
+ checkpoint(streamId: string, identity?: PhuxContextIdentity, signal?: AbortSignal): Promise<PhuxContextEmission | null>;
407
+ forceCheckpoint(streamId: string): void;
408
+ delete(streamId: string): void;
409
+ private serialized;
410
+ private emit;
411
+ private stream;
412
+ private project;
413
+ }
414
+ declare function contextAwarenessEnabled(value: string | undefined, fallback?: boolean): boolean;
415
+ declare function normalizeTerminalIdentity(value: string | undefined): string | null;
416
+
417
+ type JsonSchema = Readonly<Record<string, unknown>>;
418
+ interface ToolContext {
419
+ readonly sessionID: string;
420
+ readonly agent: string;
421
+ readonly messageID: string;
422
+ readonly id: string;
423
+ }
424
+ interface ToolResult {
425
+ readonly content: string;
426
+ readonly metadata: PhuxToolMetadata;
427
+ }
428
+ interface PhuxToolDefinition<Input = never> {
429
+ readonly name: string;
430
+ readonly description: string;
431
+ readonly input: JsonSchema;
432
+ readonly execute: (input: Input, context: ToolContext) => Promise<ToolResult>;
433
+ }
434
+
435
+ declare const MAX_MODEL_BYTES: number;
436
+ declare const MAX_MODEL_LINES = 200;
437
+ declare const DEFAULT_SHORT_TIMEOUT_MS = 10000;
438
+ interface PhuxToolMetadata {
439
+ readonly operation: "list" | "create" | "snapshot" | "send_keys" | "run" | "wait";
440
+ readonly target?: string;
441
+ readonly count?: number;
442
+ readonly exitCode?: number;
443
+ readonly durationMs?: number;
444
+ readonly outcome?: string;
445
+ readonly rows?: number;
446
+ readonly cols?: number;
447
+ readonly modelOutputTruncated?: boolean;
448
+ readonly phuxOutputTruncated?: boolean;
449
+ }
450
+ interface PhuxToolRuntime {
451
+ readonly cli: PhuxCli;
452
+ readonly environmentTarget?: string;
453
+ getSelectedTarget(): string | undefined;
454
+ selectTarget(target: string): void;
455
+ targetSelected?(context: ToolContext): void;
456
+ }
457
+ /** Build the six public OpenCode tools around one plugin-instance target selection. */
458
+ declare function createPhuxTools(runtime: PhuxToolRuntime): Record<string, PhuxToolDefinition<any>>;
459
+ declare function resolveTarget(explicit: string | undefined, runtime: Pick<PhuxToolRuntime, "getSelectedTarget" | "environmentTarget">): string;
460
+ /** Bound terminal body text while preserving the header and explicit notices. */
461
+ declare function boundedResult(header: string, body: string, phuxTruncated?: boolean): {
462
+ readonly text: string;
463
+ readonly truncated: boolean;
464
+ };
465
+
466
+ type OpenCodeLifecycleState = "idle" | "working";
467
+ interface OpenCodeLifecycleAdapter {
468
+ agentShow(options: ExecutionOptions & {
469
+ readonly target: string;
470
+ }): Promise<AgentStateList>;
471
+ agentSet(target: string, record: AgentRecord, options?: ExecutionOptions): Promise<AgentRecord>;
472
+ agentClear(target: string, options?: ExecutionOptions): Promise<void>;
473
+ }
474
+ interface OpenCodeLifecycleOptions {
475
+ readonly cli?: OpenCodeLifecycleAdapter;
476
+ readonly timeoutMs?: number;
477
+ readonly onError?: (error: unknown) => void;
478
+ readonly target: () => string | undefined;
479
+ }
480
+ /**
481
+ * Best-effort metadata reporter driven only by documented session status,
482
+ * deletion, and plugin disposal signals.
483
+ */
484
+ declare class OpenCodeLifecycle {
485
+ private readonly cli;
486
+ private readonly timeoutMs;
487
+ private readonly onError;
488
+ private readonly target;
489
+ private readonly states;
490
+ private readonly owned;
491
+ private tail;
492
+ private disposed;
493
+ constructor(options: OpenCodeLifecycleOptions);
494
+ /**
495
+ * A session is alive and should carry this plugin's identity.
496
+ *
497
+ * `state` is recorded for {@link targetSelected}'s fallback but is NOT
498
+ * written to the record: the server derives state from `rules/opencode.toml`,
499
+ * and declaring one would stand that detector down (phux-w7z2.38). The event
500
+ * still matters as a liveness trigger, which is why the signature keeps it.
501
+ */
502
+ observeState(sessionId: string, state: OpenCodeLifecycleState): Promise<void>;
503
+ /** A tool invocation is an honest working signal if no status event was seen yet. */
504
+ targetSelected(sessionId: string): Promise<void>;
505
+ deleteSession(sessionId: string): Promise<void>;
506
+ dispose(): Promise<void>;
507
+ settled(): Promise<void>;
508
+ private enqueue;
509
+ private publish;
510
+ private clearSession;
511
+ private clearOwned;
512
+ private execution;
513
+ }
514
+ interface OpenCodeLifecycleEvent {
515
+ readonly type: string;
516
+ readonly properties: Record<string, unknown>;
517
+ }
518
+ declare function handleLifecycleEvent(lifecycle: OpenCodeLifecycle, event: OpenCodeLifecycleEvent): Promise<void>;
519
+
520
+ /** Plugin settings plus injectable seams for library and contract tests. */
521
+ interface PhuxOpenCodeOptions {
522
+ readonly executable?: string;
523
+ readonly socket?: string;
524
+ readonly lifecycleTimeoutMs?: number;
525
+ readonly contextAwareness?: boolean;
526
+ readonly contextTimeoutMs?: number;
527
+ readonly cli?: PhuxCli;
528
+ readonly env?: NodeJS.ProcessEnv;
529
+ readonly onLifecycleError?: (error: unknown) => void;
530
+ }
531
+ /** Build a V2 plugin with optional test-only defaults. */
532
+ declare function createPhuxPlugin(defaults?: PhuxOpenCodeOptions): Plugin.Plugin;
533
+ declare const PhuxPlugin: Plugin.Plugin;
534
+
535
+ export { type AgentTargetOptions, type CreateOptions, DEFAULT_SHORT_TIMEOUT_MS, type ExecutionOptions, MAX_MODEL_BYTES, MAX_MODEL_LINES, OpenCodeLifecycle, type OpenCodeLifecycleAdapter, type OpenCodeLifecycleEvent, type OpenCodeLifecycleOptions, type OpenCodeLifecycleState, PhuxCli, type PhuxCliOptions, PhuxContextAwareness, type PhuxContextAwarenessOptions, type PhuxContextEmission, type PhuxContextIdentity, type PhuxOpenCodeOptions, PhuxPlugin, type PhuxProbe, type PhuxToolDefinition, type PhuxToolMetadata, type PhuxToolRuntime, type RunOptions, type SnapshotOptions, type ToolContext, type ToolResult, type WaitOptions, type WaitOutcome, boundedResult, contextAwarenessEnabled, createPhuxPlugin, createPhuxTools, PhuxPlugin as default, handleLifecycleEvent, normalizeTerminalIdentity, resolveTarget };