@oh-my-pi/pi-coding-agent 15.11.7 → 15.12.0
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/CHANGELOG.md +63 -1
- package/dist/cli.js +8106 -7708
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/collab/crypto.d.ts +7 -0
- package/dist/types/collab/guest.d.ts +23 -0
- package/dist/types/collab/host.d.ts +29 -0
- package/dist/types/collab/protocol.d.ts +113 -0
- package/dist/types/collab/relay-client.d.ts +22 -0
- package/dist/types/commands/join.d.ts +12 -0
- package/dist/types/config/settings-schema.d.ts +60 -5
- package/dist/types/export/custom-share.d.ts +1 -2
- package/dist/types/export/html/index.d.ts +39 -1
- package/dist/types/export/share.d.ts +43 -0
- package/dist/types/extensibility/slash-commands.d.ts +1 -11
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/agent-hub.d.ts +32 -1
- package/dist/types/modes/components/collab-prompt-message.d.ts +10 -0
- package/dist/types/modes/components/hook-selector.d.ts +4 -6
- package/dist/types/modes/components/segment-track.d.ts +11 -6
- package/dist/types/modes/components/status-line/component.d.ts +10 -2
- package/dist/types/modes/components/status-line/types.d.ts +11 -0
- package/dist/types/modes/controllers/event-controller.d.ts +7 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -1
- package/dist/types/modes/controllers/session-focus-controller.d.ts +31 -0
- package/dist/types/modes/interactive-mode.d.ts +16 -0
- package/dist/types/modes/session-observer-registry.d.ts +7 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +20 -0
- package/dist/types/session/agent-session.d.ts +13 -0
- package/dist/types/session/codex-auto-reset.d.ts +8 -4
- package/dist/types/session/session-manager.d.ts +21 -0
- package/dist/types/session/snapcompact-inline.d.ts +6 -3
- package/dist/types/slash-commands/builtin-registry.d.ts +9 -0
- package/dist/types/task/executor.d.ts +7 -0
- package/dist/types/task/types.d.ts +9 -0
- package/package.json +14 -13
- package/scripts/bench-guard.ts +71 -0
- package/scripts/build-binary.ts +4 -0
- package/scripts/bundle-dist.ts +4 -0
- package/scripts/generate-share-viewer.ts +34 -0
- package/src/cli/args.ts +2 -0
- package/src/cli-commands.ts +1 -0
- package/src/collab/crypto.ts +63 -0
- package/src/collab/guest.ts +450 -0
- package/src/collab/host.ts +556 -0
- package/src/collab/protocol.ts +232 -0
- package/src/collab/relay-client.ts +216 -0
- package/src/commands/join.ts +39 -0
- package/src/config/model-registry.ts +22 -14
- package/src/config/settings-schema.ts +67 -5
- package/src/config/settings.ts +12 -0
- package/src/export/custom-share.ts +1 -1
- package/src/export/html/index.ts +122 -17
- package/src/export/html/share-loader.js +102 -0
- package/src/export/html/template.css +745 -459
- package/src/export/html/template.html +6 -3
- package/src/export/html/template.js +240 -915
- package/src/export/html/tool-views.generated.js +38 -0
- package/src/export/share.ts +268 -0
- package/src/extensibility/slash-commands.ts +1 -97
- package/src/internal-urls/docs-index.generated.ts +74 -73
- package/src/main.ts +33 -11
- package/src/modes/components/agent-hub.ts +659 -431
- package/src/modes/components/assistant-message.ts +126 -6
- package/src/modes/components/collab-prompt-message.ts +30 -0
- package/src/modes/components/hook-selector.ts +4 -5
- package/src/modes/components/segment-track.ts +44 -7
- package/src/modes/components/status-line/component.ts +59 -6
- package/src/modes/components/status-line/presets.ts +1 -1
- package/src/modes/components/status-line/segments.ts +18 -1
- package/src/modes/components/status-line/types.ts +12 -0
- package/src/modes/components/tips.txt +4 -1
- package/src/modes/controllers/command-controller.ts +55 -96
- package/src/modes/controllers/event-controller.ts +45 -16
- package/src/modes/controllers/input-controller.ts +175 -9
- package/src/modes/controllers/selector-controller.ts +13 -15
- package/src/modes/controllers/session-focus-controller.ts +112 -0
- package/src/modes/controllers/streaming-reveal.ts +7 -0
- package/src/modes/interactive-mode.ts +56 -6
- package/src/modes/session-observer-registry.ts +11 -0
- package/src/modes/theme/theme.ts +6 -0
- package/src/modes/types.ts +20 -0
- package/src/modes/utils/ui-helpers.ts +23 -13
- package/src/prompts/tools/job.md +1 -1
- package/src/sdk.ts +239 -36
- package/src/session/agent-session.ts +82 -7
- package/src/session/codex-auto-reset.ts +23 -11
- package/src/session/session-manager.ts +44 -0
- package/src/session/snapcompact-inline.ts +9 -3
- package/src/slash-commands/builtin-registry.ts +261 -24
- package/src/task/executor.ts +14 -0
- package/src/task/index.ts +5 -1
- package/src/task/render.ts +76 -5
- package/src/task/types.ts +9 -0
- package/src/tiny/worker.ts +17 -95
- package/src/tools/job.ts +6 -9
- package/src/tools/read.ts +38 -5
- package/src/tools/write.ts +13 -42
- package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
- package/dist/types/export/html/template.generated.d.ts +0 -1
- package/dist/types/export/html/template.macro.d.ts +0 -5
- package/dist/types/tiny/compiled-runtime.d.ts +0 -35
- package/scripts/generate-template.ts +0 -33
- package/src/bun-imports.d.ts +0 -28
- package/src/export/html/template.generated.ts +0 -2
- package/src/export/html/template.macro.ts +0 -25
- package/src/tiny/compiled-runtime.ts +0 -179
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface Args {
|
|
|
26
26
|
sessionDir?: string;
|
|
27
27
|
providerSessionId?: string;
|
|
28
28
|
fork?: string;
|
|
29
|
+
/** Collab link to join at startup (set by the `join` subcommand; no CLI flag). */
|
|
30
|
+
join?: string;
|
|
29
31
|
models?: string[];
|
|
30
32
|
tools?: string[];
|
|
31
33
|
noTools?: boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CollabFrame } from "./protocol";
|
|
2
|
+
export declare function generateRoomKey(): Uint8Array;
|
|
3
|
+
export declare function generateWriteToken(): Uint8Array;
|
|
4
|
+
export declare function importRoomKey(raw: Uint8Array): Promise<CryptoKey>;
|
|
5
|
+
export declare function seal(key: CryptoKey, frame: CollabFrame): Promise<Uint8Array>;
|
|
6
|
+
/** Inverse of {@link seal}. Throws on auth failure or malformed input. */
|
|
7
|
+
export declare function open(key: CryptoKey, data: Uint8Array): Promise<CollabFrame>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { AgentHubRemote } from "../modes/components/agent-hub";
|
|
3
|
+
import type { InteractiveModeContext } from "../modes/types";
|
|
4
|
+
import { AgentRegistry } from "../registry/agent-registry";
|
|
5
|
+
import { type CollabSessionState } from "./protocol";
|
|
6
|
+
/** Commands a guest may run locally; everything else is host-only. */
|
|
7
|
+
export declare const COLLAB_GUEST_ALLOWED_COMMANDS: Record<string, true>;
|
|
8
|
+
export declare class CollabGuestLink {
|
|
9
|
+
#private;
|
|
10
|
+
state: CollabSessionState | null;
|
|
11
|
+
/** Local mirror of the host's agent ecosystem (refs carry `session: null`). */
|
|
12
|
+
readonly agentRegistry: AgentRegistry;
|
|
13
|
+
/** Agent Hub actions routed to the host over the wire. */
|
|
14
|
+
get hubRemote(): AgentHubRemote;
|
|
15
|
+
/** True when this guest joined through a read-only (view) link. */
|
|
16
|
+
get readOnly(): boolean;
|
|
17
|
+
constructor(ctx: InteractiveModeContext);
|
|
18
|
+
join(link: string): Promise<void>;
|
|
19
|
+
/** User-initiated leave (or post-disconnect cleanup): restore the previous session. */
|
|
20
|
+
leave(_reason: string): Promise<void>;
|
|
21
|
+
sendPrompt(text: string, images?: ImageContent[]): void;
|
|
22
|
+
sendAbort(): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host side of a collab live session.
|
|
3
|
+
*
|
|
4
|
+
* Taps the host session's event stream and SessionManager append chokepoint,
|
|
5
|
+
* broadcasting entries/events/state to guests through the relay. Guests prompt
|
|
6
|
+
* and abort through us; the host machine runs the agent and tools. The host's
|
|
7
|
+
* subagent ecosystem is mirrored too: task EventBus traffic (observer HUD),
|
|
8
|
+
* agent-registry snapshots (Agent Hub table), hub chat/kill/revive commands,
|
|
9
|
+
* and incremental subagent-transcript reads.
|
|
10
|
+
*/
|
|
11
|
+
import type { InteractiveModeContext } from "../modes/types";
|
|
12
|
+
import { type CollabParticipant } from "./protocol";
|
|
13
|
+
/** Display name for this process's user in collab sessions. */
|
|
14
|
+
export declare function collabDisplayName(ctx: InteractiveModeContext): string;
|
|
15
|
+
export declare class CollabHost {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(ctx: InteractiveModeContext);
|
|
18
|
+
get link(): string;
|
|
19
|
+
/** Browser deep link (`https://<relay>/#<link>`) — the relay serves the web client at `/`. */
|
|
20
|
+
get webLink(): string;
|
|
21
|
+
/** Read-only variant of {@link link}: bare room key, no write token. */
|
|
22
|
+
get viewLink(): string;
|
|
23
|
+
/** Read-only variant of {@link webLink}. */
|
|
24
|
+
get webViewLink(): string;
|
|
25
|
+
get participants(): CollabParticipant[];
|
|
26
|
+
start(relayUrl: string): Promise<void>;
|
|
27
|
+
/** Broadcast a goodbye, detach all taps, and close the socket. */
|
|
28
|
+
stop(reason: string): Promise<void>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collab live-session wire protocol.
|
|
3
|
+
*
|
|
4
|
+
* Hub topology: the host is authoritative, guests never peer. All session
|
|
5
|
+
* payloads (`CollabFrame`) travel AES-256-GCM sealed; the relay only sees the
|
|
6
|
+
* plaintext envelope (`[4B uint32 BE peerId][sealed payload]`) plus TEXT JSON
|
|
7
|
+
* control messages that carry no session data.
|
|
8
|
+
*/
|
|
9
|
+
import type { ImageContent, Model } from "@oh-my-pi/pi-ai";
|
|
10
|
+
import type { BusChannel, GuestFrame, ParsedCollabLink, Participant, SessionState, AgentSnapshot as WireAgentSnapshot } from "@oh-my-pi/pi-wire";
|
|
11
|
+
import { DEFAULT_RELAY_URL, ENVELOPE_HEADER_LENGTH, ROOM_ID_BYTES } from "@oh-my-pi/pi-wire";
|
|
12
|
+
import type { ContextUsage } from "../extensibility/extensions/types";
|
|
13
|
+
import type { AgentSessionEvent } from "../session/agent-session";
|
|
14
|
+
import type { SessionEntry, SessionHeader } from "../session/session-manager";
|
|
15
|
+
export type { CollabPromptDetails, ParsedCollabLink, RelayControlMessage, RelayControlToGuest, RelayControlToHost, } from "@oh-my-pi/pi-wire";
|
|
16
|
+
export { COLLAB_PROMPT_MESSAGE_TYPE, COLLAB_PROTO } from "@oh-my-pi/pi-wire";
|
|
17
|
+
export { DEFAULT_RELAY_URL, ENVELOPE_HEADER_LENGTH, ROOM_ID_BYTES };
|
|
18
|
+
export type CollabParticipant = Participant;
|
|
19
|
+
export type AgentSnapshot = WireAgentSnapshot;
|
|
20
|
+
/** Debounced footer snapshot broadcast by the host. */
|
|
21
|
+
export type CollabSessionState = SessionState & {
|
|
22
|
+
/**
|
|
23
|
+
* Host model (full catalog object). Guests apply it to their replica
|
|
24
|
+
* agent state so model display and context-window math are native.
|
|
25
|
+
*/
|
|
26
|
+
model?: Model;
|
|
27
|
+
/** Host status-line context numbers (guest system prompt/tools differ, so local estimates drift). */
|
|
28
|
+
contextUsage?: ContextUsage;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Encrypted payload frames (inside AES-GCM, JSON). The wire package pins the
|
|
32
|
+
* JSON skeleton (`WireFrame`); host-side frames carry the rich session types
|
|
33
|
+
* that serialize into those shapes.
|
|
34
|
+
*/
|
|
35
|
+
export type CollabFrame = Exclude<GuestFrame, {
|
|
36
|
+
t: "prompt";
|
|
37
|
+
}> | {
|
|
38
|
+
t: "prompt";
|
|
39
|
+
text: string;
|
|
40
|
+
images?: ImageContent[];
|
|
41
|
+
} | {
|
|
42
|
+
t: "welcome";
|
|
43
|
+
proto: number;
|
|
44
|
+
header: SessionHeader;
|
|
45
|
+
entries: SessionEntry[];
|
|
46
|
+
state: CollabSessionState;
|
|
47
|
+
agents: AgentSnapshot[];
|
|
48
|
+
/** True when this peer joined through a read-only (view) link. */
|
|
49
|
+
readOnly?: boolean;
|
|
50
|
+
} | {
|
|
51
|
+
t: "entry";
|
|
52
|
+
entry: SessionEntry;
|
|
53
|
+
} | {
|
|
54
|
+
t: "event";
|
|
55
|
+
event: AgentSessionEvent;
|
|
56
|
+
} | {
|
|
57
|
+
t: "state";
|
|
58
|
+
state: CollabSessionState;
|
|
59
|
+
}
|
|
60
|
+
/** Mirrored EventBus traffic (task subagent lifecycle/progress channels only). */
|
|
61
|
+
| {
|
|
62
|
+
t: "bus";
|
|
63
|
+
channel: BusChannel;
|
|
64
|
+
data: unknown;
|
|
65
|
+
}
|
|
66
|
+
/** Full agent-registry snapshot (debounced on registry change). */
|
|
67
|
+
| {
|
|
68
|
+
t: "agents";
|
|
69
|
+
agents: AgentSnapshot[];
|
|
70
|
+
}
|
|
71
|
+
/** Targeted reply to fetch-transcript; `text` is decoded JSONL from `fromByte`, `newSize` the next offset base. */
|
|
72
|
+
| {
|
|
73
|
+
t: "transcript";
|
|
74
|
+
reqId: number;
|
|
75
|
+
text: string;
|
|
76
|
+
newSize: number;
|
|
77
|
+
error?: string;
|
|
78
|
+
} | {
|
|
79
|
+
t: "bye";
|
|
80
|
+
reason: string;
|
|
81
|
+
} | {
|
|
82
|
+
t: "error";
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
export declare function packEnvelope(peerId: number, sealed: Uint8Array): Uint8Array;
|
|
86
|
+
export declare function unpackEnvelope(data: Uint8Array): {
|
|
87
|
+
peerId: number;
|
|
88
|
+
payload: Uint8Array;
|
|
89
|
+
} | null;
|
|
90
|
+
/** Rewrite the peerId in place without copying the payload. */
|
|
91
|
+
export declare function rewriteEnvelopePeer(data: Uint8Array, peerId: number): void;
|
|
92
|
+
export declare function generateRoomId(): string;
|
|
93
|
+
/**
|
|
94
|
+
* Render the shareable link. Compact forms: the default relay collapses to
|
|
95
|
+
* `<roomId>#<key>`, other wss relays drop the scheme (`host[:port]/r/…`);
|
|
96
|
+
* only localhost ws:// links keep their full URL so parsing cannot
|
|
97
|
+
* mis-infer wss.
|
|
98
|
+
*
|
|
99
|
+
* Full links append the write token to the key in the fragment
|
|
100
|
+
* (`base64url(key ∥ writeToken)`); read-only (view) links carry the bare
|
|
101
|
+
* 32-byte key, which is also the pre-token link format.
|
|
102
|
+
*/
|
|
103
|
+
export declare function formatCollabLink(relayUrl: string, roomId: string, key: Uint8Array, writeToken?: Uint8Array): string;
|
|
104
|
+
/**
|
|
105
|
+
* Render the browser deep link: `http(s)://<relay-host>/#<collab-link>`. The
|
|
106
|
+
* relay serves the web client at `/`, and the whole collab link (including the
|
|
107
|
+
* room key) rides in the fragment, so it never appears in any HTTP request.
|
|
108
|
+
* Terminals auto-link the https form, making it click-to-join.
|
|
109
|
+
*/
|
|
110
|
+
export declare function formatCollabWebLink(relayUrl: string, roomId: string, key: Uint8Array, writeToken?: Uint8Array): string;
|
|
111
|
+
export declare function parseCollabLink(link: string): ParsedCollabLink | {
|
|
112
|
+
error: string;
|
|
113
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CollabFrame, RelayControlMessage } from "./protocol";
|
|
2
|
+
export interface CollabSocketOptions {
|
|
3
|
+
/** wss://host[:port]/r/<roomId> — no query string. */
|
|
4
|
+
wsUrl: string;
|
|
5
|
+
role: "host" | "guest";
|
|
6
|
+
key: CryptoKey;
|
|
7
|
+
}
|
|
8
|
+
export declare class CollabSocket {
|
|
9
|
+
#private;
|
|
10
|
+
/** Fires after every successful (re)connect. */
|
|
11
|
+
onOpen?: () => void;
|
|
12
|
+
onFrame?: (frame: CollabFrame, fromPeer: number) => void;
|
|
13
|
+
onControl?: (msg: RelayControlMessage) => void;
|
|
14
|
+
/** Fires once per terminal close (intentional, fatal code, or bad key). willReconnect=true for transient drops that will retry. */
|
|
15
|
+
onClose?: (reason: string, willReconnect: boolean) => void;
|
|
16
|
+
constructor(opts: CollabSocketOptions);
|
|
17
|
+
get isOpen(): boolean;
|
|
18
|
+
connect(): void;
|
|
19
|
+
send(frame: CollabFrame, targetPeer?: number): void;
|
|
20
|
+
/** Intentional close: clears any retry timer, suppresses reconnect. A later connect() starts fresh. */
|
|
21
|
+
close(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from "@oh-my-pi/pi-utils/cli";
|
|
2
|
+
export default class Join extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
link: import("@oh-my-pi/pi-utils/cli").ArgDescriptor & {
|
|
6
|
+
description: string;
|
|
7
|
+
required: true;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
static examples: string[];
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -33,7 +33,7 @@ export declare const TAB_METADATA: Record<SettingTab, {
|
|
|
33
33
|
*/
|
|
34
34
|
export declare const TAB_GROUPS: Record<SettingTab, readonly string[]>;
|
|
35
35
|
/** Status line segment identifiers */
|
|
36
|
-
export type StatusLineSegmentId = "pi" | "model" | "mode" | "path" | "git" | "pr" | "subagents" | "token_in" | "token_out" | "token_total" | "token_rate" | "cost" | "context_pct" | "context_total" | "time_spent" | "time" | "session" | "hostname" | "cache_read" | "cache_write" | "cache_hit" | "session_name" | "usage";
|
|
36
|
+
export type StatusLineSegmentId = "pi" | "model" | "mode" | "path" | "git" | "pr" | "subagents" | "token_in" | "token_out" | "token_total" | "token_rate" | "cost" | "context_pct" | "context_total" | "time_spent" | "time" | "session" | "hostname" | "cache_read" | "cache_write" | "cache_hit" | "session_name" | "usage" | "collab";
|
|
37
37
|
/** Submenu choice metadata. */
|
|
38
38
|
export type SubmenuOption<V extends string = string> = {
|
|
39
39
|
value: V;
|
|
@@ -1394,6 +1394,46 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1394
1394
|
readonly description: "Notify when the ask tool is waiting for input";
|
|
1395
1395
|
};
|
|
1396
1396
|
};
|
|
1397
|
+
readonly "collab.relayUrl": {
|
|
1398
|
+
readonly type: "string";
|
|
1399
|
+
readonly default: "wss://my.omp.sh";
|
|
1400
|
+
readonly ui: {
|
|
1401
|
+
readonly tab: "interaction";
|
|
1402
|
+
readonly group: "Collab";
|
|
1403
|
+
readonly label: "Relay URL";
|
|
1404
|
+
readonly description: "Relay used by /collab (wss://host[:port]; self-host with the omp-collab-relay service)";
|
|
1405
|
+
};
|
|
1406
|
+
};
|
|
1407
|
+
readonly "collab.displayName": {
|
|
1408
|
+
readonly type: "string";
|
|
1409
|
+
readonly default: "";
|
|
1410
|
+
readonly ui: {
|
|
1411
|
+
readonly tab: "interaction";
|
|
1412
|
+
readonly group: "Collab";
|
|
1413
|
+
readonly label: "Display Name";
|
|
1414
|
+
readonly description: "Name shown to other collab participants (default: OS username)";
|
|
1415
|
+
};
|
|
1416
|
+
};
|
|
1417
|
+
readonly "share.serverUrl": {
|
|
1418
|
+
readonly type: "string";
|
|
1419
|
+
readonly default: "https://my.omp.sh/s";
|
|
1420
|
+
readonly ui: {
|
|
1421
|
+
readonly tab: "interaction";
|
|
1422
|
+
readonly group: "Collab";
|
|
1423
|
+
readonly label: "Share Server";
|
|
1424
|
+
readonly description: "Share viewer/upload base used by /share (encrypted blob upload + viewer; links are <base>/<id>#<key>)";
|
|
1425
|
+
};
|
|
1426
|
+
};
|
|
1427
|
+
readonly "share.redactSecrets": {
|
|
1428
|
+
readonly type: "boolean";
|
|
1429
|
+
readonly default: true;
|
|
1430
|
+
readonly ui: {
|
|
1431
|
+
readonly tab: "interaction";
|
|
1432
|
+
readonly group: "Collab";
|
|
1433
|
+
readonly label: "Share Secret Redaction";
|
|
1434
|
+
readonly description: "Run the secret obfuscator over /share snapshots before upload (uses the secrets.* config)";
|
|
1435
|
+
};
|
|
1436
|
+
};
|
|
1397
1437
|
readonly "stt.enabled": {
|
|
1398
1438
|
readonly type: "boolean";
|
|
1399
1439
|
readonly default: false;
|
|
@@ -4189,13 +4229,27 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
4189
4229
|
};
|
|
4190
4230
|
};
|
|
4191
4231
|
readonly "codexResets.autoRedeem": {
|
|
4192
|
-
readonly type: "
|
|
4193
|
-
readonly
|
|
4232
|
+
readonly type: "enum";
|
|
4233
|
+
readonly values: readonly ["unset", "yes", "no"];
|
|
4234
|
+
readonly default: "unset";
|
|
4194
4235
|
readonly ui: {
|
|
4195
4236
|
readonly tab: "providers";
|
|
4196
4237
|
readonly group: "Services";
|
|
4197
4238
|
readonly label: "Codex Auto-Redeem Saved Resets";
|
|
4198
|
-
readonly description: "When a turn is blocked by the Codex weekly limit on the active account and no other account is available,
|
|
4239
|
+
readonly description: "When a turn is blocked by the Codex weekly limit on the active account and no other account is available, run the conservative saved-reset check. unset asks before spending the first eligible reset, yes spends eligible resets without prompting, and no disables the check entirely. Requires retries enabled.";
|
|
4240
|
+
readonly options: readonly [{
|
|
4241
|
+
readonly value: "unset";
|
|
4242
|
+
readonly label: "Unset";
|
|
4243
|
+
readonly description: "Check eligibility, then ask before spending the first saved reset.";
|
|
4244
|
+
}, {
|
|
4245
|
+
readonly value: "yes";
|
|
4246
|
+
readonly label: "Yes";
|
|
4247
|
+
readonly description: "Spend eligible saved resets without prompting.";
|
|
4248
|
+
}, {
|
|
4249
|
+
readonly value: "no";
|
|
4250
|
+
readonly label: "No";
|
|
4251
|
+
readonly description: "Do not run the saved-reset auto-redeem check.";
|
|
4252
|
+
}];
|
|
4199
4253
|
};
|
|
4200
4254
|
};
|
|
4201
4255
|
readonly "codexResets.minBlockedMinutes": {
|
|
@@ -4567,8 +4621,9 @@ export interface ShellMinimizerSettings {
|
|
|
4567
4621
|
sourceOutlineLevel: "default" | "aggressive";
|
|
4568
4622
|
legacyFilters: boolean | undefined;
|
|
4569
4623
|
}
|
|
4624
|
+
export type CodexAutoRedeemMode = "unset" | "yes" | "no";
|
|
4570
4625
|
export interface CodexResetsSettings {
|
|
4571
|
-
autoRedeem:
|
|
4626
|
+
autoRedeem: CodexAutoRedeemMode;
|
|
4572
4627
|
minBlockedMinutes: number;
|
|
4573
4628
|
keepCredits: number;
|
|
4574
4629
|
}
|
|
@@ -5,7 +5,7 @@ export interface CustomShareResult {
|
|
|
5
5
|
message?: string;
|
|
6
6
|
}
|
|
7
7
|
export type CustomShareFn = (htmlPath: string) => Promise<CustomShareResult | string | undefined>;
|
|
8
|
-
interface LoadedCustomShare {
|
|
8
|
+
export interface LoadedCustomShare {
|
|
9
9
|
path: string;
|
|
10
10
|
fn: CustomShareFn;
|
|
11
11
|
}
|
|
@@ -17,4 +17,3 @@ export declare function getCustomSharePath(): string | null;
|
|
|
17
17
|
* Load the custom share script if it exists.
|
|
18
18
|
*/
|
|
19
19
|
export declare function loadCustomShare(): Promise<LoadedCustomShare | null>;
|
|
20
|
-
export {};
|
|
@@ -1,9 +1,47 @@
|
|
|
1
1
|
import type { AgentState } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import { SessionManager } from "../../session/session-manager";
|
|
2
|
+
import { type SessionEntry, type SessionHeader, SessionManager } from "../../session/session-manager";
|
|
3
|
+
/** Compose the standalone export template: minified CSS, tool renderers, and viewer JS inlined. */
|
|
4
|
+
export declare function getTemplate(): string;
|
|
3
5
|
export interface ExportOptions {
|
|
4
6
|
outputPath?: string;
|
|
5
7
|
themeName?: string;
|
|
8
|
+
/** Embed subagent session transcripts found next to the session file (default true). */
|
|
9
|
+
includeSubSessions?: boolean;
|
|
6
10
|
}
|
|
11
|
+
/** Generate CSS custom properties for theme. Exported for the share-viewer build script. */
|
|
12
|
+
export declare function generateThemeVars(themeName?: string): Promise<string>;
|
|
13
|
+
/** Embedded subagent session transcript, keyed by slash-joined agent path in `SessionData.subSessions`. */
|
|
14
|
+
export interface SubSession {
|
|
15
|
+
/** Bare agent id (session file stem), e.g. "ToolAsk". */
|
|
16
|
+
agentId: string;
|
|
17
|
+
/** Key of the parent sub-session, or null when spawned by the main session. */
|
|
18
|
+
parent: string | null;
|
|
19
|
+
header: SessionHeader | null;
|
|
20
|
+
entries: SessionEntry[];
|
|
21
|
+
leafId: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface SessionData {
|
|
24
|
+
header: SessionHeader | null;
|
|
25
|
+
entries: SessionEntry[];
|
|
26
|
+
leafId: string | null;
|
|
27
|
+
systemPrompt?: string;
|
|
28
|
+
tools?: {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
}[];
|
|
32
|
+
subSessions?: Record<string, SubSession>;
|
|
33
|
+
}
|
|
34
|
+
/** Snapshot the session (plus optional agent state) into the JSON shape the viewer renders. */
|
|
35
|
+
export declare function buildSessionData(sm: SessionManager, state?: AgentState): SessionData;
|
|
36
|
+
/**
|
|
37
|
+
* Collect subagent session transcripts stored next to a session file.
|
|
38
|
+
*
|
|
39
|
+
* A session at `<dir>/<name>.jsonl` keeps its subagent sessions at `<dir>/<name>/<AgentId>.jsonl`;
|
|
40
|
+
* each subagent's own children nest the same way under `<dir>/<name>/<AgentId>/`. Keys in the
|
|
41
|
+
* returned record are slash-joined ids relative to the main session ("ToolAsk", "ToolAsk/Helper").
|
|
42
|
+
* Corrupt or empty files are skipped silently.
|
|
43
|
+
*/
|
|
44
|
+
export declare function collectSubSessions(sessionFile: string): Promise<Record<string, SubSession>>;
|
|
7
45
|
/** Export session to HTML using SessionManager and AgentState. */
|
|
8
46
|
export declare function exportSessionToHtml(sm: SessionManager, state?: AgentState, options?: ExportOptions | string): Promise<string>;
|
|
9
47
|
/** Export session file to HTML (standalone). */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AgentState } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import { DEFAULT_SHARE_URL } from "@oh-my-pi/pi-wire";
|
|
3
|
+
import type { SecretObfuscator } from "../secrets/obfuscator";
|
|
4
|
+
import type { SessionManager } from "../session/session-manager";
|
|
5
|
+
import { type SessionData } from "./html";
|
|
6
|
+
export { DEFAULT_SHARE_URL };
|
|
7
|
+
/** Hard cap for blobs accepted by the share server (mirrors relay shareMaxBytes). */
|
|
8
|
+
export declare const SERVER_MAX_SEALED_BYTES = 1000000;
|
|
9
|
+
export interface ShareSessionOptions {
|
|
10
|
+
/** Share server/viewer base URL; defaults to {@link DEFAULT_SHARE_URL}. */
|
|
11
|
+
serverUrl?: string;
|
|
12
|
+
/** Agent state for system prompt + tool descriptions in the snapshot. */
|
|
13
|
+
state?: AgentState;
|
|
14
|
+
/**
|
|
15
|
+
* Redacts the snapshot before sealing: deep-walks every string (entries,
|
|
16
|
+
* header, system prompt, tool descriptions) through the obfuscator, so
|
|
17
|
+
* secrets that landed in persisted entries (tool outputs reading .env,
|
|
18
|
+
* etc.) never leave the machine. Pass undefined to skip.
|
|
19
|
+
*/
|
|
20
|
+
obfuscator?: SecretObfuscator;
|
|
21
|
+
}
|
|
22
|
+
export interface ShareSessionResult {
|
|
23
|
+
/** Viewer link: `<serverUrl>/<id>#<key>`. */
|
|
24
|
+
url: string;
|
|
25
|
+
method: "gist" | "server";
|
|
26
|
+
/** Underlying gist URL (gist method only). */
|
|
27
|
+
gistUrl?: string;
|
|
28
|
+
/** True when content was trimmed to fit the upload budget. */
|
|
29
|
+
truncated: boolean;
|
|
30
|
+
sealedBytes: number;
|
|
31
|
+
}
|
|
32
|
+
/** Build the snapshot that gets sealed and uploaded, redacted when an obfuscator is provided. */
|
|
33
|
+
export declare function buildShareSnapshot(sm: SessionManager, options?: ShareSessionOptions): SessionData;
|
|
34
|
+
/** Share the session; tries a secret gist first, then the share server. */
|
|
35
|
+
export declare function shareSession(sm: SessionManager, options?: ShareSessionOptions): Promise<ShareSessionResult>;
|
|
36
|
+
/** Strip trailing slashes so `<base>/<id>` composes cleanly. */
|
|
37
|
+
export declare function normalizeShareServerUrl(serverUrl?: string): string;
|
|
38
|
+
interface SealedSession {
|
|
39
|
+
sealed: Uint8Array<ArrayBuffer>;
|
|
40
|
+
truncated: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Seal `data`, trimming content until the sealed blob fits `maxBytes`. Exported for tests. */
|
|
43
|
+
export declare function sealToFit(key: CryptoKey, data: SessionData, maxBytes: number): Promise<SealedSession>;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { AutocompleteItem } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import { type BuiltinSlashCommand } from "../slash-commands/builtin-registry";
|
|
3
1
|
export type SlashCommandSource = "extension" | "prompt" | "skill";
|
|
4
2
|
export type SlashCommandLocation = "user" | "project" | "path";
|
|
5
3
|
export interface SlashCommandInfo {
|
|
@@ -9,15 +7,7 @@ export interface SlashCommandInfo {
|
|
|
9
7
|
location?: SlashCommandLocation;
|
|
10
8
|
path?: string;
|
|
11
9
|
}
|
|
12
|
-
export type { BuiltinSlashCommand, SubcommandDef } from "../slash-commands/
|
|
13
|
-
/**
|
|
14
|
-
* Materialized builtin slash commands with completion functions derived from
|
|
15
|
-
* declarative subcommand/hint definitions.
|
|
16
|
-
*/
|
|
17
|
-
export declare const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand & {
|
|
18
|
-
getArgumentCompletions?: (prefix: string) => AutocompleteItem[] | null;
|
|
19
|
-
getInlineHint?: (argumentText: string) => string | null;
|
|
20
|
-
}>;
|
|
10
|
+
export type { BuiltinSlashCommand, SubcommandDef } from "../slash-commands/types";
|
|
21
11
|
/**
|
|
22
12
|
* Represents a custom slash command loaded from a file
|
|
23
13
|
*/
|
package/dist/types/main.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Args } from "./cli/args";
|
|
2
2
|
import { ModelRegistry } from "./config/model-registry";
|
|
3
|
+
import { type ScopedModel } from "./config/model-resolver";
|
|
3
4
|
import { Settings } from "./config/settings";
|
|
4
5
|
import { InteractiveMode } from "./modes/interactive-mode";
|
|
5
6
|
import type { SubmittedUserInput } from "./modes/types";
|
|
@@ -12,6 +13,7 @@ export interface InteractiveModeNotify {
|
|
|
12
13
|
kind: "warn" | "error" | "info";
|
|
13
14
|
message: string;
|
|
14
15
|
}
|
|
16
|
+
export declare function buildModelScopeNotification(scopedModelsForDisplay: readonly Pick<ScopedModel, "model" | "thinkingLevel" | "explicitThinkingLevel">[], startupQuiet: boolean): InteractiveModeNotify | null;
|
|
15
17
|
export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested">, session: Pick<AgentSession, "prompt" | "promptCustomMessage">, input: SubmittedUserInput): Promise<void>;
|
|
16
18
|
type AcpSessionFactory = (cwd: string) => Promise<AgentSession>;
|
|
17
19
|
export interface AcpSessionFactoryOptions {
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import { Container, type TUI } from "@oh-my-pi/pi-tui";
|
|
2
3
|
import type { KeyId } from "../../config/keybindings";
|
|
4
|
+
import type { MessageRenderer } from "../../extensibility/extensions/types";
|
|
3
5
|
import { IrcBus } from "../../irc/bus";
|
|
4
6
|
import { AgentLifecycleManager } from "../../registry/agent-lifecycle";
|
|
5
7
|
import { AgentRegistry } from "../../registry/agent-registry";
|
|
6
8
|
import type { SessionObserverRegistry } from "../session-observer-registry";
|
|
9
|
+
/** Guest-side proxy for hub actions executed on the collab host. */
|
|
10
|
+
export interface AgentHubRemote {
|
|
11
|
+
chat(id: string, text: string): void;
|
|
12
|
+
kill(id: string): void;
|
|
13
|
+
revive(id: string): void;
|
|
14
|
+
/** Mirrors readFileIncremental: text from fromByte (complete JSONL lines), newSize = next fromByte base; null = unavailable. */
|
|
15
|
+
readTranscript(id: string, fromByte: number): Promise<{
|
|
16
|
+
text: string;
|
|
17
|
+
newSize: number;
|
|
18
|
+
} | null>;
|
|
19
|
+
}
|
|
7
20
|
export interface AgentHubDeps {
|
|
8
21
|
/** Progress/status snapshot source (task lifecycle + progress channels). */
|
|
9
22
|
observers: SessionObserverRegistry;
|
|
@@ -17,6 +30,24 @@ export interface AgentHubDeps {
|
|
|
17
30
|
lifecycle?: AgentLifecycleManager;
|
|
18
31
|
/** Injectable for tests; defaults to the process-global bus. */
|
|
19
32
|
irc?: IrcBus;
|
|
33
|
+
/** TUI handle for transcript components; tests omit it and get a render-only stub. */
|
|
34
|
+
ui?: TUI;
|
|
35
|
+
/** Tool lookup for transcript renderers (labels, custom render functions). */
|
|
36
|
+
getTool?: (name: string) => AgentTool | undefined;
|
|
37
|
+
/** Extension message renderers for custom messages in the transcript. */
|
|
38
|
+
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
39
|
+
/** Cwd used by tool renderers for path shortening; defaults to the project dir. */
|
|
40
|
+
cwd?: string;
|
|
41
|
+
/** Mirrors the main transcript's thinking-block visibility. */
|
|
42
|
+
hideThinkingBlock?: () => boolean;
|
|
43
|
+
/** Keys toggling tool output expansion (app.tools.expand). */
|
|
44
|
+
expandKeys?: KeyId[];
|
|
45
|
+
/** Focus the main view on this agent's live session (ctx.focusAgentSession). When absent (collab guest, tests), Enter opens the in-hub chat view instead. */
|
|
46
|
+
focusAgent?: (id: string) => Promise<void>;
|
|
47
|
+
/** Current main session file; used to seed parked historical subagents after restart. */
|
|
48
|
+
sessionFile?: string | null;
|
|
49
|
+
/** Collab guest: route actions/transcripts to the host instead of local sessions. */
|
|
50
|
+
remote?: AgentHubRemote;
|
|
20
51
|
}
|
|
21
52
|
export declare class AgentHubOverlayComponent extends Container {
|
|
22
53
|
#private;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import type { CollabPromptDetails } from "../../collab/protocol";
|
|
3
|
+
import type { CustomMessage } from "../../session/messages";
|
|
4
|
+
/**
|
|
5
|
+
* Renders a collab guest prompt on every participant's transcript: a
|
|
6
|
+
* user-message-styled bubble prefixed with the author's name.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CollabPromptMessageComponent extends Container {
|
|
9
|
+
constructor(message: CustomMessage<CollabPromptDetails>);
|
|
10
|
+
}
|
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
* Displays a list of string options with keyboard navigation.
|
|
4
4
|
*/
|
|
5
5
|
import { Container, type TUI } from "@oh-my-pi/pi-tui";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
/** One segment of a {@link HookSelectorSlider} — a label and an optional
|
|
7
|
+
* detail line (e.g. the resolved model name) shown beneath the track while
|
|
8
|
+
* the segment is active. Segment colors come from the track's theme palette,
|
|
9
|
+
* assigned by position. */
|
|
10
10
|
export interface HookSelectorSliderSegment {
|
|
11
11
|
label: string;
|
|
12
|
-
/** Theme color for the segment label; defaults to `accent`. */
|
|
13
|
-
color?: ThemeColor;
|
|
14
12
|
/** Secondary line rendered under the track when this segment is selected. */
|
|
15
13
|
detail?: string;
|
|
16
14
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared renderer for a horizontal row of colored "segments" styled after the
|
|
3
|
-
* status line: each segment
|
|
4
|
-
* as a powerline chip (its
|
|
5
|
-
* flanked by triangle caps) and the
|
|
6
|
-
* thin separator.
|
|
3
|
+
* status line: each segment is colored by its track position from the theme's
|
|
4
|
+
* own palette, the active one is filled as a powerline chip (its color as the
|
|
5
|
+
* background, a luminance-matched label, flanked by triangle caps) and the
|
|
6
|
+
* rest are plain colored labels joined by a thin separator.
|
|
7
7
|
*
|
|
8
8
|
* Used by the plan-mode model-tier slider ({@link HookSelectorComponent}) and
|
|
9
9
|
* the ctrl+p role-cycle status so both surfaces read identically.
|
|
@@ -11,9 +11,14 @@
|
|
|
11
11
|
import { type ThemeColor } from "../theme/theme";
|
|
12
12
|
export interface TrackSegment {
|
|
13
13
|
label: string;
|
|
14
|
-
/** Theme color for the segment; defaults to `accent`. */
|
|
15
|
-
color?: ThemeColor;
|
|
16
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve up to `count` theme colors that render distinctly under the active
|
|
17
|
+
* theme, in candidate preference order. May return fewer than `count` when the
|
|
18
|
+
* theme has fewer distinct hues (e.g. monochrome themes) — callers wrap with
|
|
19
|
+
* modulo. Never returns an empty array: `accent` always resolves.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSegmentPalette(count: number): ThemeColor[];
|
|
17
22
|
/**
|
|
18
23
|
* Render `segments` as a colored chip track with `activeIndex` filled. Returns
|
|
19
24
|
* a single line of styled text with no surrounding caption or arrows — callers
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { type Component } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { AgentSession } from "../../../session/agent-session";
|
|
3
|
-
import type { EffectiveStatusLineSettings, StatusLineSettings } from "./types";
|
|
3
|
+
import type { CollabStatus, EffectiveStatusLineSettings, StatusLineSettings } from "./types";
|
|
4
4
|
export declare class StatusLineComponent implements Component {
|
|
5
5
|
#private;
|
|
6
|
-
private
|
|
6
|
+
private session;
|
|
7
7
|
constructor(session: AgentSession);
|
|
8
|
+
/**
|
|
9
|
+
* Re-point the status line at another session (focus proxy). Invalidate: model/context/usage all derive
|
|
10
|
+
* from it. `focusedAgentId` is the focused subagent id while the view is proxied, undefined for main.
|
|
11
|
+
*/
|
|
12
|
+
setSession(session: AgentSession, focusedAgentId?: string): void;
|
|
8
13
|
updateSettings(settings: StatusLineSettings): void;
|
|
9
14
|
getEffectiveSettingsForTest(): EffectiveStatusLineSettings;
|
|
10
15
|
setAutoCompactEnabled(enabled: boolean): void;
|
|
11
16
|
setSubagentCount(count: number): void;
|
|
17
|
+
/** Active subagent count as currently displayed (collab state mirroring). */
|
|
18
|
+
get subagentCount(): number;
|
|
12
19
|
setSessionStartTime(time: number): void;
|
|
13
20
|
setPlanModeStatus(status: {
|
|
14
21
|
enabled: boolean;
|
|
@@ -21,6 +28,7 @@ export declare class StatusLineComponent implements Component {
|
|
|
21
28
|
enabled: boolean;
|
|
22
29
|
paused: boolean;
|
|
23
30
|
} | undefined): void;
|
|
31
|
+
setCollabStatus(status: CollabStatus | null): void;
|
|
24
32
|
setHookStatus(key: string, text: string | undefined): void;
|
|
25
33
|
watchBranch(onBranchChange: () => void): void;
|
|
26
34
|
dispose(): void;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import type { CollabSessionState } from "../../../collab/protocol";
|
|
1
2
|
import type { StatusLinePreset, StatusLineSegmentId, StatusLineSeparatorStyle } from "../../../config/settings-schema";
|
|
2
3
|
import type { AgentSession } from "../../../session/agent-session";
|
|
3
4
|
export type { StatusLinePreset, StatusLineSegmentId, StatusLineSeparatorStyle };
|
|
5
|
+
/** Collab session indicator + (guest-only) host-state override for segments. */
|
|
6
|
+
export interface CollabStatus {
|
|
7
|
+
role: "host" | "guest";
|
|
8
|
+
participantCount: number;
|
|
9
|
+
/** Guest only: host footer snapshot that overrides locally computed values. */
|
|
10
|
+
stateOverride?: CollabSessionState | null;
|
|
11
|
+
}
|
|
4
12
|
export interface StatusLineSegmentOptions {
|
|
5
13
|
model?: {
|
|
6
14
|
showThinkingLevel?: boolean;
|
|
@@ -37,6 +45,8 @@ export type EffectiveStatusLineSettings = Required<Pick<StatusLineSettings, "lef
|
|
|
37
45
|
export type RGB = readonly [number, number, number];
|
|
38
46
|
export interface SegmentContext {
|
|
39
47
|
session: AgentSession;
|
|
48
|
+
/** Focused subagent id while the view is proxied at its session, undefined otherwise. */
|
|
49
|
+
focusedAgentId?: string | undefined;
|
|
40
50
|
width: number;
|
|
41
51
|
options: StatusLineSegmentOptions;
|
|
42
52
|
planMode: {
|
|
@@ -50,6 +60,7 @@ export interface SegmentContext {
|
|
|
50
60
|
enabled: boolean;
|
|
51
61
|
paused: boolean;
|
|
52
62
|
} | null;
|
|
63
|
+
collab: CollabStatus | null;
|
|
53
64
|
usageStats: {
|
|
54
65
|
input: number;
|
|
55
66
|
output: number;
|