@operator-labs/darwin 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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/dist/app.d.ts +5 -0
  4. package/dist/app.js +469 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/cli.d.ts +1 -0
  7. package/dist/cli.js +134 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +8 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/lib/auth.d.ts +15 -0
  13. package/dist/lib/auth.js +71 -0
  14. package/dist/lib/auth.js.map +1 -0
  15. package/dist/lib/autocomplete.d.ts +18 -0
  16. package/dist/lib/autocomplete.js +124 -0
  17. package/dist/lib/autocomplete.js.map +1 -0
  18. package/dist/lib/command-surface.d.ts +52 -0
  19. package/dist/lib/command-surface.js +198 -0
  20. package/dist/lib/command-surface.js.map +1 -0
  21. package/dist/lib/config.d.ts +25 -0
  22. package/dist/lib/config.js +99 -0
  23. package/dist/lib/config.js.map +1 -0
  24. package/dist/lib/darwin-local.d.ts +31 -0
  25. package/dist/lib/darwin-local.js +195 -0
  26. package/dist/lib/darwin-local.js.map +1 -0
  27. package/dist/lib/local-sessions.d.ts +66 -0
  28. package/dist/lib/local-sessions.js +357 -0
  29. package/dist/lib/local-sessions.js.map +1 -0
  30. package/dist/lib/operator-harness.d.ts +13 -0
  31. package/dist/lib/operator-harness.js +185 -0
  32. package/dist/lib/operator-harness.js.map +1 -0
  33. package/dist/lib/operator.d.ts +2 -0
  34. package/dist/lib/operator.js +13 -0
  35. package/dist/lib/operator.js.map +1 -0
  36. package/dist/lib/pi-tools.d.ts +19 -0
  37. package/dist/lib/pi-tools.js +73 -0
  38. package/dist/lib/pi-tools.js.map +1 -0
  39. package/dist/theme.d.ts +21 -0
  40. package/dist/theme.js +64 -0
  41. package/dist/theme.js.map +1 -0
  42. package/dist/ui/components/answer-box.d.ts +6 -0
  43. package/dist/ui/components/answer-box.js +17 -0
  44. package/dist/ui/components/answer-box.js.map +1 -0
  45. package/dist/ui/components/chat-log.d.ts +18 -0
  46. package/dist/ui/components/chat-log.js +72 -0
  47. package/dist/ui/components/chat-log.js.map +1 -0
  48. package/dist/ui/components/custom-editor.d.ts +6 -0
  49. package/dist/ui/components/custom-editor.js +17 -0
  50. package/dist/ui/components/custom-editor.js.map +1 -0
  51. package/dist/ui/components/footer.d.ts +6 -0
  52. package/dist/ui/components/footer.js +15 -0
  53. package/dist/ui/components/footer.js.map +1 -0
  54. package/dist/ui/components/intro.d.ts +11 -0
  55. package/dist/ui/components/intro.js +62 -0
  56. package/dist/ui/components/intro.js.map +1 -0
  57. package/dist/ui/components/note-box.d.ts +6 -0
  58. package/dist/ui/components/note-box.js +17 -0
  59. package/dist/ui/components/note-box.js.map +1 -0
  60. package/dist/ui/components/tool-event.d.ts +9 -0
  61. package/dist/ui/components/tool-event.js +58 -0
  62. package/dist/ui/components/tool-event.js.map +1 -0
  63. package/dist/ui/components/user-query.d.ts +6 -0
  64. package/dist/ui/components/user-query.js +16 -0
  65. package/dist/ui/components/user-query.js.map +1 -0
  66. package/dist/ui/components/working-indicator.d.ts +12 -0
  67. package/dist/ui/components/working-indicator.js +30 -0
  68. package/dist/ui/components/working-indicator.js.map +1 -0
  69. package/dist/utils/markdown-table.d.ts +8 -0
  70. package/dist/utils/markdown-table.js +123 -0
  71. package/dist/utils/markdown-table.js.map +1 -0
  72. package/package.json +41 -0
@@ -0,0 +1,357 @@
1
+ import * as fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ function darwinDir(workspaceRoot) {
4
+ return path.join(workspaceRoot, ".darwin");
5
+ }
6
+ function legacySessionDir(workspaceRoot) {
7
+ return path.join(darwinDir(workspaceRoot), "sessions");
8
+ }
9
+ function projectConfigFile(workspaceRoot) {
10
+ return path.join(darwinDir(workspaceRoot), "config.json");
11
+ }
12
+ function sessionsFile(workspaceRoot) {
13
+ return path.join(darwinDir(workspaceRoot), "sessions.jsonl");
14
+ }
15
+ function deriveTitle(messages) {
16
+ const firstUserMessage = messages.find((message) => message.role === "user")?.text.trim();
17
+ return deriveShortTitle(firstUserMessage);
18
+ }
19
+ function deriveShortTitle(text) {
20
+ if (!text || text.trim() === "") {
21
+ return "New session";
22
+ }
23
+ const singleLine = text.replace(/\s+/g, " ").trim();
24
+ return singleLine.length <= 72 ? singleLine : `${singleLine.slice(0, 69)}...`;
25
+ }
26
+ function isSessionMessageRole(value) {
27
+ return value === "user" || value === "assistant";
28
+ }
29
+ function isMessageHistoryItem(value) {
30
+ return value.type === "user_message" || value.type === "assistant_message";
31
+ }
32
+ function historyItemToMessage(item) {
33
+ return {
34
+ role: item.type === "user_message" ? "user" : "assistant",
35
+ text: item.text,
36
+ createdAt: item.createdAt,
37
+ };
38
+ }
39
+ function messageToHistoryItem(message) {
40
+ return {
41
+ type: message.role === "user" ? "user_message" : "assistant_message",
42
+ text: message.text,
43
+ createdAt: message.createdAt,
44
+ };
45
+ }
46
+ function historyToMessages(history) {
47
+ return history.filter(isMessageHistoryItem).map(historyItemToMessage);
48
+ }
49
+ function normalizeMessages(messages) {
50
+ if (!Array.isArray(messages)) {
51
+ return [];
52
+ }
53
+ return messages.flatMap((message) => {
54
+ if (typeof message !== "object" ||
55
+ message === null ||
56
+ !isSessionMessageRole(message.role) ||
57
+ typeof message.text !== "string" ||
58
+ typeof message.createdAt !== "string") {
59
+ return [];
60
+ }
61
+ return [
62
+ {
63
+ role: message.role,
64
+ text: message.text,
65
+ createdAt: message.createdAt,
66
+ },
67
+ ];
68
+ });
69
+ }
70
+ function normalizeHistory(history) {
71
+ if (!Array.isArray(history)) {
72
+ return [];
73
+ }
74
+ return history.flatMap((item) => {
75
+ if (typeof item !== "object" || item === null || typeof item.type !== "string") {
76
+ return [];
77
+ }
78
+ const type = item.type;
79
+ const createdAt = item.createdAt;
80
+ if (typeof createdAt !== "string") {
81
+ return [];
82
+ }
83
+ switch (type) {
84
+ case "user_message":
85
+ case "assistant_message": {
86
+ const text = item.text;
87
+ if (typeof text !== "string") {
88
+ return [];
89
+ }
90
+ return [{ type, text, createdAt }];
91
+ }
92
+ case "local_tool_call": {
93
+ const tool = item.tool;
94
+ const args = item.args;
95
+ if (typeof tool !== "string" || typeof args !== "object" || args === null || Array.isArray(args)) {
96
+ return [];
97
+ }
98
+ return [
99
+ {
100
+ type: "local_tool_call",
101
+ tool: tool,
102
+ args: args,
103
+ createdAt,
104
+ },
105
+ ];
106
+ }
107
+ case "local_tool_result": {
108
+ const tool = item.tool;
109
+ const args = item.args;
110
+ const summary = item.summary;
111
+ const output = item.output;
112
+ const isError = item.isError;
113
+ if (typeof tool !== "string" ||
114
+ typeof args !== "object" ||
115
+ args === null ||
116
+ Array.isArray(args) ||
117
+ typeof summary !== "string" ||
118
+ typeof output !== "string" ||
119
+ typeof isError !== "boolean") {
120
+ return [];
121
+ }
122
+ return [
123
+ {
124
+ type: "local_tool_result",
125
+ tool: tool,
126
+ args: args,
127
+ summary,
128
+ output,
129
+ details: item.details,
130
+ isError,
131
+ createdAt,
132
+ },
133
+ ];
134
+ }
135
+ default:
136
+ return [];
137
+ }
138
+ });
139
+ }
140
+ function normalizeSession(session) {
141
+ const normalizedMessages = normalizeMessages(session.messages);
142
+ const normalizedHistory = normalizeHistory(session.history);
143
+ const history = normalizedHistory.length > 0 || normalizedMessages.length === 0
144
+ ? normalizedHistory
145
+ : normalizedMessages.map(messageToHistoryItem);
146
+ const messages = history.length > 0 ? historyToMessages(history) : normalizedMessages;
147
+ return {
148
+ ...session,
149
+ title: session.title?.trim() ? session.title : deriveTitle(messages),
150
+ messages,
151
+ history,
152
+ };
153
+ }
154
+ async function pathExists(target) {
155
+ try {
156
+ await fs.access(target);
157
+ return true;
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
163
+ async function ensureJsonlFile(target) {
164
+ if (await pathExists(target)) {
165
+ return;
166
+ }
167
+ await fs.writeFile(target, "", "utf8");
168
+ }
169
+ async function ensureProjectConfigFile(workspaceRoot) {
170
+ const target = projectConfigFile(workspaceRoot);
171
+ if (await pathExists(target)) {
172
+ return;
173
+ }
174
+ const config = {
175
+ createdAt: new Date().toISOString(),
176
+ };
177
+ await fs.writeFile(target, JSON.stringify(config, null, 2) + "\n", "utf8");
178
+ }
179
+ async function readJsonlRecords(target) {
180
+ try {
181
+ const raw = await fs.readFile(target, "utf8");
182
+ return raw
183
+ .split("\n")
184
+ .map((line) => line.trim())
185
+ .filter(Boolean)
186
+ .flatMap((line) => {
187
+ try {
188
+ return [JSON.parse(line)];
189
+ }
190
+ catch {
191
+ return [];
192
+ }
193
+ });
194
+ }
195
+ catch {
196
+ return [];
197
+ }
198
+ }
199
+ async function appendJsonlRecord(target, value) {
200
+ await fs.appendFile(target, `${JSON.stringify(value)}\n`, "utf8");
201
+ }
202
+ function pickLatestById(records) {
203
+ const latest = new Map();
204
+ for (const record of records) {
205
+ const existing = latest.get(record.id);
206
+ if (!existing || record.updatedAt.localeCompare(existing.updatedAt) >= 0) {
207
+ latest.set(record.id, record);
208
+ }
209
+ }
210
+ return latest;
211
+ }
212
+ async function readLegacySessions(workspaceRoot) {
213
+ const dir = legacySessionDir(workspaceRoot);
214
+ try {
215
+ const entries = await fs.readdir(dir, { withFileTypes: true });
216
+ const sessions = [];
217
+ for (const entry of entries) {
218
+ if (!entry.isFile() || !entry.name.endsWith(".json")) {
219
+ continue;
220
+ }
221
+ try {
222
+ const raw = await fs.readFile(path.join(dir, entry.name), "utf8");
223
+ sessions.push(normalizeSession(JSON.parse(raw)));
224
+ }
225
+ catch {
226
+ continue;
227
+ }
228
+ }
229
+ return sessions;
230
+ }
231
+ catch {
232
+ return [];
233
+ }
234
+ }
235
+ async function readSessionMap(workspaceRoot) {
236
+ const jsonlSessions = (await readJsonlRecords(sessionsFile(workspaceRoot))).map(normalizeSession);
237
+ const legacySessions = await readLegacySessions(workspaceRoot);
238
+ return pickLatestById([...legacySessions, ...jsonlSessions]);
239
+ }
240
+ export async function ensureDarwinWorkspace(workspaceRoot) {
241
+ const root = darwinDir(workspaceRoot);
242
+ const createdWorkspace = !(await pathExists(root));
243
+ await fs.mkdir(root, { recursive: true });
244
+ await ensureProjectConfigFile(workspaceRoot);
245
+ const hasSessionsJsonl = await pathExists(sessionsFile(workspaceRoot));
246
+ let importedLegacySessions = 0;
247
+ if (!hasSessionsJsonl) {
248
+ await ensureJsonlFile(sessionsFile(workspaceRoot));
249
+ const legacySessions = Array.from(pickLatestById(await readLegacySessions(workspaceRoot)).values()).sort((a, b) => a.updatedAt.localeCompare(b.updatedAt));
250
+ for (const session of legacySessions) {
251
+ await appendJsonlRecord(sessionsFile(workspaceRoot), session);
252
+ }
253
+ importedLegacySessions = legacySessions.length;
254
+ }
255
+ return {
256
+ createdWorkspace,
257
+ importedLegacySessions,
258
+ };
259
+ }
260
+ export async function hasDarwinWorkspace(workspaceRoot) {
261
+ return pathExists(darwinDir(workspaceRoot));
262
+ }
263
+ async function persistSession(workspaceRoot, session) {
264
+ await ensureDarwinWorkspace(workspaceRoot);
265
+ await appendJsonlRecord(sessionsFile(workspaceRoot), normalizeSession(session));
266
+ }
267
+ export async function createLocalSession(workspaceRoot) {
268
+ await ensureDarwinWorkspace(workspaceRoot);
269
+ const now = new Date().toISOString();
270
+ const session = {
271
+ id: crypto.randomUUID(),
272
+ operatorChatId: crypto.randomUUID(),
273
+ workspaceRoot,
274
+ title: "New session",
275
+ createdAt: now,
276
+ updatedAt: now,
277
+ messages: [],
278
+ history: [],
279
+ };
280
+ await persistSession(workspaceRoot, session);
281
+ return normalizeSession(session);
282
+ }
283
+ export async function saveLocalSession(workspaceRoot, session) {
284
+ const normalizedSession = normalizeSession(session);
285
+ const nextSession = normalizeSession({
286
+ ...normalizedSession,
287
+ title: deriveTitle(normalizedSession.messages),
288
+ updatedAt: new Date().toISOString(),
289
+ });
290
+ await persistSession(workspaceRoot, nextSession);
291
+ return nextSession;
292
+ }
293
+ async function appendLocalSessionHistoryItem(workspaceRoot, session, item) {
294
+ const normalizedSession = normalizeSession(session);
295
+ return saveLocalSession(workspaceRoot, {
296
+ ...normalizedSession,
297
+ history: [...normalizedSession.history, item],
298
+ });
299
+ }
300
+ export async function appendLocalSessionMessage(workspaceRoot, session, role, text) {
301
+ const createdAt = new Date().toISOString();
302
+ return appendLocalSessionHistoryItem(workspaceRoot, session, {
303
+ type: role === "user" ? "user_message" : "assistant_message",
304
+ text,
305
+ createdAt,
306
+ });
307
+ }
308
+ export async function appendLocalSessionToolCall(workspaceRoot, session, call) {
309
+ return appendLocalSessionHistoryItem(workspaceRoot, session, {
310
+ type: "local_tool_call",
311
+ tool: call.tool,
312
+ args: call.args,
313
+ createdAt: new Date().toISOString(),
314
+ });
315
+ }
316
+ export async function appendLocalSessionToolResult(workspaceRoot, session, result) {
317
+ return appendLocalSessionHistoryItem(workspaceRoot, session, {
318
+ type: "local_tool_result",
319
+ tool: result.tool,
320
+ args: result.args,
321
+ summary: result.summary,
322
+ output: result.output,
323
+ details: result.details,
324
+ isError: result.isError,
325
+ createdAt: new Date().toISOString(),
326
+ });
327
+ }
328
+ export async function listLocalSessions(workspaceRoot) {
329
+ const sessions = Array.from((await readSessionMap(workspaceRoot)).values());
330
+ return sessions
331
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))
332
+ .map((session) => ({
333
+ id: session.id,
334
+ title: session.title,
335
+ updatedAt: session.updatedAt,
336
+ messageCount: session.messages.length,
337
+ }));
338
+ }
339
+ export async function loadLocalSession(workspaceRoot, sessionIdOrPrefix) {
340
+ const sessions = Array.from((await readSessionMap(workspaceRoot)).values());
341
+ const matches = sessions.filter((session) => session.id.startsWith(sessionIdOrPrefix));
342
+ if (matches.length === 0) {
343
+ throw new Error(`No local Darwin session matches: ${sessionIdOrPrefix}`);
344
+ }
345
+ if (matches.length > 1) {
346
+ throw new Error(`Session prefix is ambiguous: ${sessionIdOrPrefix}`);
347
+ }
348
+ return normalizeSession(matches[0]);
349
+ }
350
+ export async function loadMostRecentLocalSession(workspaceRoot) {
351
+ const sessions = await listLocalSessions(workspaceRoot);
352
+ if (sessions.length === 0) {
353
+ return null;
354
+ }
355
+ return loadLocalSession(workspaceRoot, sessions[0].id);
356
+ }
357
+ //# sourceMappingURL=local-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sessions.js","sourceRoot":"","sources":["../../src/lib/local-sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DarwinSession } from "./local-sessions.js";
2
+ import { type DarwinLocalToolCall } from "./pi-tools.js";
3
+ export declare const DARWIN_HARNESS_START = "<darwin_harness>";
4
+ export declare const DARWIN_HARNESS_END = "</darwin_harness>";
5
+ export declare const DARWIN_TOOL_CALL_START = "<darwin_local_tool_call>";
6
+ export declare const DARWIN_TOOL_CALL_END = "</darwin_local_tool_call>";
7
+ export declare function getWorkspaceSnapshot(root: string): Promise<string>;
8
+ export declare function buildHarnessPrompt(params: {
9
+ workspaceRoot: string;
10
+ session: DarwinSession;
11
+ }): Promise<string>;
12
+ export declare function isToolCallPrefix(text: string): boolean;
13
+ export declare function parseToolCall(text: string): DarwinLocalToolCall | null;
@@ -0,0 +1,185 @@
1
+ import * as fs from "node:fs/promises";
2
+ import { darwinLocalToolNames } from "./pi-tools.js";
3
+ export const DARWIN_HARNESS_START = "<darwin_harness>";
4
+ export const DARWIN_HARNESS_END = "</darwin_harness>";
5
+ export const DARWIN_TOOL_CALL_START = "<darwin_local_tool_call>";
6
+ export const DARWIN_TOOL_CALL_END = "</darwin_local_tool_call>";
7
+ const MAX_HISTORY_ITEMS = 24;
8
+ const MAX_HISTORY_CHARS = 14_000;
9
+ function truncate(text, max = 16_000) {
10
+ if (text.length <= max) {
11
+ return text;
12
+ }
13
+ return `${text.slice(0, max)}\n\n[truncated]`;
14
+ }
15
+ function stableStringify(value) {
16
+ return JSON.stringify(value, null, 2);
17
+ }
18
+ function indentBlock(text, prefix = " ") {
19
+ return text
20
+ .split("\n")
21
+ .map((line) => `${prefix}${line}`)
22
+ .join("\n");
23
+ }
24
+ function toSingleLine(text) {
25
+ return text.replace(/\s+/g, " ").trim();
26
+ }
27
+ function formatHistoryItem(item, index) {
28
+ const header = `${index + 1}. ${item.type} @ ${item.createdAt}`;
29
+ switch (item.type) {
30
+ case "user_message":
31
+ case "assistant_message":
32
+ return [header, indentBlock(truncate(item.text.trim(), 2_000))].join("\n");
33
+ case "local_tool_call":
34
+ return [
35
+ header,
36
+ indentBlock(stableStringify({
37
+ tool: item.tool,
38
+ args: item.args,
39
+ })),
40
+ ].join("\n");
41
+ case "local_tool_result":
42
+ return [
43
+ header,
44
+ indentBlock(stableStringify({
45
+ tool: item.tool,
46
+ args: item.args,
47
+ summary: item.summary,
48
+ isError: item.isError,
49
+ output: truncate(item.output, 6_000),
50
+ details: item.details,
51
+ })),
52
+ ].join("\n");
53
+ }
54
+ }
55
+ function formatStructuredHistory(session) {
56
+ if (session.history.length === 0) {
57
+ return "No prior Darwin session activity.";
58
+ }
59
+ const recentItems = session.history.slice(-MAX_HISTORY_ITEMS);
60
+ const omittedCount = session.history.length - recentItems.length;
61
+ const content = [
62
+ omittedCount > 0 ? `[${omittedCount} earlier history item(s) omitted]` : "",
63
+ ...recentItems.map((item, index) => formatHistoryItem(item, index)),
64
+ ]
65
+ .filter(Boolean)
66
+ .join("\n\n");
67
+ return truncate(content, MAX_HISTORY_CHARS);
68
+ }
69
+ function getCurrentObjective(session) {
70
+ const latestUserMessage = [...session.history]
71
+ .reverse()
72
+ .find((item) => item.type === "user_message");
73
+ if (!latestUserMessage) {
74
+ return "No active user request is recorded yet.";
75
+ }
76
+ return truncate(toSingleLine(latestUserMessage.text), 2_000);
77
+ }
78
+ export async function getWorkspaceSnapshot(root) {
79
+ try {
80
+ const entries = await fs.readdir(root, { withFileTypes: true });
81
+ const visibleEntries = entries
82
+ .filter((entry) => !entry.name.startsWith("."))
83
+ .sort((a, b) => a.name.localeCompare(b.name))
84
+ .slice(0, 24)
85
+ .map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name));
86
+ return visibleEntries.length > 0 ? visibleEntries.join(", ") : "(empty)";
87
+ }
88
+ catch {
89
+ return "(unavailable)";
90
+ }
91
+ }
92
+ async function readAgentsInstructions(root) {
93
+ try {
94
+ const content = await fs.readFile(`${root}/AGENTS.md`, "utf8");
95
+ const trimmed = content.trim();
96
+ return trimmed ? truncate(trimmed, 12_000) : null;
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ }
102
+ export async function buildHarnessPrompt(params) {
103
+ const snapshot = await getWorkspaceSnapshot(params.workspaceRoot);
104
+ const agentsInstructions = await readAgentsInstructions(params.workspaceRoot);
105
+ const sessionHistory = formatStructuredHistory(params.session);
106
+ const currentObjective = getCurrentObjective(params.session);
107
+ return [
108
+ DARWIN_HARNESS_START,
109
+ "You are Darwin's local coding harness running through Operator chat.",
110
+ "Operator chat is the user-visible source of truth for this session.",
111
+ "This Darwin session maps 1:1 to the current Operator chat thread.",
112
+ "Use the structured Darwin session state below to maintain continuity across user turns and tool steps.",
113
+ "Darwin's purpose is to build and improve a Darwin Godel-machine system that automates OpenClaw deployment, experiment design, evaluation, and iteration.",
114
+ "Operate as Darwin's local coding executor for this workspace.",
115
+ "You can inspect files, edit code, run commands, and verify results end-to-end with local Pi tools when the task is local.",
116
+ "Operator-hosted resources are reachable through Operator's hosted tools when the task is remote, and likely the chat tool will be the most frequent tool to use.",
117
+ "Be precise about the boundary: local Pi tools can access the local workspace, while hosted instance access happens through Operator rather than the local filesystem.",
118
+ `Workspace root: ${params.workspaceRoot}`,
119
+ `Top-level entries: ${snapshot}`,
120
+ "Scratch pad directory: .darwin/",
121
+ "",
122
+ "Default behavior:",
123
+ "1. Inspect first. Inspect the workspace and any relevant hosted context before proposing important mutations.",
124
+ "2. Treat implementation, optimization, evaluation, and iteration as one workflow.",
125
+ "3. When experimentation is relevant, identify the optimization target, baseline, mutation surface, and evaluation path.",
126
+ "4. Make reasonable assumptions and move unless a missing detail would make the task unsafe, invalid, or impossible to evaluate.",
127
+ "5. Prefer the narrowest high-leverage mutation first.",
128
+ "",
129
+ "Rules:",
130
+ "- Do not ask the user for permission to inspect or modify local files. Use the tools.",
131
+ "- Do not use hosted Operator tools for local workspace tasks.",
132
+ "- Operator-hosted context is accessed through Operator, not through the local filesystem.",
133
+ "- You should view the Operator chat and tools as a kind of agent cloud laboratory.",
134
+ "",
135
+ "Available local Pi tools and exact argument names:",
136
+ '- `read` with `{"path":"src/app.ts","offset":0,"limit":200}`',
137
+ '- `write` with `{"path":"notes.txt","content":"..."}`',
138
+ '- `edit` with `{"path":"src/app.ts","oldText":"before","newText":"after"}`',
139
+ '- `bash` with `{"command":"npm test","timeout":120000}`',
140
+ '- `ls` with `{"path":".","limit":200}`',
141
+ '- `grep` with `{"pattern":"foo","path":"src","glob":"*.ts","ignoreCase":true,"literal":false,"context":2,"limit":200}`',
142
+ '- `find` with `{"pattern":"*.ts","path":"src","limit":200}`',
143
+ "",
144
+ "Tool protocol:",
145
+ "If you need a local tool, respond with exactly one block and nothing else:",
146
+ `${DARWIN_TOOL_CALL_START}{"tool":"read","args":{"path":"AGENTS.md"}}${DARWIN_TOOL_CALL_END}`,
147
+ "No markdown fences. No prose before or after the block.",
148
+ "After Darwin sends you a tool result, either request another local tool with the same format or answer the user directly in normal prose.",
149
+ "",
150
+ `Current Darwin objective: ${currentObjective}`,
151
+ "",
152
+ "Structured Darwin session state:",
153
+ sessionHistory,
154
+ "",
155
+ agentsInstructions ? "Project instructions:\n" + agentsInstructions : "No AGENTS.md instructions were loaded.",
156
+ DARWIN_HARNESS_END,
157
+ ].join("\n");
158
+ }
159
+ export function isToolCallPrefix(text) {
160
+ const trimmed = text.trimStart();
161
+ if (!trimmed) {
162
+ return false;
163
+ }
164
+ return DARWIN_TOOL_CALL_START.startsWith(trimmed) || trimmed.startsWith(DARWIN_TOOL_CALL_START);
165
+ }
166
+ export function parseToolCall(text) {
167
+ const match = text.match(new RegExp(`${DARWIN_TOOL_CALL_START}\\s*([\\s\\S]*?)\\s*${DARWIN_TOOL_CALL_END}`, "i"));
168
+ if (!match) {
169
+ return null;
170
+ }
171
+ const parsed = JSON.parse(match[1]);
172
+ const tool = parsed["tool"];
173
+ const args = parsed["args"];
174
+ if (typeof tool !== "string" || !darwinLocalToolNames.includes(tool)) {
175
+ throw new Error(`Invalid Darwin tool: ${String(tool)}`);
176
+ }
177
+ if (typeof args !== "object" || args === null || Array.isArray(args)) {
178
+ throw new Error("Darwin tool args must be an object.");
179
+ }
180
+ return {
181
+ tool: tool,
182
+ args: args,
183
+ };
184
+ }
185
+ //# sourceMappingURL=operator-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operator-harness.js","sourceRoot":"","sources":["../../src/lib/operator-harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Operator } from "@operator-labs/sdk";
2
+ export declare function createOperatorClient(): Operator;
@@ -0,0 +1,13 @@
1
+ import { Operator } from "@operator-labs/sdk";
2
+ import { getStoredApiKey, getStoredBaseUrl } from "./config.js";
3
+ export function createOperatorClient() {
4
+ const apiKey = getStoredApiKey();
5
+ if (!apiKey) {
6
+ throw new Error("No API key configured. Run `/login` first.");
7
+ }
8
+ return new Operator({
9
+ apiKey,
10
+ baseUrl: getStoredBaseUrl(),
11
+ });
12
+ }
13
+ //# sourceMappingURL=operator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operator.js","sourceRoot":"","sources":["../../src/lib/operator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,QAAQ,CAAC;QAClB,MAAM;QACN,OAAO,EAAE,gBAAgB,EAAE;KAC5B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare const darwinLocalToolNames: readonly ["read", "bash", "edit", "write", "grep", "find", "ls"];
2
+ export type DarwinLocalToolName = (typeof darwinLocalToolNames)[number];
3
+ export interface DarwinLocalToolCall {
4
+ tool: DarwinLocalToolName;
5
+ args: Record<string, unknown>;
6
+ }
7
+ export interface DarwinLocalToolResult {
8
+ tool: DarwinLocalToolName;
9
+ args: Record<string, unknown>;
10
+ summary: string;
11
+ output: string;
12
+ details: unknown;
13
+ isError: boolean;
14
+ }
15
+ export declare class PiToolHarness {
16
+ private readonly tools;
17
+ constructor(cwd: string);
18
+ execute(call: DarwinLocalToolCall): Promise<DarwinLocalToolResult>;
19
+ }