agendex-cli 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 +25 -0
- package/README.md +41 -0
- package/dist/cli.js +3124 -0
- package/package.json +33 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,3124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
13
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
35
|
+
|
|
36
|
+
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
37
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
38
|
+
var p = process || {};
|
|
39
|
+
var argv = p.argv || [];
|
|
40
|
+
var env = p.env || {};
|
|
41
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
42
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
43
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
44
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
45
|
+
};
|
|
46
|
+
var replaceClose = (string, close, replace, index) => {
|
|
47
|
+
let result = "", cursor = 0;
|
|
48
|
+
do {
|
|
49
|
+
result += string.substring(cursor, index) + replace;
|
|
50
|
+
cursor = index + close.length;
|
|
51
|
+
index = string.indexOf(close, cursor);
|
|
52
|
+
} while (~index);
|
|
53
|
+
return result + string.substring(cursor);
|
|
54
|
+
};
|
|
55
|
+
var createColors = (enabled = isColorSupported) => {
|
|
56
|
+
let f = enabled ? formatter : () => String;
|
|
57
|
+
return {
|
|
58
|
+
isColorSupported: enabled,
|
|
59
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
60
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
61
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
62
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
63
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
64
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
65
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
66
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
67
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
68
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
69
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
70
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
71
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
72
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
73
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
74
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
75
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
76
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
77
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
78
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
79
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
80
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
81
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
82
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
83
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
84
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
85
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
86
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
87
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
88
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
89
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
90
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
91
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
92
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
93
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
94
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
95
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
96
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
97
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
98
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
99
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
module.exports = createColors();
|
|
103
|
+
module.exports.createColors = createColors;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// ../../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
|
107
|
+
var require_src = __commonJS((exports, module) => {
|
|
108
|
+
var ESC = "\x1B";
|
|
109
|
+
var CSI = `${ESC}[`;
|
|
110
|
+
var beep = "\x07";
|
|
111
|
+
var cursor = {
|
|
112
|
+
to(x, y) {
|
|
113
|
+
if (!y)
|
|
114
|
+
return `${CSI}${x + 1}G`;
|
|
115
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
116
|
+
},
|
|
117
|
+
move(x, y) {
|
|
118
|
+
let ret = "";
|
|
119
|
+
if (x < 0)
|
|
120
|
+
ret += `${CSI}${-x}D`;
|
|
121
|
+
else if (x > 0)
|
|
122
|
+
ret += `${CSI}${x}C`;
|
|
123
|
+
if (y < 0)
|
|
124
|
+
ret += `${CSI}${-y}A`;
|
|
125
|
+
else if (y > 0)
|
|
126
|
+
ret += `${CSI}${y}B`;
|
|
127
|
+
return ret;
|
|
128
|
+
},
|
|
129
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
130
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
131
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
132
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
133
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
134
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
135
|
+
left: `${CSI}G`,
|
|
136
|
+
hide: `${CSI}?25l`,
|
|
137
|
+
show: `${CSI}?25h`,
|
|
138
|
+
save: `${ESC}7`,
|
|
139
|
+
restore: `${ESC}8`
|
|
140
|
+
};
|
|
141
|
+
var scroll = {
|
|
142
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
143
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
144
|
+
};
|
|
145
|
+
var erase = {
|
|
146
|
+
screen: `${CSI}2J`,
|
|
147
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
148
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
149
|
+
line: `${CSI}2K`,
|
|
150
|
+
lineEnd: `${CSI}K`,
|
|
151
|
+
lineStart: `${CSI}1K`,
|
|
152
|
+
lines(count) {
|
|
153
|
+
let clear = "";
|
|
154
|
+
for (let i = 0;i < count; i++)
|
|
155
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
156
|
+
if (count)
|
|
157
|
+
clear += cursor.left;
|
|
158
|
+
return clear;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// src/cli.ts
|
|
165
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
166
|
+
import { writeSync } from "node:fs";
|
|
167
|
+
import { resolve as resolve5 } from "node:path";
|
|
168
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
169
|
+
|
|
170
|
+
// ../shared/src/adapters/catalog.ts
|
|
171
|
+
import { homedir as homedir6 } from "node:os";
|
|
172
|
+
import { join as join6 } from "node:path";
|
|
173
|
+
|
|
174
|
+
// ../shared/src/adapters/claude-code.ts
|
|
175
|
+
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
176
|
+
import { homedir } from "node:os";
|
|
177
|
+
import { basename, join, resolve, sep } from "node:path";
|
|
178
|
+
|
|
179
|
+
// ../shared/src/hash.ts
|
|
180
|
+
import { createHash } from "node:crypto";
|
|
181
|
+
function hashPath(filePath) {
|
|
182
|
+
return createHash("sha256").update(filePath).digest("hex").slice(0, 16);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ../shared/src/adapters/claude-code.ts
|
|
186
|
+
var plansDir = join(homedir(), ".claude", "plans");
|
|
187
|
+
function extractTitle(content, filename) {
|
|
188
|
+
const match = content.match(/^#\s+(.+)/m);
|
|
189
|
+
if (match?.[1])
|
|
190
|
+
return match[1].replace(/^Plan:\s*/i, "").trim();
|
|
191
|
+
return basename(filename, ".md").split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
192
|
+
}
|
|
193
|
+
var claudeCodeAdapter = {
|
|
194
|
+
agent: "claude-code",
|
|
195
|
+
writable: true,
|
|
196
|
+
getSearchPaths() {
|
|
197
|
+
return [plansDir];
|
|
198
|
+
},
|
|
199
|
+
getWatchPaths() {
|
|
200
|
+
return [plansDir];
|
|
201
|
+
},
|
|
202
|
+
matches(filePath) {
|
|
203
|
+
if (!filePath.endsWith(".md"))
|
|
204
|
+
return false;
|
|
205
|
+
const normalized = resolve(filePath);
|
|
206
|
+
const baseDir = resolve(plansDir);
|
|
207
|
+
return normalized.startsWith(baseDir + sep);
|
|
208
|
+
},
|
|
209
|
+
async parse(filePath) {
|
|
210
|
+
try {
|
|
211
|
+
const content = await readFile(filePath, "utf-8");
|
|
212
|
+
const stats = await stat(filePath);
|
|
213
|
+
return [
|
|
214
|
+
{
|
|
215
|
+
id: hashPath(filePath),
|
|
216
|
+
agent: "claude-code",
|
|
217
|
+
title: extractTitle(content, filePath),
|
|
218
|
+
content,
|
|
219
|
+
filePath,
|
|
220
|
+
format: "md",
|
|
221
|
+
createdAt: stats.birthtime,
|
|
222
|
+
updatedAt: stats.mtime,
|
|
223
|
+
metadata: {}
|
|
224
|
+
}
|
|
225
|
+
];
|
|
226
|
+
} catch {
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
async write(plan, newContent) {
|
|
231
|
+
try {
|
|
232
|
+
await writeFile(plan.filePath, newContent, "utf-8");
|
|
233
|
+
return true;
|
|
234
|
+
} catch {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// ../shared/src/adapters/codex-cli.ts
|
|
241
|
+
import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
242
|
+
import { homedir as homedir2 } from "node:os";
|
|
243
|
+
import { basename as basename2, join as join2 } from "node:path";
|
|
244
|
+
var sessionsDir = join2(homedir2(), ".codex", "sessions");
|
|
245
|
+
var PROPOSED_PLAN_BLOCK_REGEX = /<proposed_plan>\s*([\s\S]*?)\s*<\/proposed_plan>/gi;
|
|
246
|
+
var PROPOSED_PLAN_TAG_REGEX = /<\s*\/?\s*proposed_plan\s*>/gi;
|
|
247
|
+
var ESCAPED_PROPOSED_PLAN_TAG_REGEX = /<\s*\/?\s*proposed_plan\s*>/gi;
|
|
248
|
+
function normalizeLineEndings(text) {
|
|
249
|
+
return text.replace(/\r\n?/g, `
|
|
250
|
+
`);
|
|
251
|
+
}
|
|
252
|
+
function stripProposedPlanTags(text) {
|
|
253
|
+
return text.replace(ESCAPED_PROPOSED_PLAN_TAG_REGEX, "").replace(PROPOSED_PLAN_TAG_REGEX, "");
|
|
254
|
+
}
|
|
255
|
+
function normalizeMarkdown(text) {
|
|
256
|
+
return stripProposedPlanTags(normalizeLineEndings(text)).trim();
|
|
257
|
+
}
|
|
258
|
+
function parseJsonLines(raw) {
|
|
259
|
+
const parsed = [];
|
|
260
|
+
for (const line of raw.split(`
|
|
261
|
+
`)) {
|
|
262
|
+
const trimmed = line.trim();
|
|
263
|
+
if (!trimmed)
|
|
264
|
+
continue;
|
|
265
|
+
try {
|
|
266
|
+
parsed.push(JSON.parse(trimmed));
|
|
267
|
+
} catch {}
|
|
268
|
+
}
|
|
269
|
+
return parsed;
|
|
270
|
+
}
|
|
271
|
+
function isRecord(value) {
|
|
272
|
+
return typeof value === "object" && value !== null;
|
|
273
|
+
}
|
|
274
|
+
function extractTextFromContent(content) {
|
|
275
|
+
if (typeof content === "string")
|
|
276
|
+
return content;
|
|
277
|
+
if (!Array.isArray(content))
|
|
278
|
+
return "";
|
|
279
|
+
const parts = [];
|
|
280
|
+
for (const chunk of content) {
|
|
281
|
+
if (!isRecord(chunk))
|
|
282
|
+
continue;
|
|
283
|
+
const type = typeof chunk.type === "string" ? chunk.type : "";
|
|
284
|
+
if (type !== "text" && type !== "input_text" && type !== "output_text")
|
|
285
|
+
continue;
|
|
286
|
+
if (typeof chunk.text === "string")
|
|
287
|
+
parts.push(chunk.text);
|
|
288
|
+
}
|
|
289
|
+
return parts.join(`
|
|
290
|
+
`);
|
|
291
|
+
}
|
|
292
|
+
function extractSessionMeta(lines) {
|
|
293
|
+
const meta = {};
|
|
294
|
+
for (const line of lines) {
|
|
295
|
+
if (!isRecord(line))
|
|
296
|
+
continue;
|
|
297
|
+
const legacyMeta = isRecord(line.session_meta) ? line.session_meta : undefined;
|
|
298
|
+
if (legacyMeta?.session_id && !meta.sessionId)
|
|
299
|
+
meta.sessionId = legacyMeta.session_id;
|
|
300
|
+
if (legacyMeta?.started_at && !meta.startedAt)
|
|
301
|
+
meta.startedAt = legacyMeta.started_at;
|
|
302
|
+
if (line.type !== "session_meta" || !isRecord(line.payload))
|
|
303
|
+
continue;
|
|
304
|
+
if (typeof line.payload.id === "string" && !meta.sessionId) {
|
|
305
|
+
meta.sessionId = line.payload.id;
|
|
306
|
+
}
|
|
307
|
+
if (typeof line.payload.session_id === "string" && !meta.sessionId) {
|
|
308
|
+
meta.sessionId = line.payload.session_id;
|
|
309
|
+
}
|
|
310
|
+
if (typeof line.payload.timestamp === "string" && !meta.startedAt) {
|
|
311
|
+
meta.startedAt = line.payload.timestamp;
|
|
312
|
+
}
|
|
313
|
+
if (typeof line.payload.started_at === "string" && !meta.startedAt) {
|
|
314
|
+
meta.startedAt = line.payload.started_at;
|
|
315
|
+
}
|
|
316
|
+
if (typeof line.payload.cwd === "string" && !meta.cwd) {
|
|
317
|
+
meta.cwd = line.payload.cwd;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return meta;
|
|
321
|
+
}
|
|
322
|
+
function normalizeRole(candidate, fallback = "assistant") {
|
|
323
|
+
if (typeof candidate !== "string")
|
|
324
|
+
return fallback;
|
|
325
|
+
return candidate;
|
|
326
|
+
}
|
|
327
|
+
function extractMessages(lines) {
|
|
328
|
+
const messages = [];
|
|
329
|
+
for (const line of lines) {
|
|
330
|
+
if (!isRecord(line))
|
|
331
|
+
continue;
|
|
332
|
+
if (line.type === "response_item" && isRecord(line.payload) && line.payload.type === "message") {
|
|
333
|
+
const text2 = extractTextFromContent(line.payload.content);
|
|
334
|
+
if (!text2.trim())
|
|
335
|
+
continue;
|
|
336
|
+
messages.push({
|
|
337
|
+
role: normalizeRole(line.payload.role),
|
|
338
|
+
text: text2,
|
|
339
|
+
phase: typeof line.payload.phase === "string" ? line.payload.phase : undefined
|
|
340
|
+
});
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
const hasLegacyFields = line.content !== undefined || line.role !== undefined || line.session_meta !== undefined || line.type === "message";
|
|
344
|
+
if (!hasLegacyFields || line.session_meta !== undefined)
|
|
345
|
+
continue;
|
|
346
|
+
const text = extractTextFromContent(line.content);
|
|
347
|
+
if (!text.trim())
|
|
348
|
+
continue;
|
|
349
|
+
messages.push({
|
|
350
|
+
role: normalizeRole(line.role, "user"),
|
|
351
|
+
text
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return messages;
|
|
355
|
+
}
|
|
356
|
+
function extractProposedPlanBlocks(messages) {
|
|
357
|
+
const blocks = [];
|
|
358
|
+
for (const message of messages) {
|
|
359
|
+
if (message.role !== "assistant")
|
|
360
|
+
continue;
|
|
361
|
+
const matches = message.text.matchAll(PROPOSED_PLAN_BLOCK_REGEX);
|
|
362
|
+
for (const match of matches) {
|
|
363
|
+
if (!match[1])
|
|
364
|
+
continue;
|
|
365
|
+
const block = normalizeMarkdown(match[1]);
|
|
366
|
+
if (block)
|
|
367
|
+
blocks.push(block);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return blocks;
|
|
371
|
+
}
|
|
372
|
+
function selectPlanContent(messages) {
|
|
373
|
+
const assistant = messages.filter((m) => m.role === "assistant" && m.text.trim().length > 0);
|
|
374
|
+
const planBlocks = extractProposedPlanBlocks(assistant);
|
|
375
|
+
if (planBlocks.length > 0) {
|
|
376
|
+
return {
|
|
377
|
+
content: normalizeMarkdown(planBlocks.join(`
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
`)),
|
|
382
|
+
planBlocks
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
const finalAnswerAssistant = assistant.filter((m) => m.phase === "final_answer");
|
|
386
|
+
const selected = finalAnswerAssistant.length > 0 ? finalAnswerAssistant : assistant;
|
|
387
|
+
return {
|
|
388
|
+
content: normalizeMarkdown(selected.map((m) => m.text).join(`
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
`)),
|
|
393
|
+
planBlocks: []
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function cleanTitle(title) {
|
|
397
|
+
return title.trim().replace(/^Plan:\s*/i, "").replace(/^#+\s*/, "").replace(/^\*\*|\*\*$/g, "").replace(/^`|`$/g, "").replace(/^[-*+]\s+/, "").trim();
|
|
398
|
+
}
|
|
399
|
+
function shorten(text, maxLen) {
|
|
400
|
+
if (text.length <= maxLen)
|
|
401
|
+
return text;
|
|
402
|
+
return `${text.slice(0, maxLen - 1).trimEnd()}...`;
|
|
403
|
+
}
|
|
404
|
+
function titleFromPlanBlock(block) {
|
|
405
|
+
const heading = block.match(/^\s{0,3}#{1,6}\s+(.+?)\s*$/m)?.[1];
|
|
406
|
+
if (heading)
|
|
407
|
+
return cleanTitle(heading);
|
|
408
|
+
const lines = block.split(`
|
|
409
|
+
`);
|
|
410
|
+
for (let i = 0;i < lines.length; i++) {
|
|
411
|
+
const line = lines[i]?.trim() ?? "";
|
|
412
|
+
const titleMatch = line.match(/^\*\*title\*\*(?::\s*(.+))?\s*$/i);
|
|
413
|
+
if (!titleMatch)
|
|
414
|
+
continue;
|
|
415
|
+
if (titleMatch[1]?.trim())
|
|
416
|
+
return cleanTitle(titleMatch[1]);
|
|
417
|
+
for (let j = i + 1;j < lines.length; j++) {
|
|
418
|
+
const next = lines[j]?.trim() ?? "";
|
|
419
|
+
if (!next)
|
|
420
|
+
continue;
|
|
421
|
+
return cleanTitle(next);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
for (const line of lines) {
|
|
425
|
+
const trimmed = line.trim();
|
|
426
|
+
if (!trimmed || /^---+$/.test(trimmed))
|
|
427
|
+
continue;
|
|
428
|
+
return cleanTitle(trimmed);
|
|
429
|
+
}
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
function isMeaningfulUserText(text) {
|
|
433
|
+
const normalized = normalizeLineEndings(text).trim();
|
|
434
|
+
if (!normalized)
|
|
435
|
+
return false;
|
|
436
|
+
const lower = normalized.toLowerCase();
|
|
437
|
+
if (lower.startsWith("# agents.md instructions"))
|
|
438
|
+
return false;
|
|
439
|
+
if (lower.startsWith("<environment_context>"))
|
|
440
|
+
return false;
|
|
441
|
+
if (lower.startsWith("<system-reminder>"))
|
|
442
|
+
return false;
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
function extractTitle2(messages, planBlocks, filename) {
|
|
446
|
+
if (planBlocks.length > 0 && planBlocks[0]) {
|
|
447
|
+
const planTitle = titleFromPlanBlock(planBlocks[0]);
|
|
448
|
+
if (planTitle)
|
|
449
|
+
return shorten(planTitle, 120);
|
|
450
|
+
}
|
|
451
|
+
const firstUser = messages.find((m) => m.role === "user" && isMeaningfulUserText(m.text));
|
|
452
|
+
if (firstUser) {
|
|
453
|
+
const firstLine = normalizeLineEndings(firstUser.text).split(`
|
|
454
|
+
`).map((line) => line.trim()).find(Boolean);
|
|
455
|
+
if (firstLine)
|
|
456
|
+
return shorten(cleanTitle(firstLine), 80);
|
|
457
|
+
}
|
|
458
|
+
return basename2(filename, ".jsonl");
|
|
459
|
+
}
|
|
460
|
+
function parseDate(value) {
|
|
461
|
+
if (!value)
|
|
462
|
+
return;
|
|
463
|
+
const date = new Date(value);
|
|
464
|
+
if (Number.isNaN(date.getTime()))
|
|
465
|
+
return;
|
|
466
|
+
return date;
|
|
467
|
+
}
|
|
468
|
+
var codexCliAdapter = {
|
|
469
|
+
agent: "codex-cli",
|
|
470
|
+
writable: false,
|
|
471
|
+
getSearchPaths() {
|
|
472
|
+
return [sessionsDir];
|
|
473
|
+
},
|
|
474
|
+
getWatchPaths() {
|
|
475
|
+
return [sessionsDir];
|
|
476
|
+
},
|
|
477
|
+
matches(filePath) {
|
|
478
|
+
return filePath.endsWith(".jsonl") && basename2(filePath).startsWith("rollout-");
|
|
479
|
+
},
|
|
480
|
+
async parse(filePath) {
|
|
481
|
+
try {
|
|
482
|
+
const raw = await readFile2(filePath, "utf-8");
|
|
483
|
+
const lines = parseJsonLines(raw);
|
|
484
|
+
if (lines.length === 0)
|
|
485
|
+
return [];
|
|
486
|
+
const messages = extractMessages(lines);
|
|
487
|
+
const { content, planBlocks } = selectPlanContent(messages);
|
|
488
|
+
const stats = await stat2(filePath);
|
|
489
|
+
const sessionMeta = extractSessionMeta(lines);
|
|
490
|
+
const createdAt = parseDate(sessionMeta.startedAt) ?? stats.birthtime;
|
|
491
|
+
const metadata = {};
|
|
492
|
+
if (sessionMeta.sessionId)
|
|
493
|
+
metadata.sessionId = sessionMeta.sessionId;
|
|
494
|
+
if (planBlocks.length > 0)
|
|
495
|
+
metadata.planBlocks = planBlocks.length;
|
|
496
|
+
return [
|
|
497
|
+
{
|
|
498
|
+
id: hashPath(filePath),
|
|
499
|
+
agent: "codex-cli",
|
|
500
|
+
title: extractTitle2(messages, planBlocks, filePath),
|
|
501
|
+
content,
|
|
502
|
+
filePath,
|
|
503
|
+
format: "jsonl",
|
|
504
|
+
createdAt,
|
|
505
|
+
updatedAt: stats.mtime,
|
|
506
|
+
workspace: sessionMeta.cwd,
|
|
507
|
+
metadata
|
|
508
|
+
}
|
|
509
|
+
];
|
|
510
|
+
} catch {
|
|
511
|
+
return [];
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
async write() {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// ../shared/src/adapters/continue-ide.ts
|
|
520
|
+
import { readFile as readFile3, stat as stat3 } from "node:fs/promises";
|
|
521
|
+
import { homedir as homedir3 } from "node:os";
|
|
522
|
+
import { join as join3 } from "node:path";
|
|
523
|
+
var continueDir = join3(homedir3(), ".continue", "sessions");
|
|
524
|
+
var continueIdeAdapter = {
|
|
525
|
+
agent: "continue-ide",
|
|
526
|
+
writable: false,
|
|
527
|
+
getSearchPaths() {
|
|
528
|
+
return [continueDir];
|
|
529
|
+
},
|
|
530
|
+
getWatchPaths() {
|
|
531
|
+
return [continueDir];
|
|
532
|
+
},
|
|
533
|
+
matches(filePath) {
|
|
534
|
+
return filePath.endsWith(".json");
|
|
535
|
+
},
|
|
536
|
+
async parse(filePath) {
|
|
537
|
+
try {
|
|
538
|
+
const raw = await readFile3(filePath, "utf-8");
|
|
539
|
+
const session = JSON.parse(raw);
|
|
540
|
+
if (!session.history || session.history.length === 0)
|
|
541
|
+
return [];
|
|
542
|
+
const stats = await stat3(filePath);
|
|
543
|
+
let title = "Continue Session";
|
|
544
|
+
let workspace;
|
|
545
|
+
const indexPath = join3(continueDir, "sessions.json");
|
|
546
|
+
try {
|
|
547
|
+
const indexRaw = await readFile3(indexPath, "utf-8");
|
|
548
|
+
const sessions = JSON.parse(indexRaw);
|
|
549
|
+
const sessionId = filePath.split("/").pop()?.replace(".json", "");
|
|
550
|
+
const meta = sessions.find((s) => s.sessionId === sessionId);
|
|
551
|
+
if (meta) {
|
|
552
|
+
title = meta.title || title;
|
|
553
|
+
workspace = meta.workspaceDirectory;
|
|
554
|
+
}
|
|
555
|
+
} catch {}
|
|
556
|
+
const content = (session.history ?? []).map((m) => `**${m.role}**: ${m.content}`).join(`
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
`);
|
|
561
|
+
return [
|
|
562
|
+
{
|
|
563
|
+
id: hashPath(filePath),
|
|
564
|
+
agent: "continue-ide",
|
|
565
|
+
title,
|
|
566
|
+
content,
|
|
567
|
+
filePath,
|
|
568
|
+
format: "json",
|
|
569
|
+
createdAt: stats.birthtime,
|
|
570
|
+
updatedAt: stats.mtime,
|
|
571
|
+
workspace,
|
|
572
|
+
metadata: {}
|
|
573
|
+
}
|
|
574
|
+
];
|
|
575
|
+
} catch {
|
|
576
|
+
return [];
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
async write() {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// ../shared/src/adapters/cursor.ts
|
|
585
|
+
import { existsSync } from "node:fs";
|
|
586
|
+
import { stat as stat4 } from "node:fs/promises";
|
|
587
|
+
import { homedir as homedir4 } from "node:os";
|
|
588
|
+
import { join as join4 } from "node:path";
|
|
589
|
+
function quoteIdentifier(name) {
|
|
590
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
591
|
+
}
|
|
592
|
+
var cursorAdapter = {
|
|
593
|
+
agent: "cursor",
|
|
594
|
+
writable: false,
|
|
595
|
+
getSearchPaths() {
|
|
596
|
+
return [join4(homedir4(), ".cursor", "ai-tracking")];
|
|
597
|
+
},
|
|
598
|
+
getWatchPaths() {
|
|
599
|
+
return [join4(homedir4(), ".cursor", "ai-tracking")];
|
|
600
|
+
},
|
|
601
|
+
matches(filePath) {
|
|
602
|
+
return filePath.endsWith(".db");
|
|
603
|
+
},
|
|
604
|
+
async parse(filePath) {
|
|
605
|
+
if (!existsSync(filePath))
|
|
606
|
+
return [];
|
|
607
|
+
let db = null;
|
|
608
|
+
try {
|
|
609
|
+
const { default: SqliteDatabase } = await import("better-sqlite3");
|
|
610
|
+
db = new SqliteDatabase(filePath, { fileMustExist: true, readonly: true });
|
|
611
|
+
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all();
|
|
612
|
+
const plans = [];
|
|
613
|
+
const stats = await stat4(filePath);
|
|
614
|
+
for (const table of tables) {
|
|
615
|
+
try {
|
|
616
|
+
const rows = db.prepare(`SELECT * FROM ${quoteIdentifier(table.name)} LIMIT 50`).all();
|
|
617
|
+
if (rows.length === 0)
|
|
618
|
+
continue;
|
|
619
|
+
const content = rows.map((row) => {
|
|
620
|
+
return Object.entries(row).map(([k, v]) => `**${k}**: ${String(v)}`).join(`
|
|
621
|
+
`);
|
|
622
|
+
}).join(`
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
`);
|
|
627
|
+
plans.push({
|
|
628
|
+
id: hashPath(`${filePath}:${table.name}`),
|
|
629
|
+
agent: "cursor",
|
|
630
|
+
title: `Cursor: ${table.name}`,
|
|
631
|
+
content,
|
|
632
|
+
filePath,
|
|
633
|
+
format: "sqlite",
|
|
634
|
+
createdAt: stats.birthtime,
|
|
635
|
+
updatedAt: stats.mtime,
|
|
636
|
+
metadata: { table: table.name }
|
|
637
|
+
});
|
|
638
|
+
} catch {}
|
|
639
|
+
}
|
|
640
|
+
return plans;
|
|
641
|
+
} catch {
|
|
642
|
+
return [];
|
|
643
|
+
} finally {
|
|
644
|
+
db?.close();
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
async write() {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
// ../shared/src/adapters/oh-my-opencode.ts
|
|
653
|
+
import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
|
|
654
|
+
import { readdir, readFile as readFile4, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
|
|
655
|
+
import { homedir as homedir5 } from "node:os";
|
|
656
|
+
import { basename as basename3, join as join5 } from "node:path";
|
|
657
|
+
var dataHome = process.env.XDG_DATA_HOME || join5(homedir5(), ".local", "share");
|
|
658
|
+
var opencodeSessionDir = join5(dataHome, "opencode", "storage", "session");
|
|
659
|
+
var cwdPlansDir = join5(process.cwd(), ".sisyphus", "plans");
|
|
660
|
+
var PLAN_PATH_MARKER = "/.sisyphus/plans/";
|
|
661
|
+
function normalizePath(filePath) {
|
|
662
|
+
return filePath.replace(/\\/g, "/");
|
|
663
|
+
}
|
|
664
|
+
function isRecord2(value) {
|
|
665
|
+
return typeof value === "object" && value !== null;
|
|
666
|
+
}
|
|
667
|
+
function isPlanMarkdown(filePath) {
|
|
668
|
+
const normalized = normalizePath(filePath).toLowerCase();
|
|
669
|
+
return normalized.endsWith(".md") && normalized.includes(PLAN_PATH_MARKER);
|
|
670
|
+
}
|
|
671
|
+
function isSessionFile(filePath) {
|
|
672
|
+
const normalized = normalizePath(filePath);
|
|
673
|
+
const root = normalizePath(opencodeSessionDir);
|
|
674
|
+
return normalized.startsWith(`${root}/`) && normalized.endsWith(".json");
|
|
675
|
+
}
|
|
676
|
+
function extractTitle3(content, filePath) {
|
|
677
|
+
const heading = content.match(/^\s{0,3}#{1,6}\s+(.+?)\s*$/m)?.[1];
|
|
678
|
+
if (heading)
|
|
679
|
+
return heading.replace(/^Plan:\s*/i, "").trim();
|
|
680
|
+
return basename3(filePath, ".md").split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
681
|
+
}
|
|
682
|
+
function workspaceFromPlanPath(filePath) {
|
|
683
|
+
const normalized = normalizePath(filePath);
|
|
684
|
+
const lower = normalized.toLowerCase();
|
|
685
|
+
const markerIndex = lower.lastIndexOf(PLAN_PATH_MARKER);
|
|
686
|
+
if (markerIndex <= 0)
|
|
687
|
+
return;
|
|
688
|
+
return normalized.slice(0, markerIndex);
|
|
689
|
+
}
|
|
690
|
+
function parseSessionMeta(raw) {
|
|
691
|
+
try {
|
|
692
|
+
const parsed = JSON.parse(raw);
|
|
693
|
+
if (!isRecord2(parsed))
|
|
694
|
+
return;
|
|
695
|
+
return {
|
|
696
|
+
id: typeof parsed.id === "string" ? parsed.id : undefined,
|
|
697
|
+
parentID: typeof parsed.parentID === "string" ? parsed.parentID : undefined,
|
|
698
|
+
directory: typeof parsed.directory === "string" ? parsed.directory : undefined
|
|
699
|
+
};
|
|
700
|
+
} catch {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
function discoverPlanDirectories() {
|
|
705
|
+
const dirs = new Set([cwdPlansDir]);
|
|
706
|
+
if (!existsSync2(opencodeSessionDir))
|
|
707
|
+
return Array.from(dirs);
|
|
708
|
+
try {
|
|
709
|
+
const projectDirs = readdirSync(opencodeSessionDir, { withFileTypes: true });
|
|
710
|
+
for (const projectDir of projectDirs) {
|
|
711
|
+
if (!projectDir.isDirectory())
|
|
712
|
+
continue;
|
|
713
|
+
const projectPath = join5(opencodeSessionDir, projectDir.name);
|
|
714
|
+
let sessionFiles = [];
|
|
715
|
+
try {
|
|
716
|
+
sessionFiles = readdirSync(projectPath);
|
|
717
|
+
} catch {
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
for (const file of sessionFiles) {
|
|
721
|
+
if (!file.endsWith(".json"))
|
|
722
|
+
continue;
|
|
723
|
+
try {
|
|
724
|
+
const raw = readFileSync(join5(projectPath, file), "utf-8");
|
|
725
|
+
const session = parseSessionMeta(raw);
|
|
726
|
+
if (!session?.directory)
|
|
727
|
+
continue;
|
|
728
|
+
if (session.parentID)
|
|
729
|
+
continue;
|
|
730
|
+
dirs.add(join5(session.directory, ".sisyphus", "plans"));
|
|
731
|
+
} catch {}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
} catch {}
|
|
735
|
+
return Array.from(dirs);
|
|
736
|
+
}
|
|
737
|
+
async function parsePlanFile(filePath, workspace, metadata = {}) {
|
|
738
|
+
try {
|
|
739
|
+
const content = await readFile4(filePath, "utf-8");
|
|
740
|
+
const stats = await stat5(filePath);
|
|
741
|
+
return [
|
|
742
|
+
{
|
|
743
|
+
id: hashPath(filePath),
|
|
744
|
+
agent: "oh-my-opencode",
|
|
745
|
+
title: extractTitle3(content, filePath),
|
|
746
|
+
content,
|
|
747
|
+
filePath,
|
|
748
|
+
format: "md",
|
|
749
|
+
createdAt: stats.birthtime,
|
|
750
|
+
updatedAt: stats.mtime,
|
|
751
|
+
workspace,
|
|
752
|
+
metadata
|
|
753
|
+
}
|
|
754
|
+
];
|
|
755
|
+
} catch {
|
|
756
|
+
return [];
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
async function parseSessionFile(filePath) {
|
|
760
|
+
try {
|
|
761
|
+
const raw = await readFile4(filePath, "utf-8");
|
|
762
|
+
const session = parseSessionMeta(raw);
|
|
763
|
+
if (!session?.directory)
|
|
764
|
+
return [];
|
|
765
|
+
if (session.parentID)
|
|
766
|
+
return [];
|
|
767
|
+
const plansDir2 = join5(session.directory, ".sisyphus", "plans");
|
|
768
|
+
if (!existsSync2(plansDir2))
|
|
769
|
+
return [];
|
|
770
|
+
const entries = await readdir(plansDir2, { withFileTypes: true });
|
|
771
|
+
const plans = [];
|
|
772
|
+
for (const entry of entries) {
|
|
773
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
774
|
+
continue;
|
|
775
|
+
const planPath = join5(plansDir2, entry.name);
|
|
776
|
+
const parsed = await parsePlanFile(planPath, session.directory, {
|
|
777
|
+
source: "session-index",
|
|
778
|
+
sessionId: session.id
|
|
779
|
+
});
|
|
780
|
+
plans.push(...parsed);
|
|
781
|
+
}
|
|
782
|
+
return plans;
|
|
783
|
+
} catch {
|
|
784
|
+
return [];
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
var ohMyOpencodeAdapter = {
|
|
788
|
+
agent: "oh-my-opencode",
|
|
789
|
+
writable: true,
|
|
790
|
+
getSearchPaths() {
|
|
791
|
+
return [opencodeSessionDir, ...discoverPlanDirectories()];
|
|
792
|
+
},
|
|
793
|
+
getWatchPaths() {
|
|
794
|
+
return [opencodeSessionDir, ...discoverPlanDirectories()];
|
|
795
|
+
},
|
|
796
|
+
matches(filePath) {
|
|
797
|
+
return isPlanMarkdown(filePath) || isSessionFile(filePath);
|
|
798
|
+
},
|
|
799
|
+
async parse(filePath) {
|
|
800
|
+
if (isPlanMarkdown(filePath)) {
|
|
801
|
+
return parsePlanFile(filePath, workspaceFromPlanPath(filePath), {
|
|
802
|
+
source: "plan-file"
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
if (isSessionFile(filePath)) {
|
|
806
|
+
return parseSessionFile(filePath);
|
|
807
|
+
}
|
|
808
|
+
return [];
|
|
809
|
+
},
|
|
810
|
+
async write(plan, newContent) {
|
|
811
|
+
try {
|
|
812
|
+
await writeFile2(plan.filePath, newContent, "utf-8");
|
|
813
|
+
return true;
|
|
814
|
+
} catch {
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
// ../shared/src/adapters/stub.ts
|
|
821
|
+
function createStubAdapter(agent, searchPaths, matchExt) {
|
|
822
|
+
return {
|
|
823
|
+
agent,
|
|
824
|
+
writable: false,
|
|
825
|
+
getSearchPaths: () => searchPaths,
|
|
826
|
+
getWatchPaths: () => searchPaths,
|
|
827
|
+
matches: (fp) => fp.endsWith(matchExt),
|
|
828
|
+
parse: async () => [],
|
|
829
|
+
write: async () => false
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
// ../shared/src/adapters/catalog.ts
|
|
834
|
+
var home = homedir6();
|
|
835
|
+
var ADAPTER_AGENT_ALIASES = {
|
|
836
|
+
amp: "amp",
|
|
837
|
+
antigravity: "antigravity",
|
|
838
|
+
augment: "augment",
|
|
839
|
+
"claude-code": "claude-code",
|
|
840
|
+
openclaw: "openclaw",
|
|
841
|
+
cline: "cline",
|
|
842
|
+
codebuddy: "codebuddy",
|
|
843
|
+
codex: "codex-cli",
|
|
844
|
+
"command-code": "command-code",
|
|
845
|
+
continue: "continue-ide",
|
|
846
|
+
crush: "crush",
|
|
847
|
+
cursor: "cursor",
|
|
848
|
+
droid: "droid",
|
|
849
|
+
"gemini-cli": "gemini-cli",
|
|
850
|
+
"github-copilot": "copilot-chat",
|
|
851
|
+
goose: "goose",
|
|
852
|
+
junie: "junie",
|
|
853
|
+
"iflow-cli": "iflow-cli",
|
|
854
|
+
kilo: "kilo-cli",
|
|
855
|
+
"kimi-cli": "kimi-cli",
|
|
856
|
+
"kiro-cli": "kiro-cli",
|
|
857
|
+
kode: "kode",
|
|
858
|
+
mcpjam: "mcpjam",
|
|
859
|
+
"mistral-vibe": "mistral-vibe",
|
|
860
|
+
mux: "mux",
|
|
861
|
+
opencode: "oh-my-opencode",
|
|
862
|
+
openhands: "openhands",
|
|
863
|
+
pi: "pi",
|
|
864
|
+
qoder: "qoder",
|
|
865
|
+
"qwen-code": "qwen-code",
|
|
866
|
+
replit: "replit",
|
|
867
|
+
roo: "roo",
|
|
868
|
+
trae: "trae",
|
|
869
|
+
"trae-cn": "trae-cn",
|
|
870
|
+
windsurf: "windsurf",
|
|
871
|
+
zencoder: "zencoder",
|
|
872
|
+
neovate: "neovate",
|
|
873
|
+
pochi: "pochi",
|
|
874
|
+
adal: "adal",
|
|
875
|
+
aider: "aider"
|
|
876
|
+
};
|
|
877
|
+
var CATALOG = [
|
|
878
|
+
{
|
|
879
|
+
id: "amp",
|
|
880
|
+
displayName: "Amp",
|
|
881
|
+
group: "universal",
|
|
882
|
+
implemented: false,
|
|
883
|
+
defaultEnabled: true,
|
|
884
|
+
createAdapter: () => createStubAdapter("amp", [join6(home, ".amp")], ".json")
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
id: "antigravity",
|
|
888
|
+
displayName: "Antigravity",
|
|
889
|
+
group: "other",
|
|
890
|
+
implemented: false,
|
|
891
|
+
defaultEnabled: false,
|
|
892
|
+
createAdapter: () => createStubAdapter("antigravity", [join6(home, ".gemini", "antigravity")], ".json")
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
id: "augment",
|
|
896
|
+
displayName: "Augment",
|
|
897
|
+
group: "other",
|
|
898
|
+
implemented: false,
|
|
899
|
+
defaultEnabled: false,
|
|
900
|
+
createAdapter: () => createStubAdapter("augment", [join6(home, ".augment")], ".json")
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
id: "claude-code",
|
|
904
|
+
displayName: "Claude Code",
|
|
905
|
+
group: "other",
|
|
906
|
+
implemented: true,
|
|
907
|
+
defaultEnabled: true,
|
|
908
|
+
createAdapter: () => claudeCodeAdapter
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
id: "openclaw",
|
|
912
|
+
displayName: "OpenClaw",
|
|
913
|
+
group: "other",
|
|
914
|
+
implemented: false,
|
|
915
|
+
defaultEnabled: false,
|
|
916
|
+
createAdapter: () => createStubAdapter("openclaw", [join6(home, ".openclaw")], ".md")
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
id: "cline",
|
|
920
|
+
displayName: "Cline",
|
|
921
|
+
group: "other",
|
|
922
|
+
implemented: false,
|
|
923
|
+
defaultEnabled: true,
|
|
924
|
+
createAdapter: () => createStubAdapter("cline", [
|
|
925
|
+
join6(home, "AppData", "Roaming", "Code", "User", "globalStorage", "saoudrizwan.claude-dev"),
|
|
926
|
+
join6(home, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev")
|
|
927
|
+
], ".json")
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
id: "codebuddy",
|
|
931
|
+
displayName: "CodeBuddy",
|
|
932
|
+
group: "other",
|
|
933
|
+
implemented: false,
|
|
934
|
+
defaultEnabled: false,
|
|
935
|
+
createAdapter: () => createStubAdapter("codebuddy", [join6(home, ".codebuddy")], ".md")
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
id: "codex",
|
|
939
|
+
displayName: "Codex",
|
|
940
|
+
group: "universal",
|
|
941
|
+
implemented: true,
|
|
942
|
+
defaultEnabled: true,
|
|
943
|
+
createAdapter: () => codexCliAdapter
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
id: "command-code",
|
|
947
|
+
displayName: "Command Code",
|
|
948
|
+
group: "other",
|
|
949
|
+
implemented: false,
|
|
950
|
+
defaultEnabled: false,
|
|
951
|
+
createAdapter: () => createStubAdapter("command-code", [join6(home, ".commandcode")], ".md")
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
id: "continue",
|
|
955
|
+
displayName: "Continue",
|
|
956
|
+
group: "other",
|
|
957
|
+
implemented: true,
|
|
958
|
+
defaultEnabled: true,
|
|
959
|
+
createAdapter: () => continueIdeAdapter
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
id: "crush",
|
|
963
|
+
displayName: "Crush",
|
|
964
|
+
group: "other",
|
|
965
|
+
implemented: false,
|
|
966
|
+
defaultEnabled: false,
|
|
967
|
+
createAdapter: () => createStubAdapter("crush", [join6(home, ".config", "crush")], ".json")
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
id: "cursor",
|
|
971
|
+
displayName: "Cursor",
|
|
972
|
+
group: "other",
|
|
973
|
+
implemented: true,
|
|
974
|
+
defaultEnabled: true,
|
|
975
|
+
createAdapter: () => cursorAdapter
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
id: "droid",
|
|
979
|
+
displayName: "Droid",
|
|
980
|
+
group: "other",
|
|
981
|
+
implemented: false,
|
|
982
|
+
defaultEnabled: true,
|
|
983
|
+
createAdapter: () => createStubAdapter("droid", [join6(home, ".factory", "droids")], ".md")
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
id: "gemini-cli",
|
|
987
|
+
displayName: "Gemini CLI",
|
|
988
|
+
group: "universal",
|
|
989
|
+
implemented: false,
|
|
990
|
+
defaultEnabled: false,
|
|
991
|
+
createAdapter: () => createStubAdapter("gemini-cli", [join6(home, ".gemini")], ".md")
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
id: "github-copilot",
|
|
995
|
+
displayName: "GitHub Copilot",
|
|
996
|
+
group: "universal",
|
|
997
|
+
implemented: false,
|
|
998
|
+
defaultEnabled: true,
|
|
999
|
+
createAdapter: () => createStubAdapter("copilot-chat", [join6(home, ".vscode", "User", "workspaceStorage")], ".json")
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
id: "goose",
|
|
1003
|
+
displayName: "Goose",
|
|
1004
|
+
group: "other",
|
|
1005
|
+
implemented: false,
|
|
1006
|
+
defaultEnabled: false,
|
|
1007
|
+
createAdapter: () => createStubAdapter("goose", [join6(home, ".config", "goose")], ".json")
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
id: "junie",
|
|
1011
|
+
displayName: "Junie",
|
|
1012
|
+
group: "other",
|
|
1013
|
+
implemented: false,
|
|
1014
|
+
defaultEnabled: false,
|
|
1015
|
+
createAdapter: () => createStubAdapter("junie", [join6(home, ".junie")], ".json")
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
id: "iflow-cli",
|
|
1019
|
+
displayName: "iFlow CLI",
|
|
1020
|
+
group: "other",
|
|
1021
|
+
implemented: false,
|
|
1022
|
+
defaultEnabled: false,
|
|
1023
|
+
createAdapter: () => createStubAdapter("iflow-cli", [join6(home, ".iflow")], ".json")
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
id: "kilo",
|
|
1027
|
+
displayName: "Kilo Code",
|
|
1028
|
+
group: "other",
|
|
1029
|
+
implemented: false,
|
|
1030
|
+
defaultEnabled: true,
|
|
1031
|
+
createAdapter: () => createStubAdapter("kilo-cli", [join6(home, ".kilo")], ".md")
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
id: "kimi-cli",
|
|
1035
|
+
displayName: "Kimi Code CLI",
|
|
1036
|
+
group: "universal",
|
|
1037
|
+
implemented: false,
|
|
1038
|
+
defaultEnabled: false,
|
|
1039
|
+
createAdapter: () => createStubAdapter("kimi-cli", [join6(home, ".kimi")], ".md")
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
id: "kiro-cli",
|
|
1043
|
+
displayName: "Kiro CLI",
|
|
1044
|
+
group: "other",
|
|
1045
|
+
implemented: false,
|
|
1046
|
+
defaultEnabled: false,
|
|
1047
|
+
createAdapter: () => createStubAdapter("kiro-cli", [join6(home, ".kiro")], ".json")
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
id: "kode",
|
|
1051
|
+
displayName: "Kode",
|
|
1052
|
+
group: "other",
|
|
1053
|
+
implemented: false,
|
|
1054
|
+
defaultEnabled: false,
|
|
1055
|
+
createAdapter: () => createStubAdapter("kode", [join6(home, ".kode")], ".json")
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
id: "mcpjam",
|
|
1059
|
+
displayName: "MCPJam",
|
|
1060
|
+
group: "other",
|
|
1061
|
+
implemented: false,
|
|
1062
|
+
defaultEnabled: false,
|
|
1063
|
+
createAdapter: () => createStubAdapter("mcpjam", [join6(home, ".mcpjam")], ".json")
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
id: "mistral-vibe",
|
|
1067
|
+
displayName: "Mistral Vibe",
|
|
1068
|
+
group: "other",
|
|
1069
|
+
implemented: false,
|
|
1070
|
+
defaultEnabled: false,
|
|
1071
|
+
createAdapter: () => createStubAdapter("mistral-vibe", [join6(home, ".vibe")], ".json")
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
id: "mux",
|
|
1075
|
+
displayName: "Mux",
|
|
1076
|
+
group: "other",
|
|
1077
|
+
implemented: false,
|
|
1078
|
+
defaultEnabled: false,
|
|
1079
|
+
createAdapter: () => createStubAdapter("mux", [join6(home, ".mux")], ".json")
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
id: "opencode",
|
|
1083
|
+
displayName: "OpenCode",
|
|
1084
|
+
group: "universal",
|
|
1085
|
+
implemented: true,
|
|
1086
|
+
defaultEnabled: true,
|
|
1087
|
+
createAdapter: () => ohMyOpencodeAdapter
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
id: "openhands",
|
|
1091
|
+
displayName: "OpenHands",
|
|
1092
|
+
group: "other",
|
|
1093
|
+
implemented: false,
|
|
1094
|
+
defaultEnabled: false,
|
|
1095
|
+
createAdapter: () => createStubAdapter("openhands", [join6(home, ".openhands")], ".json")
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
id: "pi",
|
|
1099
|
+
displayName: "Pi",
|
|
1100
|
+
group: "other",
|
|
1101
|
+
implemented: false,
|
|
1102
|
+
defaultEnabled: false,
|
|
1103
|
+
createAdapter: () => createStubAdapter("pi", [join6(home, ".pi", "agent")], ".md")
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
id: "qoder",
|
|
1107
|
+
displayName: "Qoder",
|
|
1108
|
+
group: "other",
|
|
1109
|
+
implemented: false,
|
|
1110
|
+
defaultEnabled: false,
|
|
1111
|
+
createAdapter: () => createStubAdapter("qoder", [join6(home, ".qoder")], ".json")
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
id: "qwen-code",
|
|
1115
|
+
displayName: "Qwen Code",
|
|
1116
|
+
group: "other",
|
|
1117
|
+
implemented: false,
|
|
1118
|
+
defaultEnabled: false,
|
|
1119
|
+
createAdapter: () => createStubAdapter("qwen-code", [join6(home, ".qwen")], ".json")
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
id: "replit",
|
|
1123
|
+
displayName: "Replit",
|
|
1124
|
+
group: "other",
|
|
1125
|
+
implemented: false,
|
|
1126
|
+
defaultEnabled: false,
|
|
1127
|
+
createAdapter: () => createStubAdapter("replit", [join6(home, ".replit")], ".md")
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
id: "roo",
|
|
1131
|
+
displayName: "Roo Code",
|
|
1132
|
+
group: "other",
|
|
1133
|
+
implemented: false,
|
|
1134
|
+
defaultEnabled: false,
|
|
1135
|
+
createAdapter: () => createStubAdapter("roo", [join6(home, ".roo")], ".md")
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
id: "trae",
|
|
1139
|
+
displayName: "Trae",
|
|
1140
|
+
group: "other",
|
|
1141
|
+
implemented: false,
|
|
1142
|
+
defaultEnabled: false,
|
|
1143
|
+
createAdapter: () => createStubAdapter("trae", [join6(home, ".trae")], ".md")
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
id: "trae-cn",
|
|
1147
|
+
displayName: "Trae CN",
|
|
1148
|
+
group: "other",
|
|
1149
|
+
implemented: false,
|
|
1150
|
+
defaultEnabled: false,
|
|
1151
|
+
createAdapter: () => createStubAdapter("trae-cn", [join6(home, ".trae-cn")], ".md")
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
id: "windsurf",
|
|
1155
|
+
displayName: "Windsurf",
|
|
1156
|
+
group: "other",
|
|
1157
|
+
implemented: false,
|
|
1158
|
+
defaultEnabled: true,
|
|
1159
|
+
createAdapter: () => createStubAdapter("windsurf", [join6(home, ".cascade_backups")], ".md")
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
id: "zencoder",
|
|
1163
|
+
displayName: "Zencoder",
|
|
1164
|
+
group: "other",
|
|
1165
|
+
implemented: false,
|
|
1166
|
+
defaultEnabled: false,
|
|
1167
|
+
createAdapter: () => createStubAdapter("zencoder", [join6(home, ".zencoder")], ".json")
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
id: "neovate",
|
|
1171
|
+
displayName: "Neovate",
|
|
1172
|
+
group: "other",
|
|
1173
|
+
implemented: false,
|
|
1174
|
+
defaultEnabled: false,
|
|
1175
|
+
createAdapter: () => createStubAdapter("neovate", [join6(home, ".neovate")], ".json")
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
id: "pochi",
|
|
1179
|
+
displayName: "Pochi",
|
|
1180
|
+
group: "other",
|
|
1181
|
+
implemented: false,
|
|
1182
|
+
defaultEnabled: false,
|
|
1183
|
+
createAdapter: () => createStubAdapter("pochi", [join6(home, ".pochi")], ".json")
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
id: "adal",
|
|
1187
|
+
displayName: "AdaL",
|
|
1188
|
+
group: "other",
|
|
1189
|
+
implemented: false,
|
|
1190
|
+
defaultEnabled: false,
|
|
1191
|
+
createAdapter: () => createStubAdapter("adal", [join6(home, ".adal")], ".json")
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
id: "aider",
|
|
1195
|
+
displayName: "Aider",
|
|
1196
|
+
group: "other",
|
|
1197
|
+
implemented: false,
|
|
1198
|
+
defaultEnabled: true,
|
|
1199
|
+
createAdapter: () => createStubAdapter("aider", [join6(home, ".aider")], ".aider.chat.history.md")
|
|
1200
|
+
}
|
|
1201
|
+
];
|
|
1202
|
+
function getAdapterCatalog() {
|
|
1203
|
+
return CATALOG.map((entry) => ({ ...entry }));
|
|
1204
|
+
}
|
|
1205
|
+
function getCatalogDefaultAdapterIds() {
|
|
1206
|
+
return CATALOG.filter((entry) => entry.defaultEnabled).map((entry) => entry.id);
|
|
1207
|
+
}
|
|
1208
|
+
function isAdapterId(value) {
|
|
1209
|
+
return CATALOG.some((entry) => entry.id === value);
|
|
1210
|
+
}
|
|
1211
|
+
var LEGACY_TO_ADAPTER_ID = new Map(Object.entries(ADAPTER_AGENT_ALIASES).map(([adapterId, agent]) => [
|
|
1212
|
+
agent,
|
|
1213
|
+
adapterId
|
|
1214
|
+
]));
|
|
1215
|
+
function resolveAdapterId(value) {
|
|
1216
|
+
if (isAdapterId(value))
|
|
1217
|
+
return value;
|
|
1218
|
+
return LEGACY_TO_ADAPTER_ID.get(value);
|
|
1219
|
+
}
|
|
1220
|
+
// ../shared/src/adapters/registry.ts
|
|
1221
|
+
var catalog = getAdapterCatalog();
|
|
1222
|
+
var catalogById = new Map(catalog.map((entry) => [entry.id, entry]));
|
|
1223
|
+
function getCatalog() {
|
|
1224
|
+
return catalog.map((entry) => ({ ...entry }));
|
|
1225
|
+
}
|
|
1226
|
+
function getDefaultAdapterIds() {
|
|
1227
|
+
return getCatalogDefaultAdapterIds();
|
|
1228
|
+
}
|
|
1229
|
+
function sanitizeEnabledAdapterIds(ids) {
|
|
1230
|
+
const selected = [];
|
|
1231
|
+
const seen = new Set;
|
|
1232
|
+
for (const id of ids) {
|
|
1233
|
+
const typedId = resolveAdapterId(id);
|
|
1234
|
+
if (!typedId || !catalogById.has(typedId))
|
|
1235
|
+
continue;
|
|
1236
|
+
if (seen.has(typedId))
|
|
1237
|
+
continue;
|
|
1238
|
+
seen.add(typedId);
|
|
1239
|
+
selected.push(typedId);
|
|
1240
|
+
}
|
|
1241
|
+
return selected;
|
|
1242
|
+
}
|
|
1243
|
+
function resolveAdapters(enabledIds) {
|
|
1244
|
+
const selectedIds = sanitizeEnabledAdapterIds(enabledIds);
|
|
1245
|
+
if (selectedIds.length === 0) {
|
|
1246
|
+
const defaults = getDefaultAdapterIds();
|
|
1247
|
+
return defaults.map((id) => {
|
|
1248
|
+
const entry = catalogById.get(id);
|
|
1249
|
+
if (!entry)
|
|
1250
|
+
throw new Error(`Adapter catalog missing entry for ${id}`);
|
|
1251
|
+
return entry.createAdapter();
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
return selectedIds.map((id) => {
|
|
1255
|
+
const entry = catalogById.get(id);
|
|
1256
|
+
if (!entry)
|
|
1257
|
+
throw new Error(`Adapter catalog missing entry for ${id}`);
|
|
1258
|
+
return entry.createAdapter();
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
function setActiveAdapters(adapters) {
|
|
1262
|
+
activeAdapters = [...adapters];
|
|
1263
|
+
}
|
|
1264
|
+
function getActiveAdapters() {
|
|
1265
|
+
return [...activeAdapters];
|
|
1266
|
+
}
|
|
1267
|
+
var activeAdapters = resolveAdapters(getDefaultAdapterIds());
|
|
1268
|
+
// ../shared/src/config.ts
|
|
1269
|
+
import { randomBytes } from "node:crypto";
|
|
1270
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
1271
|
+
import { homedir as homedir7 } from "node:os";
|
|
1272
|
+
import { join as join7 } from "node:path";
|
|
1273
|
+
|
|
1274
|
+
// ../../node_modules/.bun/@clack+core@1.0.1/node_modules/@clack/core/dist/index.mjs
|
|
1275
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1276
|
+
import { stdout as R, stdin as q } from "node:process";
|
|
1277
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
1278
|
+
import ot from "node:readline";
|
|
1279
|
+
function B(t, e, s) {
|
|
1280
|
+
if (!s.some((u) => !u.disabled))
|
|
1281
|
+
return t;
|
|
1282
|
+
const i = t + e, r = Math.max(s.length - 1, 0), n = i < 0 ? r : i > r ? 0 : i;
|
|
1283
|
+
return s[n].disabled ? B(n, e < 0 ? -1 : 1, s) : n;
|
|
1284
|
+
}
|
|
1285
|
+
var at = (t) => t === 161 || t === 164 || t === 167 || t === 168 || t === 170 || t === 173 || t === 174 || t >= 176 && t <= 180 || t >= 182 && t <= 186 || t >= 188 && t <= 191 || t === 198 || t === 208 || t === 215 || t === 216 || t >= 222 && t <= 225 || t === 230 || t >= 232 && t <= 234 || t === 236 || t === 237 || t === 240 || t === 242 || t === 243 || t >= 247 && t <= 250 || t === 252 || t === 254 || t === 257 || t === 273 || t === 275 || t === 283 || t === 294 || t === 295 || t === 299 || t >= 305 && t <= 307 || t === 312 || t >= 319 && t <= 322 || t === 324 || t >= 328 && t <= 331 || t === 333 || t === 338 || t === 339 || t === 358 || t === 359 || t === 363 || t === 462 || t === 464 || t === 466 || t === 468 || t === 470 || t === 472 || t === 474 || t === 476 || t === 593 || t === 609 || t === 708 || t === 711 || t >= 713 && t <= 715 || t === 717 || t === 720 || t >= 728 && t <= 731 || t === 733 || t === 735 || t >= 768 && t <= 879 || t >= 913 && t <= 929 || t >= 931 && t <= 937 || t >= 945 && t <= 961 || t >= 963 && t <= 969 || t === 1025 || t >= 1040 && t <= 1103 || t === 1105 || t === 8208 || t >= 8211 && t <= 8214 || t === 8216 || t === 8217 || t === 8220 || t === 8221 || t >= 8224 && t <= 8226 || t >= 8228 && t <= 8231 || t === 8240 || t === 8242 || t === 8243 || t === 8245 || t === 8251 || t === 8254 || t === 8308 || t === 8319 || t >= 8321 && t <= 8324 || t === 8364 || t === 8451 || t === 8453 || t === 8457 || t === 8467 || t === 8470 || t === 8481 || t === 8482 || t === 8486 || t === 8491 || t === 8531 || t === 8532 || t >= 8539 && t <= 8542 || t >= 8544 && t <= 8555 || t >= 8560 && t <= 8569 || t === 8585 || t >= 8592 && t <= 8601 || t === 8632 || t === 8633 || t === 8658 || t === 8660 || t === 8679 || t === 8704 || t === 8706 || t === 8707 || t === 8711 || t === 8712 || t === 8715 || t === 8719 || t === 8721 || t === 8725 || t === 8730 || t >= 8733 && t <= 8736 || t === 8739 || t === 8741 || t >= 8743 && t <= 8748 || t === 8750 || t >= 8756 && t <= 8759 || t === 8764 || t === 8765 || t === 8776 || t === 8780 || t === 8786 || t === 8800 || t === 8801 || t >= 8804 && t <= 8807 || t === 8810 || t === 8811 || t === 8814 || t === 8815 || t === 8834 || t === 8835 || t === 8838 || t === 8839 || t === 8853 || t === 8857 || t === 8869 || t === 8895 || t === 8978 || t >= 9312 && t <= 9449 || t >= 9451 && t <= 9547 || t >= 9552 && t <= 9587 || t >= 9600 && t <= 9615 || t >= 9618 && t <= 9621 || t === 9632 || t === 9633 || t >= 9635 && t <= 9641 || t === 9650 || t === 9651 || t === 9654 || t === 9655 || t === 9660 || t === 9661 || t === 9664 || t === 9665 || t >= 9670 && t <= 9672 || t === 9675 || t >= 9678 && t <= 9681 || t >= 9698 && t <= 9701 || t === 9711 || t === 9733 || t === 9734 || t === 9737 || t === 9742 || t === 9743 || t === 9756 || t === 9758 || t === 9792 || t === 9794 || t === 9824 || t === 9825 || t >= 9827 && t <= 9829 || t >= 9831 && t <= 9834 || t === 9836 || t === 9837 || t === 9839 || t === 9886 || t === 9887 || t === 9919 || t >= 9926 && t <= 9933 || t >= 9935 && t <= 9939 || t >= 9941 && t <= 9953 || t === 9955 || t === 9960 || t === 9961 || t >= 9963 && t <= 9969 || t === 9972 || t >= 9974 && t <= 9977 || t === 9979 || t === 9980 || t === 9982 || t === 9983 || t === 10045 || t >= 10102 && t <= 10111 || t >= 11094 && t <= 11097 || t >= 12872 && t <= 12879 || t >= 57344 && t <= 63743 || t >= 65024 && t <= 65039 || t === 65533 || t >= 127232 && t <= 127242 || t >= 127248 && t <= 127277 || t >= 127280 && t <= 127337 || t >= 127344 && t <= 127373 || t === 127375 || t === 127376 || t >= 127387 && t <= 127404 || t >= 917760 && t <= 917999 || t >= 983040 && t <= 1048573 || t >= 1048576 && t <= 1114109;
|
|
1286
|
+
var lt = (t) => t === 12288 || t >= 65281 && t <= 65376 || t >= 65504 && t <= 65510;
|
|
1287
|
+
var ht = (t) => t >= 4352 && t <= 4447 || t === 8986 || t === 8987 || t === 9001 || t === 9002 || t >= 9193 && t <= 9196 || t === 9200 || t === 9203 || t === 9725 || t === 9726 || t === 9748 || t === 9749 || t >= 9800 && t <= 9811 || t === 9855 || t === 9875 || t === 9889 || t === 9898 || t === 9899 || t === 9917 || t === 9918 || t === 9924 || t === 9925 || t === 9934 || t === 9940 || t === 9962 || t === 9970 || t === 9971 || t === 9973 || t === 9978 || t === 9981 || t === 9989 || t === 9994 || t === 9995 || t === 10024 || t === 10060 || t === 10062 || t >= 10067 && t <= 10069 || t === 10071 || t >= 10133 && t <= 10135 || t === 10160 || t === 10175 || t === 11035 || t === 11036 || t === 11088 || t === 11093 || t >= 11904 && t <= 11929 || t >= 11931 && t <= 12019 || t >= 12032 && t <= 12245 || t >= 12272 && t <= 12287 || t >= 12289 && t <= 12350 || t >= 12353 && t <= 12438 || t >= 12441 && t <= 12543 || t >= 12549 && t <= 12591 || t >= 12593 && t <= 12686 || t >= 12688 && t <= 12771 || t >= 12783 && t <= 12830 || t >= 12832 && t <= 12871 || t >= 12880 && t <= 19903 || t >= 19968 && t <= 42124 || t >= 42128 && t <= 42182 || t >= 43360 && t <= 43388 || t >= 44032 && t <= 55203 || t >= 63744 && t <= 64255 || t >= 65040 && t <= 65049 || t >= 65072 && t <= 65106 || t >= 65108 && t <= 65126 || t >= 65128 && t <= 65131 || t >= 94176 && t <= 94180 || t === 94192 || t === 94193 || t >= 94208 && t <= 100343 || t >= 100352 && t <= 101589 || t >= 101632 && t <= 101640 || t >= 110576 && t <= 110579 || t >= 110581 && t <= 110587 || t === 110589 || t === 110590 || t >= 110592 && t <= 110882 || t === 110898 || t >= 110928 && t <= 110930 || t === 110933 || t >= 110948 && t <= 110951 || t >= 110960 && t <= 111355 || t === 126980 || t === 127183 || t === 127374 || t >= 127377 && t <= 127386 || t >= 127488 && t <= 127490 || t >= 127504 && t <= 127547 || t >= 127552 && t <= 127560 || t === 127568 || t === 127569 || t >= 127584 && t <= 127589 || t >= 127744 && t <= 127776 || t >= 127789 && t <= 127797 || t >= 127799 && t <= 127868 || t >= 127870 && t <= 127891 || t >= 127904 && t <= 127946 || t >= 127951 && t <= 127955 || t >= 127968 && t <= 127984 || t === 127988 || t >= 127992 && t <= 128062 || t === 128064 || t >= 128066 && t <= 128252 || t >= 128255 && t <= 128317 || t >= 128331 && t <= 128334 || t >= 128336 && t <= 128359 || t === 128378 || t === 128405 || t === 128406 || t === 128420 || t >= 128507 && t <= 128591 || t >= 128640 && t <= 128709 || t === 128716 || t >= 128720 && t <= 128722 || t >= 128725 && t <= 128727 || t >= 128732 && t <= 128735 || t === 128747 || t === 128748 || t >= 128756 && t <= 128764 || t >= 128992 && t <= 129003 || t === 129008 || t >= 129292 && t <= 129338 || t >= 129340 && t <= 129349 || t >= 129351 && t <= 129535 || t >= 129648 && t <= 129660 || t >= 129664 && t <= 129672 || t >= 129680 && t <= 129725 || t >= 129727 && t <= 129733 || t >= 129742 && t <= 129755 || t >= 129760 && t <= 129768 || t >= 129776 && t <= 129784 || t >= 131072 && t <= 196605 || t >= 196608 && t <= 262141;
|
|
1288
|
+
var O = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
1289
|
+
var y = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
1290
|
+
var L = /\t{1,1000}/y;
|
|
1291
|
+
var P = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
1292
|
+
var M = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
1293
|
+
var ct = /\p{M}+/gu;
|
|
1294
|
+
var ft = { limit: 1 / 0, ellipsis: "" };
|
|
1295
|
+
var X = (t, e = {}, s = {}) => {
|
|
1296
|
+
const i = e.limit ?? 1 / 0, r = e.ellipsis ?? "", n = e?.ellipsisWidth ?? (r ? X(r, ft, s).width : 0), u = s.ansiWidth ?? 0, a = s.controlWidth ?? 0, l = s.tabWidth ?? 8, E = s.ambiguousWidth ?? 1, g = s.emojiWidth ?? 2, m = s.fullWidthWidth ?? 2, A = s.regularWidth ?? 1, V = s.wideWidth ?? 2;
|
|
1297
|
+
let h = 0, o = 0, p = t.length, v = 0, F = false, d = p, b = Math.max(0, i - n), C = 0, w = 0, c = 0, f = 0;
|
|
1298
|
+
t:
|
|
1299
|
+
for (;; ) {
|
|
1300
|
+
if (w > C || o >= p && o > h) {
|
|
1301
|
+
const ut = t.slice(C, w) || t.slice(h, o);
|
|
1302
|
+
v = 0;
|
|
1303
|
+
for (const Y of ut.replaceAll(ct, "")) {
|
|
1304
|
+
const $ = Y.codePointAt(0) || 0;
|
|
1305
|
+
if (lt($) ? f = m : ht($) ? f = V : E !== A && at($) ? f = E : f = A, c + f > b && (d = Math.min(d, Math.max(C, h) + v)), c + f > i) {
|
|
1306
|
+
F = true;
|
|
1307
|
+
break t;
|
|
1308
|
+
}
|
|
1309
|
+
v += Y.length, c += f;
|
|
1310
|
+
}
|
|
1311
|
+
C = w = 0;
|
|
1312
|
+
}
|
|
1313
|
+
if (o >= p)
|
|
1314
|
+
break;
|
|
1315
|
+
if (M.lastIndex = o, M.test(t)) {
|
|
1316
|
+
if (v = M.lastIndex - o, f = v * A, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / A))), c + f > i) {
|
|
1317
|
+
F = true;
|
|
1318
|
+
break;
|
|
1319
|
+
}
|
|
1320
|
+
c += f, C = h, w = o, o = h = M.lastIndex;
|
|
1321
|
+
continue;
|
|
1322
|
+
}
|
|
1323
|
+
if (O.lastIndex = o, O.test(t)) {
|
|
1324
|
+
if (c + u > b && (d = Math.min(d, o)), c + u > i) {
|
|
1325
|
+
F = true;
|
|
1326
|
+
break;
|
|
1327
|
+
}
|
|
1328
|
+
c += u, C = h, w = o, o = h = O.lastIndex;
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1331
|
+
if (y.lastIndex = o, y.test(t)) {
|
|
1332
|
+
if (v = y.lastIndex - o, f = v * a, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / a))), c + f > i) {
|
|
1333
|
+
F = true;
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
c += f, C = h, w = o, o = h = y.lastIndex;
|
|
1337
|
+
continue;
|
|
1338
|
+
}
|
|
1339
|
+
if (L.lastIndex = o, L.test(t)) {
|
|
1340
|
+
if (v = L.lastIndex - o, f = v * l, c + f > b && (d = Math.min(d, o + Math.floor((b - c) / l))), c + f > i) {
|
|
1341
|
+
F = true;
|
|
1342
|
+
break;
|
|
1343
|
+
}
|
|
1344
|
+
c += f, C = h, w = o, o = h = L.lastIndex;
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1347
|
+
if (P.lastIndex = o, P.test(t)) {
|
|
1348
|
+
if (c + g > b && (d = Math.min(d, o)), c + g > i) {
|
|
1349
|
+
F = true;
|
|
1350
|
+
break;
|
|
1351
|
+
}
|
|
1352
|
+
c += g, C = h, w = o, o = h = P.lastIndex;
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
o += 1;
|
|
1356
|
+
}
|
|
1357
|
+
return { width: F ? b : c, index: F ? d : p, truncated: F, ellipsed: F && i >= n };
|
|
1358
|
+
};
|
|
1359
|
+
var pt = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
1360
|
+
var S = (t, e = {}) => X(t, pt, e).width;
|
|
1361
|
+
var W = "\x1B";
|
|
1362
|
+
var Z = "";
|
|
1363
|
+
var Ft = 39;
|
|
1364
|
+
var j = "\x07";
|
|
1365
|
+
var Q = "[";
|
|
1366
|
+
var dt = "]";
|
|
1367
|
+
var tt = "m";
|
|
1368
|
+
var U = `${dt}8;;`;
|
|
1369
|
+
var et = new RegExp(`(?:\\${Q}(?<code>\\d+)m|\\${U}(?<uri>.*)${j})`, "y");
|
|
1370
|
+
var mt = (t) => {
|
|
1371
|
+
if (t >= 30 && t <= 37 || t >= 90 && t <= 97)
|
|
1372
|
+
return 39;
|
|
1373
|
+
if (t >= 40 && t <= 47 || t >= 100 && t <= 107)
|
|
1374
|
+
return 49;
|
|
1375
|
+
if (t === 1 || t === 2)
|
|
1376
|
+
return 22;
|
|
1377
|
+
if (t === 3)
|
|
1378
|
+
return 23;
|
|
1379
|
+
if (t === 4)
|
|
1380
|
+
return 24;
|
|
1381
|
+
if (t === 7)
|
|
1382
|
+
return 27;
|
|
1383
|
+
if (t === 8)
|
|
1384
|
+
return 28;
|
|
1385
|
+
if (t === 9)
|
|
1386
|
+
return 29;
|
|
1387
|
+
if (t === 0)
|
|
1388
|
+
return 0;
|
|
1389
|
+
};
|
|
1390
|
+
var st = (t) => `${W}${Q}${t}${tt}`;
|
|
1391
|
+
var it = (t) => `${W}${U}${t}${j}`;
|
|
1392
|
+
var gt = (t) => t.map((e) => S(e));
|
|
1393
|
+
var G = (t, e, s) => {
|
|
1394
|
+
const i = e[Symbol.iterator]();
|
|
1395
|
+
let r = false, n = false, u = t.at(-1), a = u === undefined ? 0 : S(u), l = i.next(), E = i.next(), g = 0;
|
|
1396
|
+
for (;!l.done; ) {
|
|
1397
|
+
const m = l.value, A = S(m);
|
|
1398
|
+
a + A <= s ? t[t.length - 1] += m : (t.push(m), a = 0), (m === W || m === Z) && (r = true, n = e.startsWith(U, g + 1)), r ? n ? m === j && (r = false, n = false) : m === tt && (r = false) : (a += A, a === s && !E.done && (t.push(""), a = 0)), l = E, E = i.next(), g += m.length;
|
|
1399
|
+
}
|
|
1400
|
+
u = t.at(-1), !a && u !== undefined && u.length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
|
1401
|
+
};
|
|
1402
|
+
var vt = (t) => {
|
|
1403
|
+
const e = t.split(" ");
|
|
1404
|
+
let s = e.length;
|
|
1405
|
+
for (;s > 0 && !(S(e[s - 1]) > 0); )
|
|
1406
|
+
s--;
|
|
1407
|
+
return s === e.length ? t : e.slice(0, s).join(" ") + e.slice(s).join("");
|
|
1408
|
+
};
|
|
1409
|
+
var Et = (t, e, s = {}) => {
|
|
1410
|
+
if (s.trim !== false && t.trim() === "")
|
|
1411
|
+
return "";
|
|
1412
|
+
let i = "", r, n;
|
|
1413
|
+
const u = t.split(" "), a = gt(u);
|
|
1414
|
+
let l = [""];
|
|
1415
|
+
for (const [h, o] of u.entries()) {
|
|
1416
|
+
s.trim !== false && (l[l.length - 1] = (l.at(-1) ?? "").trimStart());
|
|
1417
|
+
let p = S(l.at(-1) ?? "");
|
|
1418
|
+
if (h !== 0 && (p >= e && (s.wordWrap === false || s.trim === false) && (l.push(""), p = 0), (p > 0 || s.trim === false) && (l[l.length - 1] += " ", p++)), s.hard && a[h] > e) {
|
|
1419
|
+
const v = e - p, F = 1 + Math.floor((a[h] - v - 1) / e);
|
|
1420
|
+
Math.floor((a[h] - 1) / e) < F && l.push(""), G(l, o, e);
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
if (p + a[h] > e && p > 0 && a[h] > 0) {
|
|
1424
|
+
if (s.wordWrap === false && p < e) {
|
|
1425
|
+
G(l, o, e);
|
|
1426
|
+
continue;
|
|
1427
|
+
}
|
|
1428
|
+
l.push("");
|
|
1429
|
+
}
|
|
1430
|
+
if (p + a[h] > e && s.wordWrap === false) {
|
|
1431
|
+
G(l, o, e);
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
l[l.length - 1] += o;
|
|
1435
|
+
}
|
|
1436
|
+
s.trim !== false && (l = l.map((h) => vt(h)));
|
|
1437
|
+
const E = l.join(`
|
|
1438
|
+
`), g = E[Symbol.iterator]();
|
|
1439
|
+
let m = g.next(), A = g.next(), V = 0;
|
|
1440
|
+
for (;!m.done; ) {
|
|
1441
|
+
const h = m.value, o = A.value;
|
|
1442
|
+
if (i += h, h === W || h === Z) {
|
|
1443
|
+
et.lastIndex = V + 1;
|
|
1444
|
+
const F = et.exec(E)?.groups;
|
|
1445
|
+
if (F?.code !== undefined) {
|
|
1446
|
+
const d = Number.parseFloat(F.code);
|
|
1447
|
+
r = d === Ft ? undefined : d;
|
|
1448
|
+
} else
|
|
1449
|
+
F?.uri !== undefined && (n = F.uri.length === 0 ? undefined : F.uri);
|
|
1450
|
+
}
|
|
1451
|
+
const p = r ? mt(r) : undefined;
|
|
1452
|
+
o === `
|
|
1453
|
+
` ? (n && (i += it("")), r && p && (i += st(p))) : h === `
|
|
1454
|
+
` && (r && p && (i += st(r)), n && (i += it(n))), V += h.length, m = A, A = g.next();
|
|
1455
|
+
}
|
|
1456
|
+
return i;
|
|
1457
|
+
};
|
|
1458
|
+
function K(t, e, s) {
|
|
1459
|
+
return String(t).normalize().replaceAll(`\r
|
|
1460
|
+
`, `
|
|
1461
|
+
`).split(`
|
|
1462
|
+
`).map((i) => Et(i, e, s)).join(`
|
|
1463
|
+
`);
|
|
1464
|
+
}
|
|
1465
|
+
var At = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
1466
|
+
var _ = { actions: new Set(At), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true };
|
|
1467
|
+
function H(t, e) {
|
|
1468
|
+
if (typeof t == "string")
|
|
1469
|
+
return _.aliases.get(t) === e;
|
|
1470
|
+
for (const s of t)
|
|
1471
|
+
if (s !== undefined && H(s, e))
|
|
1472
|
+
return true;
|
|
1473
|
+
return false;
|
|
1474
|
+
}
|
|
1475
|
+
function _t(t, e) {
|
|
1476
|
+
if (t === e)
|
|
1477
|
+
return;
|
|
1478
|
+
const s = t.split(`
|
|
1479
|
+
`), i = e.split(`
|
|
1480
|
+
`), r = Math.max(s.length, i.length), n = [];
|
|
1481
|
+
for (let u = 0;u < r; u++)
|
|
1482
|
+
s[u] !== i[u] && n.push(u);
|
|
1483
|
+
return { lines: n, numLinesBefore: s.length, numLinesAfter: i.length, numLines: r };
|
|
1484
|
+
}
|
|
1485
|
+
var bt = globalThis.process.platform.startsWith("win");
|
|
1486
|
+
var z = Symbol("clack:cancel");
|
|
1487
|
+
function Ct(t) {
|
|
1488
|
+
return t === z;
|
|
1489
|
+
}
|
|
1490
|
+
function T(t, e) {
|
|
1491
|
+
const s = t;
|
|
1492
|
+
s.isTTY && s.setRawMode(e);
|
|
1493
|
+
}
|
|
1494
|
+
var rt = (t) => ("columns" in t) && typeof t.columns == "number" ? t.columns : 80;
|
|
1495
|
+
var nt = (t) => ("rows" in t) && typeof t.rows == "number" ? t.rows : 20;
|
|
1496
|
+
class x {
|
|
1497
|
+
input;
|
|
1498
|
+
output;
|
|
1499
|
+
_abortSignal;
|
|
1500
|
+
rl;
|
|
1501
|
+
opts;
|
|
1502
|
+
_render;
|
|
1503
|
+
_track = false;
|
|
1504
|
+
_prevFrame = "";
|
|
1505
|
+
_subscribers = new Map;
|
|
1506
|
+
_cursor = 0;
|
|
1507
|
+
state = "initial";
|
|
1508
|
+
error = "";
|
|
1509
|
+
value;
|
|
1510
|
+
userInput = "";
|
|
1511
|
+
constructor(e, s = true) {
|
|
1512
|
+
const { input: i = q, output: r = R, render: n, signal: u, ...a } = e;
|
|
1513
|
+
this.opts = a, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = s, this._abortSignal = u, this.input = i, this.output = r;
|
|
1514
|
+
}
|
|
1515
|
+
unsubscribe() {
|
|
1516
|
+
this._subscribers.clear();
|
|
1517
|
+
}
|
|
1518
|
+
setSubscriber(e, s) {
|
|
1519
|
+
const i = this._subscribers.get(e) ?? [];
|
|
1520
|
+
i.push(s), this._subscribers.set(e, i);
|
|
1521
|
+
}
|
|
1522
|
+
on(e, s) {
|
|
1523
|
+
this.setSubscriber(e, { cb: s });
|
|
1524
|
+
}
|
|
1525
|
+
once(e, s) {
|
|
1526
|
+
this.setSubscriber(e, { cb: s, once: true });
|
|
1527
|
+
}
|
|
1528
|
+
emit(e, ...s) {
|
|
1529
|
+
const i = this._subscribers.get(e) ?? [], r = [];
|
|
1530
|
+
for (const n of i)
|
|
1531
|
+
n.cb(...s), n.once && r.push(() => i.splice(i.indexOf(n), 1));
|
|
1532
|
+
for (const n of r)
|
|
1533
|
+
n();
|
|
1534
|
+
}
|
|
1535
|
+
prompt() {
|
|
1536
|
+
return new Promise((e) => {
|
|
1537
|
+
if (this._abortSignal) {
|
|
1538
|
+
if (this._abortSignal.aborted)
|
|
1539
|
+
return this.state = "cancel", this.close(), e(z);
|
|
1540
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
1541
|
+
this.state = "cancel", this.close();
|
|
1542
|
+
}, { once: true });
|
|
1543
|
+
}
|
|
1544
|
+
this.rl = ot.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), T(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
1545
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), T(this.input, false), e(this.value);
|
|
1546
|
+
}), this.once("cancel", () => {
|
|
1547
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), T(this.input, false), e(z);
|
|
1548
|
+
});
|
|
1549
|
+
});
|
|
1550
|
+
}
|
|
1551
|
+
_isActionKey(e, s) {
|
|
1552
|
+
return e === "\t";
|
|
1553
|
+
}
|
|
1554
|
+
_setValue(e) {
|
|
1555
|
+
this.value = e, this.emit("value", this.value);
|
|
1556
|
+
}
|
|
1557
|
+
_setUserInput(e, s) {
|
|
1558
|
+
this.userInput = e ?? "", this.emit("userInput", this.userInput), s && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
1559
|
+
}
|
|
1560
|
+
_clearUserInput() {
|
|
1561
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
1562
|
+
}
|
|
1563
|
+
onKeypress(e, s) {
|
|
1564
|
+
if (this._track && s.name !== "return" && (s.name && this._isActionKey(e, s) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), s?.name && (!this._track && _.aliases.has(s.name) && this.emit("cursor", _.aliases.get(s.name)), _.actions.has(s.name) && this.emit("cursor", s.name)), e && (e.toLowerCase() === "y" || e.toLowerCase() === "n") && this.emit("confirm", e.toLowerCase() === "y"), this.emit("key", e?.toLowerCase(), s), s?.name === "return") {
|
|
1565
|
+
if (this.opts.validate) {
|
|
1566
|
+
const i = this.opts.validate(this.value);
|
|
1567
|
+
i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
|
|
1568
|
+
}
|
|
1569
|
+
this.state !== "error" && (this.state = "submit");
|
|
1570
|
+
}
|
|
1571
|
+
H([e, s?.name, s?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
1572
|
+
}
|
|
1573
|
+
close() {
|
|
1574
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
1575
|
+
`), T(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
1576
|
+
}
|
|
1577
|
+
restoreCursor() {
|
|
1578
|
+
const e = K(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
1579
|
+
`).length - 1;
|
|
1580
|
+
this.output.write(import_sisteransi.cursor.move(-999, e * -1));
|
|
1581
|
+
}
|
|
1582
|
+
render() {
|
|
1583
|
+
const e = K(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
|
|
1584
|
+
if (e !== this._prevFrame) {
|
|
1585
|
+
if (this.state === "initial")
|
|
1586
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
1587
|
+
else {
|
|
1588
|
+
const s = _t(this._prevFrame, e), i = nt(this.output);
|
|
1589
|
+
if (this.restoreCursor(), s) {
|
|
1590
|
+
const r = Math.max(0, s.numLinesAfter - i), n = Math.max(0, s.numLinesBefore - i);
|
|
1591
|
+
let u = s.lines.find((a) => a >= r);
|
|
1592
|
+
if (u === undefined) {
|
|
1593
|
+
this._prevFrame = e;
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
if (s.lines.length === 1) {
|
|
1597
|
+
this.output.write(import_sisteransi.cursor.move(0, u - n)), this.output.write(import_sisteransi.erase.lines(1));
|
|
1598
|
+
const a = e.split(`
|
|
1599
|
+
`);
|
|
1600
|
+
this.output.write(a[u]), this._prevFrame = e, this.output.write(import_sisteransi.cursor.move(0, a.length - u - 1));
|
|
1601
|
+
return;
|
|
1602
|
+
} else if (s.lines.length > 1) {
|
|
1603
|
+
if (r < n)
|
|
1604
|
+
u = r;
|
|
1605
|
+
else {
|
|
1606
|
+
const l = u - n;
|
|
1607
|
+
l > 0 && this.output.write(import_sisteransi.cursor.move(0, l));
|
|
1608
|
+
}
|
|
1609
|
+
this.output.write(import_sisteransi.erase.down());
|
|
1610
|
+
const a = e.split(`
|
|
1611
|
+
`).slice(u);
|
|
1612
|
+
this.output.write(a.join(`
|
|
1613
|
+
`)), this._prevFrame = e;
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
this.output.write(import_sisteransi.erase.down());
|
|
1618
|
+
}
|
|
1619
|
+
this.output.write(e), this.state === "initial" && (this.state = "active"), this._prevFrame = e;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
function wt(t, e) {
|
|
1624
|
+
if (t === undefined || e.length === 0)
|
|
1625
|
+
return 0;
|
|
1626
|
+
const s = e.findIndex((i) => i.value === t);
|
|
1627
|
+
return s !== -1 ? s : 0;
|
|
1628
|
+
}
|
|
1629
|
+
function Dt(t, e) {
|
|
1630
|
+
return (e.label ?? String(e.value)).toLowerCase().includes(t.toLowerCase());
|
|
1631
|
+
}
|
|
1632
|
+
function St(t, e) {
|
|
1633
|
+
if (e)
|
|
1634
|
+
return t ? e : e[0];
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
class Vt extends x {
|
|
1638
|
+
filteredOptions;
|
|
1639
|
+
multiple;
|
|
1640
|
+
isNavigating = false;
|
|
1641
|
+
selectedValues = [];
|
|
1642
|
+
focusedValue;
|
|
1643
|
+
#t = 0;
|
|
1644
|
+
#s = "";
|
|
1645
|
+
#i;
|
|
1646
|
+
#e;
|
|
1647
|
+
get cursor() {
|
|
1648
|
+
return this.#t;
|
|
1649
|
+
}
|
|
1650
|
+
get userInputWithCursor() {
|
|
1651
|
+
if (!this.userInput)
|
|
1652
|
+
return import_picocolors.default.inverse(import_picocolors.default.hidden("_"));
|
|
1653
|
+
if (this._cursor >= this.userInput.length)
|
|
1654
|
+
return `${this.userInput}█`;
|
|
1655
|
+
const e = this.userInput.slice(0, this._cursor), [s, ...i] = this.userInput.slice(this._cursor);
|
|
1656
|
+
return `${e}${import_picocolors.default.inverse(s)}${i.join("")}`;
|
|
1657
|
+
}
|
|
1658
|
+
get options() {
|
|
1659
|
+
return typeof this.#e == "function" ? this.#e() : this.#e;
|
|
1660
|
+
}
|
|
1661
|
+
constructor(e) {
|
|
1662
|
+
super(e), this.#e = e.options;
|
|
1663
|
+
const s = this.options;
|
|
1664
|
+
this.filteredOptions = [...s], this.multiple = e.multiple === true, this.#i = e.filter ?? Dt;
|
|
1665
|
+
let i;
|
|
1666
|
+
if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0].value]), i)
|
|
1667
|
+
for (const r of i) {
|
|
1668
|
+
const n = s.findIndex((u) => u.value === r);
|
|
1669
|
+
n !== -1 && (this.toggleSelected(r), this.#t = n);
|
|
1670
|
+
}
|
|
1671
|
+
this.focusedValue = this.options[this.#t]?.value, this.on("key", (r, n) => this.#r(r, n)), this.on("userInput", (r) => this.#n(r));
|
|
1672
|
+
}
|
|
1673
|
+
_isActionKey(e, s) {
|
|
1674
|
+
return e === "\t" || this.multiple && this.isNavigating && s.name === "space" && e !== undefined && e !== "";
|
|
1675
|
+
}
|
|
1676
|
+
#r(e, s) {
|
|
1677
|
+
const i = s.name === "up", r = s.name === "down", n = s.name === "return";
|
|
1678
|
+
i || r ? (this.#t = B(this.#t, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#t]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = St(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (s.name === "tab" || this.isNavigating && s.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
1679
|
+
}
|
|
1680
|
+
deselectAll() {
|
|
1681
|
+
this.selectedValues = [];
|
|
1682
|
+
}
|
|
1683
|
+
toggleSelected(e) {
|
|
1684
|
+
this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((s) => s !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
|
|
1685
|
+
}
|
|
1686
|
+
#n(e) {
|
|
1687
|
+
if (e !== this.#s) {
|
|
1688
|
+
this.#s = e;
|
|
1689
|
+
const s = this.options;
|
|
1690
|
+
e ? this.filteredOptions = s.filter((n) => this.#i(e, n)) : this.filteredOptions = [...s];
|
|
1691
|
+
const i = wt(this.focusedValue, this.filteredOptions);
|
|
1692
|
+
this.#t = B(i, 0, this.filteredOptions);
|
|
1693
|
+
const r = this.filteredOptions[this.#t];
|
|
1694
|
+
r && !r.disabled ? this.focusedValue = r.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
class yt extends x {
|
|
1699
|
+
options;
|
|
1700
|
+
cursor = 0;
|
|
1701
|
+
#t;
|
|
1702
|
+
getGroupItems(e) {
|
|
1703
|
+
return this.options.filter((s) => s.group === e);
|
|
1704
|
+
}
|
|
1705
|
+
isGroupSelected(e) {
|
|
1706
|
+
const s = this.getGroupItems(e), i = this.value;
|
|
1707
|
+
return i === undefined ? false : s.every((r) => i.includes(r.value));
|
|
1708
|
+
}
|
|
1709
|
+
toggleValue() {
|
|
1710
|
+
const e = this.options[this.cursor];
|
|
1711
|
+
if (this.value === undefined && (this.value = []), e.group === true) {
|
|
1712
|
+
const s = e.value, i = this.getGroupItems(s);
|
|
1713
|
+
this.isGroupSelected(s) ? this.value = this.value.filter((r) => i.findIndex((n) => n.value === r) === -1) : this.value = [...this.value, ...i.map((r) => r.value)], this.value = Array.from(new Set(this.value));
|
|
1714
|
+
} else {
|
|
1715
|
+
const s = this.value.includes(e.value);
|
|
1716
|
+
this.value = s ? this.value.filter((i) => i !== e.value) : [...this.value, e.value];
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
constructor(e) {
|
|
1720
|
+
super(e, false);
|
|
1721
|
+
const { options: s } = e;
|
|
1722
|
+
this.#t = e.selectableGroups !== false, this.options = Object.entries(s).flatMap(([i, r]) => [{ value: i, group: true, label: i }, ...r.map((n) => ({ ...n, group: i }))]), this.value = [...e.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: i }) => i === e.cursorAt), this.#t ? 0 : 1), this.on("cursor", (i) => {
|
|
1723
|
+
switch (i) {
|
|
1724
|
+
case "left":
|
|
1725
|
+
case "up": {
|
|
1726
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1727
|
+
const r = this.options[this.cursor]?.group === true;
|
|
1728
|
+
!this.#t && r && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
1729
|
+
break;
|
|
1730
|
+
}
|
|
1731
|
+
case "down":
|
|
1732
|
+
case "right": {
|
|
1733
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1734
|
+
const r = this.options[this.cursor]?.group === true;
|
|
1735
|
+
!this.#t && r && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
1736
|
+
break;
|
|
1737
|
+
}
|
|
1738
|
+
case "space":
|
|
1739
|
+
this.toggleValue();
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
// ../../node_modules/.bun/@clack+prompts@1.0.1/node_modules/@clack/prompts/dist/index.mjs
|
|
1747
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1748
|
+
import N2 from "node:process";
|
|
1749
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
1750
|
+
function me() {
|
|
1751
|
+
return N2.platform !== "win32" ? N2.env.TERM !== "linux" : !!N2.env.CI || !!N2.env.WT_SESSION || !!N2.env.TERMINUS_SUBLIME || N2.env.ConEmuTask === "{cmd::Cmder}" || N2.env.TERM_PROGRAM === "Terminus-Sublime" || N2.env.TERM_PROGRAM === "vscode" || N2.env.TERM === "xterm-256color" || N2.env.TERM === "alacritty" || N2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
1752
|
+
}
|
|
1753
|
+
var et2 = me();
|
|
1754
|
+
var C = (t, r) => et2 ? t : r;
|
|
1755
|
+
var Rt = C("◆", "*");
|
|
1756
|
+
var dt2 = C("■", "x");
|
|
1757
|
+
var $t2 = C("▲", "x");
|
|
1758
|
+
var V = C("◇", "o");
|
|
1759
|
+
var ht2 = C("┌", "T");
|
|
1760
|
+
var d = C("│", "|");
|
|
1761
|
+
var x2 = C("└", "—");
|
|
1762
|
+
var Ot = C("┐", "T");
|
|
1763
|
+
var Pt = C("┘", "—");
|
|
1764
|
+
var Q2 = C("●", ">");
|
|
1765
|
+
var H2 = C("○", " ");
|
|
1766
|
+
var st2 = C("◻", "[•]");
|
|
1767
|
+
var U2 = C("◼", "[+]");
|
|
1768
|
+
var q2 = C("◻", "[ ]");
|
|
1769
|
+
var Nt = C("▪", "•");
|
|
1770
|
+
var rt2 = C("─", "-");
|
|
1771
|
+
var mt2 = C("╮", "+");
|
|
1772
|
+
var Wt2 = C("├", "+");
|
|
1773
|
+
var pt2 = C("╯", "+");
|
|
1774
|
+
var gt2 = C("╰", "+");
|
|
1775
|
+
var Lt2 = C("╭", "+");
|
|
1776
|
+
var ft2 = C("●", "•");
|
|
1777
|
+
var Ft2 = C("◆", "*");
|
|
1778
|
+
var yt2 = C("▲", "!");
|
|
1779
|
+
var Et2 = C("■", "x");
|
|
1780
|
+
var W2 = (t) => {
|
|
1781
|
+
switch (t) {
|
|
1782
|
+
case "initial":
|
|
1783
|
+
case "active":
|
|
1784
|
+
return import_picocolors2.default.cyan(Rt);
|
|
1785
|
+
case "cancel":
|
|
1786
|
+
return import_picocolors2.default.red(dt2);
|
|
1787
|
+
case "error":
|
|
1788
|
+
return import_picocolors2.default.yellow($t2);
|
|
1789
|
+
case "submit":
|
|
1790
|
+
return import_picocolors2.default.green(V);
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
var pe = (t) => t === 161 || t === 164 || t === 167 || t === 168 || t === 170 || t === 173 || t === 174 || t >= 176 && t <= 180 || t >= 182 && t <= 186 || t >= 188 && t <= 191 || t === 198 || t === 208 || t === 215 || t === 216 || t >= 222 && t <= 225 || t === 230 || t >= 232 && t <= 234 || t === 236 || t === 237 || t === 240 || t === 242 || t === 243 || t >= 247 && t <= 250 || t === 252 || t === 254 || t === 257 || t === 273 || t === 275 || t === 283 || t === 294 || t === 295 || t === 299 || t >= 305 && t <= 307 || t === 312 || t >= 319 && t <= 322 || t === 324 || t >= 328 && t <= 331 || t === 333 || t === 338 || t === 339 || t === 358 || t === 359 || t === 363 || t === 462 || t === 464 || t === 466 || t === 468 || t === 470 || t === 472 || t === 474 || t === 476 || t === 593 || t === 609 || t === 708 || t === 711 || t >= 713 && t <= 715 || t === 717 || t === 720 || t >= 728 && t <= 731 || t === 733 || t === 735 || t >= 768 && t <= 879 || t >= 913 && t <= 929 || t >= 931 && t <= 937 || t >= 945 && t <= 961 || t >= 963 && t <= 969 || t === 1025 || t >= 1040 && t <= 1103 || t === 1105 || t === 8208 || t >= 8211 && t <= 8214 || t === 8216 || t === 8217 || t === 8220 || t === 8221 || t >= 8224 && t <= 8226 || t >= 8228 && t <= 8231 || t === 8240 || t === 8242 || t === 8243 || t === 8245 || t === 8251 || t === 8254 || t === 8308 || t === 8319 || t >= 8321 && t <= 8324 || t === 8364 || t === 8451 || t === 8453 || t === 8457 || t === 8467 || t === 8470 || t === 8481 || t === 8482 || t === 8486 || t === 8491 || t === 8531 || t === 8532 || t >= 8539 && t <= 8542 || t >= 8544 && t <= 8555 || t >= 8560 && t <= 8569 || t === 8585 || t >= 8592 && t <= 8601 || t === 8632 || t === 8633 || t === 8658 || t === 8660 || t === 8679 || t === 8704 || t === 8706 || t === 8707 || t === 8711 || t === 8712 || t === 8715 || t === 8719 || t === 8721 || t === 8725 || t === 8730 || t >= 8733 && t <= 8736 || t === 8739 || t === 8741 || t >= 8743 && t <= 8748 || t === 8750 || t >= 8756 && t <= 8759 || t === 8764 || t === 8765 || t === 8776 || t === 8780 || t === 8786 || t === 8800 || t === 8801 || t >= 8804 && t <= 8807 || t === 8810 || t === 8811 || t === 8814 || t === 8815 || t === 8834 || t === 8835 || t === 8838 || t === 8839 || t === 8853 || t === 8857 || t === 8869 || t === 8895 || t === 8978 || t >= 9312 && t <= 9449 || t >= 9451 && t <= 9547 || t >= 9552 && t <= 9587 || t >= 9600 && t <= 9615 || t >= 9618 && t <= 9621 || t === 9632 || t === 9633 || t >= 9635 && t <= 9641 || t === 9650 || t === 9651 || t === 9654 || t === 9655 || t === 9660 || t === 9661 || t === 9664 || t === 9665 || t >= 9670 && t <= 9672 || t === 9675 || t >= 9678 && t <= 9681 || t >= 9698 && t <= 9701 || t === 9711 || t === 9733 || t === 9734 || t === 9737 || t === 9742 || t === 9743 || t === 9756 || t === 9758 || t === 9792 || t === 9794 || t === 9824 || t === 9825 || t >= 9827 && t <= 9829 || t >= 9831 && t <= 9834 || t === 9836 || t === 9837 || t === 9839 || t === 9886 || t === 9887 || t === 9919 || t >= 9926 && t <= 9933 || t >= 9935 && t <= 9939 || t >= 9941 && t <= 9953 || t === 9955 || t === 9960 || t === 9961 || t >= 9963 && t <= 9969 || t === 9972 || t >= 9974 && t <= 9977 || t === 9979 || t === 9980 || t === 9982 || t === 9983 || t === 10045 || t >= 10102 && t <= 10111 || t >= 11094 && t <= 11097 || t >= 12872 && t <= 12879 || t >= 57344 && t <= 63743 || t >= 65024 && t <= 65039 || t === 65533 || t >= 127232 && t <= 127242 || t >= 127248 && t <= 127277 || t >= 127280 && t <= 127337 || t >= 127344 && t <= 127373 || t === 127375 || t === 127376 || t >= 127387 && t <= 127404 || t >= 917760 && t <= 917999 || t >= 983040 && t <= 1048573 || t >= 1048576 && t <= 1114109;
|
|
1794
|
+
var ge = (t) => t === 12288 || t >= 65281 && t <= 65376 || t >= 65504 && t <= 65510;
|
|
1795
|
+
var fe = (t) => t >= 4352 && t <= 4447 || t === 8986 || t === 8987 || t === 9001 || t === 9002 || t >= 9193 && t <= 9196 || t === 9200 || t === 9203 || t === 9725 || t === 9726 || t === 9748 || t === 9749 || t >= 9800 && t <= 9811 || t === 9855 || t === 9875 || t === 9889 || t === 9898 || t === 9899 || t === 9917 || t === 9918 || t === 9924 || t === 9925 || t === 9934 || t === 9940 || t === 9962 || t === 9970 || t === 9971 || t === 9973 || t === 9978 || t === 9981 || t === 9989 || t === 9994 || t === 9995 || t === 10024 || t === 10060 || t === 10062 || t >= 10067 && t <= 10069 || t === 10071 || t >= 10133 && t <= 10135 || t === 10160 || t === 10175 || t === 11035 || t === 11036 || t === 11088 || t === 11093 || t >= 11904 && t <= 11929 || t >= 11931 && t <= 12019 || t >= 12032 && t <= 12245 || t >= 12272 && t <= 12287 || t >= 12289 && t <= 12350 || t >= 12353 && t <= 12438 || t >= 12441 && t <= 12543 || t >= 12549 && t <= 12591 || t >= 12593 && t <= 12686 || t >= 12688 && t <= 12771 || t >= 12783 && t <= 12830 || t >= 12832 && t <= 12871 || t >= 12880 && t <= 19903 || t >= 19968 && t <= 42124 || t >= 42128 && t <= 42182 || t >= 43360 && t <= 43388 || t >= 44032 && t <= 55203 || t >= 63744 && t <= 64255 || t >= 65040 && t <= 65049 || t >= 65072 && t <= 65106 || t >= 65108 && t <= 65126 || t >= 65128 && t <= 65131 || t >= 94176 && t <= 94180 || t === 94192 || t === 94193 || t >= 94208 && t <= 100343 || t >= 100352 && t <= 101589 || t >= 101632 && t <= 101640 || t >= 110576 && t <= 110579 || t >= 110581 && t <= 110587 || t === 110589 || t === 110590 || t >= 110592 && t <= 110882 || t === 110898 || t >= 110928 && t <= 110930 || t === 110933 || t >= 110948 && t <= 110951 || t >= 110960 && t <= 111355 || t === 126980 || t === 127183 || t === 127374 || t >= 127377 && t <= 127386 || t >= 127488 && t <= 127490 || t >= 127504 && t <= 127547 || t >= 127552 && t <= 127560 || t === 127568 || t === 127569 || t >= 127584 && t <= 127589 || t >= 127744 && t <= 127776 || t >= 127789 && t <= 127797 || t >= 127799 && t <= 127868 || t >= 127870 && t <= 127891 || t >= 127904 && t <= 127946 || t >= 127951 && t <= 127955 || t >= 127968 && t <= 127984 || t === 127988 || t >= 127992 && t <= 128062 || t === 128064 || t >= 128066 && t <= 128252 || t >= 128255 && t <= 128317 || t >= 128331 && t <= 128334 || t >= 128336 && t <= 128359 || t === 128378 || t === 128405 || t === 128406 || t === 128420 || t >= 128507 && t <= 128591 || t >= 128640 && t <= 128709 || t === 128716 || t >= 128720 && t <= 128722 || t >= 128725 && t <= 128727 || t >= 128732 && t <= 128735 || t === 128747 || t === 128748 || t >= 128756 && t <= 128764 || t >= 128992 && t <= 129003 || t === 129008 || t >= 129292 && t <= 129338 || t >= 129340 && t <= 129349 || t >= 129351 && t <= 129535 || t >= 129648 && t <= 129660 || t >= 129664 && t <= 129672 || t >= 129680 && t <= 129725 || t >= 129727 && t <= 129733 || t >= 129742 && t <= 129755 || t >= 129760 && t <= 129768 || t >= 129776 && t <= 129784 || t >= 131072 && t <= 196605 || t >= 196608 && t <= 262141;
|
|
1796
|
+
var At2 = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
1797
|
+
var it2 = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
1798
|
+
var nt2 = /\t{1,1000}/y;
|
|
1799
|
+
var wt2 = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
1800
|
+
var at2 = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
1801
|
+
var Fe = /\p{M}+/gu;
|
|
1802
|
+
var ye = { limit: 1 / 0, ellipsis: "" };
|
|
1803
|
+
var jt = (t, r = {}, s = {}) => {
|
|
1804
|
+
const i = r.limit ?? 1 / 0, a = r.ellipsis ?? "", o = r?.ellipsisWidth ?? (a ? jt(a, ye, s).width : 0), u = s.ansiWidth ?? 0, l = s.controlWidth ?? 0, n = s.tabWidth ?? 8, c = s.ambiguousWidth ?? 1, g = s.emojiWidth ?? 2, F = s.fullWidthWidth ?? 2, p = s.regularWidth ?? 1, E = s.wideWidth ?? 2;
|
|
1805
|
+
let $ = 0, m = 0, h = t.length, y2 = 0, f = false, v = h, S2 = Math.max(0, i - o), I2 = 0, B2 = 0, A = 0, w = 0;
|
|
1806
|
+
t:
|
|
1807
|
+
for (;; ) {
|
|
1808
|
+
if (B2 > I2 || m >= h && m > $) {
|
|
1809
|
+
const _2 = t.slice(I2, B2) || t.slice($, m);
|
|
1810
|
+
y2 = 0;
|
|
1811
|
+
for (const D2 of _2.replaceAll(Fe, "")) {
|
|
1812
|
+
const T2 = D2.codePointAt(0) || 0;
|
|
1813
|
+
if (ge(T2) ? w = F : fe(T2) ? w = E : c !== p && pe(T2) ? w = c : w = p, A + w > S2 && (v = Math.min(v, Math.max(I2, $) + y2)), A + w > i) {
|
|
1814
|
+
f = true;
|
|
1815
|
+
break t;
|
|
1816
|
+
}
|
|
1817
|
+
y2 += D2.length, A += w;
|
|
1818
|
+
}
|
|
1819
|
+
I2 = B2 = 0;
|
|
1820
|
+
}
|
|
1821
|
+
if (m >= h)
|
|
1822
|
+
break;
|
|
1823
|
+
if (at2.lastIndex = m, at2.test(t)) {
|
|
1824
|
+
if (y2 = at2.lastIndex - m, w = y2 * p, A + w > S2 && (v = Math.min(v, m + Math.floor((S2 - A) / p))), A + w > i) {
|
|
1825
|
+
f = true;
|
|
1826
|
+
break;
|
|
1827
|
+
}
|
|
1828
|
+
A += w, I2 = $, B2 = m, m = $ = at2.lastIndex;
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
if (At2.lastIndex = m, At2.test(t)) {
|
|
1832
|
+
if (A + u > S2 && (v = Math.min(v, m)), A + u > i) {
|
|
1833
|
+
f = true;
|
|
1834
|
+
break;
|
|
1835
|
+
}
|
|
1836
|
+
A += u, I2 = $, B2 = m, m = $ = At2.lastIndex;
|
|
1837
|
+
continue;
|
|
1838
|
+
}
|
|
1839
|
+
if (it2.lastIndex = m, it2.test(t)) {
|
|
1840
|
+
if (y2 = it2.lastIndex - m, w = y2 * l, A + w > S2 && (v = Math.min(v, m + Math.floor((S2 - A) / l))), A + w > i) {
|
|
1841
|
+
f = true;
|
|
1842
|
+
break;
|
|
1843
|
+
}
|
|
1844
|
+
A += w, I2 = $, B2 = m, m = $ = it2.lastIndex;
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
if (nt2.lastIndex = m, nt2.test(t)) {
|
|
1848
|
+
if (y2 = nt2.lastIndex - m, w = y2 * n, A + w > S2 && (v = Math.min(v, m + Math.floor((S2 - A) / n))), A + w > i) {
|
|
1849
|
+
f = true;
|
|
1850
|
+
break;
|
|
1851
|
+
}
|
|
1852
|
+
A += w, I2 = $, B2 = m, m = $ = nt2.lastIndex;
|
|
1853
|
+
continue;
|
|
1854
|
+
}
|
|
1855
|
+
if (wt2.lastIndex = m, wt2.test(t)) {
|
|
1856
|
+
if (A + g > S2 && (v = Math.min(v, m)), A + g > i) {
|
|
1857
|
+
f = true;
|
|
1858
|
+
break;
|
|
1859
|
+
}
|
|
1860
|
+
A += g, I2 = $, B2 = m, m = $ = wt2.lastIndex;
|
|
1861
|
+
continue;
|
|
1862
|
+
}
|
|
1863
|
+
m += 1;
|
|
1864
|
+
}
|
|
1865
|
+
return { width: f ? S2 : A, index: f ? v : h, truncated: f, ellipsed: f && i >= o };
|
|
1866
|
+
};
|
|
1867
|
+
var Ee = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
1868
|
+
var M2 = (t, r = {}) => jt(t, Ee, r).width;
|
|
1869
|
+
var ot2 = "\x1B";
|
|
1870
|
+
var Gt = "";
|
|
1871
|
+
var ve = 39;
|
|
1872
|
+
var Ct2 = "\x07";
|
|
1873
|
+
var kt2 = "[";
|
|
1874
|
+
var Ae = "]";
|
|
1875
|
+
var Vt2 = "m";
|
|
1876
|
+
var St2 = `${Ae}8;;`;
|
|
1877
|
+
var Ht = new RegExp(`(?:\\${kt2}(?<code>\\d+)m|\\${St2}(?<uri>.*)${Ct2})`, "y");
|
|
1878
|
+
var we = (t) => {
|
|
1879
|
+
if (t >= 30 && t <= 37 || t >= 90 && t <= 97)
|
|
1880
|
+
return 39;
|
|
1881
|
+
if (t >= 40 && t <= 47 || t >= 100 && t <= 107)
|
|
1882
|
+
return 49;
|
|
1883
|
+
if (t === 1 || t === 2)
|
|
1884
|
+
return 22;
|
|
1885
|
+
if (t === 3)
|
|
1886
|
+
return 23;
|
|
1887
|
+
if (t === 4)
|
|
1888
|
+
return 24;
|
|
1889
|
+
if (t === 7)
|
|
1890
|
+
return 27;
|
|
1891
|
+
if (t === 8)
|
|
1892
|
+
return 28;
|
|
1893
|
+
if (t === 9)
|
|
1894
|
+
return 29;
|
|
1895
|
+
if (t === 0)
|
|
1896
|
+
return 0;
|
|
1897
|
+
};
|
|
1898
|
+
var Ut = (t) => `${ot2}${kt2}${t}${Vt2}`;
|
|
1899
|
+
var Kt = (t) => `${ot2}${St2}${t}${Ct2}`;
|
|
1900
|
+
var Ce = (t) => t.map((r) => M2(r));
|
|
1901
|
+
var It2 = (t, r, s) => {
|
|
1902
|
+
const i = r[Symbol.iterator]();
|
|
1903
|
+
let a = false, o = false, u = t.at(-1), l = u === undefined ? 0 : M2(u), n = i.next(), c = i.next(), g = 0;
|
|
1904
|
+
for (;!n.done; ) {
|
|
1905
|
+
const F = n.value, p = M2(F);
|
|
1906
|
+
l + p <= s ? t[t.length - 1] += F : (t.push(F), l = 0), (F === ot2 || F === Gt) && (a = true, o = r.startsWith(St2, g + 1)), a ? o ? F === Ct2 && (a = false, o = false) : F === Vt2 && (a = false) : (l += p, l === s && !c.done && (t.push(""), l = 0)), n = c, c = i.next(), g += F.length;
|
|
1907
|
+
}
|
|
1908
|
+
u = t.at(-1), !l && u !== undefined && u.length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
|
1909
|
+
};
|
|
1910
|
+
var Se = (t) => {
|
|
1911
|
+
const r = t.split(" ");
|
|
1912
|
+
let s = r.length;
|
|
1913
|
+
for (;s > 0 && !(M2(r[s - 1]) > 0); )
|
|
1914
|
+
s--;
|
|
1915
|
+
return s === r.length ? t : r.slice(0, s).join(" ") + r.slice(s).join("");
|
|
1916
|
+
};
|
|
1917
|
+
var Ie = (t, r, s = {}) => {
|
|
1918
|
+
if (s.trim !== false && t.trim() === "")
|
|
1919
|
+
return "";
|
|
1920
|
+
let i = "", a, o;
|
|
1921
|
+
const u = t.split(" "), l = Ce(u);
|
|
1922
|
+
let n = [""];
|
|
1923
|
+
for (const [$, m] of u.entries()) {
|
|
1924
|
+
s.trim !== false && (n[n.length - 1] = (n.at(-1) ?? "").trimStart());
|
|
1925
|
+
let h = M2(n.at(-1) ?? "");
|
|
1926
|
+
if ($ !== 0 && (h >= r && (s.wordWrap === false || s.trim === false) && (n.push(""), h = 0), (h > 0 || s.trim === false) && (n[n.length - 1] += " ", h++)), s.hard && l[$] > r) {
|
|
1927
|
+
const y2 = r - h, f = 1 + Math.floor((l[$] - y2 - 1) / r);
|
|
1928
|
+
Math.floor((l[$] - 1) / r) < f && n.push(""), It2(n, m, r);
|
|
1929
|
+
continue;
|
|
1930
|
+
}
|
|
1931
|
+
if (h + l[$] > r && h > 0 && l[$] > 0) {
|
|
1932
|
+
if (s.wordWrap === false && h < r) {
|
|
1933
|
+
It2(n, m, r);
|
|
1934
|
+
continue;
|
|
1935
|
+
}
|
|
1936
|
+
n.push("");
|
|
1937
|
+
}
|
|
1938
|
+
if (h + l[$] > r && s.wordWrap === false) {
|
|
1939
|
+
It2(n, m, r);
|
|
1940
|
+
continue;
|
|
1941
|
+
}
|
|
1942
|
+
n[n.length - 1] += m;
|
|
1943
|
+
}
|
|
1944
|
+
s.trim !== false && (n = n.map(($) => Se($)));
|
|
1945
|
+
const c = n.join(`
|
|
1946
|
+
`), g = c[Symbol.iterator]();
|
|
1947
|
+
let F = g.next(), p = g.next(), E = 0;
|
|
1948
|
+
for (;!F.done; ) {
|
|
1949
|
+
const $ = F.value, m = p.value;
|
|
1950
|
+
if (i += $, $ === ot2 || $ === Gt) {
|
|
1951
|
+
Ht.lastIndex = E + 1;
|
|
1952
|
+
const f = Ht.exec(c)?.groups;
|
|
1953
|
+
if (f?.code !== undefined) {
|
|
1954
|
+
const v = Number.parseFloat(f.code);
|
|
1955
|
+
a = v === ve ? undefined : v;
|
|
1956
|
+
} else
|
|
1957
|
+
f?.uri !== undefined && (o = f.uri.length === 0 ? undefined : f.uri);
|
|
1958
|
+
}
|
|
1959
|
+
const h = a ? we(a) : undefined;
|
|
1960
|
+
m === `
|
|
1961
|
+
` ? (o && (i += Kt("")), a && h && (i += Ut(h))) : $ === `
|
|
1962
|
+
` && (a && h && (i += Ut(a)), o && (i += Kt(o))), E += $.length, F = p, p = g.next();
|
|
1963
|
+
}
|
|
1964
|
+
return i;
|
|
1965
|
+
};
|
|
1966
|
+
function J(t, r, s) {
|
|
1967
|
+
return String(t).normalize().replaceAll(`\r
|
|
1968
|
+
`, `
|
|
1969
|
+
`).split(`
|
|
1970
|
+
`).map((i) => Ie(i, r, s)).join(`
|
|
1971
|
+
`);
|
|
1972
|
+
}
|
|
1973
|
+
var be = (t, r, s, i, a) => {
|
|
1974
|
+
let o = r, u = 0;
|
|
1975
|
+
for (let l = s;l < i; l++) {
|
|
1976
|
+
const n = t[l];
|
|
1977
|
+
if (o = o - n.length, u++, o <= a)
|
|
1978
|
+
break;
|
|
1979
|
+
}
|
|
1980
|
+
return { lineCount: o, removals: u };
|
|
1981
|
+
};
|
|
1982
|
+
var X2 = (t) => {
|
|
1983
|
+
const { cursor: r, options: s, style: i } = t, a = t.output ?? process.stdout, o = rt(a), u = t.columnPadding ?? 0, l = t.rowPadding ?? 4, n = o - u, c = nt(a), g = import_picocolors2.default.dim("..."), F = t.maxItems ?? Number.POSITIVE_INFINITY, p = Math.max(c - l, 0), E = Math.max(Math.min(F, p), 5);
|
|
1984
|
+
let $ = 0;
|
|
1985
|
+
r >= E - 3 && ($ = Math.max(Math.min(r - E + 3, s.length - E), 0));
|
|
1986
|
+
let m = E < s.length && $ > 0, h = E < s.length && $ + E < s.length;
|
|
1987
|
+
const y2 = Math.min($ + E, s.length), f = [];
|
|
1988
|
+
let v = 0;
|
|
1989
|
+
m && v++, h && v++;
|
|
1990
|
+
const S2 = $ + (m ? 1 : 0), I2 = y2 - (h ? 1 : 0);
|
|
1991
|
+
for (let A = S2;A < I2; A++) {
|
|
1992
|
+
const w = J(i(s[A], A === r), n, { hard: true, trim: false }).split(`
|
|
1993
|
+
`);
|
|
1994
|
+
f.push(w), v += w.length;
|
|
1995
|
+
}
|
|
1996
|
+
if (v > p) {
|
|
1997
|
+
let A = 0, w = 0, _2 = v;
|
|
1998
|
+
const D2 = r - S2, T2 = (Y, L2) => be(f, _2, Y, L2, p);
|
|
1999
|
+
m ? ({ lineCount: _2, removals: A } = T2(0, D2), _2 > p && ({ lineCount: _2, removals: w } = T2(D2 + 1, f.length))) : ({ lineCount: _2, removals: w } = T2(D2 + 1, f.length), _2 > p && ({ lineCount: _2, removals: A } = T2(0, D2))), A > 0 && (m = true, f.splice(0, A)), w > 0 && (h = true, f.splice(f.length - w, w));
|
|
2000
|
+
}
|
|
2001
|
+
const B2 = [];
|
|
2002
|
+
m && B2.push(g);
|
|
2003
|
+
for (const A of f)
|
|
2004
|
+
for (const w of A)
|
|
2005
|
+
B2.push(w);
|
|
2006
|
+
return h && B2.push(g), B2;
|
|
2007
|
+
};
|
|
2008
|
+
function Jt(t, r) {
|
|
2009
|
+
if (!t)
|
|
2010
|
+
return true;
|
|
2011
|
+
const s = (r.label ?? String(r.value ?? "")).toLowerCase(), i = (r.hint ?? "").toLowerCase(), a = String(r.value).toLowerCase(), o = t.toLowerCase();
|
|
2012
|
+
return s.includes(o) || i.includes(o) || a.includes(o);
|
|
2013
|
+
}
|
|
2014
|
+
var xe = (t) => {
|
|
2015
|
+
const r = (i, a, o, u) => {
|
|
2016
|
+
const l = o.includes(i.value), n = i.label ?? String(i.value ?? ""), c = i.hint && u !== undefined && i.value === u ? import_picocolors2.default.dim(` (${i.hint})`) : "", g = l ? import_picocolors2.default.green(U2) : import_picocolors2.default.dim(q2);
|
|
2017
|
+
return i.disabled ? `${import_picocolors2.default.gray(q2)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.gray(n))}` : a ? `${g} ${n}${c}` : `${g} ${import_picocolors2.default.dim(n)}`;
|
|
2018
|
+
}, s = new Vt({ options: t.options, multiple: true, filter: t.filter ?? ((i, a) => Jt(i, a)), validate: () => {
|
|
2019
|
+
if (t.required && s.selectedValues.length === 0)
|
|
2020
|
+
return "Please select at least one item";
|
|
2021
|
+
}, initialValue: t.initialValues, signal: t.signal, input: t.input, output: t.output, render() {
|
|
2022
|
+
const i = `${import_picocolors2.default.gray(d)}
|
|
2023
|
+
${W2(this.state)} ${t.message}
|
|
2024
|
+
`, a = this.userInput, o = t.placeholder, u = a === "" && o !== undefined, l = this.isNavigating || u ? import_picocolors2.default.dim(u ? o : a) : this.userInputWithCursor, n = this.options, c = this.filteredOptions.length !== n.length ? import_picocolors2.default.dim(` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? "" : "es"})`) : "";
|
|
2025
|
+
switch (this.state) {
|
|
2026
|
+
case "submit":
|
|
2027
|
+
return `${i}${import_picocolors2.default.gray(d)} ${import_picocolors2.default.dim(`${this.selectedValues.length} items selected`)}`;
|
|
2028
|
+
case "cancel":
|
|
2029
|
+
return `${i}${import_picocolors2.default.gray(d)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(a))}`;
|
|
2030
|
+
default: {
|
|
2031
|
+
const g = this.state === "error" ? import_picocolors2.default.yellow : import_picocolors2.default.cyan, F = [`${import_picocolors2.default.dim("↑/↓")} to navigate`, `${import_picocolors2.default.dim(this.isNavigating ? "Space/Tab:" : "Tab:")} select`, `${import_picocolors2.default.dim("Enter:")} confirm`, `${import_picocolors2.default.dim("Type:")} to search`], p = this.filteredOptions.length === 0 && a ? [`${g(d)} ${import_picocolors2.default.yellow("No matches found")}`] : [], E = this.state === "error" ? [`${g(d)} ${import_picocolors2.default.yellow(this.error)}`] : [], $ = [...`${i}${g(d)}`.split(`
|
|
2032
|
+
`), `${g(d)} ${import_picocolors2.default.dim("Search:")} ${l}${c}`, ...p, ...E], m = [`${g(d)} ${F.join(" • ")}`, `${g(x2)}`], h = X2({ cursor: this.cursor, options: this.filteredOptions, style: (y2, f) => r(y2, f, this.selectedValues, this.focusedValue), maxItems: t.maxItems, output: t.output, rowPadding: $.length + m.length });
|
|
2033
|
+
return [...$, ...h.map((y2) => `${g(d)} ${y2}`), ...m].join(`
|
|
2034
|
+
`);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
} });
|
|
2038
|
+
return s.prompt();
|
|
2039
|
+
};
|
|
2040
|
+
var Ne = (t = "", r) => {
|
|
2041
|
+
(r?.output ?? process.stdout).write(`${import_picocolors2.default.gray(x2)} ${import_picocolors2.default.red(t)}
|
|
2042
|
+
|
|
2043
|
+
`);
|
|
2044
|
+
};
|
|
2045
|
+
var Ke = import_picocolors2.default.magenta;
|
|
2046
|
+
var zt = { light: C("─", "-"), heavy: C("━", "="), block: C("█", "#") };
|
|
2047
|
+
var Qt = `${import_picocolors2.default.gray(d)} `;
|
|
2048
|
+
|
|
2049
|
+
// ../shared/src/setup/adapter-selection.ts
|
|
2050
|
+
var MAX_VISIBLE_OPTIONS = 7;
|
|
2051
|
+
function isInteractiveTTY() {
|
|
2052
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2053
|
+
}
|
|
2054
|
+
function canPromptForAdapters() {
|
|
2055
|
+
return isInteractiveTTY();
|
|
2056
|
+
}
|
|
2057
|
+
function getPromptInitialSelection(currentIds) {
|
|
2058
|
+
const current = sanitizeEnabledAdapterIds(currentIds ?? []);
|
|
2059
|
+
if (current.length > 0)
|
|
2060
|
+
return current;
|
|
2061
|
+
return getDefaultAdapterIds();
|
|
2062
|
+
}
|
|
2063
|
+
async function promptForAdapterSelection(options = {}) {
|
|
2064
|
+
if (!isInteractiveTTY()) {
|
|
2065
|
+
throw new Error("Cannot prompt for adapter selection without an interactive TTY.");
|
|
2066
|
+
}
|
|
2067
|
+
const catalog2 = getCatalog();
|
|
2068
|
+
const lockedIds = catalog2.filter((entry) => entry.locked).map((entry) => entry.id);
|
|
2069
|
+
const initialValues = Array.from(new Set([...lockedIds, ...getPromptInitialSelection(options.currentIds)]));
|
|
2070
|
+
const promptOptions = catalog2.sort((a, b) => {
|
|
2071
|
+
if (a.group !== b.group)
|
|
2072
|
+
return a.group === "universal" ? -1 : 1;
|
|
2073
|
+
return a.displayName.localeCompare(b.displayName);
|
|
2074
|
+
}).map((entry) => ({
|
|
2075
|
+
value: entry.id,
|
|
2076
|
+
label: entry.displayName,
|
|
2077
|
+
hint: entry.group === "universal" ? entry.implemented ? "universal" : "universal, stub" : entry.implemented ? "agent adapter" : "agent adapter (stub)",
|
|
2078
|
+
disabled: Boolean(entry.locked)
|
|
2079
|
+
}));
|
|
2080
|
+
const selected = await xe({
|
|
2081
|
+
message: options.configureAdapters ? "Which adapters do you want to enable? (reconfigure)" : "Which adapters do you want to enable?",
|
|
2082
|
+
options: promptOptions,
|
|
2083
|
+
initialValues,
|
|
2084
|
+
required: true,
|
|
2085
|
+
maxItems: MAX_VISIBLE_OPTIONS,
|
|
2086
|
+
placeholder: "Type to filter adapters..."
|
|
2087
|
+
});
|
|
2088
|
+
if (Ct(selected)) {
|
|
2089
|
+
Ne("Adapter selection cancelled.");
|
|
2090
|
+
process.exit(1);
|
|
2091
|
+
}
|
|
2092
|
+
const sanitized = sanitizeEnabledAdapterIds(selected);
|
|
2093
|
+
if (sanitized.length === 0) {
|
|
2094
|
+
Ne("At least one adapter must be selected.");
|
|
2095
|
+
process.exit(1);
|
|
2096
|
+
}
|
|
2097
|
+
return sanitized;
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
// ../shared/src/config.ts
|
|
2101
|
+
var configDir = join7(homedir7(), ".agendex");
|
|
2102
|
+
var configPath = join7(configDir, "config.json");
|
|
2103
|
+
function ensureConfigDir() {
|
|
2104
|
+
if (!existsSync3(configDir))
|
|
2105
|
+
mkdirSync(configDir, { recursive: true });
|
|
2106
|
+
}
|
|
2107
|
+
function readStoredConfig() {
|
|
2108
|
+
if (!existsSync3(configPath))
|
|
2109
|
+
return null;
|
|
2110
|
+
try {
|
|
2111
|
+
const raw = JSON.parse(readFileSync2(configPath, "utf-8"));
|
|
2112
|
+
if (!raw || typeof raw !== "object")
|
|
2113
|
+
return null;
|
|
2114
|
+
return raw;
|
|
2115
|
+
} catch {
|
|
2116
|
+
return null;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
function normalizeAdapterIds(input) {
|
|
2120
|
+
if (!Array.isArray(input))
|
|
2121
|
+
return [];
|
|
2122
|
+
return sanitizeEnabledAdapterIds(input.filter((item) => typeof item === "string"));
|
|
2123
|
+
}
|
|
2124
|
+
function normalizeStoredConfig(raw) {
|
|
2125
|
+
if (!raw)
|
|
2126
|
+
return null;
|
|
2127
|
+
const token = typeof raw.token === "string" && raw.token.trim() ? raw.token : undefined;
|
|
2128
|
+
const cloudToken = typeof raw.cloudToken === "string" && raw.cloudToken.trim() ? raw.cloudToken : undefined;
|
|
2129
|
+
const convexUrl = typeof raw.convexUrl === "string" && raw.convexUrl.trim() ? raw.convexUrl : undefined;
|
|
2130
|
+
return {
|
|
2131
|
+
configVersion: 3,
|
|
2132
|
+
token,
|
|
2133
|
+
cloudToken,
|
|
2134
|
+
convexUrl,
|
|
2135
|
+
enabledAdapters: normalizeAdapterIds(raw.enabledAdapters)
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
function loadConfig() {
|
|
2139
|
+
return normalizeStoredConfig(readStoredConfig());
|
|
2140
|
+
}
|
|
2141
|
+
function saveConfig(config) {
|
|
2142
|
+
ensureConfigDir();
|
|
2143
|
+
const payload = {
|
|
2144
|
+
configVersion: 3,
|
|
2145
|
+
token: config.token,
|
|
2146
|
+
cloudToken: config.cloudToken,
|
|
2147
|
+
convexUrl: config.convexUrl,
|
|
2148
|
+
enabledAdapters: sanitizeEnabledAdapterIds(config.enabledAdapters)
|
|
2149
|
+
};
|
|
2150
|
+
writeFileSync(configPath, JSON.stringify(payload, null, 2));
|
|
2151
|
+
}
|
|
2152
|
+
function generateToken() {
|
|
2153
|
+
return randomBytes(32).toString("hex");
|
|
2154
|
+
}
|
|
2155
|
+
function loadOrCreateToken() {
|
|
2156
|
+
if (process.env.AGENDEX_TOKEN)
|
|
2157
|
+
return process.env.AGENDEX_TOKEN;
|
|
2158
|
+
const existing = loadConfig();
|
|
2159
|
+
if (existing?.token)
|
|
2160
|
+
return existing.token;
|
|
2161
|
+
const token = generateToken();
|
|
2162
|
+
saveConfig({
|
|
2163
|
+
configVersion: 3,
|
|
2164
|
+
token,
|
|
2165
|
+
enabledAdapters: existing?.enabledAdapters ?? []
|
|
2166
|
+
});
|
|
2167
|
+
console.log(`
|
|
2168
|
+
[agendex] generated auth token: ${token}`);
|
|
2169
|
+
console.log(`[agendex] saved to ${configPath}
|
|
2170
|
+
`);
|
|
2171
|
+
return token;
|
|
2172
|
+
}
|
|
2173
|
+
async function loadOrInitConfig(options = {}) {
|
|
2174
|
+
const configureAdapters = Boolean(options.configureAdapters);
|
|
2175
|
+
const existing = loadConfig();
|
|
2176
|
+
const tokenFromEnv = process.env.AGENDEX_TOKEN;
|
|
2177
|
+
const currentToken = tokenFromEnv || existing?.token || loadOrCreateToken();
|
|
2178
|
+
const storedAdapterIds = existing?.enabledAdapters ?? [];
|
|
2179
|
+
const needsSelection = configureAdapters || storedAdapterIds.length === 0;
|
|
2180
|
+
let enabledAdapters = storedAdapterIds;
|
|
2181
|
+
if (needsSelection) {
|
|
2182
|
+
if (canPromptForAdapters()) {
|
|
2183
|
+
enabledAdapters = await promptForAdapterSelection({
|
|
2184
|
+
currentIds: storedAdapterIds,
|
|
2185
|
+
configureAdapters
|
|
2186
|
+
});
|
|
2187
|
+
} else if (configureAdapters) {
|
|
2188
|
+
throw new Error("Cannot run --configure-adapters without an interactive TTY. Run this command in a terminal.");
|
|
2189
|
+
} else {
|
|
2190
|
+
enabledAdapters = getDefaultAdapterIds();
|
|
2191
|
+
console.log(`[agendex] non-interactive environment detected; auto-enabling defaults: ${enabledAdapters.join(", ")}`);
|
|
2192
|
+
}
|
|
2193
|
+
} else {
|
|
2194
|
+
enabledAdapters = sanitizeEnabledAdapterIds(storedAdapterIds);
|
|
2195
|
+
if (enabledAdapters.length === 0)
|
|
2196
|
+
enabledAdapters = getDefaultAdapterIds();
|
|
2197
|
+
}
|
|
2198
|
+
const nextConfig = {
|
|
2199
|
+
configVersion: 3,
|
|
2200
|
+
token: tokenFromEnv ? existing?.token : currentToken,
|
|
2201
|
+
cloudToken: existing?.cloudToken,
|
|
2202
|
+
convexUrl: existing?.convexUrl,
|
|
2203
|
+
enabledAdapters
|
|
2204
|
+
};
|
|
2205
|
+
saveConfig(nextConfig);
|
|
2206
|
+
return {
|
|
2207
|
+
...nextConfig,
|
|
2208
|
+
token: currentToken
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
// ../shared/src/daemon-status.ts
|
|
2212
|
+
var CLI_DAEMON_HEARTBEAT_INTERVAL_MS = 30000;
|
|
2213
|
+
var CLI_DAEMON_STALE_AFTER_MS = CLI_DAEMON_HEARTBEAT_INTERVAL_MS * 3;
|
|
2214
|
+
// ../shared/src/services/plan-service.ts
|
|
2215
|
+
import { existsSync as existsSync4, readdirSync as readdirSync2, statSync } from "node:fs";
|
|
2216
|
+
import { lstat, mkdir, readdir as readdir2, readFile as readFile5, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
|
|
2217
|
+
import { homedir as homedir8 } from "node:os";
|
|
2218
|
+
import { join as join8, resolve as resolve2, sep as sep2 } from "node:path";
|
|
2219
|
+
var USER_PLANS_DIR = join8(homedir8(), ".agendex", "plans");
|
|
2220
|
+
var store = new Map;
|
|
2221
|
+
var MAX_DEPTH = 6;
|
|
2222
|
+
var DISCOVERY_MAX_DEPTH = 4;
|
|
2223
|
+
var PROJECT_PLAN_MARKERS = [{ marker: ".sisyphus/plans", agent: "oh-my-opencode" }];
|
|
2224
|
+
var SKIP_DIRS = new Set([
|
|
2225
|
+
"node_modules",
|
|
2226
|
+
".git",
|
|
2227
|
+
"dist",
|
|
2228
|
+
"build",
|
|
2229
|
+
".cache",
|
|
2230
|
+
"vendor",
|
|
2231
|
+
"venv",
|
|
2232
|
+
"__pycache__",
|
|
2233
|
+
"target",
|
|
2234
|
+
".next",
|
|
2235
|
+
".nuxt",
|
|
2236
|
+
"Library",
|
|
2237
|
+
"Applications",
|
|
2238
|
+
"Music",
|
|
2239
|
+
"Movies",
|
|
2240
|
+
"Pictures",
|
|
2241
|
+
"Public",
|
|
2242
|
+
"AppData",
|
|
2243
|
+
"Application Data",
|
|
2244
|
+
"Program Files",
|
|
2245
|
+
"Program Files (x86)",
|
|
2246
|
+
"Windows",
|
|
2247
|
+
"ProgramData",
|
|
2248
|
+
"snap",
|
|
2249
|
+
"Downloads",
|
|
2250
|
+
"Desktop",
|
|
2251
|
+
"Dropbox",
|
|
2252
|
+
"OneDrive",
|
|
2253
|
+
"Google Drive",
|
|
2254
|
+
"iCloud Drive"
|
|
2255
|
+
]);
|
|
2256
|
+
function discoverProjectPlanDirs() {
|
|
2257
|
+
const home2 = homedir8();
|
|
2258
|
+
const results = [];
|
|
2259
|
+
function walk(dir, depth) {
|
|
2260
|
+
if (depth > DISCOVERY_MAX_DEPTH)
|
|
2261
|
+
return;
|
|
2262
|
+
for (const { marker, agent } of PROJECT_PLAN_MARKERS) {
|
|
2263
|
+
const candidate = join8(dir, marker);
|
|
2264
|
+
if (existsSync4(candidate)) {
|
|
2265
|
+
results.push({ dir: candidate, agent });
|
|
2266
|
+
return;
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
let names;
|
|
2270
|
+
try {
|
|
2271
|
+
names = readdirSync2(dir);
|
|
2272
|
+
} catch {
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
for (const name of names) {
|
|
2276
|
+
if (name.startsWith(".") && name !== ".sisyphus")
|
|
2277
|
+
continue;
|
|
2278
|
+
if (SKIP_DIRS.has(name))
|
|
2279
|
+
continue;
|
|
2280
|
+
const full = join8(dir, name);
|
|
2281
|
+
try {
|
|
2282
|
+
if (statSync(full).isDirectory())
|
|
2283
|
+
walk(full, depth + 1);
|
|
2284
|
+
} catch {}
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
walk(home2, 0);
|
|
2288
|
+
return results;
|
|
2289
|
+
}
|
|
2290
|
+
var onPlansChangedCallback;
|
|
2291
|
+
function setOnPlansChanged(callback) {
|
|
2292
|
+
onPlansChangedCallback = callback;
|
|
2293
|
+
}
|
|
2294
|
+
function notifyPlansChanged() {
|
|
2295
|
+
onPlansChangedCallback?.(Array.from(store.values()));
|
|
2296
|
+
}
|
|
2297
|
+
async function walkDir(dir, depth = 0, seen = new Set) {
|
|
2298
|
+
if (depth > MAX_DEPTH)
|
|
2299
|
+
return [];
|
|
2300
|
+
if (!existsSync4(dir))
|
|
2301
|
+
return [];
|
|
2302
|
+
const real = resolve2(dir);
|
|
2303
|
+
if (seen.has(real))
|
|
2304
|
+
return [];
|
|
2305
|
+
seen.add(real);
|
|
2306
|
+
const files = [];
|
|
2307
|
+
try {
|
|
2308
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
2309
|
+
for (const entry of entries) {
|
|
2310
|
+
const full = join8(dir, entry.name);
|
|
2311
|
+
try {
|
|
2312
|
+
const stats = await lstat(full);
|
|
2313
|
+
if (stats.isSymbolicLink())
|
|
2314
|
+
continue;
|
|
2315
|
+
if (stats.isDirectory()) {
|
|
2316
|
+
files.push(...await walkDir(full, depth + 1, seen));
|
|
2317
|
+
} else {
|
|
2318
|
+
files.push(full);
|
|
2319
|
+
}
|
|
2320
|
+
} catch {}
|
|
2321
|
+
}
|
|
2322
|
+
} catch {}
|
|
2323
|
+
return files;
|
|
2324
|
+
}
|
|
2325
|
+
async function scanUserPlans() {
|
|
2326
|
+
if (!existsSync4(USER_PLANS_DIR))
|
|
2327
|
+
return;
|
|
2328
|
+
const files = await walkDir(USER_PLANS_DIR);
|
|
2329
|
+
for (const file of files) {
|
|
2330
|
+
if (!file.endsWith(".md"))
|
|
2331
|
+
continue;
|
|
2332
|
+
try {
|
|
2333
|
+
const content = await readFile5(file, "utf-8");
|
|
2334
|
+
const stats = await stat6(file);
|
|
2335
|
+
let agent = "unknown";
|
|
2336
|
+
const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
2337
|
+
if (fmMatch) {
|
|
2338
|
+
const agentLine = fmMatch[1]?.match(/^agent:\s*(.+)$/m);
|
|
2339
|
+
if (agentLine?.[1])
|
|
2340
|
+
agent = agentLine[1].trim();
|
|
2341
|
+
}
|
|
2342
|
+
const bodyContent = fmMatch ? content.slice(fmMatch[0].length) : content;
|
|
2343
|
+
const titleMatch = bodyContent.match(/^#\s+(.+)/m);
|
|
2344
|
+
const title = titleMatch?.[1]?.trim() || file.split("/").pop()?.replace(".md", "") || "Untitled";
|
|
2345
|
+
const plan = {
|
|
2346
|
+
id: hashPath(file),
|
|
2347
|
+
agent,
|
|
2348
|
+
title,
|
|
2349
|
+
content: bodyContent,
|
|
2350
|
+
filePath: file,
|
|
2351
|
+
format: "md",
|
|
2352
|
+
createdAt: stats.birthtime,
|
|
2353
|
+
updatedAt: stats.mtime,
|
|
2354
|
+
metadata: { userCreated: true }
|
|
2355
|
+
};
|
|
2356
|
+
store.set(plan.id, plan);
|
|
2357
|
+
} catch {}
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
async function scan() {
|
|
2361
|
+
const adapters = getActiveAdapters();
|
|
2362
|
+
store.clear();
|
|
2363
|
+
const coveredPaths = new Set;
|
|
2364
|
+
for (const adapter of adapters) {
|
|
2365
|
+
for (const searchPath of adapter.getSearchPaths()) {
|
|
2366
|
+
coveredPaths.add(resolve2(searchPath));
|
|
2367
|
+
const files = await walkDir(searchPath);
|
|
2368
|
+
for (const file of files) {
|
|
2369
|
+
if (!adapter.matches(file))
|
|
2370
|
+
continue;
|
|
2371
|
+
const plans = await adapter.parse(file);
|
|
2372
|
+
for (const plan of plans) {
|
|
2373
|
+
store.set(plan.id, plan);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
const discovered = discoverProjectPlanDirs();
|
|
2379
|
+
for (const { dir, agent } of discovered) {
|
|
2380
|
+
if (coveredPaths.has(resolve2(dir)))
|
|
2381
|
+
continue;
|
|
2382
|
+
const adapter = adapters.find((a) => a.agent === agent);
|
|
2383
|
+
if (!adapter)
|
|
2384
|
+
continue;
|
|
2385
|
+
const files = await walkDir(dir);
|
|
2386
|
+
for (const file of files) {
|
|
2387
|
+
if (!adapter.matches(file))
|
|
2388
|
+
continue;
|
|
2389
|
+
const plans = await adapter.parse(file);
|
|
2390
|
+
for (const plan of plans) {
|
|
2391
|
+
store.set(plan.id, plan);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
console.log(`[agendex] discovered project plans: ${dir}`);
|
|
2395
|
+
}
|
|
2396
|
+
await scanUserPlans();
|
|
2397
|
+
notifyPlansChanged();
|
|
2398
|
+
console.log(`[agendex] indexed ${store.size} plans from ${adapters.length} adapters`);
|
|
2399
|
+
}
|
|
2400
|
+
function getAll() {
|
|
2401
|
+
return Array.from(store.values());
|
|
2402
|
+
}
|
|
2403
|
+
async function rescanFile(filePath) {
|
|
2404
|
+
const adapters = getActiveAdapters();
|
|
2405
|
+
const normalized = resolve2(filePath);
|
|
2406
|
+
for (const adapter of adapters) {
|
|
2407
|
+
if (!adapter.matches(filePath))
|
|
2408
|
+
continue;
|
|
2409
|
+
const discoveredDirs = discoverProjectPlanDirs().filter((d2) => d2.agent === adapter.agent).map((d2) => resolve2(d2.dir));
|
|
2410
|
+
const allSearchPaths = [
|
|
2411
|
+
...adapter.getSearchPaths().map((sp) => resolve2(sp)),
|
|
2412
|
+
...discoveredDirs
|
|
2413
|
+
];
|
|
2414
|
+
const isInSearchPath = allSearchPaths.some((sp) => normalized.startsWith(sp + sep2) || normalized === sp);
|
|
2415
|
+
if (!isInSearchPath)
|
|
2416
|
+
continue;
|
|
2417
|
+
const plans = await adapter.parse(filePath);
|
|
2418
|
+
for (const plan of plans) {
|
|
2419
|
+
store.set(plan.id, plan);
|
|
2420
|
+
}
|
|
2421
|
+
notifyPlansChanged();
|
|
2422
|
+
return plans;
|
|
2423
|
+
}
|
|
2424
|
+
return [];
|
|
2425
|
+
}
|
|
2426
|
+
// ../shared/src/services/watcher.ts
|
|
2427
|
+
import { existsSync as existsSync5, watch } from "node:fs";
|
|
2428
|
+
import { join as join9, resolve as resolve3 } from "node:path";
|
|
2429
|
+
var debounceTimer = null;
|
|
2430
|
+
var pendingFiles = new Set;
|
|
2431
|
+
function watchDir(dir, matchFn, onChange) {
|
|
2432
|
+
if (!existsSync5(dir))
|
|
2433
|
+
return;
|
|
2434
|
+
try {
|
|
2435
|
+
watch(dir, { recursive: true }, async (_event, filename) => {
|
|
2436
|
+
if (!filename)
|
|
2437
|
+
return;
|
|
2438
|
+
const fullPath = join9(dir, filename);
|
|
2439
|
+
if (!matchFn(fullPath))
|
|
2440
|
+
return;
|
|
2441
|
+
pendingFiles.add(fullPath);
|
|
2442
|
+
if (debounceTimer)
|
|
2443
|
+
clearTimeout(debounceTimer);
|
|
2444
|
+
debounceTimer = setTimeout(async () => {
|
|
2445
|
+
const files = [...pendingFiles];
|
|
2446
|
+
pendingFiles.clear();
|
|
2447
|
+
let allPlans = [];
|
|
2448
|
+
for (const file of files) {
|
|
2449
|
+
const plans = await rescanFile(file);
|
|
2450
|
+
allPlans = allPlans.concat(plans);
|
|
2451
|
+
}
|
|
2452
|
+
onChange?.(allPlans);
|
|
2453
|
+
}, 300);
|
|
2454
|
+
});
|
|
2455
|
+
console.log(`[agendex] watching ${dir}`);
|
|
2456
|
+
} catch {}
|
|
2457
|
+
}
|
|
2458
|
+
function startWatching(onChange) {
|
|
2459
|
+
const adapters = getActiveAdapters();
|
|
2460
|
+
const watchedPaths = new Set;
|
|
2461
|
+
for (const adapter of adapters) {
|
|
2462
|
+
for (const watchPath of adapter.getWatchPaths()) {
|
|
2463
|
+
watchedPaths.add(resolve3(watchPath));
|
|
2464
|
+
watchDir(watchPath, (f) => adapter.matches(f), onChange);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
const discovered = discoverProjectPlanDirs();
|
|
2468
|
+
for (const { dir, agent } of discovered) {
|
|
2469
|
+
if (watchedPaths.has(resolve3(dir)))
|
|
2470
|
+
continue;
|
|
2471
|
+
const adapter = adapters.find((a) => a.agent === agent);
|
|
2472
|
+
if (!adapter)
|
|
2473
|
+
continue;
|
|
2474
|
+
watchDir(dir, (f) => adapter.matches(f), onChange);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
// src/auth.ts
|
|
2478
|
+
import { spawn } from "node:child_process";
|
|
2479
|
+
import { createServer } from "node:http";
|
|
2480
|
+
var DEFAULT_SITE_URL = "https://agendex.dev";
|
|
2481
|
+
async function login(siteUrlOverride) {
|
|
2482
|
+
const { port, result } = await startCallbackServer();
|
|
2483
|
+
const callbackUrl = `http://127.0.0.1:${port}/callback`;
|
|
2484
|
+
const siteUrl = siteUrlOverride ?? DEFAULT_SITE_URL;
|
|
2485
|
+
const authUrl = `${siteUrl}/auth/cli?callback=${encodeURIComponent(callbackUrl)}`;
|
|
2486
|
+
console.log(`[agendex] Opening browser for authentication...`);
|
|
2487
|
+
console.log(`[agendex] If it doesn't open, visit: ${authUrl}`);
|
|
2488
|
+
if (process.env.AGENDEX_DISABLE_BROWSER === "1") {
|
|
2489
|
+
console.log("[agendex] Browser launch disabled by AGENDEX_DISABLE_BROWSER=1.");
|
|
2490
|
+
} else {
|
|
2491
|
+
openBrowser(authUrl);
|
|
2492
|
+
}
|
|
2493
|
+
const callback = await result;
|
|
2494
|
+
const existing = loadConfig();
|
|
2495
|
+
const config = {
|
|
2496
|
+
configVersion: 3,
|
|
2497
|
+
token: existing?.token,
|
|
2498
|
+
cloudToken: callback.token,
|
|
2499
|
+
convexUrl: callback.convexUrl,
|
|
2500
|
+
enabledAdapters: existing?.enabledAdapters ?? []
|
|
2501
|
+
};
|
|
2502
|
+
saveConfig(config);
|
|
2503
|
+
console.log(`[agendex] Logged in successfully!`);
|
|
2504
|
+
console.log(`[agendex] Cloud token saved to config.`);
|
|
2505
|
+
}
|
|
2506
|
+
function logout() {
|
|
2507
|
+
const existing = loadConfig();
|
|
2508
|
+
if (!existing) {
|
|
2509
|
+
console.log("[agendex] Not logged in.");
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
const config = {
|
|
2513
|
+
configVersion: 3,
|
|
2514
|
+
token: existing.token,
|
|
2515
|
+
cloudToken: undefined,
|
|
2516
|
+
convexUrl: undefined,
|
|
2517
|
+
enabledAdapters: existing.enabledAdapters
|
|
2518
|
+
};
|
|
2519
|
+
saveConfig(config);
|
|
2520
|
+
console.log("[agendex] Logged out. Cloud token removed.");
|
|
2521
|
+
}
|
|
2522
|
+
async function startCallbackServer() {
|
|
2523
|
+
const server = createServer();
|
|
2524
|
+
const sockets = new Set;
|
|
2525
|
+
let timeout;
|
|
2526
|
+
let settle;
|
|
2527
|
+
let fail;
|
|
2528
|
+
const result = new Promise((resolve4, reject) => {
|
|
2529
|
+
settle = resolve4;
|
|
2530
|
+
fail = reject;
|
|
2531
|
+
});
|
|
2532
|
+
const finish = (value) => {
|
|
2533
|
+
if (!settle || !fail)
|
|
2534
|
+
return;
|
|
2535
|
+
const resolve4 = settle;
|
|
2536
|
+
const reject = fail;
|
|
2537
|
+
settle = undefined;
|
|
2538
|
+
fail = undefined;
|
|
2539
|
+
if (timeout)
|
|
2540
|
+
clearTimeout(timeout);
|
|
2541
|
+
server.closeIdleConnections?.();
|
|
2542
|
+
server.closeAllConnections?.();
|
|
2543
|
+
for (const socket of sockets) {
|
|
2544
|
+
socket.destroy();
|
|
2545
|
+
}
|
|
2546
|
+
server.unref();
|
|
2547
|
+
server.close();
|
|
2548
|
+
if (value instanceof Error) {
|
|
2549
|
+
reject(value);
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2552
|
+
resolve4(value);
|
|
2553
|
+
};
|
|
2554
|
+
server.on("request", (req, res) => {
|
|
2555
|
+
const requestUrl = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
2556
|
+
if (requestUrl.pathname !== "/callback") {
|
|
2557
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
2558
|
+
res.end("Not found");
|
|
2559
|
+
return;
|
|
2560
|
+
}
|
|
2561
|
+
const token = requestUrl.searchParams.get("token");
|
|
2562
|
+
const convexUrl = requestUrl.searchParams.get("convexUrl");
|
|
2563
|
+
const success = Boolean(token && convexUrl);
|
|
2564
|
+
res.writeHead(success ? 200 : 400, {
|
|
2565
|
+
Connection: "close",
|
|
2566
|
+
"Content-Type": "text/html; charset=utf-8"
|
|
2567
|
+
});
|
|
2568
|
+
res.end(callbackPage(success));
|
|
2569
|
+
const callbackValue = success ? {
|
|
2570
|
+
token: token ?? "",
|
|
2571
|
+
convexUrl: convexUrl ?? ""
|
|
2572
|
+
} : new Error("Missing token or convexUrl in callback");
|
|
2573
|
+
res.once("finish", () => {
|
|
2574
|
+
finish(callbackValue);
|
|
2575
|
+
});
|
|
2576
|
+
res.once("close", () => {
|
|
2577
|
+
finish(callbackValue);
|
|
2578
|
+
});
|
|
2579
|
+
});
|
|
2580
|
+
server.on("connection", (socket) => {
|
|
2581
|
+
sockets.add(socket);
|
|
2582
|
+
socket.on("close", () => {
|
|
2583
|
+
sockets.delete(socket);
|
|
2584
|
+
});
|
|
2585
|
+
});
|
|
2586
|
+
await new Promise((resolve4, reject) => {
|
|
2587
|
+
server.listen(0, "127.0.0.1", () => resolve4());
|
|
2588
|
+
server.once("error", reject);
|
|
2589
|
+
});
|
|
2590
|
+
server.once("error", (error) => {
|
|
2591
|
+
finish(error instanceof Error ? error : new Error(String(error)));
|
|
2592
|
+
});
|
|
2593
|
+
timeout = setTimeout(() => {
|
|
2594
|
+
finish(new Error("Login timed out after 5 minutes"));
|
|
2595
|
+
}, 5 * 60 * 1000);
|
|
2596
|
+
const address = server.address();
|
|
2597
|
+
if (!address || typeof address === "string") {
|
|
2598
|
+
server.close();
|
|
2599
|
+
throw new Error("Unable to determine local callback port");
|
|
2600
|
+
}
|
|
2601
|
+
return {
|
|
2602
|
+
port: address.port,
|
|
2603
|
+
result
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
function callbackPage(success) {
|
|
2607
|
+
const title = success ? "Login successful" : "Login failed";
|
|
2608
|
+
const message = success ? "You can close this tab and return to your terminal." : "Missing token. Please try again.";
|
|
2609
|
+
const icon = success ? '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" style="width:32px;height:32px;color:#22c55e"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>' : '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" style="width:32px;height:32px;color:#ef4444"><path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>';
|
|
2610
|
+
return `<!DOCTYPE html>
|
|
2611
|
+
<html lang="en">
|
|
2612
|
+
<head>
|
|
2613
|
+
<meta charset="utf-8"/>
|
|
2614
|
+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
2615
|
+
<title>${title} — Agendex</title>
|
|
2616
|
+
<style>
|
|
2617
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
2618
|
+
@media(prefers-color-scheme:dark){
|
|
2619
|
+
:root{--bg:#111;--surface:#161616;--text:#e8e8e8;--secondary:#888;--tertiary:#555;--border:rgba(255,255,255,0.06)}
|
|
2620
|
+
}
|
|
2621
|
+
@media(prefers-color-scheme:light){
|
|
2622
|
+
:root{--bg:#fafafa;--surface:#fff;--text:#111;--secondary:#666;--tertiary:#999;--border:rgba(0,0,0,0.06)}
|
|
2623
|
+
}
|
|
2624
|
+
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--bg);color:var(--text);display:flex;align-items:center;justify-content:center;min-height:100vh;-webkit-font-smoothing:antialiased}
|
|
2625
|
+
.card{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:40px 48px;text-align:center;max-width:400px;width:100%;box-shadow:0 2px 16px rgba(0,0,0,0.04)}
|
|
2626
|
+
.icon{margin-bottom:16px;display:flex;justify-content:center}
|
|
2627
|
+
h1{font-size:18px;font-weight:600;letter-spacing:-0.02em;margin-bottom:8px}
|
|
2628
|
+
p{font-size:13px;color:var(--secondary);line-height:1.5}
|
|
2629
|
+
.brand{margin-top:24px;font-size:11px;color:var(--tertiary);letter-spacing:0.04em;font-weight:500}
|
|
2630
|
+
</style>
|
|
2631
|
+
</head>
|
|
2632
|
+
<body>
|
|
2633
|
+
<div class="card">
|
|
2634
|
+
<div class="icon">${icon}</div>
|
|
2635
|
+
<h1>${title}</h1>
|
|
2636
|
+
<p>${message}</p>
|
|
2637
|
+
<div class="brand">AGENDEX</div>
|
|
2638
|
+
</div>
|
|
2639
|
+
</body>
|
|
2640
|
+
</html>`;
|
|
2641
|
+
}
|
|
2642
|
+
function openBrowser(url) {
|
|
2643
|
+
if (process.platform === "darwin") {
|
|
2644
|
+
spawnBrowser("open", [url]);
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
if (process.platform === "win32") {
|
|
2648
|
+
spawnBrowser("cmd", ["/c", "start", "", url], {
|
|
2649
|
+
windowsHide: true
|
|
2650
|
+
});
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
spawnBrowser("xdg-open", [url]);
|
|
2654
|
+
}
|
|
2655
|
+
function spawnBrowser(command, args, options = {}) {
|
|
2656
|
+
const child = spawn(command, args, {
|
|
2657
|
+
detached: true,
|
|
2658
|
+
stdio: "ignore",
|
|
2659
|
+
...options
|
|
2660
|
+
});
|
|
2661
|
+
child.on("error", () => {});
|
|
2662
|
+
child.unref();
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
// src/daemon.ts
|
|
2666
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
2667
|
+
import { resolve as resolve4 } from "node:path";
|
|
2668
|
+
import { fileURLToPath } from "node:url";
|
|
2669
|
+
|
|
2670
|
+
// src/api.ts
|
|
2671
|
+
import { request as httpRequest } from "node:http";
|
|
2672
|
+
import { request as httpsRequest } from "node:https";
|
|
2673
|
+
function getCloudConfig() {
|
|
2674
|
+
const config = loadConfig();
|
|
2675
|
+
if (!config?.cloudToken)
|
|
2676
|
+
throw new Error("Not logged in. Run `agendex login` first.");
|
|
2677
|
+
if (!config.convexUrl)
|
|
2678
|
+
throw new Error("No Convex URL configured. Run `agendex login` first.");
|
|
2679
|
+
return { token: config.cloudToken, convexUrl: config.convexUrl };
|
|
2680
|
+
}
|
|
2681
|
+
async function syncPlan(plan) {
|
|
2682
|
+
const { token, convexUrl } = getCloudConfig();
|
|
2683
|
+
const url = `${convexUrl}/api/cli/sync`;
|
|
2684
|
+
const res = await requestText(url, {
|
|
2685
|
+
method: "POST",
|
|
2686
|
+
headers: {
|
|
2687
|
+
Authorization: `Bearer ${token}`,
|
|
2688
|
+
Connection: "close",
|
|
2689
|
+
"Content-Type": "application/json"
|
|
2690
|
+
},
|
|
2691
|
+
body: JSON.stringify(plan)
|
|
2692
|
+
});
|
|
2693
|
+
if (res.status < 200 || res.status >= 300) {
|
|
2694
|
+
return { ok: false, error: `${res.status}: ${res.body}` };
|
|
2695
|
+
}
|
|
2696
|
+
return { ok: true };
|
|
2697
|
+
}
|
|
2698
|
+
async function refreshStoredToken(currentToken, convexUrl) {
|
|
2699
|
+
const refreshed = await refreshToken(currentToken, convexUrl);
|
|
2700
|
+
if (!refreshed)
|
|
2701
|
+
return null;
|
|
2702
|
+
const config = loadConfig();
|
|
2703
|
+
if (config) {
|
|
2704
|
+
saveConfig({ ...config, cloudToken: refreshed.token });
|
|
2705
|
+
}
|
|
2706
|
+
return refreshed.token;
|
|
2707
|
+
}
|
|
2708
|
+
async function sendHeartbeat() {
|
|
2709
|
+
try {
|
|
2710
|
+
const { token, convexUrl } = getCloudConfig();
|
|
2711
|
+
let activeToken = token;
|
|
2712
|
+
let res = await requestText(`${convexUrl}/api/cli/heartbeat`, {
|
|
2713
|
+
method: "POST",
|
|
2714
|
+
headers: {
|
|
2715
|
+
Authorization: `Bearer ${activeToken}`,
|
|
2716
|
+
Connection: "close",
|
|
2717
|
+
"Content-Type": "application/json"
|
|
2718
|
+
}
|
|
2719
|
+
});
|
|
2720
|
+
if (res.status === 401) {
|
|
2721
|
+
const refreshedToken = await refreshStoredToken(activeToken, convexUrl);
|
|
2722
|
+
if (!refreshedToken)
|
|
2723
|
+
return;
|
|
2724
|
+
activeToken = refreshedToken;
|
|
2725
|
+
res = await requestText(`${convexUrl}/api/cli/heartbeat`, {
|
|
2726
|
+
method: "POST",
|
|
2727
|
+
headers: {
|
|
2728
|
+
Authorization: `Bearer ${activeToken}`,
|
|
2729
|
+
Connection: "close",
|
|
2730
|
+
"Content-Type": "application/json"
|
|
2731
|
+
}
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
if (res.status === 401) {
|
|
2735
|
+
return;
|
|
2736
|
+
}
|
|
2737
|
+
} catch {}
|
|
2738
|
+
}
|
|
2739
|
+
async function refreshToken(currentToken, convexUrl) {
|
|
2740
|
+
const res = await requestText(`${convexUrl}/api/cli/refresh`, {
|
|
2741
|
+
method: "POST",
|
|
2742
|
+
headers: {
|
|
2743
|
+
Authorization: `Bearer ${currentToken}`,
|
|
2744
|
+
Connection: "close",
|
|
2745
|
+
"Content-Type": "application/json"
|
|
2746
|
+
}
|
|
2747
|
+
});
|
|
2748
|
+
if (res.status < 200 || res.status >= 300)
|
|
2749
|
+
return null;
|
|
2750
|
+
const body = JSON.parse(res.body);
|
|
2751
|
+
if (!body.token)
|
|
2752
|
+
return null;
|
|
2753
|
+
return { token: body.token, expiresAt: body.expiresAt ?? 0 };
|
|
2754
|
+
}
|
|
2755
|
+
function requestText(urlString, options) {
|
|
2756
|
+
const url = new URL(urlString);
|
|
2757
|
+
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
2758
|
+
return new Promise((resolve4, reject) => {
|
|
2759
|
+
const req = request(url, {
|
|
2760
|
+
agent: false,
|
|
2761
|
+
headers: options.headers,
|
|
2762
|
+
method: options.method
|
|
2763
|
+
}, (res) => {
|
|
2764
|
+
let body = "";
|
|
2765
|
+
res.setEncoding("utf8");
|
|
2766
|
+
res.on("data", (chunk) => {
|
|
2767
|
+
body += chunk;
|
|
2768
|
+
});
|
|
2769
|
+
res.on("end", () => {
|
|
2770
|
+
resolve4({
|
|
2771
|
+
status: res.statusCode ?? 0,
|
|
2772
|
+
body
|
|
2773
|
+
});
|
|
2774
|
+
});
|
|
2775
|
+
res.on("error", reject);
|
|
2776
|
+
});
|
|
2777
|
+
req.on("error", reject);
|
|
2778
|
+
if (options.body) {
|
|
2779
|
+
req.write(options.body);
|
|
2780
|
+
}
|
|
2781
|
+
req.end();
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
// src/pid.ts
|
|
2786
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2787
|
+
import { homedir as homedir9 } from "node:os";
|
|
2788
|
+
import { dirname, join as join10 } from "node:path";
|
|
2789
|
+
var pidPath = join10(homedir9(), ".agendex", "daemon.pid");
|
|
2790
|
+
function writePid() {
|
|
2791
|
+
mkdirSync2(dirname(pidPath), { recursive: true });
|
|
2792
|
+
writeFileSync2(pidPath, String(process.pid));
|
|
2793
|
+
}
|
|
2794
|
+
function readPid() {
|
|
2795
|
+
if (!existsSync6(pidPath))
|
|
2796
|
+
return null;
|
|
2797
|
+
const raw = readFileSync3(pidPath, "utf-8").trim();
|
|
2798
|
+
const pid = Number(raw);
|
|
2799
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
2800
|
+
}
|
|
2801
|
+
function removePid() {
|
|
2802
|
+
try {
|
|
2803
|
+
unlinkSync(pidPath);
|
|
2804
|
+
} catch {}
|
|
2805
|
+
}
|
|
2806
|
+
function isRunning(pid) {
|
|
2807
|
+
try {
|
|
2808
|
+
process.kill(pid, 0);
|
|
2809
|
+
return true;
|
|
2810
|
+
} catch {
|
|
2811
|
+
return false;
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// src/daemon.ts
|
|
2816
|
+
var MAX_RESTARTS = 5;
|
|
2817
|
+
var RESTART_WINDOW_MS = 60000;
|
|
2818
|
+
var RESTART_DELAY_MS = 5000;
|
|
2819
|
+
function planToPayload(plan) {
|
|
2820
|
+
return {
|
|
2821
|
+
localPlanId: plan.id,
|
|
2822
|
+
agent: plan.agent,
|
|
2823
|
+
title: plan.title,
|
|
2824
|
+
content: plan.content,
|
|
2825
|
+
format: plan.format,
|
|
2826
|
+
filePath: plan.filePath,
|
|
2827
|
+
workspace: plan.workspace,
|
|
2828
|
+
metadata: plan.metadata,
|
|
2829
|
+
createdAt: plan.createdAt.getTime(),
|
|
2830
|
+
updatedAt: plan.updatedAt.getTime()
|
|
2831
|
+
};
|
|
2832
|
+
}
|
|
2833
|
+
async function runWorker() {
|
|
2834
|
+
const config = await loadOrInitConfig();
|
|
2835
|
+
const adapters = resolveAdapters(config.enabledAdapters);
|
|
2836
|
+
setActiveAdapters(adapters);
|
|
2837
|
+
console.log(`[agendex] daemon starting with ${config.enabledAdapters.length} adapters`);
|
|
2838
|
+
const syncQueue = [];
|
|
2839
|
+
let syncing = false;
|
|
2840
|
+
async function tryRefreshToken() {
|
|
2841
|
+
const cfg = loadConfig();
|
|
2842
|
+
if (!cfg?.cloudToken || !cfg.convexUrl)
|
|
2843
|
+
return false;
|
|
2844
|
+
const result = await refreshToken(cfg.cloudToken, cfg.convexUrl);
|
|
2845
|
+
if (!result)
|
|
2846
|
+
return false;
|
|
2847
|
+
saveConfig({ ...cfg, cloudToken: result.token });
|
|
2848
|
+
console.log("[agendex] cloud token refreshed");
|
|
2849
|
+
return true;
|
|
2850
|
+
}
|
|
2851
|
+
async function processSyncQueue() {
|
|
2852
|
+
if (syncing || syncQueue.length === 0)
|
|
2853
|
+
return;
|
|
2854
|
+
syncing = true;
|
|
2855
|
+
const batch = syncQueue.splice(0);
|
|
2856
|
+
let syncedCount = 0;
|
|
2857
|
+
let failedCount = 0;
|
|
2858
|
+
try {
|
|
2859
|
+
for (const payload of batch) {
|
|
2860
|
+
let result = await syncPlan(payload);
|
|
2861
|
+
if (!result.ok && result.error?.includes("401")) {
|
|
2862
|
+
const refreshed = await tryRefreshToken();
|
|
2863
|
+
if (refreshed) {
|
|
2864
|
+
result = await syncPlan(payload);
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
if (!result.ok) {
|
|
2868
|
+
if (result.error?.includes("401")) {
|
|
2869
|
+
console.error("[agendex] session expired. Run `agendex login` to re-authenticate.");
|
|
2870
|
+
process.exit(1);
|
|
2871
|
+
}
|
|
2872
|
+
failedCount++;
|
|
2873
|
+
console.error(`[agendex] sync failed for "${payload.title}": ${result.error}`);
|
|
2874
|
+
} else {
|
|
2875
|
+
syncedCount++;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
} catch (err) {
|
|
2879
|
+
console.error("[agendex] sync error:", err);
|
|
2880
|
+
syncQueue.unshift(...batch.slice(syncedCount + failedCount));
|
|
2881
|
+
} finally {
|
|
2882
|
+
syncing = false;
|
|
2883
|
+
}
|
|
2884
|
+
if (syncedCount > 0 || failedCount > 0) {
|
|
2885
|
+
console.log(`[agendex] sync complete: ${syncedCount} synced, ${failedCount} failed`);
|
|
2886
|
+
}
|
|
2887
|
+
if (syncQueue.length > 0)
|
|
2888
|
+
processSyncQueue();
|
|
2889
|
+
}
|
|
2890
|
+
setOnPlansChanged(() => {});
|
|
2891
|
+
console.log(`[agendex] initial scan...`);
|
|
2892
|
+
await scan();
|
|
2893
|
+
const plans = getAll();
|
|
2894
|
+
console.log(`[agendex] syncing ${plans.length} plans...`);
|
|
2895
|
+
for (const plan of plans) {
|
|
2896
|
+
syncQueue.push(planToPayload(plan));
|
|
2897
|
+
}
|
|
2898
|
+
await processSyncQueue();
|
|
2899
|
+
sendHeartbeat();
|
|
2900
|
+
setInterval(() => void sendHeartbeat(), CLI_DAEMON_HEARTBEAT_INTERVAL_MS);
|
|
2901
|
+
startWatching((changedPlans) => {
|
|
2902
|
+
for (const plan of changedPlans) {
|
|
2903
|
+
syncQueue.push(planToPayload(plan));
|
|
2904
|
+
}
|
|
2905
|
+
processSyncQueue();
|
|
2906
|
+
});
|
|
2907
|
+
console.log(`[agendex] daemon running. Watching for file changes...`);
|
|
2908
|
+
await new Promise(() => {});
|
|
2909
|
+
}
|
|
2910
|
+
async function startSupervisor() {
|
|
2911
|
+
writePid();
|
|
2912
|
+
let stopping = false;
|
|
2913
|
+
let workerProc = null;
|
|
2914
|
+
const shutdown = () => {
|
|
2915
|
+
if (stopping)
|
|
2916
|
+
return;
|
|
2917
|
+
stopping = true;
|
|
2918
|
+
console.log("[agendex] supervisor shutting down...");
|
|
2919
|
+
if (workerProc)
|
|
2920
|
+
workerProc.kill("SIGTERM");
|
|
2921
|
+
removePid();
|
|
2922
|
+
process.exit(0);
|
|
2923
|
+
};
|
|
2924
|
+
process.on("SIGTERM", shutdown);
|
|
2925
|
+
process.on("SIGINT", shutdown);
|
|
2926
|
+
const scriptPath = resolve4(process.argv[1] ?? fileURLToPath(new URL("./cli.ts", import.meta.url)));
|
|
2927
|
+
const restartTimes = [];
|
|
2928
|
+
while (!stopping) {
|
|
2929
|
+
workerProc = spawn2(process.execPath, [scriptPath, "start", "--worker"], {
|
|
2930
|
+
stdio: ["ignore", "inherit", "inherit"]
|
|
2931
|
+
});
|
|
2932
|
+
const exitCode = await new Promise((resolve5) => {
|
|
2933
|
+
workerProc?.once("exit", (code) => resolve5(code));
|
|
2934
|
+
workerProc?.once("error", (error) => {
|
|
2935
|
+
console.error("[agendex] failed to spawn worker:", error);
|
|
2936
|
+
resolve5(1);
|
|
2937
|
+
});
|
|
2938
|
+
});
|
|
2939
|
+
workerProc = null;
|
|
2940
|
+
if (stopping)
|
|
2941
|
+
break;
|
|
2942
|
+
const now = Date.now();
|
|
2943
|
+
restartTimes.push(now);
|
|
2944
|
+
while (restartTimes.length > 0 && now - restartTimes[0] > RESTART_WINDOW_MS) {
|
|
2945
|
+
restartTimes.shift();
|
|
2946
|
+
}
|
|
2947
|
+
if (restartTimes.length > MAX_RESTARTS) {
|
|
2948
|
+
console.error(`[agendex] worker crashed ${MAX_RESTARTS} times in ${RESTART_WINDOW_MS / 1000}s, giving up`);
|
|
2949
|
+
removePid();
|
|
2950
|
+
process.exit(1);
|
|
2951
|
+
}
|
|
2952
|
+
console.log(`[agendex] worker exited (code ${exitCode}), restarting in ${RESTART_DELAY_MS / 1000}s...`);
|
|
2953
|
+
await new Promise((r) => setTimeout(r, RESTART_DELAY_MS));
|
|
2954
|
+
}
|
|
2955
|
+
removePid();
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
// src/sync.ts
|
|
2959
|
+
async function syncAll() {
|
|
2960
|
+
const config = await loadOrInitConfig();
|
|
2961
|
+
const adapters = resolveAdapters(config.enabledAdapters);
|
|
2962
|
+
setActiveAdapters(adapters);
|
|
2963
|
+
console.log(`[agendex] Scanning local plans...`);
|
|
2964
|
+
await scan();
|
|
2965
|
+
const plans = getAll();
|
|
2966
|
+
console.log(`[agendex] Found ${plans.length} plans. Syncing to cloud...`);
|
|
2967
|
+
let synced = 0;
|
|
2968
|
+
let failed = 0;
|
|
2969
|
+
for (const plan of plans) {
|
|
2970
|
+
const payload = {
|
|
2971
|
+
localPlanId: plan.id,
|
|
2972
|
+
agent: plan.agent,
|
|
2973
|
+
title: plan.title,
|
|
2974
|
+
content: plan.content,
|
|
2975
|
+
format: plan.format,
|
|
2976
|
+
filePath: plan.filePath,
|
|
2977
|
+
workspace: plan.workspace,
|
|
2978
|
+
metadata: plan.metadata
|
|
2979
|
+
};
|
|
2980
|
+
const result = await syncPlan(payload);
|
|
2981
|
+
if (result.ok) {
|
|
2982
|
+
synced++;
|
|
2983
|
+
} else {
|
|
2984
|
+
failed++;
|
|
2985
|
+
console.error(`[agendex] Failed to sync "${plan.title}": ${result.error}`);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
console.log(`[agendex] Sync complete: ${synced} synced, ${failed} failed`);
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
// src/cli.ts
|
|
2992
|
+
var args = process.argv.slice(2);
|
|
2993
|
+
var command = args[0] ?? "start";
|
|
2994
|
+
var cliEntry = resolve5(process.argv[1] ?? fileURLToPath2(import.meta.url));
|
|
2995
|
+
async function main() {
|
|
2996
|
+
switch (command) {
|
|
2997
|
+
case "start": {
|
|
2998
|
+
if (args.includes("--daemon")) {
|
|
2999
|
+
await startSupervisor();
|
|
3000
|
+
return 0;
|
|
3001
|
+
}
|
|
3002
|
+
if (args.includes("--worker")) {
|
|
3003
|
+
await runWorker();
|
|
3004
|
+
return 0;
|
|
3005
|
+
}
|
|
3006
|
+
const existingPid = readPid();
|
|
3007
|
+
if (existingPid && isRunning(existingPid)) {
|
|
3008
|
+
writeStdout(`[agendex] daemon already running (PID ${existingPid})`);
|
|
3009
|
+
return 0;
|
|
3010
|
+
}
|
|
3011
|
+
if (existingPid)
|
|
3012
|
+
removePid();
|
|
3013
|
+
const child = spawn3(process.execPath, [cliEntry, "start", "--daemon"], {
|
|
3014
|
+
detached: true,
|
|
3015
|
+
stdio: "ignore"
|
|
3016
|
+
});
|
|
3017
|
+
child.unref();
|
|
3018
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
3019
|
+
const pid = readPid();
|
|
3020
|
+
writeStdout(`[agendex] daemon started${pid ? ` (PID ${pid})` : ""}`);
|
|
3021
|
+
return 0;
|
|
3022
|
+
}
|
|
3023
|
+
case "stop": {
|
|
3024
|
+
const pid = readPid();
|
|
3025
|
+
if (!pid || !isRunning(pid)) {
|
|
3026
|
+
removePid();
|
|
3027
|
+
writeStdout("[agendex] daemon is not running");
|
|
3028
|
+
return 0;
|
|
3029
|
+
}
|
|
3030
|
+
process.kill(pid, "SIGTERM");
|
|
3031
|
+
const deadline = Date.now() + 5000;
|
|
3032
|
+
while (isRunning(pid) && Date.now() < deadline) {
|
|
3033
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
3034
|
+
}
|
|
3035
|
+
if (isRunning(pid)) {
|
|
3036
|
+
writeStderr("[agendex] daemon did not stop in time");
|
|
3037
|
+
} else {
|
|
3038
|
+
removePid();
|
|
3039
|
+
writeStdout(`[agendex] daemon stopped (PID ${pid})`);
|
|
3040
|
+
}
|
|
3041
|
+
return isRunning(pid) ? 1 : 0;
|
|
3042
|
+
}
|
|
3043
|
+
case "login": {
|
|
3044
|
+
const urlIdx = args.indexOf("--url");
|
|
3045
|
+
const siteUrl = urlIdx !== -1 ? args[urlIdx + 1] : undefined;
|
|
3046
|
+
await login(siteUrl);
|
|
3047
|
+
return 0;
|
|
3048
|
+
}
|
|
3049
|
+
case "logout": {
|
|
3050
|
+
logout();
|
|
3051
|
+
return 0;
|
|
3052
|
+
}
|
|
3053
|
+
case "sync": {
|
|
3054
|
+
await syncAll();
|
|
3055
|
+
return 0;
|
|
3056
|
+
}
|
|
3057
|
+
case "status": {
|
|
3058
|
+
const config = loadConfig();
|
|
3059
|
+
const pid = readPid();
|
|
3060
|
+
const running = pid ? isRunning(pid) : false;
|
|
3061
|
+
writeStdout(`[agendex] Config version: ${config?.configVersion ?? "none"}`);
|
|
3062
|
+
writeStdout(`[agendex] Local token: ${config?.token ? "set" : "not set"}`);
|
|
3063
|
+
writeStdout(`[agendex] Cloud token: ${config?.cloudToken ? "set" : "not set"}`);
|
|
3064
|
+
writeStdout(`[agendex] Convex URL: ${config?.convexUrl ?? "not set"}`);
|
|
3065
|
+
writeStdout(`[agendex] Enabled adapters: ${config?.enabledAdapters.join(", ") || "none"}`);
|
|
3066
|
+
writeStdout(`[agendex] Daemon: ${running ? `running (PID ${pid})` : "not running"}`);
|
|
3067
|
+
return 0;
|
|
3068
|
+
}
|
|
3069
|
+
case "help":
|
|
3070
|
+
case "--help":
|
|
3071
|
+
case "-h": {
|
|
3072
|
+
writeStdout(`
|
|
3073
|
+
agendex - CLI for syncing local agent plans to the cloud
|
|
3074
|
+
|
|
3075
|
+
Usage:
|
|
3076
|
+
agendex Start daemon (default, backgrounds itself)
|
|
3077
|
+
agendex start Start daemon (backgrounds itself)
|
|
3078
|
+
agendex stop Stop the running daemon
|
|
3079
|
+
agendex login Authenticate via browser OAuth (agendex.dev)
|
|
3080
|
+
agendex login --url <url> Login to a self-hosted instance
|
|
3081
|
+
agendex logout Clear stored cloud token
|
|
3082
|
+
agendex sync One-shot scan + sync to cloud
|
|
3083
|
+
agendex status Show current config state + daemon status
|
|
3084
|
+
agendex help Show this help message
|
|
3085
|
+
`.trim());
|
|
3086
|
+
return 0;
|
|
3087
|
+
}
|
|
3088
|
+
default: {
|
|
3089
|
+
writeStderr(`Unknown command: ${command}`);
|
|
3090
|
+
writeStderr(`Run "agendex help" for usage.`);
|
|
3091
|
+
return 1;
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
var exitCode = await main().catch((err) => {
|
|
3096
|
+
writeStderr(`[agendex] ${err instanceof Error ? err.message : err}`);
|
|
3097
|
+
return 1;
|
|
3098
|
+
});
|
|
3099
|
+
await Promise.all([flushStream(process.stdout), flushStream(process.stderr)]);
|
|
3100
|
+
if (exitCode !== 0) {
|
|
3101
|
+
process.exit(exitCode);
|
|
3102
|
+
}
|
|
3103
|
+
function flushStream(stream) {
|
|
3104
|
+
if (stream.destroyed || !stream.writable) {
|
|
3105
|
+
return Promise.resolve();
|
|
3106
|
+
}
|
|
3107
|
+
return new Promise((resolve6, reject) => {
|
|
3108
|
+
stream.write("", (error) => {
|
|
3109
|
+
if (error) {
|
|
3110
|
+
reject(error);
|
|
3111
|
+
return;
|
|
3112
|
+
}
|
|
3113
|
+
resolve6();
|
|
3114
|
+
});
|
|
3115
|
+
});
|
|
3116
|
+
}
|
|
3117
|
+
function writeStdout(message) {
|
|
3118
|
+
writeSync(process.stdout.fd, `${message}
|
|
3119
|
+
`);
|
|
3120
|
+
}
|
|
3121
|
+
function writeStderr(message) {
|
|
3122
|
+
writeSync(process.stderr.fd, `${message}
|
|
3123
|
+
`);
|
|
3124
|
+
}
|