@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.
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/app.d.ts +5 -0
- package/dist/app.js +469 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +134 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth.d.ts +15 -0
- package/dist/lib/auth.js +71 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/autocomplete.d.ts +18 -0
- package/dist/lib/autocomplete.js +124 -0
- package/dist/lib/autocomplete.js.map +1 -0
- package/dist/lib/command-surface.d.ts +52 -0
- package/dist/lib/command-surface.js +198 -0
- package/dist/lib/command-surface.js.map +1 -0
- package/dist/lib/config.d.ts +25 -0
- package/dist/lib/config.js +99 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/darwin-local.d.ts +31 -0
- package/dist/lib/darwin-local.js +195 -0
- package/dist/lib/darwin-local.js.map +1 -0
- package/dist/lib/local-sessions.d.ts +66 -0
- package/dist/lib/local-sessions.js +357 -0
- package/dist/lib/local-sessions.js.map +1 -0
- package/dist/lib/operator-harness.d.ts +13 -0
- package/dist/lib/operator-harness.js +185 -0
- package/dist/lib/operator-harness.js.map +1 -0
- package/dist/lib/operator.d.ts +2 -0
- package/dist/lib/operator.js +13 -0
- package/dist/lib/operator.js.map +1 -0
- package/dist/lib/pi-tools.d.ts +19 -0
- package/dist/lib/pi-tools.js +73 -0
- package/dist/lib/pi-tools.js.map +1 -0
- package/dist/theme.d.ts +21 -0
- package/dist/theme.js +64 -0
- package/dist/theme.js.map +1 -0
- package/dist/ui/components/answer-box.d.ts +6 -0
- package/dist/ui/components/answer-box.js +17 -0
- package/dist/ui/components/answer-box.js.map +1 -0
- package/dist/ui/components/chat-log.d.ts +18 -0
- package/dist/ui/components/chat-log.js +72 -0
- package/dist/ui/components/chat-log.js.map +1 -0
- package/dist/ui/components/custom-editor.d.ts +6 -0
- package/dist/ui/components/custom-editor.js +17 -0
- package/dist/ui/components/custom-editor.js.map +1 -0
- package/dist/ui/components/footer.d.ts +6 -0
- package/dist/ui/components/footer.js +15 -0
- package/dist/ui/components/footer.js.map +1 -0
- package/dist/ui/components/intro.d.ts +11 -0
- package/dist/ui/components/intro.js +62 -0
- package/dist/ui/components/intro.js.map +1 -0
- package/dist/ui/components/note-box.d.ts +6 -0
- package/dist/ui/components/note-box.js +17 -0
- package/dist/ui/components/note-box.js.map +1 -0
- package/dist/ui/components/tool-event.d.ts +9 -0
- package/dist/ui/components/tool-event.js +58 -0
- package/dist/ui/components/tool-event.js.map +1 -0
- package/dist/ui/components/user-query.d.ts +6 -0
- package/dist/ui/components/user-query.js +16 -0
- package/dist/ui/components/user-query.js.map +1 -0
- package/dist/ui/components/working-indicator.d.ts +12 -0
- package/dist/ui/components/working-indicator.js +30 -0
- package/dist/ui/components/working-indicator.js.map +1 -0
- package/dist/utils/markdown-table.d.ts +8 -0
- package/dist/utils/markdown-table.js +123 -0
- package/dist/utils/markdown-table.js.map +1 -0
- package/package.json +41 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as readline from "node:readline/promises";
|
|
2
|
+
import { runAppWithOptions } from "./app.js";
|
|
3
|
+
import { getAuthStatus, loginViaBrowser, logout, maskApiKey, setApiKey } from "./lib/auth.js";
|
|
4
|
+
import { getCliHelpText, parseCliCommand, } from "./lib/command-surface.js";
|
|
5
|
+
import { getDarwinProjectInitPreference, getStoredApiKey, getStoredBaseUrl, initDirs, setDarwinProjectInitPreference, } from "./lib/config.js";
|
|
6
|
+
import { ensureDarwinWorkspace, hasDarwinWorkspace, listLocalSessions } from "./lib/local-sessions.js";
|
|
7
|
+
import { createOperatorClient } from "./lib/operator.js";
|
|
8
|
+
function formatSessionsOutput(sessions) {
|
|
9
|
+
if (sessions.length === 0) {
|
|
10
|
+
return "No local Darwin sessions found.";
|
|
11
|
+
}
|
|
12
|
+
return sessions
|
|
13
|
+
.slice(0, 20)
|
|
14
|
+
.map((session) => `${session.id.slice(0, 8)}\t${session.updatedAt}\t${session.messageCount}\t${session.title || "Untitled"}`)
|
|
15
|
+
.join("\n");
|
|
16
|
+
}
|
|
17
|
+
function formatInstancesOutput(instances, mode) {
|
|
18
|
+
const visible = mode === "all" ? instances : instances.filter((instance) => instance.status === "active");
|
|
19
|
+
if (visible.length === 0) {
|
|
20
|
+
return mode === "all" ? "No instances found." : "No active instances found.";
|
|
21
|
+
}
|
|
22
|
+
return visible
|
|
23
|
+
.map((instance) => {
|
|
24
|
+
const imagePart = instance.imageTag ? `\t${instance.imageTag}` : "";
|
|
25
|
+
return `${instance.id}\t${instance.name}\t${instance.status}${imagePart}`;
|
|
26
|
+
})
|
|
27
|
+
.join("\n");
|
|
28
|
+
}
|
|
29
|
+
async function printStatus() {
|
|
30
|
+
const status = await getAuthStatus();
|
|
31
|
+
console.log([
|
|
32
|
+
`authenticated: ${status.authenticated}`,
|
|
33
|
+
`baseUrl: ${getStoredBaseUrl()}`,
|
|
34
|
+
`apiKey: ${maskApiKey(getStoredApiKey()) || "none"}`,
|
|
35
|
+
`email: ${status.email ?? "n/a"}`,
|
|
36
|
+
`plan: ${status.planName ?? status.planSlug ?? "n/a"}`,
|
|
37
|
+
`tokenLimit: ${status.tokenLimit ?? "n/a"}`,
|
|
38
|
+
status.error ? `error: ${status.error}` : "",
|
|
39
|
+
]
|
|
40
|
+
.filter(Boolean)
|
|
41
|
+
.join("\n"));
|
|
42
|
+
}
|
|
43
|
+
async function promptToCreateWorkspace(workspaceRoot) {
|
|
44
|
+
const preference = getDarwinProjectInitPreference();
|
|
45
|
+
if (preference === "always") {
|
|
46
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
50
|
+
console.log("No Darwin workspace found in this project.");
|
|
51
|
+
console.log("Run Darwin interactively to create `./.darwin/`, or set `~/.darwin/config.json` to auto-create it.");
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const rl = readline.createInterface({
|
|
55
|
+
input: process.stdin,
|
|
56
|
+
output: process.stdout,
|
|
57
|
+
});
|
|
58
|
+
try {
|
|
59
|
+
const answer = (await rl.question("Create a `.darwin/` workspace in this project? [y]es/[n]o/[a]lways: "))
|
|
60
|
+
.trim()
|
|
61
|
+
.toLowerCase();
|
|
62
|
+
if (answer === "a" || answer === "always") {
|
|
63
|
+
setDarwinProjectInitPreference("always");
|
|
64
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (answer === "" || answer === "y" || answer === "yes") {
|
|
68
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
console.log("Skipped Darwin workspace creation.");
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
rl.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export async function runCli(argv = process.argv.slice(2)) {
|
|
79
|
+
initDirs();
|
|
80
|
+
const action = parseCliCommand(argv);
|
|
81
|
+
const workspaceRoot = process.cwd();
|
|
82
|
+
switch (action.type) {
|
|
83
|
+
case "help":
|
|
84
|
+
console.log(getCliHelpText());
|
|
85
|
+
return;
|
|
86
|
+
case "tui":
|
|
87
|
+
if (action.openSessionId) {
|
|
88
|
+
if (!(await hasDarwinWorkspace(workspaceRoot))) {
|
|
89
|
+
console.log("No Darwin workspace found in this project.");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
93
|
+
}
|
|
94
|
+
else if (!(await hasDarwinWorkspace(workspaceRoot))) {
|
|
95
|
+
const created = await promptToCreateWorkspace(workspaceRoot);
|
|
96
|
+
if (!created) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
102
|
+
}
|
|
103
|
+
await runAppWithOptions({ openSessionId: action.openSessionId });
|
|
104
|
+
return;
|
|
105
|
+
case "chats":
|
|
106
|
+
if (!(await hasDarwinWorkspace(workspaceRoot))) {
|
|
107
|
+
console.log("No Darwin workspace found in this project.");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
await ensureDarwinWorkspace(workspaceRoot);
|
|
111
|
+
console.log(formatSessionsOutput(await listLocalSessions(workspaceRoot)));
|
|
112
|
+
return;
|
|
113
|
+
case "status":
|
|
114
|
+
await printStatus();
|
|
115
|
+
return;
|
|
116
|
+
case "login":
|
|
117
|
+
if (action.apiKey) {
|
|
118
|
+
setApiKey(action.apiKey);
|
|
119
|
+
console.log("Stored API key.");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
console.log("Opening browser login...");
|
|
123
|
+
console.log((await loginViaBrowser()) ? "Login complete." : "Login timed out.");
|
|
124
|
+
return;
|
|
125
|
+
case "logout":
|
|
126
|
+
logout();
|
|
127
|
+
console.log("Logged out.");
|
|
128
|
+
return;
|
|
129
|
+
case "instances":
|
|
130
|
+
console.log(formatInstancesOutput(await createOperatorClient().instances.list(), action.mode));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACvB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface AuthStatus {
|
|
2
|
+
authenticated: boolean;
|
|
3
|
+
userId?: string;
|
|
4
|
+
email?: string;
|
|
5
|
+
planSlug?: string | null;
|
|
6
|
+
planName?: string | null;
|
|
7
|
+
hasPlan?: boolean;
|
|
8
|
+
tokenLimit?: number;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function maskApiKey(apiKey: string | undefined): string;
|
|
12
|
+
export declare function getAuthStatus(): Promise<AuthStatus>;
|
|
13
|
+
export declare function setApiKey(apiKey: string, baseUrl?: string): void;
|
|
14
|
+
export declare function logout(): void;
|
|
15
|
+
export declare function loginViaBrowser(baseUrl?: string): Promise<boolean>;
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Operator } from "@operator-labs/sdk";
|
|
2
|
+
import open from "open";
|
|
3
|
+
import { deleteConfig, getBaseUrl, getStoredApiKey, getStoredBaseUrl, initDirs, setConfig, } from "./config.js";
|
|
4
|
+
export function maskApiKey(apiKey) {
|
|
5
|
+
if (!apiKey) {
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
if (apiKey.length > 12) {
|
|
9
|
+
return `${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`;
|
|
10
|
+
}
|
|
11
|
+
if (apiKey.length > 4) {
|
|
12
|
+
return `${apiKey.slice(0, 4)}...`;
|
|
13
|
+
}
|
|
14
|
+
return apiKey;
|
|
15
|
+
}
|
|
16
|
+
function sleep(ms) {
|
|
17
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
+
}
|
|
19
|
+
export async function getAuthStatus() {
|
|
20
|
+
const apiKey = getStoredApiKey();
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
return { authenticated: false, error: "No API key configured" };
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const client = new Operator({
|
|
26
|
+
apiKey,
|
|
27
|
+
baseUrl: getStoredBaseUrl(),
|
|
28
|
+
});
|
|
29
|
+
return await client.health();
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return {
|
|
33
|
+
authenticated: false,
|
|
34
|
+
error: error instanceof Error ? error.message : String(error),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function setApiKey(apiKey, baseUrl) {
|
|
39
|
+
initDirs();
|
|
40
|
+
setConfig("operatorApiKey", apiKey);
|
|
41
|
+
setConfig("operatorAppUrl", baseUrl || getBaseUrl());
|
|
42
|
+
}
|
|
43
|
+
export function logout() {
|
|
44
|
+
deleteConfig("operatorApiKey");
|
|
45
|
+
}
|
|
46
|
+
export async function loginViaBrowser(baseUrl) {
|
|
47
|
+
initDirs();
|
|
48
|
+
const resolvedBaseUrl = baseUrl || getBaseUrl();
|
|
49
|
+
const sessionId = crypto.randomUUID();
|
|
50
|
+
const authUrl = `${resolvedBaseUrl}/auth/cli?session=${sessionId}`;
|
|
51
|
+
await open(authUrl);
|
|
52
|
+
for (let attempt = 0; attempt < 60; attempt += 1) {
|
|
53
|
+
await sleep(2000);
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(`${resolvedBaseUrl}/api/cli/poll?session=${sessionId}`);
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const data = (await response.json());
|
|
60
|
+
if (data.operatorApiKey) {
|
|
61
|
+
setApiKey(data.operatorApiKey, resolvedBaseUrl);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Keep polling until timeout.
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,SAAS,GACV,MAAM,aAAa,CAAC;AAarB,MAAM,UAAU,UAAU,CAAC,MAA0B;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACvB,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IAClE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC;YAC1B,MAAM;YACN,OAAO,EAAE,gBAAgB,EAAE;SAC5B,CAAC,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,OAAgB;IACxD,QAAQ,EAAE,CAAC;IACX,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,CAAC,gBAAgB,EAAE,OAAO,IAAI,UAAU,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,YAAY,CAAC,gBAAgB,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB;IACpD,QAAQ,EAAE,CAAC;IAEX,MAAM,eAAe,GAAG,OAAO,IAAI,UAAU,EAAE,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,GAAG,eAAe,qBAAqB,SAAS,EAAE,CAAC;IAEnE,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAEpB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QAElB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,eAAe,yBAAyB,SAAS,EAAE,CACvD,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAgC,CAAC;YACpE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AutocompleteItem, type AutocompleteProvider, type SlashCommand } from "@mariozechner/pi-tui";
|
|
2
|
+
export declare class DarwinAutocompleteProvider implements AutocompleteProvider {
|
|
3
|
+
private readonly combined;
|
|
4
|
+
private readonly basePath;
|
|
5
|
+
private cachedFiles;
|
|
6
|
+
private cachedAtMs;
|
|
7
|
+
constructor(commands: SlashCommand[], basePath: string);
|
|
8
|
+
getSuggestions(lines: string[], cursorLine: number, cursorCol: number): {
|
|
9
|
+
items: AutocompleteItem[];
|
|
10
|
+
prefix: string;
|
|
11
|
+
} | null;
|
|
12
|
+
applyCompletion(lines: string[], cursorLine: number, cursorCol: number, item: AutocompleteItem, prefix: string): {
|
|
13
|
+
lines: string[];
|
|
14
|
+
cursorLine: number;
|
|
15
|
+
cursorCol: number;
|
|
16
|
+
};
|
|
17
|
+
private getWorkspaceFiles;
|
|
18
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { CombinedAutocompleteProvider, fuzzyFilter, } from "@mariozechner/pi-tui";
|
|
3
|
+
const TOKEN_DELIMITERS = new Set([" ", "\t", '"', "'", "="]);
|
|
4
|
+
const FILE_CACHE_TTL_MS = 2_000;
|
|
5
|
+
const MAX_FILE_SUGGESTIONS = 24;
|
|
6
|
+
function resolveFdPath() {
|
|
7
|
+
for (const candidate of ["fd", "fdfind"]) {
|
|
8
|
+
const result = spawnSync(candidate, ["--version"], {
|
|
9
|
+
encoding: "utf8",
|
|
10
|
+
stdio: "ignore",
|
|
11
|
+
});
|
|
12
|
+
if (result.status === 0) {
|
|
13
|
+
return candidate;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function extractAtPrefix(text) {
|
|
19
|
+
let tokenStart = text.length;
|
|
20
|
+
while (tokenStart > 0 && !TOKEN_DELIMITERS.has(text[tokenStart - 1] ?? "")) {
|
|
21
|
+
tokenStart -= 1;
|
|
22
|
+
}
|
|
23
|
+
const token = text.slice(tokenStart);
|
|
24
|
+
return token.startsWith("@") ? token : null;
|
|
25
|
+
}
|
|
26
|
+
function buildFileAutocompleteItem(filePath) {
|
|
27
|
+
return {
|
|
28
|
+
value: `@${filePath}`,
|
|
29
|
+
label: filePath,
|
|
30
|
+
description: "file",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export class DarwinAutocompleteProvider {
|
|
34
|
+
combined;
|
|
35
|
+
basePath;
|
|
36
|
+
cachedFiles = null;
|
|
37
|
+
cachedAtMs = 0;
|
|
38
|
+
constructor(commands, basePath) {
|
|
39
|
+
this.basePath = basePath;
|
|
40
|
+
this.combined = new CombinedAutocompleteProvider(commands, basePath, resolveFdPath());
|
|
41
|
+
}
|
|
42
|
+
getSuggestions(lines, cursorLine, cursorCol) {
|
|
43
|
+
const builtInSuggestions = this.combined.getSuggestions(lines, cursorLine, cursorCol);
|
|
44
|
+
if (builtInSuggestions) {
|
|
45
|
+
return builtInSuggestions;
|
|
46
|
+
}
|
|
47
|
+
const currentLine = lines[cursorLine] || "";
|
|
48
|
+
const textBeforeCursor = currentLine.slice(0, cursorCol);
|
|
49
|
+
const atPrefix = extractAtPrefix(textBeforeCursor);
|
|
50
|
+
if (!atPrefix) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const query = atPrefix.slice(1);
|
|
54
|
+
const files = this.getWorkspaceFiles();
|
|
55
|
+
if (files.length === 0) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const items = files.map(buildFileAutocompleteItem);
|
|
59
|
+
const filtered = query.trim() === ""
|
|
60
|
+
? items.slice(0, MAX_FILE_SUGGESTIONS)
|
|
61
|
+
: fuzzyFilter(items, query, (item) => item.label).slice(0, MAX_FILE_SUGGESTIONS);
|
|
62
|
+
if (filtered.length === 0) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
items: filtered,
|
|
67
|
+
prefix: atPrefix,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
|
|
71
|
+
if (prefix.startsWith("@")) {
|
|
72
|
+
const currentLine = lines[cursorLine] || "";
|
|
73
|
+
const before = currentLine.slice(0, cursorCol - prefix.length);
|
|
74
|
+
const after = currentLine.slice(cursorCol);
|
|
75
|
+
const nextLine = `${before}${item.value} ${after}`;
|
|
76
|
+
const nextLines = [...lines];
|
|
77
|
+
nextLines[cursorLine] = nextLine;
|
|
78
|
+
return {
|
|
79
|
+
lines: nextLines,
|
|
80
|
+
cursorLine,
|
|
81
|
+
cursorCol: before.length + item.value.length + 1,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return this.combined.applyCompletion(lines, cursorLine, cursorCol, item, prefix);
|
|
85
|
+
}
|
|
86
|
+
getWorkspaceFiles() {
|
|
87
|
+
const now = Date.now();
|
|
88
|
+
if (this.cachedFiles && now - this.cachedAtMs < FILE_CACHE_TTL_MS) {
|
|
89
|
+
return this.cachedFiles;
|
|
90
|
+
}
|
|
91
|
+
const result = spawnSync("rg", [
|
|
92
|
+
"--files",
|
|
93
|
+
"--hidden",
|
|
94
|
+
"-g",
|
|
95
|
+
"!.git",
|
|
96
|
+
"-g",
|
|
97
|
+
"!.git/**",
|
|
98
|
+
"-g",
|
|
99
|
+
"!node_modules",
|
|
100
|
+
"-g",
|
|
101
|
+
"!node_modules/**",
|
|
102
|
+
"-g",
|
|
103
|
+
"!dist",
|
|
104
|
+
"-g",
|
|
105
|
+
"!dist/**",
|
|
106
|
+
], {
|
|
107
|
+
cwd: this.basePath,
|
|
108
|
+
encoding: "utf8",
|
|
109
|
+
});
|
|
110
|
+
if (result.status !== 0 || !result.stdout) {
|
|
111
|
+
this.cachedFiles = [];
|
|
112
|
+
this.cachedAtMs = now;
|
|
113
|
+
return this.cachedFiles;
|
|
114
|
+
}
|
|
115
|
+
this.cachedFiles = result.stdout
|
|
116
|
+
.split("\n")
|
|
117
|
+
.map((line) => line.trim())
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.sort((a, b) => a.localeCompare(b));
|
|
120
|
+
this.cachedAtMs = now;
|
|
121
|
+
return this.cachedFiles;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.js","sourceRoot":"","sources":["../../src/lib/autocomplete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EACL,4BAA4B,EAC5B,WAAW,GAIZ,MAAM,sBAAsB,CAAC;AAE9B,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAC7D,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,SAAS,aAAa;IACpB,KAAK,MAAM,SAAS,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE;YACjD,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IAC7B,OAAO,UAAU,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC3E,UAAU,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,SAAS,yBAAyB,CAAC,QAAgB;IACjD,OAAO;QACL,KAAK,EAAE,IAAI,QAAQ,EAAE;QACrB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,0BAA0B;IACpB,QAAQ,CAA+B;IACvC,QAAQ,CAAS;IAC1B,WAAW,GAAoB,IAAI,CAAC;IACpC,UAAU,GAAG,CAAC,CAAC;IAEvB,YAAY,QAAwB,EAAE,QAAgB;QACpD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,4BAA4B,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,cAAc,CACZ,KAAe,EACf,UAAkB,EAClB,SAAiB;QAEjB,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACtF,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACnD,MAAM,QAAQ,GACZ,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;YACjB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC;YACtC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAErF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IAED,eAAe,CACb,KAAe,EACf,UAAkB,EAClB,SAAiB,EACjB,IAAsB,EACtB,MAAc;QAEd,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;YACnD,MAAM,SAAS,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;YAC7B,SAAS,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;YAEjC,OAAO;gBACL,KAAK,EAAE,SAAS;gBAChB,UAAU;gBACV,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;aACjD,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAEO,iBAAiB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,WAAW,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,iBAAiB,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CACtB,IAAI,EACJ;YACE,SAAS;YACT,UAAU;YACV,IAAI;YACJ,OAAO;YACP,IAAI;YACJ,UAAU;YACV,IAAI;YACJ,eAAe;YACf,IAAI;YACJ,kBAAkB;YAClB,IAAI;YACJ,OAAO;YACP,IAAI;YACJ,UAAU;SACX,EACD;YACE,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,QAAQ,EAAE,MAAM;SACjB,CACF,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YACtB,OAAO,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM;aAC7B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type InstanceListMode = "active" | "all";
|
|
2
|
+
export interface CommandSpec {
|
|
3
|
+
phrase: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export type TuiCommandAction = {
|
|
7
|
+
type: "help";
|
|
8
|
+
} | {
|
|
9
|
+
type: "quit";
|
|
10
|
+
} | {
|
|
11
|
+
type: "clear";
|
|
12
|
+
} | {
|
|
13
|
+
type: "login";
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "logout";
|
|
17
|
+
} | {
|
|
18
|
+
type: "status";
|
|
19
|
+
} | {
|
|
20
|
+
type: "new";
|
|
21
|
+
} | {
|
|
22
|
+
type: "chats";
|
|
23
|
+
} | {
|
|
24
|
+
type: "open";
|
|
25
|
+
sessionId: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: "instances";
|
|
28
|
+
mode: InstanceListMode;
|
|
29
|
+
};
|
|
30
|
+
export type CliCommandAction = {
|
|
31
|
+
type: "help";
|
|
32
|
+
} | {
|
|
33
|
+
type: "tui";
|
|
34
|
+
openSessionId?: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: "login";
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
} | {
|
|
39
|
+
type: "logout";
|
|
40
|
+
} | {
|
|
41
|
+
type: "status";
|
|
42
|
+
} | {
|
|
43
|
+
type: "chats";
|
|
44
|
+
} | {
|
|
45
|
+
type: "instances";
|
|
46
|
+
mode: InstanceListMode;
|
|
47
|
+
};
|
|
48
|
+
export declare function getTuiCommandSpecs(): CommandSpec[];
|
|
49
|
+
export declare function getCliHelpText(): string;
|
|
50
|
+
export declare function getTuiHelpText(): string;
|
|
51
|
+
export declare function parseCliCommand(argv: string[]): CliCommandAction;
|
|
52
|
+
export declare function parseTuiCommand(header: string): TuiCommandAction | null;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
const tuiCommandSpecs = [
|
|
2
|
+
{ phrase: "?", description: "Show usage" },
|
|
3
|
+
{ phrase: "/help", description: "Show usage" },
|
|
4
|
+
{ phrase: "/quit", description: "Exit the app" },
|
|
5
|
+
{ phrase: "/clear", description: "Clear the timeline" },
|
|
6
|
+
{ phrase: "/login", description: "Authenticate with Operator" },
|
|
7
|
+
{ phrase: "/logout", description: "Clear stored API key" },
|
|
8
|
+
{ phrase: "/status", description: "Show current auth status" },
|
|
9
|
+
{ phrase: "/new", description: "Start a new local Darwin session" },
|
|
10
|
+
{ phrase: "/chats", description: "List local Darwin sessions" },
|
|
11
|
+
{ phrase: "/open", description: "Open a local session by ID" },
|
|
12
|
+
{ phrase: "/instances", description: "List instances" },
|
|
13
|
+
];
|
|
14
|
+
const cliHelpLines = [
|
|
15
|
+
"Darwin",
|
|
16
|
+
"",
|
|
17
|
+
"Usage:",
|
|
18
|
+
" darwin Start the TUI with a fresh session",
|
|
19
|
+
" darwin new Start the TUI with a fresh session",
|
|
20
|
+
" darwin open <id> Open a saved local session in the TUI",
|
|
21
|
+
" darwin chats List saved local sessions",
|
|
22
|
+
" darwin status Show auth and endpoint info",
|
|
23
|
+
" darwin login [apiKey] Authenticate in the browser or store an API key",
|
|
24
|
+
" darwin logout Remove the stored API key",
|
|
25
|
+
" darwin instances [all] List instances",
|
|
26
|
+
"",
|
|
27
|
+
"Flag aliases:",
|
|
28
|
+
" --new --open --chats --status --login --logout --instances --help",
|
|
29
|
+
"",
|
|
30
|
+
"Notes:",
|
|
31
|
+
" /clear and /quit remain TUI-only commands.",
|
|
32
|
+
];
|
|
33
|
+
const tuiHelpLines = [
|
|
34
|
+
"**Darwin**",
|
|
35
|
+
"",
|
|
36
|
+
"Darwin is a CLI for evolving and evaluating OpenClaw agents from the current workspace.",
|
|
37
|
+
"Use it to run short experiment loops, inspect local code, and steer Operator-backed agent work.",
|
|
38
|
+
"Text without a leading `/` goes through Operator chat with Darwin's local Pi tool harness.",
|
|
39
|
+
"",
|
|
40
|
+
"**Session**",
|
|
41
|
+
"",
|
|
42
|
+
"`/new` Start a fresh Darwin chat thread",
|
|
43
|
+
"`/chats` List local Darwin sessions",
|
|
44
|
+
"`/open <id>` Reopen a local session by id or prefix",
|
|
45
|
+
"`/clear` Clear the current timeline view",
|
|
46
|
+
"",
|
|
47
|
+
"**Auth**",
|
|
48
|
+
"",
|
|
49
|
+
"`/login` Authenticate in the browser",
|
|
50
|
+
"`/login <api-key>` Store an Operator API key directly",
|
|
51
|
+
"`/status` Show auth, plan, and endpoint info",
|
|
52
|
+
"`/logout` Remove the stored API key",
|
|
53
|
+
"",
|
|
54
|
+
"**Operator**",
|
|
55
|
+
"",
|
|
56
|
+
"`/instances` List active instances",
|
|
57
|
+
"`/instances all` List all instances",
|
|
58
|
+
"",
|
|
59
|
+
"**General**",
|
|
60
|
+
"",
|
|
61
|
+
"`?` Show this help",
|
|
62
|
+
"`/help` Show this help",
|
|
63
|
+
"`/quit` Exit Darwin",
|
|
64
|
+
];
|
|
65
|
+
function parseInstancesMode(value) {
|
|
66
|
+
return value === "all" ? "all" : "active";
|
|
67
|
+
}
|
|
68
|
+
function normalizeCliCommandToken(token) {
|
|
69
|
+
if (!token) {
|
|
70
|
+
return token;
|
|
71
|
+
}
|
|
72
|
+
const aliases = {
|
|
73
|
+
"--new": "new",
|
|
74
|
+
"--open": "open",
|
|
75
|
+
"--chats": "chats",
|
|
76
|
+
"--status": "status",
|
|
77
|
+
"--login": "login",
|
|
78
|
+
"--logout": "logout",
|
|
79
|
+
"--instances": "instances",
|
|
80
|
+
"--help": "help",
|
|
81
|
+
"-h": "help",
|
|
82
|
+
};
|
|
83
|
+
return aliases[token] ?? token;
|
|
84
|
+
}
|
|
85
|
+
export function getTuiCommandSpecs() {
|
|
86
|
+
return [...tuiCommandSpecs];
|
|
87
|
+
}
|
|
88
|
+
export function getCliHelpText() {
|
|
89
|
+
return cliHelpLines.join("\n");
|
|
90
|
+
}
|
|
91
|
+
export function getTuiHelpText() {
|
|
92
|
+
return tuiHelpLines.join("\n");
|
|
93
|
+
}
|
|
94
|
+
export function parseCliCommand(argv) {
|
|
95
|
+
const args = [...argv];
|
|
96
|
+
const command = normalizeCliCommandToken(args.shift());
|
|
97
|
+
if (!command) {
|
|
98
|
+
return { type: "tui" };
|
|
99
|
+
}
|
|
100
|
+
switch (command) {
|
|
101
|
+
case "help":
|
|
102
|
+
return { type: "help" };
|
|
103
|
+
case "new":
|
|
104
|
+
if (args.length > 0) {
|
|
105
|
+
throw new Error("`darwin new` does not accept extra arguments.");
|
|
106
|
+
}
|
|
107
|
+
return { type: "tui" };
|
|
108
|
+
case "open": {
|
|
109
|
+
const sessionId = args.shift();
|
|
110
|
+
if (!sessionId) {
|
|
111
|
+
throw new Error("Usage: darwin open <id>");
|
|
112
|
+
}
|
|
113
|
+
if (args.length > 0) {
|
|
114
|
+
throw new Error("`darwin open` accepts exactly one session id.");
|
|
115
|
+
}
|
|
116
|
+
return { type: "tui", openSessionId: sessionId };
|
|
117
|
+
}
|
|
118
|
+
case "chats":
|
|
119
|
+
if (args.length > 0) {
|
|
120
|
+
throw new Error("`darwin chats` does not accept extra arguments.");
|
|
121
|
+
}
|
|
122
|
+
return { type: "chats" };
|
|
123
|
+
case "status":
|
|
124
|
+
if (args.length > 0) {
|
|
125
|
+
throw new Error("`darwin status` does not accept extra arguments.");
|
|
126
|
+
}
|
|
127
|
+
return { type: "status" };
|
|
128
|
+
case "login":
|
|
129
|
+
if (args.length > 1) {
|
|
130
|
+
throw new Error("Usage: darwin login [apiKey]");
|
|
131
|
+
}
|
|
132
|
+
return { type: "login", apiKey: args[0] };
|
|
133
|
+
case "logout":
|
|
134
|
+
if (args.length > 0) {
|
|
135
|
+
throw new Error("`darwin logout` does not accept extra arguments.");
|
|
136
|
+
}
|
|
137
|
+
return { type: "logout" };
|
|
138
|
+
case "instances":
|
|
139
|
+
if (args.length > 1 || (args[0] && args[0] !== "all" && args[0] !== "active")) {
|
|
140
|
+
throw new Error("Usage: darwin instances [all|active]");
|
|
141
|
+
}
|
|
142
|
+
return { type: "instances", mode: parseInstancesMode(args[0]) };
|
|
143
|
+
default:
|
|
144
|
+
throw new Error(`Unknown command: ${command}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export function parseTuiCommand(header) {
|
|
148
|
+
const trimmed = header.trim();
|
|
149
|
+
if (trimmed === "?") {
|
|
150
|
+
return { type: "help" };
|
|
151
|
+
}
|
|
152
|
+
if (!trimmed.startsWith("/")) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const raw = trimmed.slice(1).trim();
|
|
156
|
+
if (raw === "") {
|
|
157
|
+
throw new Error("Unknown command: /");
|
|
158
|
+
}
|
|
159
|
+
if (/^help$/i.test(raw)) {
|
|
160
|
+
return { type: "help" };
|
|
161
|
+
}
|
|
162
|
+
if (/^(quit|exit)$/i.test(raw)) {
|
|
163
|
+
return { type: "quit" };
|
|
164
|
+
}
|
|
165
|
+
if (/^clear$/i.test(raw)) {
|
|
166
|
+
return { type: "clear" };
|
|
167
|
+
}
|
|
168
|
+
if (/^new(?:\s+chat)?$/i.test(raw)) {
|
|
169
|
+
return { type: "new" };
|
|
170
|
+
}
|
|
171
|
+
if (/^chats?$/i.test(raw)) {
|
|
172
|
+
return { type: "chats" };
|
|
173
|
+
}
|
|
174
|
+
const loginMatch = raw.match(/^login(?:\s+(.+))?$/i);
|
|
175
|
+
if (loginMatch) {
|
|
176
|
+
return { type: "login", apiKey: loginMatch[1]?.trim() || undefined };
|
|
177
|
+
}
|
|
178
|
+
if (/^logout$/i.test(raw)) {
|
|
179
|
+
return { type: "logout" };
|
|
180
|
+
}
|
|
181
|
+
if (/^status$/i.test(raw)) {
|
|
182
|
+
return { type: "status" };
|
|
183
|
+
}
|
|
184
|
+
const openMatch = raw.match(/^open(?:\s+chat)?\s+(.+)$/i);
|
|
185
|
+
if (openMatch) {
|
|
186
|
+
return { type: "open", sessionId: openMatch[1].trim() };
|
|
187
|
+
}
|
|
188
|
+
const instancesMatch = raw.match(/^instances?(?:\s+(.+))?$/i);
|
|
189
|
+
if (instancesMatch) {
|
|
190
|
+
const mode = instancesMatch[1]?.trim();
|
|
191
|
+
if (mode && mode !== "all" && mode !== "active") {
|
|
192
|
+
throw new Error("Usage: /instances [all]");
|
|
193
|
+
}
|
|
194
|
+
return { type: "instances", mode: parseInstancesMode(mode) };
|
|
195
|
+
}
|
|
196
|
+
throw new Error(`Unknown command: ${header.trim()}`);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=command-surface.js.map
|