@agentdocumentformat/cli 0.8.0 → 0.8.2
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/dist/adf.mjs +6 -6
- package/dist/chunks/{App-A5GUFCFJ.mjs → App-4AZZJNN2.mjs} +511 -406
- package/dist/chunks/{adf-schema-YJSGLMA4.mjs → adf-schema-AIPBQTR2.mjs} +9 -3
- package/dist/chunks/{chunk-AZYOXXVL.mjs → chunk-2Z7X3UUR.mjs} +11 -198
- package/dist/chunks/{chunk-4OGZFUKA.mjs → chunk-7JZXMDDF.mjs} +33 -1
- package/dist/chunks/{chunk-V2T6NZX2.mjs → chunk-AEAJDCVK.mjs} +1 -1
- package/dist/chunks/{chunk-NZO5O4VN.mjs → chunk-BR3AD5QZ.mjs} +7 -1
- package/dist/chunks/{chunk-WVTPPOKK.mjs → chunk-BS3USVEA.mjs} +14 -3
- package/dist/chunks/{chunk-JVPZIMXW.mjs → chunk-D7A77SNL.mjs} +1 -1
- package/dist/chunks/{chunk-LCMANRYY.mjs → chunk-E7LC6SHP.mjs} +1 -1
- package/dist/chunks/{chunk-LGL6ML37.mjs → chunk-F3WSCAJD.mjs} +1 -1
- package/dist/chunks/{chunk-6XQZGYMK.mjs → chunk-IMVMSU3A.mjs} +6 -2
- package/dist/chunks/{chunk-C4GA5SI4.mjs → chunk-KCIRFUZH.mjs} +2 -2
- package/dist/chunks/{chunk-YRMKSHW3.mjs → chunk-LVF2DRBR.mjs} +25 -12
- package/dist/chunks/{chunk-PRPTKMQW.mjs → chunk-RHBGCOS3.mjs} +2 -2
- package/dist/chunks/{chunk-WX6QCUWI.mjs → chunk-RJDOVMM4.mjs} +95 -12
- package/dist/chunks/{chunk-G6NBFYG5.mjs → chunk-SOSPQPEN.mjs} +189 -0
- package/dist/chunks/chunk-VENQBMOA.mjs +62 -0
- package/dist/chunks/{chunk-XT2BJUFC.mjs → chunk-YRBFIDLB.mjs} +33 -6
- package/dist/chunks/{claude-subscription-33BMZB6I.mjs → claude-subscription-EB4LAAVV.mjs} +3 -3
- package/dist/chunks/{cli-I47IFDHJ.mjs → cli-PCVFB6B4.mjs} +5 -5
- package/dist/chunks/{commands-E4EQUHE5.mjs → commands-KOMPXJZS.mjs} +3 -3
- package/dist/chunks/{daemon-FQ5BV3AP.mjs → daemon-HEQ3FUYH.mjs} +729 -111
- package/dist/chunks/{daemon-control-L3CLG63P.mjs → daemon-control-MKN7G5M3.mjs} +4 -4
- package/dist/chunks/{layout-EPJQNFAI.mjs → layout-ECWGJF6M.mjs} +2 -2
- package/dist/chunks/{open-TLGS2Z3Q.mjs → open-3OR6WT4T.mjs} +4 -4
- package/dist/chunks/{pipeline-executor-FD4FBWQA.mjs → pipeline-executor-DRYEEFDR.mjs} +4 -4
- package/dist/chunks/{remote-access-cli-XXAPQWH6.mjs → remote-access-cli-GLEEP7DI.mjs} +2 -2
- package/dist/chunks/sdk-OJOAF4DP.mjs +30014 -0
- package/dist/chunks/{store-ZRN2WCFB.mjs → store-55CQSAOX.mjs} +3 -2
- package/dist/chunks/{tui-SPSPDADM.mjs → tui-RAUVFOYY.mjs} +11 -11
- package/package.json +2 -2
- package/dist/chunks/sdk-5FD2ZP7N.mjs +0 -28422
- package/dist/chunks/{chunk-APRU6PHC.mjs → chunk-JZ7AQNPM.mjs} +3 -3
|
@@ -6,7 +6,7 @@ const __filename = __adfFileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = __adfDirname(__filename);
|
|
7
7
|
import {
|
|
8
8
|
DaemonClient
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IMVMSU3A.mjs";
|
|
10
10
|
import {
|
|
11
11
|
auth_flow_exports
|
|
12
12
|
} from "./chunk-BHY7QDCM.mjs";
|
|
@@ -20,38 +20,19 @@ import {
|
|
|
20
20
|
readLayout,
|
|
21
21
|
setMouse,
|
|
22
22
|
setSidebarHidden
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-JZ7AQNPM.mjs";
|
|
24
24
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
isCredentialsLocked,
|
|
37
|
-
isTrackedKey,
|
|
38
|
-
parseServer,
|
|
39
|
-
servedText,
|
|
40
|
-
serverBadge,
|
|
41
|
-
serverText,
|
|
42
|
-
shallowEqual,
|
|
43
|
-
shortUrl,
|
|
44
|
-
siteKind,
|
|
45
|
-
siteOf,
|
|
46
|
-
stoppedError,
|
|
47
|
-
stoppedLabel,
|
|
48
|
-
transcriptKey,
|
|
49
|
-
useActions,
|
|
50
|
-
useClient,
|
|
51
|
-
useStore,
|
|
52
|
-
useTuiSelector
|
|
53
|
-
} from "./chunk-WX6QCUWI.mjs";
|
|
54
|
-
import "./chunk-75DC5EWN.mjs";
|
|
25
|
+
isMouseGarbage,
|
|
26
|
+
lastRawInput,
|
|
27
|
+
newlineKey,
|
|
28
|
+
noteRawInput,
|
|
29
|
+
noteShiftEnter,
|
|
30
|
+
parseMouse,
|
|
31
|
+
superArrow,
|
|
32
|
+
terminalCaps,
|
|
33
|
+
useTerminalCaps,
|
|
34
|
+
writeTerminal
|
|
35
|
+
} from "./chunk-7XYNI52E.mjs";
|
|
55
36
|
import {
|
|
56
37
|
CHANNELS_OVERLAY,
|
|
57
38
|
CHANNEL_ORDER,
|
|
@@ -123,13 +104,7 @@ import {
|
|
|
123
104
|
validateCredentials,
|
|
124
105
|
validateMcpForm,
|
|
125
106
|
validateProvider
|
|
126
|
-
} from "./chunk-
|
|
127
|
-
import {
|
|
128
|
-
require_jsx_runtime
|
|
129
|
-
} from "./chunk-7CV2SA3H.mjs";
|
|
130
|
-
import {
|
|
131
|
-
cjs
|
|
132
|
-
} from "./chunk-SGUTYISF.mjs";
|
|
107
|
+
} from "./chunk-2Z7X3UUR.mjs";
|
|
133
108
|
import {
|
|
134
109
|
WELCOME_INTRO,
|
|
135
110
|
WELCOME_OVERLAY,
|
|
@@ -156,8 +131,7 @@ import {
|
|
|
156
131
|
guarded_fetch_exports,
|
|
157
132
|
skills_catalog_schema_exports
|
|
158
133
|
} from "./chunk-HBOFZRUS.mjs";
|
|
159
|
-
import "./chunk-
|
|
160
|
-
import "./chunk-G6NBFYG5.mjs";
|
|
134
|
+
import "./chunk-SOSPQPEN.mjs";
|
|
161
135
|
import {
|
|
162
136
|
Box_default,
|
|
163
137
|
Text,
|
|
@@ -176,28 +150,54 @@ import {
|
|
|
176
150
|
useTheme
|
|
177
151
|
} from "./chunk-NZLEPJ5M.mjs";
|
|
178
152
|
import {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
153
|
+
DaemonError,
|
|
154
|
+
MAIN_LOOP,
|
|
155
|
+
PROMPT_PREFILL_KEY,
|
|
156
|
+
SERVER_STOPPED_TEXT,
|
|
157
|
+
StoreProvider,
|
|
158
|
+
askQuestion,
|
|
159
|
+
emptyTranscript,
|
|
160
|
+
findTracked,
|
|
161
|
+
folderName,
|
|
162
|
+
isAsyncInput,
|
|
163
|
+
isBusyState,
|
|
164
|
+
isCredentialsLocked,
|
|
165
|
+
isTrackedKey,
|
|
166
|
+
parseServer,
|
|
167
|
+
servedText,
|
|
168
|
+
serverBadge,
|
|
169
|
+
serverText,
|
|
170
|
+
shallowEqual,
|
|
171
|
+
shortUrl,
|
|
172
|
+
siteKind,
|
|
173
|
+
siteOf,
|
|
174
|
+
stoppedError,
|
|
175
|
+
stoppedLabel,
|
|
176
|
+
transcriptKey,
|
|
177
|
+
useActions,
|
|
178
|
+
useClient,
|
|
179
|
+
useStore,
|
|
180
|
+
useTuiSelector
|
|
181
|
+
} from "./chunk-RJDOVMM4.mjs";
|
|
182
|
+
import "./chunk-75DC5EWN.mjs";
|
|
183
|
+
import {
|
|
184
|
+
require_jsx_runtime
|
|
185
|
+
} from "./chunk-7CV2SA3H.mjs";
|
|
186
|
+
import {
|
|
187
|
+
cjs
|
|
188
|
+
} from "./chunk-SGUTYISF.mjs";
|
|
189
|
+
import "./chunk-7JZXMDDF.mjs";
|
|
190
190
|
import {
|
|
191
191
|
require_react
|
|
192
192
|
} from "./chunk-6GJ4QHRI.mjs";
|
|
193
193
|
import {
|
|
194
194
|
ADF_SKILLS_REGISTRY_URL
|
|
195
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-E7LC6SHP.mjs";
|
|
196
196
|
import "./chunk-UYY5M2PB.mjs";
|
|
197
197
|
import "./chunk-2NAP2ZF7.mjs";
|
|
198
198
|
import "./chunk-LKFHERRV.mjs";
|
|
199
|
-
import "./chunk-
|
|
200
|
-
import "./chunk-
|
|
199
|
+
import "./chunk-AEAJDCVK.mjs";
|
|
200
|
+
import "./chunk-BS3USVEA.mjs";
|
|
201
201
|
import "./chunk-WJGPNHGX.mjs";
|
|
202
202
|
import "./chunk-PAK5JCO2.mjs";
|
|
203
203
|
import "./chunk-ZPB3HYM7.mjs";
|
|
@@ -205,7 +205,10 @@ import "./chunk-LTX74NU6.mjs";
|
|
|
205
205
|
import {
|
|
206
206
|
require_dist
|
|
207
207
|
} from "./chunk-APHX6HSV.mjs";
|
|
208
|
-
import
|
|
208
|
+
import {
|
|
209
|
+
agent_commands_exports
|
|
210
|
+
} from "./chunk-VENQBMOA.mjs";
|
|
211
|
+
import "./chunk-BR3AD5QZ.mjs";
|
|
209
212
|
import "./chunk-ZJKXHM4Q.mjs";
|
|
210
213
|
import "./chunk-RIX34QHC.mjs";
|
|
211
214
|
import {
|
|
@@ -217,11 +220,317 @@ import {
|
|
|
217
220
|
var import_react60 = __toESM(require_react(), 1);
|
|
218
221
|
|
|
219
222
|
// src/main/tui/app/shell-context.ts
|
|
220
|
-
var import_react = __toESM(require_react(), 1)
|
|
223
|
+
var import_react = __toESM(require_react(), 1);
|
|
224
|
+
|
|
225
|
+
// src/shared/utils/skills-panel.ts
|
|
226
|
+
var skills_panel_exports = {};
|
|
227
|
+
__export(skills_panel_exports, {
|
|
228
|
+
MAX_CATALOG_SOURCES: () => MAX_CATALOG_SOURCES,
|
|
229
|
+
MAX_REGISTRY_BYTES: () => MAX_REGISTRY_BYTES,
|
|
230
|
+
MAX_SKILLS: () => MAX_SKILLS,
|
|
231
|
+
MAX_SKILL_FILE_BYTES: () => MAX_SKILL_FILE_BYTES,
|
|
232
|
+
SKILLS_REGISTRY_PATH: () => SKILLS_REGISTRY_PATH,
|
|
233
|
+
SKILLS_STATE_PATH: () => SKILLS_STATE_PATH,
|
|
234
|
+
SKILL_MANIFEST: () => SKILL_MANIFEST,
|
|
235
|
+
addCatalogSource: () => addCatalogSource,
|
|
236
|
+
catalogSourceLabel: () => catalogSourceLabel,
|
|
237
|
+
estimateTokens: () => estimateTokens,
|
|
238
|
+
filterCatalogEntries: () => filterCatalogEntries,
|
|
239
|
+
installedSkillNames: () => installedSkillNames,
|
|
240
|
+
isCatalogUrl: () => isCatalogUrl,
|
|
241
|
+
mergeCatalogResults: () => mergeCatalogResults,
|
|
242
|
+
mergeDisabledList: () => mergeDisabledList,
|
|
243
|
+
normalizeCatalogSources: () => normalizeCatalogSources,
|
|
244
|
+
parseSkillsRegistry: () => parseSkillsRegistry,
|
|
245
|
+
sanitizeDisplayText: () => sanitizeDisplayText,
|
|
246
|
+
skillProblems: () => skillProblems,
|
|
247
|
+
unindexedHint: () => unindexedHint
|
|
248
|
+
});
|
|
249
|
+
var SKILLS_REGISTRY_PATH = "skills-registry.json", SKILLS_STATE_PATH = "skills-state.json", SKILL_MANIFEST = /^skills\/([^/]+)\/SKILL\.md$/, MAX_SKILLS = 48, MAX_REGISTRY_BYTES = 32 * 1024, MAX_SKILL_FILE_BYTES = 256 * 1024;
|
|
250
|
+
function parseSkillsRegistry(text) {
|
|
251
|
+
if (!text) return null;
|
|
252
|
+
try {
|
|
253
|
+
let doc = JSON.parse(text);
|
|
254
|
+
if (doc?.schema !== 1 || typeof doc.skills != "object" || doc.skills === null) return null;
|
|
255
|
+
let entries = [];
|
|
256
|
+
for (let value of Object.values(doc.skills)) {
|
|
257
|
+
let skill = value;
|
|
258
|
+
typeof skill?.name != "string" || typeof skill?.path != "string" || entries.push({
|
|
259
|
+
name: skill.name,
|
|
260
|
+
description: typeof skill.description == "string" ? skill.description : void 0,
|
|
261
|
+
path: skill.path,
|
|
262
|
+
enabled: skill.enabled !== !1
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
let rejected = [];
|
|
266
|
+
if (Array.isArray(doc.rejected))
|
|
267
|
+
for (let raw of doc.rejected) {
|
|
268
|
+
let row4 = raw;
|
|
269
|
+
typeof row4?.path != "string" || typeof row4?.reason != "string" || rejected.push({ path: row4.path, reason: row4.reason, name: SKILL_MANIFEST.exec(row4.path)?.[1] ?? null });
|
|
270
|
+
}
|
|
271
|
+
return { entries: entries.sort((a, b) => a.name.localeCompare(b.name)), rejected };
|
|
272
|
+
} catch {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function mergeDisabledList(existingText, name, enabled) {
|
|
277
|
+
let doc = {};
|
|
278
|
+
if (existingText)
|
|
279
|
+
try {
|
|
280
|
+
let parsed = JSON.parse(existingText);
|
|
281
|
+
parsed && typeof parsed == "object" && !Array.isArray(parsed) && (doc = parsed);
|
|
282
|
+
} catch {
|
|
283
|
+
}
|
|
284
|
+
let current = Array.isArray(doc.disabled) ? doc.disabled.filter((entry) => typeof entry == "string") : [], next = new Set(current);
|
|
285
|
+
return enabled ? next.delete(name) : next.add(name), JSON.stringify({ ...doc, schema: 1, disabled: [...next].sort() }, null, 2) + `
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
var UNSAFE_DISPLAY_CHARS = /[\u0000-\u001F\u007F-\u009F\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g;
|
|
289
|
+
function sanitizeDisplayText(value) {
|
|
290
|
+
return value ? value.replace(UNSAFE_DISPLAY_CHARS, " ").replace(/\s+/g, " ").trim() : "";
|
|
291
|
+
}
|
|
292
|
+
function isCatalogUrl(value) {
|
|
293
|
+
let trimmed = value.trim();
|
|
294
|
+
if (!trimmed) return !1;
|
|
295
|
+
try {
|
|
296
|
+
return new URL(trimmed).protocol === "https:";
|
|
297
|
+
} catch {
|
|
298
|
+
return !1;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function estimateTokens(bytes) {
|
|
302
|
+
return Math.ceil(bytes / 4);
|
|
303
|
+
}
|
|
304
|
+
var MAX_CATALOG_SOURCES = 8;
|
|
305
|
+
function normalizeCatalogSources(stored) {
|
|
306
|
+
if (!Array.isArray(stored)) return [ADF_SKILLS_REGISTRY_URL];
|
|
307
|
+
let sources2 = [], seen = /* @__PURE__ */ new Set();
|
|
308
|
+
for (let raw of stored) {
|
|
309
|
+
if (typeof raw != "string") continue;
|
|
310
|
+
let url2 = raw.trim();
|
|
311
|
+
if (!(!isCatalogUrl(url2) || seen.has(url2)) && (seen.add(url2), sources2.push(url2), sources2.length >= MAX_CATALOG_SOURCES))
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
return sources2;
|
|
315
|
+
}
|
|
316
|
+
function addCatalogSource(sources2, raw) {
|
|
317
|
+
let url2 = raw.trim();
|
|
318
|
+
return url2 ? isCatalogUrl(url2) ? sources2.includes(url2) ? { ok: !1, error: "That source is already listed." } : sources2.length >= MAX_CATALOG_SOURCES ? { ok: !1, error: `At most ${MAX_CATALOG_SOURCES} catalog sources.` } : { ok: !0, sources: [...sources2, url2] } : { ok: !1, error: "A catalog source must be an https:// URL." } : { ok: !1, error: "Enter a catalog URL." };
|
|
319
|
+
}
|
|
320
|
+
function catalogSourceLabel(url2, publisher) {
|
|
321
|
+
let named = sanitizeDisplayText(publisher);
|
|
322
|
+
if (named) return named;
|
|
323
|
+
try {
|
|
324
|
+
return new URL(url2).hostname;
|
|
325
|
+
} catch {
|
|
326
|
+
return url2;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function mergeCatalogResults(results) {
|
|
330
|
+
let merged = [], seen = /* @__PURE__ */ new Set();
|
|
331
|
+
for (let result of results) {
|
|
332
|
+
if (!result.ok) continue;
|
|
333
|
+
let sourceLabel = catalogSourceLabel(result.url, result.publisher);
|
|
334
|
+
for (let entry of result.entries)
|
|
335
|
+
seen.has(entry.name) || (seen.add(entry.name), merged.push({ ...entry, sourceUrl: result.url, sourceLabel }));
|
|
336
|
+
}
|
|
337
|
+
return merged.sort((a, b) => a.name.localeCompare(b.name));
|
|
338
|
+
}
|
|
339
|
+
function filterCatalogEntries(entries, query) {
|
|
340
|
+
let needle = query.trim().toLowerCase();
|
|
341
|
+
if (!needle) return entries;
|
|
342
|
+
let byName2 = [], byDescription = [];
|
|
343
|
+
for (let entry of entries)
|
|
344
|
+
entry.name.toLowerCase().includes(needle) ? byName2.push(entry) : entry.description.toLowerCase().includes(needle) && byDescription.push(entry);
|
|
345
|
+
return [...byName2, ...byDescription];
|
|
346
|
+
}
|
|
347
|
+
function installedSkillNames(files2) {
|
|
348
|
+
let names = /* @__PURE__ */ new Set();
|
|
349
|
+
for (let file of files2) {
|
|
350
|
+
let match = SKILL_MANIFEST.exec(file.path);
|
|
351
|
+
match && names.add(match[1]);
|
|
352
|
+
}
|
|
353
|
+
return names;
|
|
354
|
+
}
|
|
355
|
+
function skillProblems(installedNames, registry) {
|
|
356
|
+
if (!registry) return [];
|
|
357
|
+
let indexed = new Set(registry.entries.map((s) => s.name)), rows = /* @__PURE__ */ new Map();
|
|
358
|
+
for (let name of installedNames)
|
|
359
|
+
indexed.has(name) || rows.set(name, { label: name, path: `skills/${name}/SKILL.md`, reason: null, isPackage: !0 });
|
|
360
|
+
for (let rejection of registry.rejected) {
|
|
361
|
+
let key = rejection.name ?? rejection.path;
|
|
362
|
+
rejection.name && indexed.has(rejection.name) || rows.set(key, {
|
|
363
|
+
label: rejection.name ?? rejection.path,
|
|
364
|
+
path: rejection.path,
|
|
365
|
+
reason: rejection.reason,
|
|
366
|
+
isPackage: rejection.name !== null
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return [...rows.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([key, row4]) => ({ key, ...row4 }));
|
|
370
|
+
}
|
|
371
|
+
function unindexedHint() {
|
|
372
|
+
return `not indexed \u2014 the folder name must be lowercase kebab-case and match the frontmatter name, description must be one line under 500 characters, and the file must be under ${Math.round(MAX_SKILL_FILE_BYTES / 1024)} KB. The catalog also stops at ${MAX_SKILLS} skills or ${Math.round(MAX_REGISTRY_BYTES / 1024)} KB, whichever comes first.`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// src/main/tui/commands/registry.ts
|
|
376
|
+
function collectCommands(views, builtins = []) {
|
|
377
|
+
let commands3 = [], actions4 = [], conflicts = [], byName2 = /* @__PURE__ */ new Map(), actionIds = /* @__PURE__ */ new Set(), addCommand = (command, owner) => {
|
|
378
|
+
let withView = command.view ? command : { ...command, view: owner };
|
|
379
|
+
for (let name of [command.name, ...command.aliases ?? []]) {
|
|
380
|
+
let key = name.toLowerCase(), existing = byName2.get(key);
|
|
381
|
+
if (existing) {
|
|
382
|
+
conflicts.push(`/${key} from ${owner} is shadowed by ${existing.view ?? "builtin"}`);
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
byName2.set(key, withView);
|
|
386
|
+
}
|
|
387
|
+
commands3.push(withView);
|
|
388
|
+
}, addAction = (action, owner) => {
|
|
389
|
+
if (actionIds.has(action.id)) {
|
|
390
|
+
conflicts.push(`palette action ${action.id} from ${owner} is a duplicate`);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
actionIds.add(action.id), actions4.push(action.view ? action : { ...action, view: owner });
|
|
394
|
+
};
|
|
395
|
+
for (let builtin of builtins) {
|
|
396
|
+
for (let command of builtin.commands ?? []) addCommand(command, "builtin");
|
|
397
|
+
for (let action of builtin.actions ?? []) addAction(action, "builtin");
|
|
398
|
+
}
|
|
399
|
+
for (let view2 of views) {
|
|
400
|
+
for (let command of view2.commands ?? []) addCommand(command, view2.id);
|
|
401
|
+
for (let action of view2.actions ?? []) addAction(action, view2.id);
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
commands: commands3,
|
|
405
|
+
actions: actions4,
|
|
406
|
+
conflicts,
|
|
407
|
+
find: (name) => byName2.get(name.toLowerCase())
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function parseSlash(text) {
|
|
411
|
+
let trimmed = text.trimStart();
|
|
412
|
+
if (!trimmed.startsWith("/") || trimmed.startsWith("//")) return null;
|
|
413
|
+
let match = trimmed.slice(1).match(/^(\S*)\s*([\s\S]*)$/);
|
|
414
|
+
if (!match) return null;
|
|
415
|
+
let rest = match[2] ?? "";
|
|
416
|
+
return { name: match[1].toLowerCase(), args: splitArgs(rest), rest };
|
|
417
|
+
}
|
|
418
|
+
function splitArgs(text) {
|
|
419
|
+
let args = [], pattern = /"((?:[^"\\]|\\.)*)"|'([^']*)'|(\S+)/g, m;
|
|
420
|
+
for (; m = pattern.exec(text); ) args.push(m[1] !== void 0 ? m[1].replace(/\\(.)/g, "$1") : m[2] ?? m[3]);
|
|
421
|
+
return args;
|
|
422
|
+
}
|
|
423
|
+
function createScope(store, exit) {
|
|
424
|
+
let state = store.getState(), selected = state.selectedAgentId, stoppedKey = isTrackedKey(selected) ? selected : null, agentId = stoppedKey ? null : selected;
|
|
425
|
+
return {
|
|
426
|
+
store,
|
|
427
|
+
actions: store.actions,
|
|
428
|
+
client: store.client,
|
|
429
|
+
state: () => store.getState(),
|
|
430
|
+
agentId,
|
|
431
|
+
stoppedKey,
|
|
432
|
+
loop: agentId ? state.selectedLoop[agentId] ?? MAIN_LOOP : MAIN_LOOP,
|
|
433
|
+
print: (text, level = "info") => store.actions.toast(text, level),
|
|
434
|
+
exit
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
async function runSlash(text, registry, store, exit) {
|
|
438
|
+
let parsed = parseSlash(text);
|
|
439
|
+
if (!parsed) return !1;
|
|
440
|
+
let scope = createScope(store, exit), command = registry.find(parsed.name);
|
|
441
|
+
if (!command)
|
|
442
|
+
return store.actions.toast(`Unknown command /${parsed.name} \u2014 /help lists commands`, "warn"), !0;
|
|
443
|
+
if (command.agentCommand && /[\r\n]/.test(text))
|
|
444
|
+
return store.actions.toast(`/${command.name}: agent commands must be one line`, "warn"), !0;
|
|
445
|
+
if (command.available && !command.available(scope))
|
|
446
|
+
return store.actions.toast(`/${command.name} is not available here`, "warn"), !0;
|
|
447
|
+
let ctx = { ...scope, args: parsed.args, rest: parsed.rest };
|
|
448
|
+
try {
|
|
449
|
+
await command.run(ctx);
|
|
450
|
+
} catch (err) {
|
|
451
|
+
store.actions.toast(`/${command.name}: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
452
|
+
}
|
|
453
|
+
return !0;
|
|
454
|
+
}
|
|
455
|
+
function completeSlash(text, registry, scope) {
|
|
456
|
+
let parsed = parseSlash(text);
|
|
457
|
+
if (!parsed) return [];
|
|
458
|
+
if (/\s/.test(text.trimStart().slice(1))) {
|
|
459
|
+
let command = registry.find(parsed.name);
|
|
460
|
+
return command?.complete ? command.complete(parsed.rest, scope).map((value) => ({ value: `/${command.name} ${value}`, command })) : [];
|
|
461
|
+
}
|
|
462
|
+
let seen = /* @__PURE__ */ new Set(), out = [];
|
|
463
|
+
for (let command of registry.commands) {
|
|
464
|
+
if (seen.has(command) || command.available && !command.available(scope)) continue;
|
|
465
|
+
[command.name, ...command.aliases ?? []].some((n) => n.startsWith(parsed.name)) && (seen.add(command), out.push({ value: `/${command.name}`, command }));
|
|
466
|
+
}
|
|
467
|
+
let exact = (c) => [c.name, ...c.aliases ?? []].some((n) => n.toLowerCase() === parsed.name);
|
|
468
|
+
return [...out.filter((o) => exact(o.command)), ...out.filter((o) => !exact(o.command))];
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/main/tui/commands/agent-commands.ts
|
|
472
|
+
var { validateAgentCommands, parseAuthorizeToken } = cjs(agent_commands_exports), { sanitizeDisplayText: sanitizeDisplayText2 } = cjs(skills_panel_exports);
|
|
473
|
+
function validAgentCommands(value) {
|
|
474
|
+
if (!Array.isArray(value)) return [];
|
|
475
|
+
let invalid = new Set(validateAgentCommands(value).map((issue) => issue.index));
|
|
476
|
+
return value.slice(0, 64).filter((_, index) => !invalid.has(index));
|
|
477
|
+
}
|
|
478
|
+
function registered(ctx) {
|
|
479
|
+
return validAgentCommands(ctx.agentId ? ctx.state().agents[ctx.agentId]?.config?.commands : void 0);
|
|
480
|
+
}
|
|
481
|
+
async function run(ctx, name, args) {
|
|
482
|
+
if (!ctx.agentId) {
|
|
483
|
+
ctx.print(ctx.stoppedKey ? `Agent is off. Start it, then run /${name} again.` : "Select an agent first.", "warn");
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
await ctx.actions.runAgentCommand(ctx.agentId, ctx.loop, name, args);
|
|
487
|
+
}
|
|
488
|
+
function namedArgs(rest) {
|
|
489
|
+
let match = rest.trimStart().match(/^(\S+)(?:\s+([\s\S]*))?$/);
|
|
490
|
+
return match ? { name: match[1], args: match[2] ?? "" } : void 0;
|
|
491
|
+
}
|
|
492
|
+
var agentCommand = {
|
|
493
|
+
name: "command",
|
|
494
|
+
args: "<name> [args]",
|
|
495
|
+
description: "Run an agent lambda command; add !authorize for one authorized run",
|
|
496
|
+
agentCommand: "*",
|
|
497
|
+
complete: (partial, scope) => registered(scope).filter((command) => command.name.startsWith(partial)).map((command) => command.name),
|
|
498
|
+
run: async (ctx) => {
|
|
499
|
+
let input = namedArgs(ctx.rest);
|
|
500
|
+
if (!input) {
|
|
501
|
+
ctx.print("Usage: /command <name> [args] [!authorize]", "warn");
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
await run(ctx, input.name, input.args);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
function withAgentCommands(base2, value) {
|
|
508
|
+
let dynamic = validAgentCommands(value).filter((command) => !base2.find(command.name)).map((command) => ({
|
|
509
|
+
name: command.name,
|
|
510
|
+
args: sanitizeDisplayText2(command.usage) || void 0,
|
|
511
|
+
description: `${sanitizeDisplayText2(command.description)}${command.locked ? " [locked]" : ""}`,
|
|
512
|
+
view: "chat",
|
|
513
|
+
agentCommand: command.name,
|
|
514
|
+
run: (ctx) => run(ctx, command.name, ctx.rest)
|
|
515
|
+
}));
|
|
516
|
+
return { ...base2, commands: [...base2.commands, ...dynamic], find: (name) => base2.find(name) ?? dynamic.find((command) => command.name === name.toLowerCase()) };
|
|
517
|
+
}
|
|
518
|
+
function isAuthorizedCommandInput(text, registry) {
|
|
519
|
+
let parsed = parseSlash(text), name = parsed && registry.find(parsed.name)?.agentCommand;
|
|
520
|
+
if (!parsed || !name) return !1;
|
|
521
|
+
let args = name === "*" ? namedArgs(parsed.rest)?.args : parsed.rest;
|
|
522
|
+
return args !== void 0 && parseAuthorizeToken(args).authorize;
|
|
523
|
+
}
|
|
524
|
+
function hasCommandArguments(rest) {
|
|
525
|
+
return parseAuthorizeToken(rest).args.length > 0;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// src/main/tui/app/shell-context.ts
|
|
529
|
+
var ShellContext = (0, import_react.createContext)(null);
|
|
221
530
|
function useShell() {
|
|
222
|
-
let value = (0, import_react.useContext)(ShellContext);
|
|
531
|
+
let value = (0, import_react.useContext)(ShellContext), commands3 = useTuiSelector((state) => state.agents[state.selectedAgentId ?? ""]?.config?.commands), registry = (0, import_react.useMemo)(() => value ? withAgentCommands(value.registry, commands3) : void 0, [value?.registry, commands3]);
|
|
223
532
|
if (!value) throw new Error("useShell must be used inside the TUI shell");
|
|
224
|
-
return value;
|
|
533
|
+
return { ...value, registry };
|
|
225
534
|
}
|
|
226
535
|
|
|
227
536
|
// src/main/tui/app/Shell.tsx
|
|
@@ -1594,151 +1903,57 @@ function AgentRow({ row: row4, selected, focused, width, unread }) {
|
|
|
1594
1903
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: !0, color: c.fg(selected ? theme2.color.accent : theme2.color.text), children: [
|
|
1595
1904
|
" ",
|
|
1596
1905
|
name
|
|
1597
|
-
] }),
|
|
1598
|
-
stateText ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(theme2.color.muted), children: [
|
|
1599
|
-
" ",
|
|
1600
|
-
stateText
|
|
1601
|
-
] }) : null,
|
|
1602
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(fill) }),
|
|
1603
|
-
badges.map((badge, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: !0, color: c.fg(badge.startsWith(theme2.glyph.warn) ? theme2.color.warn : badge.startsWith(theme2.glyph.loop) ? theme2.color.loop : theme2.color.info), children: [
|
|
1604
|
-
" ",
|
|
1605
|
-
badge
|
|
1606
|
-
] }, badge))
|
|
1607
|
-
] });
|
|
1608
|
-
}
|
|
1609
|
-
function FolderRow({ row: row4, width }) {
|
|
1610
|
-
let theme2 = useTheme(), count = `${row4.loaded}/${row4.total}`, name = truncate(folderName(row4.path), Math.max(3, width - displayWidth(count) - 1));
|
|
1611
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
1612
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: !0, color: theme2.color.muted, children: name }),
|
|
1613
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(Math.max(1, width - displayWidth(name) - displayWidth(count))) }),
|
|
1614
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: theme2.color.dim, children: count })
|
|
1615
|
-
] });
|
|
1616
|
-
}
|
|
1617
|
-
function StoppedRow({ row: row4, selected, focused, width, errors, busy }) {
|
|
1618
|
-
let theme2 = useTheme(), c = rowColors(theme2, selected, focused), { entry } = row4, label2 = busy ? busy === "starting" ? "starting" : "loading" : stoppedLabel(entry, errors), glyph = stoppedGlyph(theme2, entry, errors), nameRoom = Math.max(3, width - 4), name = truncate(entry.agent.name, nameRoom), stateRoom = nameRoom - displayWidth(name) - 1, stateText = stateRoom >= 4 ? truncate(label2, stateRoom) : "", labelColor = label2 === "needs review" ? theme2.color.warn : label2 === "load error" || label2 === "unreadable" ? theme2.color.error : theme2.color.dim;
|
|
1619
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { backgroundColor: c.bg, inverse: c.inverse, underline: c.underline, wrap: "truncate-end", children: [
|
|
1620
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
1621
|
-
busy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner, { color: c.fg(theme2.color.live) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(glyph.color), children: glyph.glyph }),
|
|
1622
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(selected ? theme2.color.accent : theme2.color.muted), bold: selected, children: [
|
|
1623
|
-
" ",
|
|
1624
|
-
name
|
|
1625
|
-
] }),
|
|
1626
|
-
stateText ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(labelColor), children: [
|
|
1627
|
-
" ",
|
|
1628
|
-
stateText
|
|
1629
|
-
] }) : null
|
|
1630
|
-
] });
|
|
1631
|
-
}
|
|
1632
|
-
function LoopRow({ row: row4, selected, focused, width, nextRun }) {
|
|
1633
|
-
let theme2 = useTheme(), { loop, agent: agent2 } = row4, d = describeLoop(agent2, loop), c = rowColors(theme2, selected, focused), hint = d.kind === "running" ? d.label : d.kind === "disabled" ? "off" : nextRun !== void 0 ? formatIn(nextRun) : "", nameRoom = Math.max(3, width - 5 - (hint ? displayWidth(hint) + 1 : 0)), name = truncate(loop.info.name, nameRoom), fill = Math.max(0, width - 5 - displayWidth(name) - (hint ? displayWidth(hint) + 1 : 0)), nameColor = loop.info.enabled ? loop.info.isMain ? theme2.color.accent : theme2.color.loop : theme2.color.dim;
|
|
1634
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { backgroundColor: c.bg, inverse: c.inverse, underline: c.underline, wrap: "truncate-end", children: [
|
|
1635
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
1636
|
-
d.kind === "running" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner, { color: c.fg(theme2.color.loop) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(d.kind === "disabled" ? theme2.color.dim : theme2.color.muted), children: d.kind === "disabled" ? "-" : theme2.glyph.ring }),
|
|
1637
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(nameColor), children: [
|
|
1638
|
-
" ",
|
|
1639
|
-
theme2.glyph.loop
|
|
1640
|
-
] }),
|
|
1641
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(nameColor), bold: selected, children: name }),
|
|
1642
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(fill) }),
|
|
1643
|
-
hint ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(d.kind === "running" ? theme2.color.live : theme2.color.muted), children: [
|
|
1644
|
-
" ",
|
|
1645
|
-
hint
|
|
1646
|
-
] }) : null
|
|
1647
|
-
] });
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
// src/main/tui/commands/registry.ts
|
|
1651
|
-
function collectCommands(views, builtins = []) {
|
|
1652
|
-
let commands3 = [], actions4 = [], conflicts = [], byName2 = /* @__PURE__ */ new Map(), actionIds = /* @__PURE__ */ new Set(), addCommand = (command, owner) => {
|
|
1653
|
-
let withView = command.view ? command : { ...command, view: owner };
|
|
1654
|
-
for (let name of [command.name, ...command.aliases ?? []]) {
|
|
1655
|
-
let key = name.toLowerCase(), existing = byName2.get(key);
|
|
1656
|
-
if (existing) {
|
|
1657
|
-
conflicts.push(`/${key} from ${owner} is shadowed by ${existing.view ?? "builtin"}`);
|
|
1658
|
-
continue;
|
|
1659
|
-
}
|
|
1660
|
-
byName2.set(key, withView);
|
|
1661
|
-
}
|
|
1662
|
-
commands3.push(withView);
|
|
1663
|
-
}, addAction = (action, owner) => {
|
|
1664
|
-
if (actionIds.has(action.id)) {
|
|
1665
|
-
conflicts.push(`palette action ${action.id} from ${owner} is a duplicate`);
|
|
1666
|
-
return;
|
|
1667
|
-
}
|
|
1668
|
-
actionIds.add(action.id), actions4.push(action.view ? action : { ...action, view: owner });
|
|
1669
|
-
};
|
|
1670
|
-
for (let builtin of builtins) {
|
|
1671
|
-
for (let command of builtin.commands ?? []) addCommand(command, "builtin");
|
|
1672
|
-
for (let action of builtin.actions ?? []) addAction(action, "builtin");
|
|
1673
|
-
}
|
|
1674
|
-
for (let view2 of views) {
|
|
1675
|
-
for (let command of view2.commands ?? []) addCommand(command, view2.id);
|
|
1676
|
-
for (let action of view2.actions ?? []) addAction(action, view2.id);
|
|
1677
|
-
}
|
|
1678
|
-
return {
|
|
1679
|
-
commands: commands3,
|
|
1680
|
-
actions: actions4,
|
|
1681
|
-
conflicts,
|
|
1682
|
-
find: (name) => byName2.get(name.toLowerCase())
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
function parseSlash(text) {
|
|
1686
|
-
let trimmed = text.trimStart();
|
|
1687
|
-
if (!trimmed.startsWith("/") || trimmed.startsWith("//")) return null;
|
|
1688
|
-
let match = trimmed.slice(1).match(/^(\S*)\s*([\s\S]*)$/);
|
|
1689
|
-
if (!match) return null;
|
|
1690
|
-
let rest = match[2] ?? "";
|
|
1691
|
-
return { name: match[1].toLowerCase(), args: splitArgs(rest), rest };
|
|
1692
|
-
}
|
|
1693
|
-
function splitArgs(text) {
|
|
1694
|
-
let args = [], pattern = /"((?:[^"\\]|\\.)*)"|'([^']*)'|(\S+)/g, m;
|
|
1695
|
-
for (; m = pattern.exec(text); ) args.push(m[1] !== void 0 ? m[1].replace(/\\(.)/g, "$1") : m[2] ?? m[3]);
|
|
1696
|
-
return args;
|
|
1697
|
-
}
|
|
1698
|
-
function createScope(store, exit) {
|
|
1699
|
-
let state = store.getState(), selected = state.selectedAgentId, stoppedKey = isTrackedKey(selected) ? selected : null, agentId = stoppedKey ? null : selected;
|
|
1700
|
-
return {
|
|
1701
|
-
store,
|
|
1702
|
-
actions: store.actions,
|
|
1703
|
-
client: store.client,
|
|
1704
|
-
state: () => store.getState(),
|
|
1705
|
-
agentId,
|
|
1706
|
-
stoppedKey,
|
|
1707
|
-
loop: agentId ? state.selectedLoop[agentId] ?? MAIN_LOOP : MAIN_LOOP,
|
|
1708
|
-
print: (text, level = "info") => store.actions.toast(text, level),
|
|
1709
|
-
exit
|
|
1710
|
-
};
|
|
1906
|
+
] }),
|
|
1907
|
+
stateText ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(theme2.color.muted), children: [
|
|
1908
|
+
" ",
|
|
1909
|
+
stateText
|
|
1910
|
+
] }) : null,
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(fill) }),
|
|
1912
|
+
badges.map((badge, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: !0, color: c.fg(badge.startsWith(theme2.glyph.warn) ? theme2.color.warn : badge.startsWith(theme2.glyph.loop) ? theme2.color.loop : theme2.color.info), children: [
|
|
1913
|
+
" ",
|
|
1914
|
+
badge
|
|
1915
|
+
] }, badge))
|
|
1916
|
+
] });
|
|
1711
1917
|
}
|
|
1712
|
-
|
|
1713
|
-
let
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
return store.actions.toast(`/${command.name} is not available here`, "warn"), !0;
|
|
1720
|
-
let ctx = { ...scope, args: parsed.args, rest: parsed.rest };
|
|
1721
|
-
try {
|
|
1722
|
-
await command.run(ctx);
|
|
1723
|
-
} catch (err) {
|
|
1724
|
-
store.actions.toast(`/${command.name}: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
1725
|
-
}
|
|
1726
|
-
return !0;
|
|
1918
|
+
function FolderRow({ row: row4, width }) {
|
|
1919
|
+
let theme2 = useTheme(), count = `${row4.loaded}/${row4.total}`, name = truncate(folderName(row4.path), Math.max(3, width - displayWidth(count) - 1));
|
|
1920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: !0, color: theme2.color.muted, children: name }),
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(Math.max(1, width - displayWidth(name) - displayWidth(count))) }),
|
|
1923
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: theme2.color.dim, children: count })
|
|
1924
|
+
] });
|
|
1727
1925
|
}
|
|
1728
|
-
function
|
|
1729
|
-
let
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1926
|
+
function StoppedRow({ row: row4, selected, focused, width, errors, busy }) {
|
|
1927
|
+
let theme2 = useTheme(), c = rowColors(theme2, selected, focused), { entry } = row4, label2 = busy ? busy === "starting" ? "starting" : "loading" : stoppedLabel(entry, errors), glyph = stoppedGlyph(theme2, entry, errors), nameRoom = Math.max(3, width - 4), name = truncate(entry.agent.name, nameRoom), stateRoom = nameRoom - displayWidth(name) - 1, stateText = stateRoom >= 4 ? truncate(label2, stateRoom) : "", labelColor = label2 === "needs review" ? theme2.color.warn : label2 === "load error" || label2 === "unreadable" ? theme2.color.error : theme2.color.dim;
|
|
1928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { backgroundColor: c.bg, inverse: c.inverse, underline: c.underline, wrap: "truncate-end", children: [
|
|
1929
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
1930
|
+
busy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner, { color: c.fg(theme2.color.live) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(glyph.color), children: glyph.glyph }),
|
|
1931
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(selected ? theme2.color.accent : theme2.color.muted), bold: selected, children: [
|
|
1932
|
+
" ",
|
|
1933
|
+
name
|
|
1934
|
+
] }),
|
|
1935
|
+
stateText ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(labelColor), children: [
|
|
1936
|
+
" ",
|
|
1937
|
+
stateText
|
|
1938
|
+
] }) : null
|
|
1939
|
+
] });
|
|
1940
|
+
}
|
|
1941
|
+
function LoopRow({ row: row4, selected, focused, width, nextRun }) {
|
|
1942
|
+
let theme2 = useTheme(), { loop, agent: agent2 } = row4, d = describeLoop(agent2, loop), c = rowColors(theme2, selected, focused), hint = d.kind === "running" ? d.label : d.kind === "disabled" ? "off" : nextRun !== void 0 ? formatIn(nextRun) : "", nameRoom = Math.max(3, width - 5 - (hint ? displayWidth(hint) + 1 : 0)), name = truncate(loop.info.name, nameRoom), fill = Math.max(0, width - 5 - displayWidth(name) - (hint ? displayWidth(hint) + 1 : 0)), nameColor = loop.info.enabled ? loop.info.isMain ? theme2.color.accent : theme2.color.loop : theme2.color.dim;
|
|
1943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { backgroundColor: c.bg, inverse: c.inverse, underline: c.underline, wrap: "truncate-end", children: [
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " " }),
|
|
1945
|
+
d.kind === "running" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spinner, { color: c.fg(theme2.color.loop) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(d.kind === "disabled" ? theme2.color.dim : theme2.color.muted), children: d.kind === "disabled" ? "-" : theme2.glyph.ring }),
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(nameColor), children: [
|
|
1947
|
+
" ",
|
|
1948
|
+
theme2.glyph.loop
|
|
1949
|
+
] }),
|
|
1950
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: c.fg(nameColor), bold: selected, children: name }),
|
|
1951
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: " ".repeat(fill) }),
|
|
1952
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: c.fg(d.kind === "running" ? theme2.color.live : theme2.color.muted), children: [
|
|
1953
|
+
" ",
|
|
1954
|
+
hint
|
|
1955
|
+
] }) : null
|
|
1956
|
+
] });
|
|
1742
1957
|
}
|
|
1743
1958
|
|
|
1744
1959
|
// src/main/tui/app/StatusBar.tsx
|
|
@@ -1919,6 +2134,8 @@ function insertIntoPrompt(text) {
|
|
|
1919
2134
|
return promptApi.current ? (promptApi.current.insert(text), !0) : !1;
|
|
1920
2135
|
}
|
|
1921
2136
|
function slashEnterAction(value, command) {
|
|
2137
|
+
if (command.agentCommand && command.agentCommand !== "*")
|
|
2138
|
+
return command.args?.includes("<") && !hasCommandArguments(parseSlash(value)?.rest ?? "") ? { insert: `${value} ` } : { run: value };
|
|
1922
2139
|
if (/[\\/]$/.test(value)) return { insert: value };
|
|
1923
2140
|
let required = command.args?.match(/<[^>]+>/g)?.length ?? 0;
|
|
1924
2141
|
return (parseSlash(value)?.args.length ?? 0) >= required ? { run: value } : { insert: `${value} ` };
|
|
@@ -2010,39 +2227,45 @@ function Prompt({ width, focused }) {
|
|
|
2010
2227
|
] }) : null
|
|
2011
2228
|
] }, item.key)) }) : null,
|
|
2012
2229
|
badge ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComposerTop, { width, focused, badge }) : null,
|
|
2013
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
if (
|
|
2039
|
-
|
|
2040
|
-
|
|
2230
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { borderStyle: theme2.ascii ? "classic" : "round", borderTop: !badge, borderColor: focused ? theme2.color.borderFocus : theme2.color.border, paddingX: 1, width, flexDirection: "column", children: [
|
|
2231
|
+
isAuthorizedCommandInput(value, registry) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: theme2.color.warn, wrap: "truncate-end", children: [
|
|
2232
|
+
theme2.glyph.warn,
|
|
2233
|
+
" Authorized run"
|
|
2234
|
+
] }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2236
|
+
TextInput,
|
|
2237
|
+
{
|
|
2238
|
+
value,
|
|
2239
|
+
onChange: (next) => {
|
|
2240
|
+
setValue(next), setMenuIndex(0), setDismissed(!1);
|
|
2241
|
+
},
|
|
2242
|
+
onSubmit: submit,
|
|
2243
|
+
placeholder: placeholder3,
|
|
2244
|
+
history,
|
|
2245
|
+
focused,
|
|
2246
|
+
apiRef: promptApi,
|
|
2247
|
+
onKey: (_input, key, api) => {
|
|
2248
|
+
if (!menuOpen) return !1;
|
|
2249
|
+
if (key.escape)
|
|
2250
|
+
return setDismissed(!0), !0;
|
|
2251
|
+
if (key.upArrow)
|
|
2252
|
+
return setMenuIndex((i) => (i - 1 + menu.length) % menu.length), !0;
|
|
2253
|
+
if (key.downArrow)
|
|
2254
|
+
return setMenuIndex((i) => (i + 1) % menu.length), !0;
|
|
2255
|
+
if (key.tab) {
|
|
2256
|
+
let next = menu[highlighted].accept();
|
|
2257
|
+
return api.setValue(next.value, next.cursor), !0;
|
|
2258
|
+
}
|
|
2259
|
+
if (key.return && !key.shift && !key.meta) {
|
|
2260
|
+
if (api.value !== value) return !1;
|
|
2261
|
+
let item = menu[highlighted], outcome = menuEnter(api.value, item.accept(), item.command);
|
|
2262
|
+
return "insert" in outcome ? (api.setValue(outcome.insert, outcome.cursor), !0) : (api.setValue(outcome.submit), !1);
|
|
2263
|
+
}
|
|
2264
|
+
return !1;
|
|
2041
2265
|
}
|
|
2042
|
-
return !1;
|
|
2043
2266
|
}
|
|
2044
|
-
|
|
2045
|
-
|
|
2267
|
+
)
|
|
2268
|
+
] })
|
|
2046
2269
|
] });
|
|
2047
2270
|
}
|
|
2048
2271
|
|
|
@@ -3703,7 +3926,7 @@ function itemHeight(item, width, flags) {
|
|
|
3703
3926
|
case "notice":
|
|
3704
3927
|
return 1;
|
|
3705
3928
|
case "context":
|
|
3706
|
-
return flags.expanded ? 1 + wrappedHeight(item.text || " ", w - 2) + 1 : 1;
|
|
3929
|
+
return flags.expanded ? 1 + wrappedHeight(item.text || (item.ownerCommand?.status === "running" ? "Running\u2026" : item.ownerCommand ? "(empty)" : " "), w - 2) + (item.ownerCommand?.status === "denied" ? wrappedHeight("Add !authorize to allow restricted calls for one run.", w - 2) : 0) + 1 : 1;
|
|
3707
3930
|
case "error":
|
|
3708
3931
|
return wrappedHeight(item.text, w - 2) + 1;
|
|
3709
3932
|
}
|
|
@@ -3745,6 +3968,9 @@ ${answer}` : askQuestion(item.input);
|
|
|
3745
3968
|
return item.answer ? `${item.question}
|
|
3746
3969
|
|
|
3747
3970
|
${item.answer}` : item.question;
|
|
3971
|
+
case "context":
|
|
3972
|
+
return item.ownerCommand ? `${item.ownerCommand.command} [${item.ownerCommand.status}${item.ownerCommand.authorized ? ", authorized" : ""}]
|
|
3973
|
+
${item.text}` : item.text;
|
|
3748
3974
|
default:
|
|
3749
3975
|
return item.text;
|
|
3750
3976
|
}
|
|
@@ -5558,7 +5784,7 @@ async function editText(text, options = {}) {
|
|
|
5558
5784
|
var schemaParse = null;
|
|
5559
5785
|
async function loadSchema() {
|
|
5560
5786
|
if (schemaParse) return schemaParse;
|
|
5561
|
-
let schema = cjs(await import("./adf-schema-
|
|
5787
|
+
let schema = cjs(await import("./adf-schema-AIPBQTR2.mjs")).AgentConfigSchema;
|
|
5562
5788
|
return schemaParse = (value) => schema.safeParse(value), schemaParse;
|
|
5563
5789
|
}
|
|
5564
5790
|
function changedKeysBetween(a, b) {
|
|
@@ -5807,8 +6033,8 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5807
6033
|
}
|
|
5808
6034
|
await act("Save notes", { kind: "notes", id }, () => store.client.updateTemplate(id, { description, warning })) && (await refresh2(id), done(`Notes of ${label2(id)} saved`, { kind: "detail", id }));
|
|
5809
6035
|
}, edit = async (id, what, back) => {
|
|
5810
|
-
let suspend = (
|
|
5811
|
-
await
|
|
6036
|
+
let suspend = (run2) => suspendTerminal(async () => {
|
|
6037
|
+
await run2();
|
|
5812
6038
|
});
|
|
5813
6039
|
(what === "instructions" ? await editTemplateInstructions(store.actions, suspend, id) : what === "config" ? await editTemplateConfig(store.actions, suspend, id) : await editTemplateSeedFile(store.actions, suspend, id, what)) === "saved" && await refresh2(id), setStep(back);
|
|
5814
6040
|
}, removeExtra = async (id, path) => {
|
|
@@ -6042,156 +6268,6 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
6042
6268
|
// src/main/tui/skills/SkillsDialog.tsx
|
|
6043
6269
|
var import_react23 = __toESM(require_react(), 1);
|
|
6044
6270
|
|
|
6045
|
-
// src/shared/utils/skills-panel.ts
|
|
6046
|
-
var skills_panel_exports = {};
|
|
6047
|
-
__export(skills_panel_exports, {
|
|
6048
|
-
MAX_CATALOG_SOURCES: () => MAX_CATALOG_SOURCES,
|
|
6049
|
-
MAX_REGISTRY_BYTES: () => MAX_REGISTRY_BYTES,
|
|
6050
|
-
MAX_SKILLS: () => MAX_SKILLS,
|
|
6051
|
-
MAX_SKILL_FILE_BYTES: () => MAX_SKILL_FILE_BYTES,
|
|
6052
|
-
SKILLS_REGISTRY_PATH: () => SKILLS_REGISTRY_PATH,
|
|
6053
|
-
SKILLS_STATE_PATH: () => SKILLS_STATE_PATH,
|
|
6054
|
-
SKILL_MANIFEST: () => SKILL_MANIFEST,
|
|
6055
|
-
addCatalogSource: () => addCatalogSource,
|
|
6056
|
-
catalogSourceLabel: () => catalogSourceLabel,
|
|
6057
|
-
estimateTokens: () => estimateTokens,
|
|
6058
|
-
filterCatalogEntries: () => filterCatalogEntries,
|
|
6059
|
-
installedSkillNames: () => installedSkillNames,
|
|
6060
|
-
isCatalogUrl: () => isCatalogUrl,
|
|
6061
|
-
mergeCatalogResults: () => mergeCatalogResults,
|
|
6062
|
-
mergeDisabledList: () => mergeDisabledList,
|
|
6063
|
-
normalizeCatalogSources: () => normalizeCatalogSources,
|
|
6064
|
-
parseSkillsRegistry: () => parseSkillsRegistry,
|
|
6065
|
-
sanitizeDisplayText: () => sanitizeDisplayText,
|
|
6066
|
-
skillProblems: () => skillProblems,
|
|
6067
|
-
unindexedHint: () => unindexedHint
|
|
6068
|
-
});
|
|
6069
|
-
var SKILLS_REGISTRY_PATH = "skills-registry.json", SKILLS_STATE_PATH = "skills-state.json", SKILL_MANIFEST = /^skills\/([^/]+)\/SKILL\.md$/, MAX_SKILLS = 48, MAX_REGISTRY_BYTES = 32 * 1024, MAX_SKILL_FILE_BYTES = 256 * 1024;
|
|
6070
|
-
function parseSkillsRegistry(text) {
|
|
6071
|
-
if (!text) return null;
|
|
6072
|
-
try {
|
|
6073
|
-
let doc = JSON.parse(text);
|
|
6074
|
-
if (doc?.schema !== 1 || typeof doc.skills != "object" || doc.skills === null) return null;
|
|
6075
|
-
let entries = [];
|
|
6076
|
-
for (let value of Object.values(doc.skills)) {
|
|
6077
|
-
let skill = value;
|
|
6078
|
-
typeof skill?.name != "string" || typeof skill?.path != "string" || entries.push({
|
|
6079
|
-
name: skill.name,
|
|
6080
|
-
description: typeof skill.description == "string" ? skill.description : void 0,
|
|
6081
|
-
path: skill.path,
|
|
6082
|
-
enabled: skill.enabled !== !1
|
|
6083
|
-
});
|
|
6084
|
-
}
|
|
6085
|
-
let rejected = [];
|
|
6086
|
-
if (Array.isArray(doc.rejected))
|
|
6087
|
-
for (let raw of doc.rejected) {
|
|
6088
|
-
let row4 = raw;
|
|
6089
|
-
typeof row4?.path != "string" || typeof row4?.reason != "string" || rejected.push({ path: row4.path, reason: row4.reason, name: SKILL_MANIFEST.exec(row4.path)?.[1] ?? null });
|
|
6090
|
-
}
|
|
6091
|
-
return { entries: entries.sort((a, b) => a.name.localeCompare(b.name)), rejected };
|
|
6092
|
-
} catch {
|
|
6093
|
-
return null;
|
|
6094
|
-
}
|
|
6095
|
-
}
|
|
6096
|
-
function mergeDisabledList(existingText, name, enabled) {
|
|
6097
|
-
let doc = {};
|
|
6098
|
-
if (existingText)
|
|
6099
|
-
try {
|
|
6100
|
-
let parsed = JSON.parse(existingText);
|
|
6101
|
-
parsed && typeof parsed == "object" && !Array.isArray(parsed) && (doc = parsed);
|
|
6102
|
-
} catch {
|
|
6103
|
-
}
|
|
6104
|
-
let current = Array.isArray(doc.disabled) ? doc.disabled.filter((entry) => typeof entry == "string") : [], next = new Set(current);
|
|
6105
|
-
return enabled ? next.delete(name) : next.add(name), JSON.stringify({ ...doc, schema: 1, disabled: [...next].sort() }, null, 2) + `
|
|
6106
|
-
`;
|
|
6107
|
-
}
|
|
6108
|
-
var UNSAFE_DISPLAY_CHARS = /[\u0000-\u001F\u007F-\u009F\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g;
|
|
6109
|
-
function sanitizeDisplayText(value) {
|
|
6110
|
-
return value ? value.replace(UNSAFE_DISPLAY_CHARS, " ").replace(/\s+/g, " ").trim() : "";
|
|
6111
|
-
}
|
|
6112
|
-
function isCatalogUrl(value) {
|
|
6113
|
-
let trimmed = value.trim();
|
|
6114
|
-
if (!trimmed) return !1;
|
|
6115
|
-
try {
|
|
6116
|
-
return new URL(trimmed).protocol === "https:";
|
|
6117
|
-
} catch {
|
|
6118
|
-
return !1;
|
|
6119
|
-
}
|
|
6120
|
-
}
|
|
6121
|
-
function estimateTokens(bytes) {
|
|
6122
|
-
return Math.ceil(bytes / 4);
|
|
6123
|
-
}
|
|
6124
|
-
var MAX_CATALOG_SOURCES = 8;
|
|
6125
|
-
function normalizeCatalogSources(stored) {
|
|
6126
|
-
if (!Array.isArray(stored)) return [ADF_SKILLS_REGISTRY_URL];
|
|
6127
|
-
let sources2 = [], seen = /* @__PURE__ */ new Set();
|
|
6128
|
-
for (let raw of stored) {
|
|
6129
|
-
if (typeof raw != "string") continue;
|
|
6130
|
-
let url2 = raw.trim();
|
|
6131
|
-
if (!(!isCatalogUrl(url2) || seen.has(url2)) && (seen.add(url2), sources2.push(url2), sources2.length >= MAX_CATALOG_SOURCES))
|
|
6132
|
-
break;
|
|
6133
|
-
}
|
|
6134
|
-
return sources2;
|
|
6135
|
-
}
|
|
6136
|
-
function addCatalogSource(sources2, raw) {
|
|
6137
|
-
let url2 = raw.trim();
|
|
6138
|
-
return url2 ? isCatalogUrl(url2) ? sources2.includes(url2) ? { ok: !1, error: "That source is already listed." } : sources2.length >= MAX_CATALOG_SOURCES ? { ok: !1, error: `At most ${MAX_CATALOG_SOURCES} catalog sources.` } : { ok: !0, sources: [...sources2, url2] } : { ok: !1, error: "A catalog source must be an https:// URL." } : { ok: !1, error: "Enter a catalog URL." };
|
|
6139
|
-
}
|
|
6140
|
-
function catalogSourceLabel(url2, publisher) {
|
|
6141
|
-
let named = sanitizeDisplayText(publisher);
|
|
6142
|
-
if (named) return named;
|
|
6143
|
-
try {
|
|
6144
|
-
return new URL(url2).hostname;
|
|
6145
|
-
} catch {
|
|
6146
|
-
return url2;
|
|
6147
|
-
}
|
|
6148
|
-
}
|
|
6149
|
-
function mergeCatalogResults(results) {
|
|
6150
|
-
let merged = [], seen = /* @__PURE__ */ new Set();
|
|
6151
|
-
for (let result of results) {
|
|
6152
|
-
if (!result.ok) continue;
|
|
6153
|
-
let sourceLabel = catalogSourceLabel(result.url, result.publisher);
|
|
6154
|
-
for (let entry of result.entries)
|
|
6155
|
-
seen.has(entry.name) || (seen.add(entry.name), merged.push({ ...entry, sourceUrl: result.url, sourceLabel }));
|
|
6156
|
-
}
|
|
6157
|
-
return merged.sort((a, b) => a.name.localeCompare(b.name));
|
|
6158
|
-
}
|
|
6159
|
-
function filterCatalogEntries(entries, query) {
|
|
6160
|
-
let needle = query.trim().toLowerCase();
|
|
6161
|
-
if (!needle) return entries;
|
|
6162
|
-
let byName2 = [], byDescription = [];
|
|
6163
|
-
for (let entry of entries)
|
|
6164
|
-
entry.name.toLowerCase().includes(needle) ? byName2.push(entry) : entry.description.toLowerCase().includes(needle) && byDescription.push(entry);
|
|
6165
|
-
return [...byName2, ...byDescription];
|
|
6166
|
-
}
|
|
6167
|
-
function installedSkillNames(files2) {
|
|
6168
|
-
let names = /* @__PURE__ */ new Set();
|
|
6169
|
-
for (let file of files2) {
|
|
6170
|
-
let match = SKILL_MANIFEST.exec(file.path);
|
|
6171
|
-
match && names.add(match[1]);
|
|
6172
|
-
}
|
|
6173
|
-
return names;
|
|
6174
|
-
}
|
|
6175
|
-
function skillProblems(installedNames, registry) {
|
|
6176
|
-
if (!registry) return [];
|
|
6177
|
-
let indexed = new Set(registry.entries.map((s) => s.name)), rows = /* @__PURE__ */ new Map();
|
|
6178
|
-
for (let name of installedNames)
|
|
6179
|
-
indexed.has(name) || rows.set(name, { label: name, path: `skills/${name}/SKILL.md`, reason: null, isPackage: !0 });
|
|
6180
|
-
for (let rejection of registry.rejected) {
|
|
6181
|
-
let key = rejection.name ?? rejection.path;
|
|
6182
|
-
rejection.name && indexed.has(rejection.name) || rows.set(key, {
|
|
6183
|
-
label: rejection.name ?? rejection.path,
|
|
6184
|
-
path: rejection.path,
|
|
6185
|
-
reason: rejection.reason,
|
|
6186
|
-
isPackage: rejection.name !== null
|
|
6187
|
-
});
|
|
6188
|
-
}
|
|
6189
|
-
return [...rows.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([key, row4]) => ({ key, ...row4 }));
|
|
6190
|
-
}
|
|
6191
|
-
function unindexedHint() {
|
|
6192
|
-
return `not indexed \u2014 the folder name must be lowercase kebab-case and match the frontmatter name, description must be one line under 500 characters, and the file must be under ${Math.round(MAX_SKILL_FILE_BYTES / 1024)} KB. The catalog also stops at ${MAX_SKILLS} skills or ${Math.round(MAX_REGISTRY_BYTES / 1024)} KB, whichever comes first.`;
|
|
6193
|
-
}
|
|
6194
|
-
|
|
6195
6271
|
// src/shared/utils/skill-preview.ts
|
|
6196
6272
|
var skill_preview_exports = {};
|
|
6197
6273
|
__export(skill_preview_exports, {
|
|
@@ -6716,7 +6792,7 @@ var {
|
|
|
6716
6792
|
installedSkillNames: installedSkillNames2,
|
|
6717
6793
|
isCatalogUrl: isCatalogUrl2,
|
|
6718
6794
|
parseSkillsRegistry: parseSkillsRegistry2,
|
|
6719
|
-
sanitizeDisplayText:
|
|
6795
|
+
sanitizeDisplayText: sanitizeDisplayText3,
|
|
6720
6796
|
skillProblems: skillProblems2
|
|
6721
6797
|
} = cjs(skills_panel_exports), { splitSkillDocument: splitSkillDocument2 } = cjs(skill_preview_exports), { SKILL_NAME } = cjs(skills_catalog_schema_exports), SKILLS_OVERLAY = "skills", looksLikePath = (value) => /^(\.{1,2}([\\/]|$)|[\\/]|~([\\/]|$)|[A-Za-z]:[\\/])/.test(value) || /[\\/]/.test(value) || /\.md$/i.test(value);
|
|
6722
6798
|
function parseAddTarget2(raw) {
|
|
@@ -6769,7 +6845,7 @@ function settleOverrides(overrides, registryText) {
|
|
|
6769
6845
|
function tokenLabel(tokens) {
|
|
6770
6846
|
return tokens == null ? "" : tokens >= 1e3 ? `~${(tokens / 1e3).toFixed(tokens >= 1e4 ? 0 : 1)}k tok` : `~${tokens} tok`;
|
|
6771
6847
|
}
|
|
6772
|
-
var safe = (value) =>
|
|
6848
|
+
var safe = (value) => sanitizeDisplayText3(value), packageKey = (source) => source.type === "catalog" ? `catalog:${source.entry.sourceUrl}#${source.entry.name}` : source.type === "url" ? `url:${source.url}` : `disk:${source.path}`, frontmatterField = (manifest, key) => splitSkillDocument2(manifest).fields.find((f) => f.key === key)?.value, isSkillName = (value) => !!value && SKILL_NAME.test(value);
|
|
6773
6849
|
function manifestProblem(manifest) {
|
|
6774
6850
|
return Buffer.byteLength(manifest, "utf-8") > MAX_SKILL_FILE_BYTES2 ? `SKILL.md is over ${Math.round(MAX_SKILL_FILE_BYTES2 / 1024)} KB, the indexer would reject it` : manifest.slice(0, 8192).includes("\0") ? "SKILL.md is not text" : null;
|
|
6775
6851
|
}
|
|
@@ -6869,10 +6945,10 @@ async function readSkillFile(client, agentId, path) {
|
|
|
6869
6945
|
}
|
|
6870
6946
|
var stateQueues = /* @__PURE__ */ new Map();
|
|
6871
6947
|
function enqueue(agentId, task) {
|
|
6872
|
-
let
|
|
6873
|
-
return stateQueues.set(agentId,
|
|
6948
|
+
let run2 = (stateQueues.get(agentId) ?? Promise.resolve()).then(task, task);
|
|
6949
|
+
return stateQueues.set(agentId, run2.then(() => {
|
|
6874
6950
|
}, () => {
|
|
6875
|
-
})),
|
|
6951
|
+
})), run2;
|
|
6876
6952
|
}
|
|
6877
6953
|
function setSkillMuted(client, agentId, name, enabled) {
|
|
6878
6954
|
return enqueue(agentId, async () => {
|
|
@@ -7127,7 +7203,7 @@ function SkillsDialog({ overlay, close, width, height }) {
|
|
|
7127
7203
|
actions: store.actions,
|
|
7128
7204
|
agentId,
|
|
7129
7205
|
agentLabel: who,
|
|
7130
|
-
suspend: (
|
|
7206
|
+
suspend: (run2) => suspendTerminal(run2)
|
|
7131
7207
|
}, { kind: "file", path }), bump();
|
|
7132
7208
|
}, install = async (pkg2, key) => {
|
|
7133
7209
|
if (read().installs[key]?.status === "installing") return;
|
|
@@ -10106,6 +10182,34 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10106
10182
|
item.text
|
|
10107
10183
|
] });
|
|
10108
10184
|
case "context": {
|
|
10185
|
+
if (item.ownerCommand) {
|
|
10186
|
+
let command = item.ownerCommand, tone = command.status === "running" ? theme2.color.tool : command.status === "ok" ? theme2.color.success : theme2.color.error;
|
|
10187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", width: w, children: [
|
|
10188
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
10189
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: tone, children: command.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Spinner, { color: tone }) : command.status === "ok" ? g.check : g.cross }),
|
|
10190
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { bold: !0, color: theme2.color.tool, children: [
|
|
10191
|
+
" You ran ",
|
|
10192
|
+
command.command
|
|
10193
|
+
] }),
|
|
10194
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { color: tone, children: [
|
|
10195
|
+
" [",
|
|
10196
|
+
command.status === "denied" ? "permission denied" : command.status,
|
|
10197
|
+
"]"
|
|
10198
|
+
] }),
|
|
10199
|
+
command.authorized && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: theme2.color.warn, children: " [authorized]" }),
|
|
10200
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { color: theme2.color.dim, children: [
|
|
10201
|
+
" ",
|
|
10202
|
+
item.unrecorded ? "[not recorded]" : item.deferred ? "[recording after current step]" : "",
|
|
10203
|
+
" ",
|
|
10204
|
+
expanded ? g.expanded : `${g.collapsed} Enter`
|
|
10205
|
+
] })
|
|
10206
|
+
] }),
|
|
10207
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
|
|
10208
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { wrap: "wrap", color: theme2.color.muted, children: item.text || (command.status === "running" ? "Running\u2026" : "(empty)") }),
|
|
10209
|
+
command.status === "denied" && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { wrap: "wrap", color: theme2.color.warn, children: "Add !authorize to allow restricted calls for one run." })
|
|
10210
|
+
] })
|
|
10211
|
+
] });
|
|
10212
|
+
}
|
|
10109
10213
|
let label2 = item.category === "compaction" ? "compacted history summary" : `context ${g.sep} ${item.category}`;
|
|
10110
10214
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", width: w, children: [
|
|
10111
10215
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.dim, children: [
|
|
@@ -10597,6 +10701,7 @@ function stepLoop(ctx, delta) {
|
|
|
10597
10701
|
}
|
|
10598
10702
|
var chatCommands = {
|
|
10599
10703
|
commands: [
|
|
10704
|
+
agentCommand,
|
|
10600
10705
|
{
|
|
10601
10706
|
name: "interrupt",
|
|
10602
10707
|
aliases: ["abort"],
|
|
@@ -11753,7 +11858,7 @@ function FilesTab(props) {
|
|
|
11753
11858
|
actions: actions4,
|
|
11754
11859
|
agentId,
|
|
11755
11860
|
agentLabel: agentLabel5,
|
|
11756
|
-
suspend: (
|
|
11861
|
+
suspend: (run2) => suspendTerminal(run2)
|
|
11757
11862
|
}, target2, { create }) === "written") {
|
|
11758
11863
|
let key = targetKey(target2);
|
|
11759
11864
|
invalidate(key), await reloadList(), reveal(key);
|
|
@@ -12410,8 +12515,8 @@ var { CronExpressionParser } = cjs(cronParserNs), DEFAULT_NEW_LOOP_TOOLS = ["loo
|
|
|
12410
12515
|
function validateLoopName(name, existing = []) {
|
|
12411
12516
|
return name ? name === MAIN_LOOP ? '"main" is the implicit host loop' : LOOP_NAME_PATTERN.test(name) ? existing.includes(name) ? `A loop named "${name}" already exists` : null : "1-32 chars: lowercase letters, digits, _ or -, starting with a letter or digit" : "Name is required";
|
|
12412
12517
|
}
|
|
12413
|
-
function validateGoal(goal) {
|
|
12414
|
-
return goal.trim() ? goal.length > LOOP_GOAL_MAX_CHARS ? `Goal is ${goal.length} chars; the limit is ${LOOP_GOAL_MAX_CHARS}` : null
|
|
12518
|
+
function validateGoal(goal, autostart = !1) {
|
|
12519
|
+
return !goal.trim() && autostart ? "Autostart needs a goal: add one or turn autostart off" : goal.length > LOOP_GOAL_MAX_CHARS ? `Goal is ${goal.length} chars; the limit is ${LOOP_GOAL_MAX_CHARS}` : null;
|
|
12415
12520
|
}
|
|
12416
12521
|
function hostLoopTools(config2) {
|
|
12417
12522
|
if (!config2 || !Array.isArray(config2.tools)) return null;
|
|
@@ -13315,12 +13420,12 @@ function draftFromValues(v) {
|
|
|
13315
13420
|
function LoopWizard({ overlay, close, width, height }) {
|
|
13316
13421
|
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), agent2 = useAgent(props.agentId), loops2 = useLoops(props.agentId) ?? [], timers = useAgentTimers(props.agentId), { suspendTerminal } = use_app_default(), config2 = agent2?.config, host = hostLoopTools(config2), existing = props.mode === "edit" ? loops2.find((l) => l.info.name === props.name)?.info.config ?? void 0 : void 0, provider = config2?.model?.provider, models = useModelList(props.agentId, provider), takenNames = loops2.map((l) => l.info.name), initialTemplate = props.mode === "create" ? findTemplate(props.template) : void 0, [step, setStep] = (0, import_react43.useState)(props.mode === "create" && !initialTemplate ? "template" : "form"), [template, setTemplate] = (0, import_react43.useState)(initialTemplate), [values, setValues] = (0, import_react43.useState)(() => initialValues2(props, existing, initialTemplate, host, takenNames)), [touched, setTouched] = (0, import_react43.useState)(!1), [outcome, setOutcome] = (0, import_react43.useState)(null), dialogWidth = Math.max(40, Math.min(width - 4, 96)), inner = dialogWidth - 4, bodyRows = Math.max(6, height - 8), label2 = agent2 ? agentName3(store.getState(), props.agentId) : props.agentId, wanted = Array.isArray(values.tools) ? values.tools : [], options = toolOptions(host, [...wanted, ...existing?.tools ?? [], ...template?.tools ?? []]), draft = draftFromValues(values), loopName = props.mode === "edit" ? props.name ?? "" : String(values.name ?? ""), schedule = scheduleToTimer(draft, loopName), existingTimers = timers.data ? timersForLoop(timers.data, loopName) : [], errors = (0, import_react43.useMemo)(() => {
|
|
13317
13422
|
let e = {};
|
|
13318
|
-
props.mode === "create" && (e.name = validateLoopName(String(values.name ?? ""), takenNames) ?? void 0), e.goal = validateGoal(String(values.goal ?? "")) ?? void 0;
|
|
13423
|
+
props.mode === "create" && (e.name = validateLoopName(String(values.name ?? ""), takenNames) ?? void 0), e.goal = validateGoal(String(values.goal ?? ""), !!values.autostart) ?? void 0;
|
|
13319
13424
|
let compact2 = String(values.compact ?? "").trim();
|
|
13320
13425
|
return compact2 && !(Number.isInteger(Number(compact2)) && Number(compact2) > 0) && (e.compact = "Whole number of tokens, or empty to inherit"), String(values.model ?? "").trim() && !String(values.provider ?? "").trim() && (e.provider = "Provider id is required with a model"), schedule.error && (e.scheduleValue = schedule.error), e;
|
|
13321
13426
|
}, [values, schedule.error, props.mode, existing]), hasErrors = Object.values(errors).some(Boolean), fields = [
|
|
13322
13427
|
{ kind: "text", key: "name", label: "Name", placeholder: "e.g. consolidator", readOnly: props.mode === "edit", hint: "lowercase letters, digits, _ -; cannot be renamed later" },
|
|
13323
|
-
{ kind: "text", key: "goal", label: "Goal", multiline: !0, rows: 5, editor: !0, placeholder: "What this loop works on
|
|
13428
|
+
{ kind: "text", key: "goal", label: "Goal", multiline: !0, rows: 5, editor: !0, placeholder: "Optional. What this loop works on; added to its instructions.", hint: "Enter newline \xB7 Ctrl+O open in $EDITOR \xB7 \u2193 next field" },
|
|
13324
13429
|
{ kind: "checklist", key: "tools", label: "Tools", rows: 7, options: options.map((o) => ({ value: o.name, note: o.unavailable ? "not granted by host" : void 0 })), hint: host ? "restricted to tools the host has enabled; loop_compact/loop_clear are added by the runtime" : "host tool list unknown: the daemon validates on save" },
|
|
13325
13430
|
{ kind: "combo", key: "model", label: "Model", options: models.data?.models ?? [], placeholder: `inherit (${config2?.model?.model_id ?? "host model"})`, hint: models.data?.error ? `models: ${models.data.error}` : `\u2190\u2192 pick a ${provider ?? ""} model, type any id, empty = inherit` },
|
|
13326
13431
|
{ kind: "text", key: "provider", label: "Provider", hidden: !String(values.model ?? "").trim(), hint: "provider id for the override (another configured provider is allowed)" },
|
|
@@ -13346,10 +13451,10 @@ function LoopWizard({ overlay, close, width, height }) {
|
|
|
13346
13451
|
}
|
|
13347
13452
|
setStep("review");
|
|
13348
13453
|
}, createInput = () => {
|
|
13349
|
-
let model2 = String(values.model ?? "").trim(), compact2 = String(values.compact ?? "").trim();
|
|
13454
|
+
let model2 = String(values.model ?? "").trim(), compact2 = String(values.compact ?? "").trim(), goal = String(values.goal ?? "").trim();
|
|
13350
13455
|
return {
|
|
13351
13456
|
name: String(values.name),
|
|
13352
|
-
goal:
|
|
13457
|
+
...goal ? { goal } : {},
|
|
13353
13458
|
tools: wanted,
|
|
13354
13459
|
enabled: !!values.enabled,
|
|
13355
13460
|
autostart: !!values.autostart,
|
|
@@ -13459,7 +13564,7 @@ function initialValues2(props, existing, template, host, taken) {
|
|
|
13459
13564
|
if (props.mode === "edit" && existing)
|
|
13460
13565
|
return {
|
|
13461
13566
|
name: existing.name,
|
|
13462
|
-
goal: existing.goal,
|
|
13567
|
+
goal: existing.goal ?? "",
|
|
13463
13568
|
tools: [...existing.tools ?? []],
|
|
13464
13569
|
model: existing.model?.model_id ?? "",
|
|
13465
13570
|
provider: existing.model?.provider ?? "",
|
|
@@ -13513,7 +13618,7 @@ function TemplatePicker({ width, height, onPick, onCancel }) {
|
|
|
13513
13618
|
);
|
|
13514
13619
|
}
|
|
13515
13620
|
function CreateReview({ input, schedulePreview, width, rows }) {
|
|
13516
|
-
let theme2 = useTheme(), goalLines = input.goal.split(`
|
|
13621
|
+
let theme2 = useTheme(), goalLines = (input.goal || "(none)").split(`
|
|
13517
13622
|
`), goalRows = Math.max(2, Math.min(goalLines.length, rows - 12)), line = (k, v) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
13518
13623
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Text, { color: theme2.color.muted, children: k.padEnd(14) }),
|
|
13519
13624
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Text, { color: theme2.color.text, children: truncate(v, width - 14) })
|
|
@@ -14824,8 +14929,8 @@ function settingRows(config2, extras = {}) {
|
|
|
14824
14929
|
|
|
14825
14930
|
// src/main/tui/views/inspect/settings-ops.ts
|
|
14826
14931
|
var queue = Promise.resolve();
|
|
14827
|
-
function serial(
|
|
14828
|
-
let next = queue.then(
|
|
14932
|
+
function serial(run2) {
|
|
14933
|
+
let next = queue.then(run2, run2);
|
|
14829
14934
|
return queue = next.catch(() => {
|
|
14830
14935
|
}), next;
|
|
14831
14936
|
}
|
|
@@ -16836,9 +16941,9 @@ function IdentityTab2({ width, height, focused }) {
|
|
|
16836
16941
|
] });
|
|
16837
16942
|
}
|
|
16838
16943
|
function NetworkTab(props) {
|
|
16839
|
-
let store = useStore(), actions4 = useActions(), ask = async (title, message,
|
|
16944
|
+
let store = useStore(), actions4 = useActions(), ask = async (title, message, run2, done, reload) => {
|
|
16840
16945
|
if (!await actions4.confirm({ title, message, danger: !0 })) return;
|
|
16841
|
-
await actions4.run(title,
|
|
16946
|
+
await actions4.run(title, run2) !== void 0 && actions4.toast(done, "success"), reload();
|
|
16842
16947
|
};
|
|
16843
16948
|
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
|
|
16844
16949
|
ReportTab,
|