pi-ca-leash 0.10.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/AGENTS.md +77 -0
- package/ARCHITECTURE.md +290 -0
- package/CHANGELOG.md +158 -0
- package/DEVELOPMENT.md +197 -0
- package/KNOWN_LIMITS.md +80 -0
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/extensions/backend-tool-actions.test.ts +59 -0
- package/extensions/backend-tool-actions.ts +31 -0
- package/extensions/command-drivers.test.ts +37 -0
- package/extensions/command-drivers.ts +126 -0
- package/extensions/command-parity.test.ts +560 -0
- package/extensions/command-visibility.test.ts +21 -0
- package/extensions/command-visibility.ts +10 -0
- package/extensions/index.ts +3218 -0
- package/extensions/llm-tools.test.ts +537 -0
- package/extensions/model-catalog.test.ts +34 -0
- package/extensions/model-catalog.ts +173 -0
- package/extensions/peer-history.test.ts +141 -0
- package/extensions/peer-history.ts +90 -0
- package/extensions/peer-naming.test.ts +25 -0
- package/extensions/peer-naming.ts +129 -0
- package/extensions/peer-relay.test.ts +122 -0
- package/extensions/peer-relay.ts +83 -0
- package/extensions/peer-ux.test.ts +239 -0
- package/extensions/peer-ux.ts +327 -0
- package/extensions/persistence.test.ts +68 -0
- package/extensions/persistence.ts +67 -0
- package/extensions/prompts/extension-log-tool.md +5 -0
- package/extensions/prompts/peer-ask-tool.md +5 -0
- package/extensions/prompts/peer-bridge-system.md +4 -0
- package/extensions/prompts/peer-history-tool.md +3 -0
- package/extensions/prompts/peer-init-user-help.md +11 -0
- package/extensions/prompts/peer-init.md +17 -0
- package/extensions/prompts/peer-interrupt-tool.md +2 -0
- package/extensions/prompts/peer-list-tool.md +3 -0
- package/extensions/prompts/peer-no-babysitting.md +6 -0
- package/extensions/prompts/peer-send-tool.md +5 -0
- package/extensions/prompts/peer-start-tool.md +7 -0
- package/extensions/prompts/peer-stop-tool.md +3 -0
- package/extensions/prompts/runtime-models-tool.md +6 -0
- package/extensions/prompts/subagent-list-tool.md +3 -0
- package/extensions/prompts/subagent-run-tool.md +6 -0
- package/extensions/prompts/subagent-status-tool.md +2 -0
- package/extensions/prompts/team-list-tool.md +2 -0
- package/extensions/prompts/team-message-tool.md +2 -0
- package/extensions/prompts/team-spawn-tool.md +5 -0
- package/extensions/prompts/team-stop-tool.md +2 -0
- package/extensions/prompts/team-task-tool.md +3 -0
- package/extensions/prompts.ts +41 -0
- package/extensions/runtime-driver.test.ts +38 -0
- package/extensions/runtime-driver.ts +33 -0
- package/extensions/runtime-safety.test.ts +21 -0
- package/extensions/runtime-safety.ts +49 -0
- package/extensions/support.test.ts +144 -0
- package/extensions/support.ts +205 -0
- package/extensions/tool-inputs.test.ts +45 -0
- package/extensions/tool-inputs.ts +79 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.d.ts +48 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.js +406 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/bridge.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.js +18 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.d.ts +5 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.js +5 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.js +31 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.js +347 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/pi-intercom-transport.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.d.ts +103 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/intercom-bridge/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.js +26 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.js +12 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/driver-config.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.d.ts +8 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.js +320 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/claude-sdk.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.d.ts +24 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.js +266 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/codex-cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.d.ts +72 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.js +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/drivers/messages.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.d.ts +6 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.js +5 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.d.ts +16 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.js +94 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.d.ts +31 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.js +409 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/runtime.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.d.ts +185 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/runtime/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/runtime/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.d.ts +34 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.js +327 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/backend.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.js +17 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.js +4 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.d.ts +12 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.js +81 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.d.ts +72 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/subagents-backend/package.json +32 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.d.ts +27 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.js +194 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/backend.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.d.ts +2 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.js +21 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/cli.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.d.ts +4 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.js +4 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/index.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.d.ts +8 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.js +66 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/persistence.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.d.ts +41 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.js +2 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/dist/types.js.map +1 -0
- package/node_modules/@pi-claude-code-agent/teams-backend/package.json +33 -0
- package/package.json +98 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { BridgeTransportStatus } from "@pi-claude-code-agent/intercom-bridge";
|
|
2
|
+
import type { SubagentRunRecord } from "@pi-claude-code-agent/subagents-backend";
|
|
3
|
+
|
|
4
|
+
export interface DashboardState {
|
|
5
|
+
lastEvent: string;
|
|
6
|
+
lastEventAt: number;
|
|
7
|
+
lastRefreshedAt: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface AttentionLedgerEntry {
|
|
11
|
+
note: string;
|
|
12
|
+
lastNotifiedNote?: string;
|
|
13
|
+
acknowledgedNote?: string;
|
|
14
|
+
snoozedUntil?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AttentionLedger {
|
|
18
|
+
runs: Record<string, AttentionLedgerEntry>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface AttentionView {
|
|
22
|
+
run: SubagentRunRecord;
|
|
23
|
+
status: "active" | "acked" | "snoozed";
|
|
24
|
+
snoozedUntil?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AttentionReconciliation {
|
|
28
|
+
ledger: AttentionLedger;
|
|
29
|
+
notify: SubagentRunRecord[];
|
|
30
|
+
active: AttentionView[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createDashboardState(lastEvent: string, now = Date.now()): DashboardState {
|
|
34
|
+
return {
|
|
35
|
+
lastEvent,
|
|
36
|
+
lastEventAt: now,
|
|
37
|
+
lastRefreshedAt: now,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function recordDashboardEvent(state: DashboardState, lastEvent: string, now = Date.now()): void {
|
|
42
|
+
state.lastEvent = lastEvent;
|
|
43
|
+
state.lastEventAt = now;
|
|
44
|
+
state.lastRefreshedAt = now;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function recordDashboardRefresh(state: DashboardState, now = Date.now()): void {
|
|
48
|
+
state.lastRefreshedAt = now;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function detectConnectivityTransition(previous: boolean | undefined, next: boolean): "connected" | "disconnected" | undefined {
|
|
52
|
+
if (previous === undefined || previous === next) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return next ? "connected" : "disconnected";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function shouldRebindTransport(status: BridgeTransportStatus | undefined): boolean {
|
|
59
|
+
if (!status) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return status.boundPeers > status.connectedPeers;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function shouldSkipBackgroundRefresh(state: DashboardState, now: number, minIntervalMs: number): boolean {
|
|
66
|
+
return (now - state.lastRefreshedAt) < minIntervalMs;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface WidgetSignatureInput {
|
|
70
|
+
peerRows: Array<{
|
|
71
|
+
name: string;
|
|
72
|
+
state: string;
|
|
73
|
+
activity: string;
|
|
74
|
+
lastUpdateAt?: string;
|
|
75
|
+
model?: string;
|
|
76
|
+
contextPercentage?: number;
|
|
77
|
+
}>;
|
|
78
|
+
transportDegraded: boolean;
|
|
79
|
+
lastEvent: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Stable string fingerprint of visible widget content.
|
|
83
|
+
export function computeWidgetSignature(input: WidgetSignatureInput): string {
|
|
84
|
+
return JSON.stringify(input);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function createAttentionLedger(): AttentionLedger {
|
|
88
|
+
return { runs: {} };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function reconcileAttentionLedger(
|
|
92
|
+
ledger: AttentionLedger,
|
|
93
|
+
runs: SubagentRunRecord[],
|
|
94
|
+
now = Date.now(),
|
|
95
|
+
): AttentionReconciliation {
|
|
96
|
+
const nextRuns: AttentionLedger["runs"] = {};
|
|
97
|
+
const notify: SubagentRunRecord[] = [];
|
|
98
|
+
const active: AttentionView[] = [];
|
|
99
|
+
|
|
100
|
+
for (const run of runs.filter((item) => hasAttentionNote(item.note))) {
|
|
101
|
+
const note = run.note ?? "Needs attention";
|
|
102
|
+
const previous = ledger.runs[run.runId];
|
|
103
|
+
const entry: AttentionLedgerEntry = previous?.note === note
|
|
104
|
+
? { ...previous, note }
|
|
105
|
+
: { note };
|
|
106
|
+
|
|
107
|
+
if (entry.snoozedUntil && entry.snoozedUntil <= now) {
|
|
108
|
+
delete entry.snoozedUntil;
|
|
109
|
+
delete entry.lastNotifiedNote;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const view = buildAttentionView(run, entry, now);
|
|
113
|
+
|
|
114
|
+
if (view.status === "active" && entry.lastNotifiedNote !== note) {
|
|
115
|
+
entry.lastNotifiedNote = note;
|
|
116
|
+
notify.push(run);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
nextRuns[run.runId] = entry;
|
|
120
|
+
active.push(view);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
active.sort((a, b) => b.run.updatedAt.localeCompare(a.run.updatedAt));
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
ledger: { runs: nextRuns },
|
|
127
|
+
notify,
|
|
128
|
+
active,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function acknowledgeAttention(ledger: AttentionLedger, runId: string): AttentionLedger {
|
|
133
|
+
const entry = ledger.runs[runId];
|
|
134
|
+
if (!entry) {
|
|
135
|
+
return ledger;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
runs: {
|
|
139
|
+
...ledger.runs,
|
|
140
|
+
[runId]: {
|
|
141
|
+
...entry,
|
|
142
|
+
acknowledgedNote: entry.note,
|
|
143
|
+
snoozedUntil: undefined,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function snoozeAttention(ledger: AttentionLedger, runId: string, snoozedUntil: number): AttentionLedger {
|
|
150
|
+
const entry = ledger.runs[runId];
|
|
151
|
+
if (!entry) {
|
|
152
|
+
return ledger;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
runs: {
|
|
156
|
+
...ledger.runs,
|
|
157
|
+
[runId]: {
|
|
158
|
+
...entry,
|
|
159
|
+
snoozedUntil,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function listAttentionViews(
|
|
166
|
+
ledger: AttentionLedger,
|
|
167
|
+
runs: SubagentRunRecord[],
|
|
168
|
+
now = Date.now(),
|
|
169
|
+
): AttentionView[] {
|
|
170
|
+
return runs
|
|
171
|
+
.filter((run) => hasAttentionNote(run.note))
|
|
172
|
+
.map((run) => {
|
|
173
|
+
const note = run.note ?? "Needs attention";
|
|
174
|
+
const previous = ledger.runs[run.runId];
|
|
175
|
+
const entry = previous?.note === note ? { ...previous, note } : { note };
|
|
176
|
+
return buildAttentionView(run, entry, now);
|
|
177
|
+
})
|
|
178
|
+
.sort((a, b) => b.run.updatedAt.localeCompare(a.run.updatedAt));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function describeAttentionState(view: AttentionView, now = Date.now()): string {
|
|
182
|
+
if (view.status === "acked") {
|
|
183
|
+
return "acked";
|
|
184
|
+
}
|
|
185
|
+
if (view.status === "snoozed" && view.snoozedUntil) {
|
|
186
|
+
const remainingMs = Math.max(0, view.snoozedUntil - now);
|
|
187
|
+
const remainingMinutes = Math.max(1, Math.ceil(remainingMs / 60_000));
|
|
188
|
+
return `snoozed ${remainingMinutes}m`;
|
|
189
|
+
}
|
|
190
|
+
return "active";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function hasAttentionNote(note: string | undefined): boolean {
|
|
194
|
+
return Boolean(note && note.toLowerCase().includes("needs attention"));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function buildAttentionView(run: SubagentRunRecord, entry: AttentionLedgerEntry, now: number): AttentionView {
|
|
198
|
+
const acknowledged = entry.acknowledgedNote === entry.note;
|
|
199
|
+
const snoozed = !acknowledged && (entry.snoozedUntil ?? 0) > now;
|
|
200
|
+
return {
|
|
201
|
+
run,
|
|
202
|
+
status: acknowledged ? "acked" : snoozed ? "snoozed" : "active",
|
|
203
|
+
snoozedUntil: entry.snoozedUntil,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { parseSubagentRunToolInput, parseTeamSpawnToolInput } from "./tool-inputs.ts";
|
|
4
|
+
|
|
5
|
+
test("parseSubagentRunToolInput applies defaults and parses codex driver", () => {
|
|
6
|
+
assert.deepEqual(parseSubagentRunToolInput({
|
|
7
|
+
task: " do work ",
|
|
8
|
+
driver: "codex-cli",
|
|
9
|
+
async: true,
|
|
10
|
+
}), {
|
|
11
|
+
task: "do work",
|
|
12
|
+
name: "claude-subagent",
|
|
13
|
+
prompt: "You are delegated worker. Be concise and execution-focused.",
|
|
14
|
+
driver: "codex-cli",
|
|
15
|
+
model: undefined,
|
|
16
|
+
cwd: undefined,
|
|
17
|
+
async: true,
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("parseSubagentRunToolInput rejects missing task and invalid driver", () => {
|
|
22
|
+
assert.throws(() => parseSubagentRunToolInput({}), /task required/);
|
|
23
|
+
assert.throws(() => parseSubagentRunToolInput({ task: "x", driver: "wat" }), /driver must be claude-sdk or codex-cli/);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("parseTeamSpawnToolInput trims strings and parses claude driver", () => {
|
|
27
|
+
assert.deepEqual(parseTeamSpawnToolInput({
|
|
28
|
+
name: " worker ",
|
|
29
|
+
prompt: " hello ",
|
|
30
|
+
driver: "claude-sdk",
|
|
31
|
+
model: " o4-mini ",
|
|
32
|
+
cwd: " /tmp ",
|
|
33
|
+
}), {
|
|
34
|
+
name: "worker",
|
|
35
|
+
prompt: "hello",
|
|
36
|
+
driver: "claude-sdk",
|
|
37
|
+
model: "o4-mini",
|
|
38
|
+
cwd: "/tmp",
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("parseTeamSpawnToolInput rejects missing required fields and invalid driver", () => {
|
|
43
|
+
assert.throws(() => parseTeamSpawnToolInput({ name: "worker" }), /name and prompt required/);
|
|
44
|
+
assert.throws(() => parseTeamSpawnToolInput({ name: "worker", prompt: "hi", driver: "wat" }), /driver must be claude-sdk or codex-cli/);
|
|
45
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { parseRuntimeDriverName } from "./runtime-driver.js";
|
|
2
|
+
|
|
3
|
+
export interface ParsedSubagentRunToolInput {
|
|
4
|
+
task: string;
|
|
5
|
+
name: string;
|
|
6
|
+
prompt: string;
|
|
7
|
+
driver?: "claude-sdk" | "codex-cli";
|
|
8
|
+
model?: string;
|
|
9
|
+
cwd?: string;
|
|
10
|
+
async: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ParsedTeamSpawnToolInput {
|
|
14
|
+
name: string;
|
|
15
|
+
prompt: string;
|
|
16
|
+
driver?: "claude-sdk" | "codex-cli";
|
|
17
|
+
model?: string;
|
|
18
|
+
cwd?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DEFAULT_SUBAGENT_NAME = "claude-subagent";
|
|
22
|
+
const DEFAULT_SUBAGENT_PROMPT = "You are delegated worker. Be concise and execution-focused.";
|
|
23
|
+
|
|
24
|
+
export function parseSubagentRunToolInput(input: {
|
|
25
|
+
task?: unknown;
|
|
26
|
+
name?: unknown;
|
|
27
|
+
prompt?: unknown;
|
|
28
|
+
driver?: unknown;
|
|
29
|
+
model?: unknown;
|
|
30
|
+
cwd?: unknown;
|
|
31
|
+
async?: unknown;
|
|
32
|
+
}): ParsedSubagentRunToolInput {
|
|
33
|
+
const task = String(input.task ?? "").trim();
|
|
34
|
+
if (!task) {
|
|
35
|
+
throw new Error("task required");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const driver = input.driver == null ? undefined : parseRuntimeDriverName(input.driver);
|
|
39
|
+
if (input.driver != null && !driver) {
|
|
40
|
+
throw new Error("driver must be claude-sdk or codex-cli");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
task,
|
|
45
|
+
name: typeof input.name === "string" ? input.name.trim() || DEFAULT_SUBAGENT_NAME : DEFAULT_SUBAGENT_NAME,
|
|
46
|
+
prompt: typeof input.prompt === "string" ? input.prompt.trim() || DEFAULT_SUBAGENT_PROMPT : DEFAULT_SUBAGENT_PROMPT,
|
|
47
|
+
driver,
|
|
48
|
+
model: typeof input.model === "string" ? input.model.trim() || undefined : undefined,
|
|
49
|
+
cwd: typeof input.cwd === "string" ? input.cwd.trim() || undefined : undefined,
|
|
50
|
+
async: input.async === true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function parseTeamSpawnToolInput(input: {
|
|
55
|
+
name?: unknown;
|
|
56
|
+
prompt?: unknown;
|
|
57
|
+
driver?: unknown;
|
|
58
|
+
model?: unknown;
|
|
59
|
+
cwd?: unknown;
|
|
60
|
+
}): ParsedTeamSpawnToolInput {
|
|
61
|
+
const name = String(input.name ?? "").trim();
|
|
62
|
+
const prompt = String(input.prompt ?? "").trim();
|
|
63
|
+
if (!name || !prompt) {
|
|
64
|
+
throw new Error("name and prompt required");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const driver = input.driver == null ? undefined : parseRuntimeDriverName(input.driver);
|
|
68
|
+
if (input.driver != null && !driver) {
|
|
69
|
+
throw new Error("driver must be claude-sdk or codex-cli");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
name,
|
|
74
|
+
prompt,
|
|
75
|
+
driver,
|
|
76
|
+
model: typeof input.model === "string" ? input.model.trim() || undefined : undefined,
|
|
77
|
+
cwd: typeof input.cwd === "string" ? input.cwd.trim() || undefined : undefined,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type RuntimeEvent, type RuntimeStatus } from "@pi-claude-code-agent/runtime";
|
|
2
|
+
import type { AskResult, AttachPeerInput, BridgeOptions, BridgePeer, BridgeState, BridgeTransport, BridgeTransportIncomingMessage, BridgeTransportStatus, IntercomInboundMessage, InterruptPeerResult, LaunchPeerInput } from "./types.js";
|
|
3
|
+
declare const BRIDGE_SYSTEM_PROMPT: string;
|
|
4
|
+
export declare class ClaudeRuntimeIntercomBridge {
|
|
5
|
+
private readonly runtime;
|
|
6
|
+
private readonly storageDir;
|
|
7
|
+
private transport?;
|
|
8
|
+
private readonly pollIntervalMs;
|
|
9
|
+
private readonly askTimeoutMs;
|
|
10
|
+
private readonly peers;
|
|
11
|
+
constructor(options?: BridgeOptions);
|
|
12
|
+
launchPeer(input: LaunchPeerInput): Promise<BridgePeer>;
|
|
13
|
+
attachPeer(input: AttachPeerInput): Promise<BridgePeer>;
|
|
14
|
+
listPeers(): Promise<BridgePeer[]>;
|
|
15
|
+
status(name: string): Promise<BridgePeer | undefined>;
|
|
16
|
+
send(name: string, message: Omit<IntercomInboundMessage, "kind">, options?: {
|
|
17
|
+
waitForIdle?: boolean;
|
|
18
|
+
}): Promise<BridgePeer>;
|
|
19
|
+
ask(name: string, message: Omit<IntercomInboundMessage, "kind">): Promise<AskResult>;
|
|
20
|
+
reply(name: string, message: Omit<IntercomInboundMessage, "kind">): Promise<BridgePeer>;
|
|
21
|
+
interrupt(name: string): Promise<BridgePeer>;
|
|
22
|
+
interruptWithResult(name: string): Promise<InterruptPeerResult>;
|
|
23
|
+
stop(name: string): Promise<BridgePeer>;
|
|
24
|
+
disconnect(name: string): Promise<BridgePeer>;
|
|
25
|
+
setTransport(transport?: BridgeTransport): Promise<void>;
|
|
26
|
+
restorePeers(): Promise<BridgePeer[]>;
|
|
27
|
+
transportStatus(): Promise<BridgeTransportStatus | undefined>;
|
|
28
|
+
hasTransport(): boolean;
|
|
29
|
+
close(): Promise<void>;
|
|
30
|
+
private deliver;
|
|
31
|
+
private waitForTerminalStateOrCurrent;
|
|
32
|
+
private waitForTerminalState;
|
|
33
|
+
private syncPeerFromRuntime;
|
|
34
|
+
private peerFromStatus;
|
|
35
|
+
private registerTransportPeer;
|
|
36
|
+
private unregisterTransportPeer;
|
|
37
|
+
private handleTransportMessage;
|
|
38
|
+
private rememberPeer;
|
|
39
|
+
private forgetPeer;
|
|
40
|
+
private requirePeer;
|
|
41
|
+
private assertPeerNameAvailable;
|
|
42
|
+
}
|
|
43
|
+
declare function formatInboundMessage(message: IntercomInboundMessage): string;
|
|
44
|
+
declare function extractReplyText(events: RuntimeEvent[]): string;
|
|
45
|
+
declare function extractLatestReplyText(events: RuntimeEvent[]): string;
|
|
46
|
+
declare function mapRuntimeState(state: RuntimeStatus["state"], registered: boolean): BridgeState;
|
|
47
|
+
declare function formatTransportInboundText(message: BridgeTransportIncomingMessage): string;
|
|
48
|
+
export { BRIDGE_SYSTEM_PROMPT, extractLatestReplyText, extractReplyText, formatInboundMessage, formatTransportInboundText, mapRuntimeState };
|