@tt-a1i/openpi 0.1.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.
Files changed (114) hide show
  1. package/README.md +643 -0
  2. package/SETUP.md +74 -0
  3. package/THIRD_PARTY_NOTICES.md +16 -0
  4. package/assets/openpi-package.png +0 -0
  5. package/assets/readme-hero-mobile.svg +72 -0
  6. package/assets/readme-hero.svg +118 -0
  7. package/assets/readme-runtime-mobile.svg +91 -0
  8. package/assets/readme-runtime.svg +111 -0
  9. package/extensions/ask-user/handoff.ts +205 -0
  10. package/extensions/ask-user/index.ts +1110 -0
  11. package/extensions/ask-user/limits.ts +89 -0
  12. package/extensions/ask-user/prompt.ts +76 -0
  13. package/extensions/background-terminals/index.ts +653 -0
  14. package/extensions/background-terminals/src/domain.ts +99 -0
  15. package/extensions/background-terminals/src/manager.ts +989 -0
  16. package/extensions/background-terminals/src/output.ts +84 -0
  17. package/extensions/background-terminals/src/prompt.ts +195 -0
  18. package/extensions/background-terminals/src/result-delivery.ts +43 -0
  19. package/extensions/background-terminals/src/runtime.ts +36 -0
  20. package/extensions/background-terminals/src/ui/output-view.ts +55 -0
  21. package/extensions/background-terminals/src/ui/ps.ts +642 -0
  22. package/extensions/background-terminals/src/ui/tool-result.ts +146 -0
  23. package/extensions/background-terminals/src/watch.ts +192 -0
  24. package/extensions/context-pivot/index.ts +222 -0
  25. package/extensions/copy-all/index.ts +65 -0
  26. package/extensions/cron/index.ts +173 -0
  27. package/extensions/cron/schedule.ts +127 -0
  28. package/extensions/file-mutation-display/index.ts +105 -0
  29. package/extensions/file-mutation-display/render.ts +107 -0
  30. package/extensions/file-search/index.ts +515 -0
  31. package/extensions/file-search/src/args.ts +129 -0
  32. package/extensions/file-search/src/binaries.ts +419 -0
  33. package/extensions/file-search/src/output.ts +142 -0
  34. package/extensions/file-search/src/process.ts +309 -0
  35. package/extensions/file-search/src/prompt.ts +53 -0
  36. package/extensions/git-info/index.ts +272 -0
  37. package/extensions/git-info/src/changed-files-view.ts +414 -0
  38. package/extensions/git-info/src/process.ts +107 -0
  39. package/extensions/git-info/src/refresh-coordinator.ts +13 -0
  40. package/extensions/git-info/src/runtime.ts +28 -0
  41. package/extensions/goal/controller.ts +794 -0
  42. package/extensions/goal/index.ts +521 -0
  43. package/extensions/goal/prompts.ts +122 -0
  44. package/extensions/goal/state.ts +763 -0
  45. package/extensions/goal/ui.ts +158 -0
  46. package/extensions/model-info/index.ts +234 -0
  47. package/extensions/plan-mode/bash-policy.ts +313 -0
  48. package/extensions/plan-mode/index.ts +539 -0
  49. package/extensions/post-edit/index.ts +129 -0
  50. package/extensions/sessions/LICENSE.upstream +21 -0
  51. package/extensions/sessions/git-stats.ts +226 -0
  52. package/extensions/sessions/index.ts +1092 -0
  53. package/extensions/sessions/sessions.ts +385 -0
  54. package/extensions/setup/index.ts +408 -0
  55. package/extensions/shared/activity-status.ts +65 -0
  56. package/extensions/shared/below-editor-navigation.ts +343 -0
  57. package/extensions/shared/child-session.ts +352 -0
  58. package/extensions/shared/context-utilization.ts +47 -0
  59. package/extensions/shared/dashboard-state.ts +102 -0
  60. package/extensions/shared/plan-mode-state.ts +65 -0
  61. package/extensions/shared/setup-config.ts +971 -0
  62. package/extensions/shared/subagent-roles.ts +22 -0
  63. package/extensions/shared/terminal-text.ts +38 -0
  64. package/extensions/shared/tool-call-timeout.ts +104 -0
  65. package/extensions/shared/worktree.ts +526 -0
  66. package/extensions/subagents/index.ts +1225 -0
  67. package/extensions/subagents/navigation.ts +121 -0
  68. package/extensions/subagents/src/agent-types.ts +543 -0
  69. package/extensions/subagents/src/backend.ts +63 -0
  70. package/extensions/subagents/src/backends/pi.ts +493 -0
  71. package/extensions/subagents/src/backends/stub.ts +296 -0
  72. package/extensions/subagents/src/by-the-way.ts +21 -0
  73. package/extensions/subagents/src/domain.ts +271 -0
  74. package/extensions/subagents/src/format.ts +48 -0
  75. package/extensions/subagents/src/manager.ts +769 -0
  76. package/extensions/subagents/src/prompt.ts +190 -0
  77. package/extensions/subagents/src/result-delivery.ts +20 -0
  78. package/extensions/subagents/src/runtime.ts +51 -0
  79. package/extensions/subagents/src/ui/takeover.ts +615 -0
  80. package/extensions/subagents/src/ui/transcript.ts +293 -0
  81. package/extensions/subagents/src/ui/wait-result.ts +89 -0
  82. package/extensions/suggestions/index.ts +172 -0
  83. package/extensions/suggestions/src/config.ts +12 -0
  84. package/extensions/suggestions/src/predictor.ts +147 -0
  85. package/extensions/suggestions/src/prompt.ts +20 -0
  86. package/extensions/suggestions/src/transcript.ts +233 -0
  87. package/extensions/suggestions/src/ui.ts +224 -0
  88. package/extensions/tasks/index.ts +512 -0
  89. package/extensions/tasks/tasks.ts +649 -0
  90. package/extensions/tasks/ui.ts +421 -0
  91. package/extensions/turn-time/index.ts +61 -0
  92. package/extensions/ui-customization/footer.ts +512 -0
  93. package/extensions/ui-customization/index.ts +217 -0
  94. package/extensions/workflows/acceptance.ts +298 -0
  95. package/extensions/workflows/artifacts.ts +225 -0
  96. package/extensions/workflows/controller.ts +210 -0
  97. package/extensions/workflows/dashboard.ts +1226 -0
  98. package/extensions/workflows/index.ts +1884 -0
  99. package/extensions/workflows/journal.ts +188 -0
  100. package/extensions/workflows/meta.ts +250 -0
  101. package/extensions/workflows/model.ts +423 -0
  102. package/extensions/workflows/navigation.ts +93 -0
  103. package/extensions/workflows/prompt.ts +212 -0
  104. package/extensions/workflows/replay-safety.ts +577 -0
  105. package/extensions/workflows/runner.ts +786 -0
  106. package/extensions/workflows/sandbox-child.cjs +402 -0
  107. package/extensions/workflows/sandbox.ts +397 -0
  108. package/extensions/workflows/serialization.ts +162 -0
  109. package/extensions/workflows/worktree-handoff.ts +216 -0
  110. package/package.json +87 -0
  111. package/scripts/prepare-effect-tsgo.mjs +16 -0
  112. package/skills/background-terminals/SKILL.md +30 -0
  113. package/skills/subagents/SKILL.md +15 -0
  114. package/themes/github-dark-default.json +89 -0
@@ -0,0 +1,226 @@
1
+ import { execFile } from "node:child_process";
2
+ import type { SessionInfoLike } from "./sessions.ts";
3
+
4
+ export interface SessionStats {
5
+ add: number;
6
+ mod: number;
7
+ del: number;
8
+ }
9
+
10
+ interface StatsLoaderOptions {
11
+ cache?: Map<string, SessionStats>;
12
+ maxCache?: number;
13
+ maxConcurrency?: number;
14
+ runGit?: (
15
+ args: string[],
16
+ cwd: string,
17
+ signal: AbortSignal,
18
+ ) => Promise<string>;
19
+ }
20
+
21
+ interface QueueEntry {
22
+ signal: AbortSignal;
23
+ start: (done: () => void) => void;
24
+ cancel: () => void;
25
+ }
26
+
27
+ const GIT_STATS_TIMEOUT_MS = 3_000;
28
+ const DEFAULT_MAX_CACHE = 256;
29
+ const DEFAULT_MAX_CONCURRENCY = 4;
30
+
31
+ const abortError = () => {
32
+ const error = new Error("Session stats load was cancelled.");
33
+ error.name = "AbortError";
34
+ return error;
35
+ };
36
+
37
+ function createQueue(maxConcurrency: number) {
38
+ const queue: QueueEntry[] = [];
39
+ let active = 0;
40
+
41
+ const pump = () => {
42
+ while (active < maxConcurrency && queue.length > 0) {
43
+ const entry = queue.shift()!;
44
+ if (entry.signal.aborted) {
45
+ entry.cancel();
46
+ continue;
47
+ }
48
+ active++;
49
+ entry.start(() => {
50
+ active--;
51
+ pump();
52
+ });
53
+ }
54
+ };
55
+
56
+ const run = <A>(task: () => Promise<A>, signal: AbortSignal) =>
57
+ new Promise<A>((resolve, reject) => {
58
+ let started = false;
59
+ let settled = false;
60
+ const finish = (complete: () => void) => {
61
+ if (settled) return;
62
+ settled = true;
63
+ signal.removeEventListener("abort", cancelQueued);
64
+ complete();
65
+ };
66
+ const cancelQueued = () => {
67
+ if (started || settled) return;
68
+ // Leave the cancelled entry in place for the next linear pump. Removing
69
+ // every entry from a large shared-signal queue would make abort O(n²).
70
+ finish(() => reject(abortError()));
71
+ };
72
+ const entry: QueueEntry = {
73
+ signal,
74
+ cancel: cancelQueued,
75
+ start: (done) => {
76
+ if (settled) {
77
+ done();
78
+ return;
79
+ }
80
+ started = true;
81
+ signal.removeEventListener("abort", cancelQueued);
82
+ void task()
83
+ .then(
84
+ (value) => finish(() => resolve(value)),
85
+ (error) => finish(() => reject(error)),
86
+ )
87
+ .finally(done);
88
+ },
89
+ };
90
+
91
+ signal.addEventListener("abort", cancelQueued, { once: true });
92
+ queue.push(entry);
93
+ pump();
94
+ });
95
+
96
+ return { run };
97
+ }
98
+
99
+ const runGit = (args: string[], cwd: string, signal: AbortSignal) =>
100
+ new Promise<string>((resolve) => {
101
+ try {
102
+ execFile(
103
+ "git",
104
+ args,
105
+ {
106
+ cwd,
107
+ encoding: "utf8",
108
+ timeout: GIT_STATS_TIMEOUT_MS,
109
+ signal,
110
+ },
111
+ (error, stdout) => resolve(error ? "" : stdout),
112
+ );
113
+ } catch {
114
+ resolve("");
115
+ }
116
+ });
117
+
118
+ const calculateStats = (outputs: readonly string[]) => {
119
+ let added = 0;
120
+ let deleted = 0;
121
+ for (const output of outputs) {
122
+ for (const line of output.split("\n")) {
123
+ const [rawAdded, rawDeleted] = line.trim().split(/\s+/);
124
+ const nextAdded = Number.parseInt(rawAdded ?? "", 10);
125
+ const nextDeleted = Number.parseInt(rawDeleted ?? "", 10);
126
+ if (!Number.isNaN(nextAdded)) added += nextAdded;
127
+ if (!Number.isNaN(nextDeleted)) deleted += nextDeleted;
128
+ }
129
+ }
130
+
131
+ const mod = Math.min(added, deleted);
132
+ return { add: added - mod, mod, del: deleted - mod };
133
+ };
134
+
135
+ export function createSessionStatsLoader(options: StatsLoaderOptions = {}) {
136
+ const cache = options.cache ?? new Map<string, SessionStats>();
137
+ const maxCache = options.maxCache ?? DEFAULT_MAX_CACHE;
138
+ const execute = options.runGit ?? runGit;
139
+ const queue = createQueue(
140
+ Math.max(1, options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY),
141
+ );
142
+ const loading = new Map<string, AbortSignal>();
143
+
144
+ const loadOne = async (
145
+ session: SessionInfoLike,
146
+ isLatestForCwd: boolean,
147
+ signal: AbortSignal,
148
+ onUpdate: () => void,
149
+ ) => {
150
+ const key = session.path;
151
+ if (cache.has(key)) return;
152
+ const currentLoad = loading.get(key);
153
+ if (currentLoad && !currentLoad.aborted) return;
154
+ loading.set(key, signal);
155
+
156
+ const after = session.created
157
+ ? session.created.toISOString()
158
+ : new Date(session.modified.getTime() - 24 * 3600 * 1000).toISOString();
159
+ const before = session.modified.toISOString();
160
+
161
+ try {
162
+ const outputs = await Promise.all([
163
+ queue
164
+ .run(
165
+ () =>
166
+ execute(
167
+ [
168
+ "log",
169
+ `--after=${after}`,
170
+ `--before=${before}`,
171
+ "--numstat",
172
+ "--pretty=format:",
173
+ ],
174
+ session.cwd,
175
+ signal,
176
+ ),
177
+ signal,
178
+ )
179
+ .catch(() => ""),
180
+ isLatestForCwd
181
+ ? queue
182
+ .run(
183
+ () => execute(["diff", "--numstat"], session.cwd, signal),
184
+ signal,
185
+ )
186
+ .catch(() => "")
187
+ : Promise.resolve(""),
188
+ ]);
189
+ if (signal.aborted || loading.get(key) !== signal) return;
190
+
191
+ if (cache.size >= maxCache) {
192
+ const oldest = cache.keys().next().value;
193
+ if (oldest !== undefined) cache.delete(oldest);
194
+ }
195
+ cache.set(key, calculateStats(outputs));
196
+ onUpdate();
197
+ } finally {
198
+ if (loading.get(key) === signal) loading.delete(key);
199
+ }
200
+ };
201
+
202
+ const load = (
203
+ sessions: SessionInfoLike[],
204
+ signal: AbortSignal,
205
+ onUpdate: () => void,
206
+ ) => {
207
+ const latestByCwd = new Map<string, string>();
208
+ for (const session of sessions) {
209
+ if (!latestByCwd.has(session.cwd)) {
210
+ latestByCwd.set(session.cwd, session.path);
211
+ }
212
+ }
213
+ return Promise.all(
214
+ sessions.map((session) =>
215
+ loadOne(
216
+ session,
217
+ latestByCwd.get(session.cwd) === session.path,
218
+ signal,
219
+ onUpdate,
220
+ ),
221
+ ),
222
+ ).then(() => undefined);
223
+ };
224
+
225
+ return { cache, load };
226
+ }