@tt-a1i/openpi 0.4.0 → 0.5.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/README.md +102 -40
- package/SETUP.md +22 -6
- package/assets/openpi-launch-card-v1.webp +0 -0
- package/bin/openpi.js +145 -0
- package/extensions/background-terminals/index.ts +30 -2
- package/extensions/background-terminals/src/domain.ts +2 -0
- package/extensions/background-terminals/src/manager.ts +486 -106
- package/extensions/background-terminals/src/output.ts +33 -0
- package/extensions/background-terminals/src/prompt.ts +13 -5
- package/extensions/background-terminals/src/result-delivery.ts +4 -1
- package/extensions/clear-context/index.ts +83 -0
- package/extensions/context-pivot/index.ts +16 -6
- package/extensions/cron/schedule.ts +7 -1
- package/extensions/file-mutation-display/render.ts +17 -257
- package/extensions/file-search/src/binaries.ts +57 -41
- package/extensions/git-read/index.ts +1 -3
- package/extensions/model-info/index.ts +21 -33
- package/extensions/model-info/session-metrics.ts +96 -0
- package/extensions/plan-mode/bash-policy.ts +54 -9
- package/extensions/plan-mode/index.ts +7 -2
- package/extensions/post-edit/index.ts +16 -6
- package/extensions/sessions/git-stats.ts +258 -72
- package/extensions/sessions/index.ts +153 -86
- package/extensions/sessions/preview-cache.ts +104 -0
- package/extensions/sessions/preview-loader.ts +856 -0
- package/extensions/sessions/sessions.ts +43 -4
- package/extensions/setup/index.ts +123 -127
- package/extensions/shared/activity-status.ts +30 -0
- package/extensions/shared/agent-session-page.ts +319 -0
- package/extensions/shared/agent-tool-renderer.ts +218 -0
- package/extensions/shared/agent-transcript.ts +524 -0
- package/extensions/shared/capability-intent.ts +1 -1
- package/extensions/shared/child-session.ts +437 -21
- package/extensions/shared/result-delivery.ts +34 -0
- package/extensions/shared/setup-config.ts +73 -33
- package/extensions/shared/setup-episode-state.ts +1 -1
- package/extensions/shared/terminal-text.ts +110 -23
- package/extensions/shared/text-projection.ts +72 -15
- package/extensions/shared/tool-activity.ts +382 -0
- package/extensions/shared/tool-surface.ts +29 -2
- package/extensions/shared/transcript-viewport.ts +46 -0
- package/extensions/shared/web-observer-registry.ts +390 -0
- package/extensions/shared/worktree.ts +11 -0
- package/extensions/subagents/index.ts +270 -59
- package/extensions/subagents/navigation.ts +34 -5
- package/extensions/subagents/src/backend.ts +12 -1
- package/extensions/subagents/src/backends/pi.ts +375 -66
- package/extensions/subagents/src/domain.ts +5 -0
- package/extensions/subagents/src/manager.ts +34 -2
- package/extensions/subagents/src/prompt.ts +32 -4
- package/extensions/subagents/src/result-artifact.ts +4 -0
- package/extensions/subagents/src/result-delivery.ts +7 -1
- package/extensions/subagents/src/runtime.ts +15 -1
- package/extensions/subagents/src/ui/takeover.ts +73 -257
- package/extensions/subagents/src/ui/transcript.ts +38 -535
- package/extensions/subagents/src/ui/wait-result.ts +103 -15
- package/extensions/suggestions/src/ui.ts +10 -4
- package/extensions/tasks/index.ts +0 -3
- package/extensions/ui-customization/footer.ts +0 -40
- package/extensions/ui-customization/index.ts +0 -4
- package/extensions/user-input-fold/index.ts +1 -1
- package/extensions/web/index.ts +234 -0
- package/extensions/workflows/artifacts.ts +137 -47
- package/extensions/workflows/completion-projection.ts +457 -0
- package/extensions/workflows/coordinator.ts +8 -10
- package/extensions/workflows/dashboard.ts +167 -228
- package/extensions/workflows/handoff.ts +70 -16
- package/extensions/workflows/index.ts +488 -198
- package/extensions/workflows/journal.ts +148 -13
- package/extensions/workflows/model.ts +74 -4
- package/extensions/workflows/navigation.ts +32 -8
- package/extensions/workflows/progress-projection.ts +306 -0
- package/extensions/workflows/prompt.ts +66 -6
- package/extensions/workflows/replay-safety.ts +42 -21
- package/extensions/workflows/result-delivery.ts +128 -64
- package/extensions/workflows/retention.ts +593 -0
- package/extensions/workflows/runner.ts +388 -279
- package/extensions/workflows/sandbox-child.cjs +25 -3
- package/extensions/workflows/sandbox.ts +62 -8
- package/extensions/workflows/serialization.ts +325 -17
- package/extensions/workflows/tool-renderer.ts +22 -0
- package/extensions/workflows/transcript.ts +149 -0
- package/extensions/workspace-cleanup-guard/index.ts +54 -0
- package/extensions/workspace-cleanup-guard/workspace-provenance.ts +563 -0
- package/package.json +28 -8
- package/skills/subagents/REFERENCE.md +189 -0
- package/skills/subagents/SKILL.md +1 -1
- package/skills/workflows/REFERENCE.md +4 -2
- package/web/adapter/pi-adapter.ts +661 -0
- package/web/host/browser-launcher.ts +20 -0
- package/web/host/static-assets.ts +4 -0
- package/web/host/terminal-status.ts +38 -0
- package/web/host/web-host.ts +789 -0
- package/web/http-dispatcher.ts +125 -0
- package/web/protocol/types.ts +462 -0
- package/web/runtime/pi-runtime.ts +991 -0
- package/web/runtime/types.ts +71 -0
- package/web/runtime/web-host-lease.ts +497 -0
- package/web/trace.ts +18 -0
- package/web/ui/app.js +1398 -0
- package/web/ui/index.html +139 -0
- package/web/ui/styles.css +598 -0
- package/web/vite.config.mjs +34 -0
- package/extensions/execution-convergence/active-evidence.ts +0 -129
- package/extensions/execution-convergence/index.ts +0 -442
- package/extensions/execution-convergence/workspace-provenance.ts +0 -338
- package/extensions/setup/intercom-fs-helper.cjs +0 -130
- package/extensions/setup/intercom.ts +0 -603
- package/extensions/subagents/src/backends/stub.ts +0 -303
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import {
|
|
3
|
+
AgentTranscriptRenderer,
|
|
4
|
+
buildPairingIndex,
|
|
5
|
+
type AgentTranscriptDocument,
|
|
6
|
+
type AgentTranscriptItem,
|
|
7
|
+
type AgentTranscriptPart,
|
|
8
|
+
} from "../shared/agent-transcript.ts";
|
|
9
|
+
import type { TranscriptEntry } from "./model.ts";
|
|
10
|
+
import { workflowToolRenderer } from "./tool-renderer.ts";
|
|
11
|
+
|
|
12
|
+
/** Project the bounded Workflow artifact into the shared operator document. */
|
|
13
|
+
function buildWorkflowTranscriptDocument(
|
|
14
|
+
transcript: ReadonlyArray<TranscriptEntry>,
|
|
15
|
+
cwd?: string,
|
|
16
|
+
): AgentTranscriptDocument {
|
|
17
|
+
const items: AgentTranscriptItem[] = [];
|
|
18
|
+
const pendingByName = new Map<string, string[]>();
|
|
19
|
+
|
|
20
|
+
const appendAssistantPart = (part: AgentTranscriptPart) => {
|
|
21
|
+
const previous = items[items.length - 1];
|
|
22
|
+
if (previous?.kind === "assistant") {
|
|
23
|
+
items[items.length - 1] = {
|
|
24
|
+
...previous,
|
|
25
|
+
parts: [...previous.parts, part],
|
|
26
|
+
};
|
|
27
|
+
} else {
|
|
28
|
+
items.push({ kind: "assistant", parts: [part] });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
for (let index = 0; index < transcript.length; index++) {
|
|
33
|
+
const entry = transcript[index]!;
|
|
34
|
+
if (entry.role === "user") {
|
|
35
|
+
items.push({ kind: "user", text: entry.text });
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (entry.role === "assistant") {
|
|
39
|
+
appendAssistantPart({ type: "text", text: entry.text });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (entry.role === "thinking") {
|
|
43
|
+
appendAssistantPart({ type: "thinking", text: entry.text });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const name = entry.name ?? "unknown";
|
|
48
|
+
if (entry.role === "tool") {
|
|
49
|
+
const toolId = entry.toolCallId ?? `workflow-tool-${index}`;
|
|
50
|
+
appendAssistantPart({
|
|
51
|
+
type: "toolCall",
|
|
52
|
+
toolId,
|
|
53
|
+
name,
|
|
54
|
+
argsPreview: entry.text,
|
|
55
|
+
});
|
|
56
|
+
const pending = pendingByName.get(name) ?? [];
|
|
57
|
+
pending.push(toolId);
|
|
58
|
+
pendingByName.set(name, pending);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const pending = pendingByName.get(name);
|
|
63
|
+
let toolId: string;
|
|
64
|
+
if (entry.toolCallId) {
|
|
65
|
+
toolId = entry.toolCallId;
|
|
66
|
+
const pendingIndex = pending?.indexOf(toolId) ?? -1;
|
|
67
|
+
if (pendingIndex >= 0) pending?.splice(pendingIndex, 1);
|
|
68
|
+
} else {
|
|
69
|
+
toolId = pending?.shift() ?? `workflow-result-${index}`;
|
|
70
|
+
}
|
|
71
|
+
items.push({
|
|
72
|
+
kind: "toolResult",
|
|
73
|
+
toolId,
|
|
74
|
+
name,
|
|
75
|
+
isError: entry.isError === true,
|
|
76
|
+
outputPreview: entry.text,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const toolRenderer = workflowToolRenderer(transcript);
|
|
81
|
+
return {
|
|
82
|
+
items,
|
|
83
|
+
pairing: buildPairingIndex(items),
|
|
84
|
+
cwd,
|
|
85
|
+
...(toolRenderer ? { toolRenderer } : {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Preserve the shared renderer's identity cache between Workflow repaint ticks. */
|
|
90
|
+
export class WorkflowTranscriptAdapter {
|
|
91
|
+
private previousEntries?: ReadonlyArray<TranscriptEntry>;
|
|
92
|
+
private previousCwd?: string;
|
|
93
|
+
private previousToolRenderer?: AgentTranscriptDocument["toolRenderer"];
|
|
94
|
+
private previousDocument?: AgentTranscriptDocument;
|
|
95
|
+
|
|
96
|
+
document(
|
|
97
|
+
transcript: ReadonlyArray<TranscriptEntry>,
|
|
98
|
+
cwd?: string,
|
|
99
|
+
): AgentTranscriptDocument {
|
|
100
|
+
const toolRenderer = workflowToolRenderer(transcript);
|
|
101
|
+
if (
|
|
102
|
+
this.previousDocument &&
|
|
103
|
+
this.previousCwd === cwd &&
|
|
104
|
+
this.previousToolRenderer === toolRenderer &&
|
|
105
|
+
this.previousEntries?.length === transcript.length &&
|
|
106
|
+
this.previousEntries.every((entry, index) => entry === transcript[index])
|
|
107
|
+
) {
|
|
108
|
+
return this.previousDocument;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const document = buildWorkflowTranscriptDocument(transcript, cwd);
|
|
112
|
+
this.previousEntries = [...transcript];
|
|
113
|
+
this.previousCwd = cwd;
|
|
114
|
+
this.previousToolRenderer = toolRenderer;
|
|
115
|
+
this.previousDocument = document;
|
|
116
|
+
return document;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function workflowTranscriptDocument(
|
|
121
|
+
transcript: ReadonlyArray<TranscriptEntry>,
|
|
122
|
+
cwd?: string,
|
|
123
|
+
) {
|
|
124
|
+
return buildWorkflowTranscriptDocument(transcript, cwd);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class WorkflowTranscriptRenderer {
|
|
128
|
+
private adapter = new WorkflowTranscriptAdapter();
|
|
129
|
+
private renderer = new AgentTranscriptRenderer();
|
|
130
|
+
|
|
131
|
+
render(
|
|
132
|
+
transcript: ReadonlyArray<TranscriptEntry>,
|
|
133
|
+
cwd: string | undefined,
|
|
134
|
+
width: number,
|
|
135
|
+
theme: Theme,
|
|
136
|
+
options?: { readonly now?: number; readonly expanded?: boolean },
|
|
137
|
+
) {
|
|
138
|
+
return this.renderer.render(
|
|
139
|
+
this.adapter.document(transcript, cwd),
|
|
140
|
+
width,
|
|
141
|
+
theme,
|
|
142
|
+
options,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
invalidate() {
|
|
147
|
+
this.renderer.invalidate();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ExtensionAPI,
|
|
3
|
+
isToolCallEventType,
|
|
4
|
+
} from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { createWorkspaceCleanupGuard } from "./workspace-provenance.ts";
|
|
6
|
+
|
|
7
|
+
const DELETE_CONFIRMATION_TITLE = "Delete pre-existing workspace files?";
|
|
8
|
+
|
|
9
|
+
function deleteConfirmationMessage(paths: readonly string[]) {
|
|
10
|
+
return `The command would delete files that existed before this agent changed them:\n\n${paths.map((candidate) => `- ${candidate}`).join("\n")}\n\nAllow this exact deletion?`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function workspaceCleanupGuard(pi: ExtensionAPI) {
|
|
14
|
+
const workspaceCleanup = createWorkspaceCleanupGuard();
|
|
15
|
+
|
|
16
|
+
pi.on("tool_call", async (event, ctx) => {
|
|
17
|
+
if (isToolCallEventType("write", event)) {
|
|
18
|
+
await workspaceCleanup.beforeWrite({
|
|
19
|
+
id: event.toolCallId,
|
|
20
|
+
path: event.input.path,
|
|
21
|
+
cwd: ctx.cwd,
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!isToolCallEventType("bash", event)) return;
|
|
26
|
+
|
|
27
|
+
const cleanupDecision = await workspaceCleanup.before({
|
|
28
|
+
id: event.toolCallId,
|
|
29
|
+
command: event.input.command,
|
|
30
|
+
cwd: ctx.cwd,
|
|
31
|
+
confirmDelete: (paths) =>
|
|
32
|
+
ctx.ui.confirm(
|
|
33
|
+
DELETE_CONFIRMATION_TITLE,
|
|
34
|
+
deleteConfirmationMessage(paths),
|
|
35
|
+
{ signal: ctx.signal },
|
|
36
|
+
),
|
|
37
|
+
});
|
|
38
|
+
if (cleanupDecision.kind === "block") {
|
|
39
|
+
return { block: true, reason: cleanupDecision.reason };
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
pi.on("tool_result", async (event) => {
|
|
44
|
+
if (event.toolName !== "bash" && event.toolName !== "write") return;
|
|
45
|
+
await workspaceCleanup.after({
|
|
46
|
+
id: event.toolCallId,
|
|
47
|
+
isError: event.isError,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
pi.on("agent_settled", () => {
|
|
52
|
+
workspaceCleanup.reset();
|
|
53
|
+
});
|
|
54
|
+
}
|