@agentdocumentformat/cli 0.7.7 → 0.8.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/README.md +1 -1
- package/dist/adf.mjs +59 -8
- package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
- package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
- package/dist/chunks/{App-5KXVPMBV.mjs → App-A5GUFCFJ.mjs} +279 -291
- package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
- package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
- package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
- package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
- package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
- package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
- package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
- package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
- package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
- package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-YJSGLMA4.mjs} +2 -2
- package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
- package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
- package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
- package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
- package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
- package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-4OGZFUKA.mjs} +126 -67
- package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-6XQZGYMK.mjs} +246 -67
- package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
- package/dist/chunks/chunk-AZYOXXVL.mjs +865 -0
- package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
- package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
- package/dist/chunks/chunk-C4GA5SI4.mjs +12799 -0
- package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
- package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
- package/dist/chunks/{chunk-HPVFJYXR.mjs → chunk-ESP3VNMX.mjs} +1 -1
- package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-G6NBFYG5.mjs} +152 -824
- package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
- package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
- package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
- package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
- package/dist/chunks/chunk-JVPZIMXW.mjs +976 -0
- package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
- package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
- package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
- package/dist/chunks/{chunk-4N4ASPH6.mjs → chunk-LCMANRYY.mjs} +4 -254
- package/dist/chunks/{chunk-TPRZQ7Z4.mjs → chunk-LGL6ML37.mjs} +4 -4
- package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
- package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
- package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
- package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
- package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
- package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
- package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-NZO5O4VN.mjs} +1 -1
- package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
- package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
- package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
- package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
- package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-PRPTKMQW.mjs} +67 -26
- package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
- package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
- package/dist/chunks/chunk-V2T6NZX2.mjs +517 -0
- package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
- package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
- package/dist/chunks/chunk-WVTPPOKK.mjs +290 -0
- package/dist/chunks/{chunk-J74STFKE.mjs → chunk-WX6QCUWI.mjs} +272 -51
- package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
- package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-XT2BJUFC.mjs} +15 -6
- package/dist/chunks/chunk-YRMKSHW3.mjs +9076 -0
- package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
- package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
- package/dist/chunks/claude-subscription-33BMZB6I.mjs +29 -0
- package/dist/chunks/{cli-AFHQ2XTN.mjs → cli-I47IFDHJ.mjs} +797 -56
- package/dist/chunks/{commands-XNJMCD5L.mjs → commands-E4EQUHE5.mjs} +5 -2
- package/dist/chunks/{daemon-CHZHTLGR.mjs → daemon-FQ5BV3AP.mjs} +84550 -70518
- package/dist/chunks/daemon-control-L3CLG63P.mjs +59 -0
- package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
- package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
- package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
- package/dist/chunks/{environment-NX277MQG.mjs → environment-R47X44GM.mjs} +1 -1
- package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
- package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
- package/dist/chunks/{open-VAU7PXT6.mjs → open-TLGS2Z3Q.mjs} +4 -4
- package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
- package/dist/chunks/{pipeline-executor-U6IMCCP3.mjs → pipeline-executor-FD4FBWQA.mjs} +8 -5
- package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
- package/dist/chunks/remote-access-cli-XXAPQWH6.mjs +268 -0
- package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
- package/dist/chunks/sdk-5FD2ZP7N.mjs +28422 -0
- package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
- package/dist/chunks/{store-HUVDJPYN.mjs → store-ZRN2WCFB.mjs} +6 -3
- package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
- package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
- package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
- package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
- package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
- package/dist/chunks/{tui-4ZWZKD4C.mjs → tui-SPSPDADM.mjs} +17 -14
- package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
- package/dist/chunks/{whatsapp-AVKT3CTJ.mjs → whatsapp-YJFFVN4Q.mjs} +8 -8
- package/package.json +1 -1
- package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
- package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
- package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
- package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
- package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
- package/dist/chunks/chunk-ZROSGV65.mjs +0 -3112
- package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
- package/dist/chunks/{telegram-YI2OHNTD.mjs → telegram-JYY2VDTI.mjs} +4 -4
|
@@ -5,9 +5,11 @@ const require = __adfCreateRequire(import.meta.url);
|
|
|
5
5
|
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = __adfDirname(__filename);
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
DaemonClient
|
|
9
|
+
} from "./chunk-6XQZGYMK.mjs";
|
|
10
|
+
import {
|
|
11
|
+
auth_flow_exports
|
|
12
|
+
} from "./chunk-BHY7QDCM.mjs";
|
|
11
13
|
import {
|
|
12
14
|
createMouseController,
|
|
13
15
|
getScreenText,
|
|
@@ -20,6 +22,8 @@ import {
|
|
|
20
22
|
setSidebarHidden
|
|
21
23
|
} from "./chunk-APRU6PHC.mjs";
|
|
22
24
|
import {
|
|
25
|
+
DaemonError,
|
|
26
|
+
MAIN_LOOP,
|
|
23
27
|
PROMPT_PREFILL_KEY,
|
|
24
28
|
SERVER_STOPPED_TEXT,
|
|
25
29
|
StoreProvider,
|
|
@@ -29,6 +33,7 @@ import {
|
|
|
29
33
|
folderName,
|
|
30
34
|
isAsyncInput,
|
|
31
35
|
isBusyState,
|
|
36
|
+
isCredentialsLocked,
|
|
32
37
|
isTrackedKey,
|
|
33
38
|
parseServer,
|
|
34
39
|
servedText,
|
|
@@ -45,7 +50,8 @@ import {
|
|
|
45
50
|
useClient,
|
|
46
51
|
useStore,
|
|
47
52
|
useTuiSelector
|
|
48
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-WX6QCUWI.mjs";
|
|
54
|
+
import "./chunk-75DC5EWN.mjs";
|
|
49
55
|
import {
|
|
50
56
|
CHANNELS_OVERLAY,
|
|
51
57
|
CHANNEL_ORDER,
|
|
@@ -117,10 +123,13 @@ import {
|
|
|
117
123
|
validateCredentials,
|
|
118
124
|
validateMcpForm,
|
|
119
125
|
validateProvider
|
|
120
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-AZYOXXVL.mjs";
|
|
121
127
|
import {
|
|
122
128
|
require_jsx_runtime
|
|
123
129
|
} from "./chunk-7CV2SA3H.mjs";
|
|
130
|
+
import {
|
|
131
|
+
cjs
|
|
132
|
+
} from "./chunk-SGUTYISF.mjs";
|
|
124
133
|
import {
|
|
125
134
|
WELCOME_INTRO,
|
|
126
135
|
WELCOME_OVERLAY,
|
|
@@ -130,37 +139,25 @@ import {
|
|
|
130
139
|
nextStepIndex,
|
|
131
140
|
welcomeFacts,
|
|
132
141
|
welcomeSteps
|
|
133
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-O7XKQ6CH.mjs";
|
|
143
|
+
import {
|
|
144
|
+
getPrefs,
|
|
145
|
+
savePrefs
|
|
146
|
+
} from "./chunk-5QU5VY7N.mjs";
|
|
134
147
|
import {
|
|
135
148
|
THEMES,
|
|
136
149
|
applyTheme,
|
|
137
150
|
findTheme,
|
|
138
151
|
nextThemeName,
|
|
139
152
|
themeNames
|
|
140
|
-
} from "./chunk-
|
|
141
|
-
import {
|
|
142
|
-
DaemonClient
|
|
143
|
-
} from "./chunk-VN7UH7I5.mjs";
|
|
144
|
-
import {
|
|
145
|
-
DaemonError,
|
|
146
|
-
MAIN_LOOP,
|
|
147
|
-
isCredentialsLocked
|
|
148
|
-
} from "./chunk-XNPZBLYL.mjs";
|
|
153
|
+
} from "./chunk-GAZO6UMI.mjs";
|
|
149
154
|
import {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
import {
|
|
157
|
-
ADF_SKILLS_REGISTRY_URL,
|
|
158
|
-
checkFetchTarget,
|
|
159
|
-
context_breakdown_exports
|
|
160
|
-
} from "./chunk-4N4ASPH6.mjs";
|
|
161
|
-
import "./chunk-2NAP2ZF7.mjs";
|
|
162
|
-
import "./chunk-5PO5PKRV.mjs";
|
|
163
|
-
import "./chunk-VMHTYDH4.mjs";
|
|
155
|
+
context_breakdown_exports,
|
|
156
|
+
guarded_fetch_exports,
|
|
157
|
+
skills_catalog_schema_exports
|
|
158
|
+
} from "./chunk-HBOFZRUS.mjs";
|
|
159
|
+
import "./chunk-4OGZFUKA.mjs";
|
|
160
|
+
import "./chunk-G6NBFYG5.mjs";
|
|
164
161
|
import {
|
|
165
162
|
Box_default,
|
|
166
163
|
Text,
|
|
@@ -177,7 +174,7 @@ import {
|
|
|
177
174
|
ThemeContext,
|
|
178
175
|
stateColor,
|
|
179
176
|
useTheme
|
|
180
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-NZLEPJ5M.mjs";
|
|
181
178
|
import {
|
|
182
179
|
isMouseGarbage,
|
|
183
180
|
lastRawInput,
|
|
@@ -193,18 +190,24 @@ import {
|
|
|
193
190
|
import {
|
|
194
191
|
require_react
|
|
195
192
|
} from "./chunk-6GJ4QHRI.mjs";
|
|
193
|
+
import {
|
|
194
|
+
ADF_SKILLS_REGISTRY_URL
|
|
195
|
+
} from "./chunk-LCMANRYY.mjs";
|
|
196
196
|
import "./chunk-UYY5M2PB.mjs";
|
|
197
|
-
import "./chunk-
|
|
198
|
-
import "./chunk-
|
|
199
|
-
import "./chunk-
|
|
197
|
+
import "./chunk-2NAP2ZF7.mjs";
|
|
198
|
+
import "./chunk-LKFHERRV.mjs";
|
|
199
|
+
import "./chunk-V2T6NZX2.mjs";
|
|
200
|
+
import "./chunk-WVTPPOKK.mjs";
|
|
201
|
+
import "./chunk-WJGPNHGX.mjs";
|
|
202
|
+
import "./chunk-PAK5JCO2.mjs";
|
|
203
|
+
import "./chunk-ZPB3HYM7.mjs";
|
|
204
|
+
import "./chunk-LTX74NU6.mjs";
|
|
200
205
|
import {
|
|
201
206
|
require_dist
|
|
202
207
|
} from "./chunk-APHX6HSV.mjs";
|
|
203
|
-
import
|
|
204
|
-
|
|
205
|
-
} from "./chunk-ZJKXHM4Q.mjs";
|
|
208
|
+
import "./chunk-NZO5O4VN.mjs";
|
|
209
|
+
import "./chunk-ZJKXHM4Q.mjs";
|
|
206
210
|
import "./chunk-RIX34QHC.mjs";
|
|
207
|
-
import "./chunk-CD3ATSXE.mjs";
|
|
208
211
|
import {
|
|
209
212
|
__export,
|
|
210
213
|
__toESM
|
|
@@ -508,10 +511,10 @@ function TextInput(props) {
|
|
|
508
511
|
var import_react3 = __toESM(require_react(), 1);
|
|
509
512
|
|
|
510
513
|
// src/main/tui/auth/model.ts
|
|
511
|
-
var AUTH_OVERLAY = "auth", SUBSCRIPTIONS = ["chatgpt", "grok"], SUBSCRIPTION_LABELS = { chatgpt: "ChatGPT", grok: "Grok" }, AUTH_EXPLAINER = "The daemon keeps its own sign-in, separate from ADF Studio\u2019s. Agents that use these providers need no changes.";
|
|
514
|
+
var AUTH_OVERLAY = "auth", SUBSCRIPTIONS = ["chatgpt", "grok", "claude"], SUBSCRIPTION_LABELS = { chatgpt: "ChatGPT", grok: "Grok", claude: "Claude" }, CLAUDE_EXPLAINER = "Claude signs in through Claude Code on the daemon host; ADF stores no Claude credentials. The sign-in is shared with Claude Code there.", AUTH_EXPLAINER = "The daemon keeps its own sign-in, separate from ADF Studio\u2019s. Agents that use these providers need no changes.";
|
|
512
515
|
function subscriptionOfType(type, id) {
|
|
513
516
|
let t = `${type ?? ""} ${id ?? ""}`.toLowerCase();
|
|
514
|
-
return t.includes("chatgpt-subscription") || !type && /chatgpt/.test(t) ? "chatgpt" : t.includes("grok-subscription") || !type && /grok/.test(t) ? "grok" : null;
|
|
517
|
+
return t.includes("chatgpt-subscription") || !type && /chatgpt/.test(t) ? "chatgpt" : t.includes("grok-subscription") || !type && /grok/.test(t) ? "grok" : t.includes("claude-subscription") ? "claude" : null;
|
|
515
518
|
}
|
|
516
519
|
function statusOf(auth, provider) {
|
|
517
520
|
let value = auth?.[provider];
|
|
@@ -538,9 +541,14 @@ function formatExpiry(expiresAt, now = Date.now()) {
|
|
|
538
541
|
}
|
|
539
542
|
function describeStatus(status) {
|
|
540
543
|
if (!status) return { text: "unknown", ok: !1 };
|
|
544
|
+
if (status.installed === !1) return { text: `Claude Code not installed${status.installUrl ? ` (${status.installUrl})` : ""}`, ok: !1 };
|
|
545
|
+
if (status.updateRequired) return { text: `Claude Code ${status.version ?? ""} is too old \xB7 ADF needs ${status.minVersion ?? "a newer version"} or newer (run \`claude update\`)`, ok: !1 };
|
|
546
|
+
let cc = status.version ? ` \xB7 Claude Code ${status.version}` : "";
|
|
541
547
|
if (status.authenticated) {
|
|
548
|
+
let failed = status.flowError && !status.flowPending ? ` \xB7 last sign-in failed: ${status.flowError}` : "";
|
|
549
|
+
if (status.plan) return { text: `signed in${status.email ? ` as ${status.email}` : ""} \xB7 ${status.plan} plan${cc}${failed}`, ok: !0 };
|
|
542
550
|
let expiry = formatExpiry(status.expiresAt);
|
|
543
|
-
return { text: `signed in${status.email ? ` as ${status.email}` : ""}${expiry ? ` \xB7 token ${expiry.startsWith("expired") ? expiry : `renews in ${expiry}`}` : ""}`, ok: !0 };
|
|
551
|
+
return { text: `signed in${status.email ? ` as ${status.email}` : ""}${expiry ? ` \xB7 token ${expiry.startsWith("expired") ? expiry : `renews in ${expiry}`}` : ""}${failed}`, ok: !0 };
|
|
544
552
|
}
|
|
545
553
|
return status.flowPending ? { text: "sign-in in progress", ok: !1 } : status.flowError ? { text: `not signed in (last attempt: ${status.flowError})`, ok: !1 } : { text: "not signed in", ok: !1 };
|
|
546
554
|
}
|
|
@@ -1037,6 +1045,9 @@ function completePath(input, options = {}) {
|
|
|
1037
1045
|
}
|
|
1038
1046
|
return { value: dirPart + (common.length > base2.length ? common : base2), candidates };
|
|
1039
1047
|
}
|
|
1048
|
+
function lockedNote(fields) {
|
|
1049
|
+
return fields && fields.length > 0 ? `; locked against agent edits: ${fields.join(", ")}` : "";
|
|
1050
|
+
}
|
|
1040
1051
|
|
|
1041
1052
|
// src/main/tui/views/fleet/data.ts
|
|
1042
1053
|
var import_react4 = __toESM(require_react(), 1);
|
|
@@ -1250,13 +1261,14 @@ ${bits}` : "";
|
|
|
1250
1261
|
if (!await store.actions.confirm({
|
|
1251
1262
|
title: "Review required",
|
|
1252
1263
|
message: `${filePath} has not been reviewed on this daemon.${summary}
|
|
1253
|
-
Accept the review and load it
|
|
1264
|
+
Accept the review and load it? Accepting also locks its security-sensitive settings against the agent's own edits, as Studio does.`,
|
|
1254
1265
|
confirmLabel: "Accept + load",
|
|
1255
1266
|
danger: !0
|
|
1256
1267
|
}))
|
|
1257
1268
|
return store.actions.toast("Not loaded (review declined)", "warn"), !1;
|
|
1258
1269
|
try {
|
|
1259
|
-
|
|
1270
|
+
let accepted = await store.client.acceptReview(filePath);
|
|
1271
|
+
return store.actions.toast(`Review accepted for ${filePath}${lockedNote(accepted.lockedFields)}`, "success", 6e3), !0;
|
|
1260
1272
|
} catch (err) {
|
|
1261
1273
|
return failure(store, null, "Accept review", err), !1;
|
|
1262
1274
|
}
|
|
@@ -3830,7 +3842,7 @@ function wakesText(timers, now = Date.now(), sep4 = "\xB7") {
|
|
|
3830
3842
|
}
|
|
3831
3843
|
|
|
3832
3844
|
// src/main/tui/auth/flow.ts
|
|
3833
|
-
var { loginChatGpt, loginGrok, openBrowser
|
|
3845
|
+
var { loginChatGpt, loginClaude, loginGrok, openBrowser } = cjs(auth_flow_exports), seams = { openBrowser };
|
|
3834
3846
|
function openUrl(url2) {
|
|
3835
3847
|
seams.openBrowser(url2);
|
|
3836
3848
|
}
|
|
@@ -3843,7 +3855,7 @@ async function signIn(client, provider, signal, handlers) {
|
|
|
3843
3855
|
startCallbackServer: seams.startCallbackServer
|
|
3844
3856
|
};
|
|
3845
3857
|
try {
|
|
3846
|
-
return provider === "chatgpt" ? await loginChatGpt(deps, { daemonUrl: client.baseUrl, onStart: (info) => handlers.onChatGpt?.(info) }) : await loginGrok(deps, { onStart: (info) => handlers.onGrok?.(info) });
|
|
3858
|
+
return provider === "claude" ? await loginClaude(deps, { onStart: (info) => handlers.onClaude?.(info) }) : provider === "chatgpt" ? await loginChatGpt(deps, { daemonUrl: client.baseUrl, onStart: (info) => handlers.onChatGpt?.(info) }) : await loginGrok(deps, { onStart: (info) => handlers.onGrok?.(info) });
|
|
3847
3859
|
} catch (err) {
|
|
3848
3860
|
return signal.aborted ? { ok: !1, error: "Sign-in cancelled", cancelled: !0 } : { ok: !1, error: err instanceof Error ? err.message : String(err) };
|
|
3849
3861
|
}
|
|
@@ -3852,14 +3864,15 @@ async function signIn(client, provider, signal, handlers) {
|
|
|
3852
3864
|
// src/main/tui/auth/AuthDialog.tsx
|
|
3853
3865
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
3854
3866
|
function AuthDialog({ overlay, close, width }) {
|
|
3855
|
-
let theme2 = useTheme(), store = useStore(), auth = useTuiSelector((s) => s.auth), props = overlay.props ?? {}, [cursor, setCursor] = (0, import_react15.useState)(Math.max(0, SUBSCRIPTIONS.indexOf(props.login ?? "chatgpt"))), [flow, setFlow] = (0, import_react15.useState)({ kind: "list" }), [note, setNote] = (0, import_react15.useState)(null), abort = (0, import_react15.useRef)(null), dialogWidth = Math.max(50, Math.min(width - 4, 84));
|
|
3867
|
+
let theme2 = useTheme(), store = useStore(), auth = useTuiSelector((s) => s.auth), props = overlay.props ?? {}, [cursor, setCursor] = (0, import_react15.useState)(Math.max(0, SUBSCRIPTIONS.indexOf(props.login ?? "chatgpt"))), [flow, setFlow] = (0, import_react15.useState)({ kind: "list" }), [note, setNote] = (0, import_react15.useState)(null), [pasted, setPasted] = (0, import_react15.useState)(""), abort = (0, import_react15.useRef)(null), dialogWidth = Math.max(50, Math.min(width - 4, 84));
|
|
3856
3868
|
(0, import_react15.useEffect)(() => (store.actions.refreshAuth(), props.login && start(props.login), () => abort.current?.abort()), []);
|
|
3857
3869
|
let start = (provider) => {
|
|
3858
3870
|
abort.current?.abort();
|
|
3859
3871
|
let ctrl = new AbortController();
|
|
3860
|
-
abort.current = ctrl, setNote(null), setFlow({ kind: "running", provider }), signIn(store.client, provider, ctrl.signal, {
|
|
3872
|
+
abort.current = ctrl, setNote(null), setPasted(""), setFlow({ kind: "running", provider }), signIn(store.client, provider, ctrl.signal, {
|
|
3861
3873
|
onChatGpt: (info) => setFlow({ kind: "running", provider, url: info.authUrl, relay: info.mode === "relay" ? info.redirectUri : void 0 }),
|
|
3862
|
-
onGrok: (info) => setFlow({ kind: "running", provider, url: info.verificationUri, code: info.userCode })
|
|
3874
|
+
onGrok: (info) => setFlow({ kind: "running", provider, url: info.verificationUri, code: info.userCode }),
|
|
3875
|
+
onClaude: (info) => setFlow({ kind: "running", provider, url: info.url || void 0, started: !0 })
|
|
3863
3876
|
}).then((outcome) => {
|
|
3864
3877
|
if (ctrl.signal.aborted && !outcome.ok) return;
|
|
3865
3878
|
abort.current = null, store.actions.refreshAuth();
|
|
@@ -3868,6 +3881,12 @@ function AuthDialog({ overlay, close, width }) {
|
|
|
3868
3881
|
});
|
|
3869
3882
|
}, cancel = () => {
|
|
3870
3883
|
flow.kind === "running" && (abort.current?.abort(), abort.current = null, setNote(`${SUBSCRIPTION_LABELS[flow.provider]} sign-in cancelled.`), setFlow({ kind: "list" }));
|
|
3884
|
+
}, sendCode = (value) => {
|
|
3885
|
+
let code = value.trim();
|
|
3886
|
+
return code ? (setPasted(""), setNote("Sending the code to Claude Code\u2026"), store.client.submitClaudeCode(code).then(
|
|
3887
|
+
() => setNote("Code sent. Waiting for Claude Code to finish\u2026"),
|
|
3888
|
+
(err) => setNote(`Could not send the code: ${err instanceof Error ? err.message : String(err)}`)
|
|
3889
|
+
), !0) : !1;
|
|
3871
3890
|
}, copyUrl = (url2) => {
|
|
3872
3891
|
url2 && copyToClipboard(url2).then((ok) => setNote(ok ? "URL copied to the clipboard." : "Could not copy; select the URL with the mouse instead."));
|
|
3873
3892
|
};
|
|
@@ -3892,25 +3911,30 @@ function AuthDialog({ overlay, close, width }) {
|
|
|
3892
3911
|
} else (input === "n" || key.escape) && setFlow({ kind: "list" });
|
|
3893
3912
|
return !0;
|
|
3894
3913
|
case "running":
|
|
3895
|
-
return key.escape ? (cancel(), !0) : (input === "c" && copyUrl(flow.url), !0);
|
|
3914
|
+
return key.escape ? (cancel(), !0) : (input === "c" && flow.provider !== "claude" && copyUrl(flow.url), !0);
|
|
3896
3915
|
case "done":
|
|
3897
3916
|
return key.escape || key.return ? (flow.outcome.ok ? close() : setFlow({ kind: "list" }), !0) : input === "r" && !flow.outcome.ok ? (start(flow.provider), !0) : (input === "c" && copyUrl(flow.url), !0);
|
|
3898
3917
|
}
|
|
3899
3918
|
}, { layer: "overlay" });
|
|
3900
3919
|
let noteLine = note ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, wrap: "wrap", children: note }) : null;
|
|
3901
3920
|
if (flow.kind === "running" || flow.kind === "done") {
|
|
3902
|
-
let label2 = SUBSCRIPTION_LABELS[flow.provider], running2 = flow.kind === "running", code = running2 ? flow.code : void 0, url2 = flow.url, hints2 = running2 ? [...url2 ? [{ keys: "c", label: "copy URL" }] : [], { keys: "esc", label: "cancel" }] : flow.outcome.ok ? [{ keys: "enter", label: "close" }] : [{ keys: "r", label: "try again" }, { keys: "esc", label: "back" }];
|
|
3921
|
+
let label2 = SUBSCRIPTION_LABELS[flow.provider], running2 = flow.kind === "running", code = running2 ? flow.code : void 0, url2 = flow.url, claude = flow.provider === "claude", claudeWaiting = running2 && claude && !!flow.started, hints2 = running2 ? claude ? [...claudeWaiting ? [{ keys: "enter", label: "send code" }] : [], { keys: "esc", label: "cancel" }] : [...url2 ? [{ keys: "c", label: "copy URL" }] : [], { keys: "esc", label: "cancel" }] : flow.outcome.ok ? [{ keys: "enter", label: "close" }] : [{ keys: "r", label: "try again" }, { keys: "esc", label: "back" }];
|
|
3903
3922
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Modal, { title: `Sign in to ${label2}`, width: dialogWidth, hints: hints2, children: [
|
|
3904
|
-
running2 && !url2 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner, { label: `asking the daemon to start ${label2} sign-in\u2026` }) : null,
|
|
3923
|
+
running2 && !url2 && !(running2 && flow.started) ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner, { label: `asking the daemon to start ${label2} sign-in\u2026` }) : null,
|
|
3924
|
+
claude ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, wrap: "wrap", children: CLAUDE_EXPLAINER }) : null,
|
|
3905
3925
|
code ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [
|
|
3906
3926
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, children: "Enter this code in the browser:" }),
|
|
3907
3927
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { borderStyle: theme2.ascii ? "classic" : "double", borderColor: theme2.color.accent, paddingX: 3, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { bold: !0, color: theme2.color.accent, children: spacedCode(code) }) })
|
|
3908
3928
|
] }) : null,
|
|
3909
3929
|
url2 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3910
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, children: code ? "on this page (the browser should open it):" : "The browser should open. If it does not, open this URL:" }),
|
|
3930
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, children: code ? "on this page (the browser should open it):" : claude ? "Claude Code is opening the sign-in page in the browser on the daemon host. If it does not open there, open this URL:" : "The browser should open. If it does not, open this URL:" }),
|
|
3911
3931
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.info, wrap: "wrap", children: url2 })
|
|
3912
3932
|
] }) : null,
|
|
3913
|
-
|
|
3933
|
+
claudeWaiting ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
3934
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.text, children: "If the page shows a code, paste it here (or wait):" }),
|
|
3935
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { borderStyle: theme2.ascii ? "classic" : "round", borderColor: theme2.color.borderFocus, paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TextInput, { value: pasted, onChange: setPasted, onSubmit: sendCode, focused: !0, keyLayer: "overlay", maxRows: 2, placeholder: "code from the Claude sign-in page" }) })
|
|
3936
|
+
] }) : null,
|
|
3937
|
+
running2 && (url2 || claudeWaiting) ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner, { label: flow.relay ? `waiting for you to finish in the browser\u2026 (callback on ${flow.relay})` : "waiting for you to finish in the browser\u2026" }) }) : null,
|
|
3914
3938
|
running2 ? null : flow.outcome.ok ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text, { bold: !0, color: theme2.color.success, children: [
|
|
3915
3939
|
theme2.glyph.check,
|
|
3916
3940
|
" Signed in to ",
|
|
@@ -4482,8 +4506,8 @@ var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1), MODEL_OVERLAY = "i
|
|
|
4482
4506
|
function providerChoices(providers, auth) {
|
|
4483
4507
|
return providers.map((p) => {
|
|
4484
4508
|
let type = String(p.type ?? ""), id = String(p.id ?? ""), name = String(p.name ?? id);
|
|
4485
|
-
if (type === "chatgpt-subscription" || type === "grok-subscription") {
|
|
4486
|
-
let signedIn = type === "chatgpt-subscription" ? auth?.chatgpt : auth?.grok;
|
|
4509
|
+
if (type === "chatgpt-subscription" || type === "grok-subscription" || type === "claude-subscription") {
|
|
4510
|
+
let signedIn = type === "chatgpt-subscription" ? auth?.chatgpt : type === "grok-subscription" ? auth?.grok : auth?.claude;
|
|
4487
4511
|
return { id, name, type, access: signedIn?.authenticated ? "signed in" : "not signed in (/login)", ready: !!signedIn?.authenticated };
|
|
4488
4512
|
}
|
|
4489
4513
|
if (p.hasApiKey === !0) return { id, name, type, access: "key set", ready: !0 };
|
|
@@ -4631,14 +4655,14 @@ var { normalizeAuthProvider } = cjs(auth_flow_exports);
|
|
|
4631
4655
|
function openAuth(actions4, props = {}) {
|
|
4632
4656
|
actions4.pushOverlay({ kind: AUTH_OVERLAY, props: { ...props } });
|
|
4633
4657
|
}
|
|
4634
|
-
var complete = (partial) => ["chatgpt", "grok"].filter((v) => v.startsWith(partial.trim().toLowerCase())), authCommand = {
|
|
4658
|
+
var complete = (partial) => ["chatgpt", "grok", "claude"].filter((v) => v.startsWith(partial.trim().toLowerCase())), authCommand = {
|
|
4635
4659
|
name: "auth",
|
|
4636
|
-
description: "Provider sign-in: ChatGPT and
|
|
4660
|
+
description: "Provider sign-in: ChatGPT, Grok and Claude status, sign in, sign out",
|
|
4637
4661
|
run: (ctx) => openAuth(ctx.actions)
|
|
4638
4662
|
}, loginCommand = {
|
|
4639
4663
|
name: "login",
|
|
4640
|
-
args: "[chatgpt|grok]",
|
|
4641
|
-
description: "Sign the daemon in to ChatGPT (browser)
|
|
4664
|
+
args: "[chatgpt|grok|claude]",
|
|
4665
|
+
description: "Sign the daemon in to ChatGPT (browser), Grok (device code) or Claude (Claude Code on the daemon host)",
|
|
4642
4666
|
complete,
|
|
4643
4667
|
run: (ctx) => {
|
|
4644
4668
|
if (!ctx.args[0]) {
|
|
@@ -4647,29 +4671,30 @@ var complete = (partial) => ["chatgpt", "grok"].filter((v) => v.startsWith(parti
|
|
|
4647
4671
|
}
|
|
4648
4672
|
let provider = normalizeAuthProvider(ctx.args[0]);
|
|
4649
4673
|
if (!provider) {
|
|
4650
|
-
ctx.print("Usage: /login [chatgpt|grok]", "warn");
|
|
4674
|
+
ctx.print("Usage: /login [chatgpt|grok|claude]", "warn");
|
|
4651
4675
|
return;
|
|
4652
4676
|
}
|
|
4653
4677
|
openAuth(ctx.actions, { login: provider });
|
|
4654
4678
|
}
|
|
4655
4679
|
}, logoutCommand = {
|
|
4656
4680
|
name: "logout",
|
|
4657
|
-
args: "<chatgpt|grok>",
|
|
4658
|
-
description: "Sign the daemon out of ChatGPT or
|
|
4681
|
+
args: "<chatgpt|grok|claude>",
|
|
4682
|
+
description: "Sign the daemon out of ChatGPT, Grok or Claude (asks)",
|
|
4659
4683
|
complete,
|
|
4660
4684
|
run: async (ctx) => {
|
|
4661
4685
|
let provider = normalizeAuthProvider(ctx.args[0]);
|
|
4662
4686
|
if (!provider) {
|
|
4663
|
-
ctx.print("Usage: /logout <chatgpt|grok>", "warn");
|
|
4687
|
+
ctx.print("Usage: /logout <chatgpt|grok|claude>", "warn");
|
|
4664
4688
|
return;
|
|
4665
4689
|
}
|
|
4666
|
-
let label2 = SUBSCRIPTION_LABELS[provider];
|
|
4667
|
-
await ctx.actions.confirm({ title: `Sign out of ${label2}`, message: `Sign the daemon out of ${label2}? Agents using it stop working until you sign in again
|
|
4690
|
+
let label2 = SUBSCRIPTION_LABELS[provider], shared = provider === "claude" ? " This also signs Claude Code out on the daemon host." : "";
|
|
4691
|
+
await ctx.actions.confirm({ title: `Sign out of ${label2}`, message: `Sign the daemon out of ${label2}? Agents using it stop working until you sign in again.${shared}`, confirmLabel: "Sign out", danger: !0 }) && await ctx.actions.logoutSubscription(provider);
|
|
4668
4692
|
}
|
|
4669
4693
|
}, authActions = [
|
|
4670
|
-
{ id: "shell.auth", title: "Provider sign-in", hint: "ChatGPT, Grok", group: "Actions", keywords: ["auth", "login", "sign in", "subscription", "account"], run: (ctx) => openAuth(ctx.actions) },
|
|
4694
|
+
{ id: "shell.auth", title: "Provider sign-in", hint: "ChatGPT, Grok, Claude", group: "Actions", keywords: ["auth", "login", "sign in", "subscription", "account"], run: (ctx) => openAuth(ctx.actions) },
|
|
4671
4695
|
{ id: "shell.auth.chatgpt", title: "Sign in to ChatGPT", group: "Actions", keywords: ["login", "openai", "codex", "auth"], available: (s) => !statusOf(s.state().auth, "chatgpt")?.authenticated, run: (ctx) => openAuth(ctx.actions, { login: "chatgpt" }) },
|
|
4672
|
-
{ id: "shell.auth.grok", title: "Sign in to Grok", group: "Actions", keywords: ["login", "xai", "auth", "device code"], available: (s) => !statusOf(s.state().auth, "grok")?.authenticated, run: (ctx) => openAuth(ctx.actions, { login: "grok" }) }
|
|
4696
|
+
{ id: "shell.auth.grok", title: "Sign in to Grok", group: "Actions", keywords: ["login", "xai", "auth", "device code"], available: (s) => !statusOf(s.state().auth, "grok")?.authenticated, run: (ctx) => openAuth(ctx.actions, { login: "grok" }) },
|
|
4697
|
+
{ id: "shell.auth.claude", title: "Sign in to Claude", group: "Actions", keywords: ["login", "anthropic", "claude code", "auth", "subscription"], available: (s) => !statusOf(s.state().auth, "claude")?.authenticated, run: (ctx) => openAuth(ctx.actions, { login: "claude" }) }
|
|
4673
4698
|
];
|
|
4674
4699
|
|
|
4675
4700
|
// src/main/tui/setup/ProviderDialog.tsx
|
|
@@ -5533,7 +5558,7 @@ async function editText(text, options = {}) {
|
|
|
5533
5558
|
var schemaParse = null;
|
|
5534
5559
|
async function loadSchema() {
|
|
5535
5560
|
if (schemaParse) return schemaParse;
|
|
5536
|
-
let schema = cjs(await import("./adf-schema-
|
|
5561
|
+
let schema = cjs(await import("./adf-schema-YJSGLMA4.mjs")).AgentConfigSchema;
|
|
5537
5562
|
return schemaParse = (value) => schema.safeParse(value), schemaParse;
|
|
5538
5563
|
}
|
|
5539
5564
|
function changedKeysBetween(a, b) {
|
|
@@ -5738,6 +5763,10 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5738
5763
|
}, openReview = async (id, back) => {
|
|
5739
5764
|
let r = await act("Review", back, () => store.client.templateReview(id));
|
|
5740
5765
|
if (r) {
|
|
5766
|
+
if (r.identityReady === !1) {
|
|
5767
|
+
close(), openIdentity(store, { mode: "status", then: TEMPLATES_OVERLAY, thenProps: { id }, reason: `Review: ${r.message ?? "Set up the owner identity first."}` });
|
|
5768
|
+
return;
|
|
5769
|
+
}
|
|
5741
5770
|
if (!r.needsReview) {
|
|
5742
5771
|
await refresh2(), done(`${label2(id)} is already reviewed`, back);
|
|
5743
5772
|
return;
|
|
@@ -5881,7 +5910,7 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5881
5910
|
}
|
|
5882
5911
|
if (step.kind === "review")
|
|
5883
5912
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Modal, { title: `Review ${theme2.glyph.sep} ${label2(step.id)} template`, width: dialogWidth, hints: [{ keys: "y enter", label: "claim + accept" }, { keys: "up down", label: "scroll" }, { keys: "n esc", label: "cancel" }], children: [
|
|
5884
|
-
step.review ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LinesView, { lines: reviewLines(step.review.summary, inner), width: inner, height: fitLines(reviewLines(step.review.summary, inner).length), keyLayer: "overlay" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Spinner, { label: "reading the template\u2026" }),
|
|
5913
|
+
step.review?.summary ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LinesView, { lines: reviewLines(step.review.summary, inner), width: inner, height: fitLines(reviewLines(step.review.summary, inner).length), keyLayer: "overlay" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Spinner, { label: "reading the template\u2026" }),
|
|
5885
5914
|
errorLine
|
|
5886
5915
|
] });
|
|
5887
5916
|
if (step.kind === "files") {
|
|
@@ -6482,20 +6511,62 @@ function describeDiff(before, after, preview = 6) {
|
|
|
6482
6511
|
return diff.changes.length > preview && lines.push(` \u2026 ${diff.changes.length - preview} more changed lines`), { summary, lines };
|
|
6483
6512
|
}
|
|
6484
6513
|
|
|
6514
|
+
// src/shared/types/resource-revision.types.ts
|
|
6515
|
+
var resource_revision_types_exports = {};
|
|
6516
|
+
__export(resource_revision_types_exports, {
|
|
6517
|
+
describeWriter: () => describeWriter
|
|
6518
|
+
});
|
|
6519
|
+
function describeWriter(writer2) {
|
|
6520
|
+
if (!writer2) return "someone else";
|
|
6521
|
+
switch (writer2.kind) {
|
|
6522
|
+
case "agent":
|
|
6523
|
+
return "the agent";
|
|
6524
|
+
case "cli":
|
|
6525
|
+
return "the CLI or another API client";
|
|
6526
|
+
case "client":
|
|
6527
|
+
return writer2.client === "studio" ? "another Studio window" : writer2.client === "tui" ? "the terminal app" : `another client (${writer2.client})`;
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
|
|
6531
|
+
// src/main/tui/util/revisions.ts
|
|
6532
|
+
var { describeWriter: describeWriter2 } = cjs(resource_revision_types_exports);
|
|
6533
|
+
function revisionOf(result) {
|
|
6534
|
+
let revision = result?.revision;
|
|
6535
|
+
return typeof revision == "number" ? revision : void 0;
|
|
6536
|
+
}
|
|
6537
|
+
function staleRevisionOf(err) {
|
|
6538
|
+
if (!(err instanceof DaemonError) || err.status !== 409) return null;
|
|
6539
|
+
let body = err.body;
|
|
6540
|
+
return body?.code !== "stale_revision" || typeof body.revision != "number" ? null : { revision: body.revision, writer: body.writer ?? null };
|
|
6541
|
+
}
|
|
6542
|
+
function changedBy(stale) {
|
|
6543
|
+
return `changed by ${describeWriter2(stale.writer)}`;
|
|
6544
|
+
}
|
|
6545
|
+
async function writeOver(write2) {
|
|
6546
|
+
try {
|
|
6547
|
+
return { ok: await write2() };
|
|
6548
|
+
} catch (err) {
|
|
6549
|
+
let stale = staleRevisionOf(err);
|
|
6550
|
+
if (stale) return { stale };
|
|
6551
|
+
throw err;
|
|
6552
|
+
}
|
|
6553
|
+
}
|
|
6554
|
+
|
|
6485
6555
|
// src/main/tui/views/files/io.ts
|
|
6486
6556
|
async function loadTarget(client, agentId, target2) {
|
|
6487
6557
|
if (target2.kind === "document" || target2.kind === "mind") {
|
|
6488
|
-
let
|
|
6489
|
-
return { target: target2, text: text2, binary: !1, mime: "text/markdown", size: Buffer.byteLength(text2, "utf-8") };
|
|
6558
|
+
let result = target2.kind === "document" ? await client.document(agentId) : await client.mind(agentId), text2 = result.content ?? "";
|
|
6559
|
+
return { target: target2, text: text2, binary: !1, mime: "text/markdown", size: Buffer.byteLength(text2, "utf-8"), revision: revisionOf(result) };
|
|
6490
6560
|
}
|
|
6491
|
-
let file = await client.file(agentId, target2.path), base2 = { target: target2, mime: file.mime_type, size: file.size, protection: file.protection, authorized: file.authorized, updatedAt: file.updated_at };
|
|
6561
|
+
let file = await client.file(agentId, target2.path), base2 = { target: target2, mime: file.mime_type, size: file.size, protection: file.protection, authorized: file.authorized, updatedAt: file.updated_at, revision: revisionOf(file) };
|
|
6492
6562
|
if (file.encoding === "base64")
|
|
6493
6563
|
return { ...base2, binary: !0, bytes: Buffer.from(file.content_base64 ?? "", "base64") };
|
|
6494
6564
|
let text = file.content ?? "";
|
|
6495
6565
|
return looksBinary(text) ? { ...base2, binary: !0, bytes: Buffer.from(text, "utf-8") } : { ...base2, text, binary: !1 };
|
|
6496
6566
|
}
|
|
6497
|
-
async function writeTarget(client, agentId, target2, text) {
|
|
6498
|
-
|
|
6567
|
+
async function writeTarget(client, agentId, target2, text, baseRevision) {
|
|
6568
|
+
let base2 = baseRevision === "absent" ? { mustNotExist: !0 } : baseRevision !== void 0 ? { baseRevision } : {}, agent2 = `/agents/${encodeURIComponent(agentId)}`;
|
|
6569
|
+
return target2.kind === "document" ? revisionOf(await client.request("PUT", `${agent2}/document`, { body: { content: text, ...base2 } })) : target2.kind === "mind" ? revisionOf(await client.request("PUT", `${agent2}/mind`, { body: { content: text, ...base2 } })) : revisionOf(await client.request("PUT", `${agent2}/files/content`, { query: { path: target2.path }, body: { content: text, ...base2 } }));
|
|
6499
6570
|
}
|
|
6500
6571
|
var pathCache = /* @__PURE__ */ new Map();
|
|
6501
6572
|
function cacheFiles(agentId, files2) {
|
|
@@ -6547,13 +6618,13 @@ async function editTarget(deps, target2, options = {}) {
|
|
|
6547
6618
|
}
|
|
6548
6619
|
if (original.charCodeAt(0) !== 65279 && (edited = stripBom2(edited)), edited === original && !options.create)
|
|
6549
6620
|
return await cleanup(), actions4.toast(`No changes to ${label2}`, "info"), "unchanged";
|
|
6550
|
-
let concurrent = null;
|
|
6621
|
+
let concurrent = null, baseRevision = options.create ? "absent" : void 0;
|
|
6551
6622
|
if (options.create)
|
|
6552
6623
|
target2.kind === "file" && (await client.files(agentId).catch(() => null))?.files.some((f) => f.path === target2.path) && (concurrent = "was created by someone else while you were editing");
|
|
6553
6624
|
else
|
|
6554
6625
|
try {
|
|
6555
6626
|
let current = await loadTarget(client, agentId, target2);
|
|
6556
|
-
current.text !== original && (concurrent = `changed while you were editing (their change: ${describeDiff(original, current.text ?? "", 0).summary})`);
|
|
6627
|
+
baseRevision = current.revision, current.text !== original && (concurrent = `changed while you were editing (their change: ${describeDiff(original, current.text ?? "", 0).summary})`);
|
|
6557
6628
|
} catch (err) {
|
|
6558
6629
|
concurrent = err.status === 404 ? "was deleted while you were editing" : `could not be re-checked (${err instanceof Error ? err.message : String(err)})`;
|
|
6559
6630
|
}
|
|
@@ -6563,195 +6634,44 @@ async function editTarget(deps, target2, options = {}) {
|
|
|
6563
6634
|
...diff.lines
|
|
6564
6635
|
].filter((line) => line !== null).join(`
|
|
6565
6636
|
`);
|
|
6566
|
-
|
|
6637
|
+
if (!await actions4.confirm({
|
|
6567
6638
|
title: concurrent ? `Concurrent change: ${label2}` : `${options.create ? "Create" : "Save"} ${label2}`,
|
|
6568
6639
|
message,
|
|
6569
6640
|
confirmLabel: concurrent ? "Overwrite" : options.create ? "Create" : "Write",
|
|
6570
6641
|
cancelLabel: "Discard",
|
|
6571
6642
|
danger: !!concurrent
|
|
6572
|
-
})
|
|
6573
|
-
}
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
var guarded_fetch_exports = {};
|
|
6577
|
-
__export(guarded_fetch_exports, {
|
|
6578
|
-
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
6579
|
-
MAX_FETCH_REDIRECTS: () => MAX_FETCH_REDIRECTS,
|
|
6580
|
-
daemonGuardPort: () => daemonGuardPort,
|
|
6581
|
-
guardedFetch: () => guardedFetch,
|
|
6582
|
-
isFetchFailure: () => isFetchFailure
|
|
6583
|
-
});
|
|
6584
|
-
var DEFAULT_DAEMON_PORT = 7385, MAX_FETCH_REDIRECTS = 3;
|
|
6585
|
-
function daemonGuardPort() {
|
|
6586
|
-
return Number(process.env.ADF_DAEMON_PORT) || DEFAULT_DAEMON_PORT;
|
|
6587
|
-
}
|
|
6588
|
-
function isFetchFailure(result) {
|
|
6589
|
-
return "error" in result;
|
|
6643
|
+
}))
|
|
6644
|
+
return actions4.toast(`Not written. Your edited copy is kept at ${file}`, "warn", 12e3), "discarded";
|
|
6645
|
+
let written = await writeOverConflicts(actions4, label2, file, (base2) => actions4.run(`Write ${label2}`, (c) => writeOver(() => writeTarget(c, agentId, target2, edited, base2))), baseRevision);
|
|
6646
|
+
return written === "reloaded" ? "discarded" : written ? (await cleanup(), actions4.toast(`${options.create ? "Created" : "Saved"} ${label2} (${diff.summary})`, "success"), "written") : (actions4.toast(`Write failed. Your edited copy is kept at ${file}`, "error", 12e3), "failed");
|
|
6590
6647
|
}
|
|
6591
|
-
async function
|
|
6592
|
-
let
|
|
6593
|
-
if (!body) return Buffer.alloc(0);
|
|
6594
|
-
if (typeof body.getReader != "function") {
|
|
6595
|
-
let bytes = Buffer.from(new Uint8Array(await response.arrayBuffer()));
|
|
6596
|
-
return bytes.length > maxBytes ? { error: `exceeds ${maxBytes} bytes` } : bytes;
|
|
6597
|
-
}
|
|
6598
|
-
let reader2 = body.getReader(), chunks = [], total = 0;
|
|
6648
|
+
async function writeOverConflicts(actions4, label2, file, write2, baseRevision) {
|
|
6649
|
+
let base2 = baseRevision;
|
|
6599
6650
|
for (; ; ) {
|
|
6600
|
-
let
|
|
6601
|
-
if (
|
|
6602
|
-
if (
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
}
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
}
|
|
6615
|
-
async function guardedFetch(url2, options) {
|
|
6616
|
-
let { maxBytes, timeoutMs } = options, maxRedirects = options.maxRedirects ?? MAX_FETCH_REDIRECTS, daemonPort = daemonGuardPort(), current;
|
|
6617
|
-
try {
|
|
6618
|
-
current = new URL(url2).toString();
|
|
6619
|
-
} catch {
|
|
6620
|
-
return { error: `invalid URL: ${String(url2).slice(0, 200)}` };
|
|
6621
|
-
}
|
|
6622
|
-
let controller = new AbortController(), timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
6623
|
-
try {
|
|
6624
|
-
for (let hop = 0; ; hop++) {
|
|
6625
|
-
let protocol = new URL(current).protocol;
|
|
6626
|
-
if (protocol !== "https:")
|
|
6627
|
-
return { error: `only https URLs may be fetched (got "${protocol}")` };
|
|
6628
|
-
let blocked = await checkFetchTarget(current, { allowLocal: !1, daemonPort });
|
|
6629
|
-
if (blocked) return { error: blocked };
|
|
6630
|
-
let response = await fetch(current, { signal: controller.signal, redirect: "manual" });
|
|
6631
|
-
if (response.status >= 300 && response.status <= 399) {
|
|
6632
|
-
let location = response.headers.get("location");
|
|
6633
|
-
if (!location) return { error: `redirect without a location header (HTTP ${response.status})` };
|
|
6634
|
-
if (hop >= maxRedirects) return { error: `too many redirects (>${maxRedirects})` };
|
|
6635
|
-
try {
|
|
6636
|
-
await response.body?.cancel();
|
|
6637
|
-
} catch {
|
|
6638
|
-
}
|
|
6639
|
-
try {
|
|
6640
|
-
current = new URL(location, current).toString();
|
|
6641
|
-
} catch {
|
|
6642
|
-
return { error: `redirect to an unusable location: ${location.slice(0, 200)}` };
|
|
6643
|
-
}
|
|
6644
|
-
continue;
|
|
6645
|
-
}
|
|
6646
|
-
if (!response.ok) return { error: `HTTP ${response.status} ${response.statusText}`.trim() };
|
|
6647
|
-
let lengthHeader = response.headers.get("content-length"), declared = lengthHeader === null ? NaN : Number(lengthHeader);
|
|
6648
|
-
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
6649
|
-
try {
|
|
6650
|
-
await response.body?.cancel();
|
|
6651
|
-
} catch {
|
|
6652
|
-
}
|
|
6653
|
-
return { error: `exceeds ${maxBytes} bytes` };
|
|
6654
|
-
}
|
|
6655
|
-
let bytes = await readCapped(response, maxBytes);
|
|
6656
|
-
return Buffer.isBuffer(bytes) ? { bytes, contentType: response.headers.get("content-type") ?? "" } : bytes;
|
|
6651
|
+
let result = await write2(base2);
|
|
6652
|
+
if (!result) return;
|
|
6653
|
+
if ("ok" in result) return !0;
|
|
6654
|
+
let copy = typeof file == "string" ? ` (your edited copy stays at ${file})` : file ? " (your edited version is kept in a file)" : "";
|
|
6655
|
+
if (!await actions4.confirm({
|
|
6656
|
+
title: `${label2} changed while you were editing`,
|
|
6657
|
+
message: `${label2} was ${changedBy(result.stale)} after you opened it.
|
|
6658
|
+
Overwrite replaces their version with yours. Reload keeps theirs${copy}.`,
|
|
6659
|
+
confirmLabel: "Overwrite",
|
|
6660
|
+
cancelLabel: "Reload theirs",
|
|
6661
|
+
danger: !0
|
|
6662
|
+
})) {
|
|
6663
|
+
let kept = typeof file == "function" ? await file().catch(() => null) : file;
|
|
6664
|
+
return actions4.toast(`${label2} not written: kept their version${kept ? `. Your edited copy is at ${kept}` : ""}`, "warn", 12e3), "reloaded";
|
|
6657
6665
|
}
|
|
6658
|
-
|
|
6659
|
-
let message = err instanceof Error ? err.message : String(err);
|
|
6660
|
-
return { error: err instanceof Error && err.name === "AbortError" ? `request timed out after ${timeoutMs}ms` : message };
|
|
6661
|
-
} finally {
|
|
6662
|
-
clearTimeout(timer);
|
|
6666
|
+
base2 = result.stale.revision;
|
|
6663
6667
|
}
|
|
6664
6668
|
}
|
|
6665
6669
|
|
|
6666
|
-
// src/shared/schemas/skills-catalog.schema.ts
|
|
6667
|
-
var skills_catalog_schema_exports = {};
|
|
6668
|
-
__export(skills_catalog_schema_exports, {
|
|
6669
|
-
MAX_CATALOG_BYTES: () => MAX_CATALOG_BYTES,
|
|
6670
|
-
MAX_PACKAGE_FILES: () => MAX_PACKAGE_FILES,
|
|
6671
|
-
MAX_SKILL_PACKAGE_BYTES: () => MAX_SKILL_PACKAGE_BYTES,
|
|
6672
|
-
SKILL_NAME: () => SKILL_NAME,
|
|
6673
|
-
SkillCatalogEntrySchema: () => SkillCatalogEntrySchema,
|
|
6674
|
-
parseSkillsCatalogDocument: () => parseSkillsCatalogDocument,
|
|
6675
|
-
resolvePackageFilePath: () => resolvePackageFilePath
|
|
6676
|
-
});
|
|
6677
|
-
var SKILL_NAME = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/, PATH_SEGMENT = /^[A-Za-z0-9._-]+$/, MAX_PACKAGE_FILES = 32, MAX_CATALOG_BYTES = 512 * 1024, MAX_SKILL_PACKAGE_BYTES = 256 * 1024, UNSAFE_TEXT = /[\u0000-\u001F\u007F-\u009F\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/, safeText = (value) => !UNSAFE_TEXT.test(value), UNSAFE_TEXT_MESSAGE = "must not contain control or bidirectional-override characters";
|
|
6678
|
-
function resolvePackageFilePath(name, raw) {
|
|
6679
|
-
if (typeof raw != "string") return null;
|
|
6680
|
-
let directory = `skills/${name}/`, candidate = raw.trim().replace(/\\/g, "/");
|
|
6681
|
-
if (!candidate) return null;
|
|
6682
|
-
for (; candidate.startsWith("./"); ) candidate = candidate.slice(2);
|
|
6683
|
-
if (candidate.startsWith("/")) return null;
|
|
6684
|
-
let relative2 = candidate.startsWith(directory) ? candidate.slice(directory.length) : candidate;
|
|
6685
|
-
return !relative2 || relative2.split("/").some((segment) => segment === "." || segment === ".." || !PATH_SEGMENT.test(segment)) || relative2 === "SKILL.md" ? null : relative2;
|
|
6686
|
-
}
|
|
6687
|
-
var SkillPackageFileSchema = external_exports.object({
|
|
6688
|
-
path: external_exports.string().min(1).refine(safeText, UNSAFE_TEXT_MESSAGE),
|
|
6689
|
-
raw_url: external_exports.string().url()
|
|
6690
|
-
}), SkillCatalogEntrySchema = external_exports.object({
|
|
6691
|
-
name: external_exports.string().regex(SKILL_NAME),
|
|
6692
|
-
description: external_exports.string().min(1).max(500).refine(safeText, UNSAFE_TEXT_MESSAGE),
|
|
6693
|
-
/** Path inside the publishing repo — display only. */
|
|
6694
|
-
path: external_exports.string().min(1).refine(safeText, UNSAFE_TEXT_MESSAGE).optional(),
|
|
6695
|
-
/** Where the SKILL.md body is fetched from on install. */
|
|
6696
|
-
raw_url: external_exports.string().url(),
|
|
6697
|
-
/** Resources installed beside SKILL.md, package-relative after parsing. */
|
|
6698
|
-
files: external_exports.array(SkillPackageFileSchema).max(MAX_PACKAGE_FILES).optional()
|
|
6699
|
-
}).superRefine((entry, ctx) => {
|
|
6700
|
-
if (!entry.files) return;
|
|
6701
|
-
let seen = /* @__PURE__ */ new Set();
|
|
6702
|
-
entry.files.forEach((file, index) => {
|
|
6703
|
-
let relative2 = resolvePackageFilePath(entry.name, file.path);
|
|
6704
|
-
if (!relative2) {
|
|
6705
|
-
ctx.addIssue({
|
|
6706
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6707
|
-
path: ["files", index, "path"],
|
|
6708
|
-
message: `must stay inside skills/${entry.name}/ and cannot be SKILL.md`
|
|
6709
|
-
});
|
|
6710
|
-
return;
|
|
6711
|
-
}
|
|
6712
|
-
if (seen.has(relative2)) {
|
|
6713
|
-
ctx.addIssue({
|
|
6714
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6715
|
-
path: ["files", index, "path"],
|
|
6716
|
-
message: "duplicate package path"
|
|
6717
|
-
});
|
|
6718
|
-
return;
|
|
6719
|
-
}
|
|
6720
|
-
seen.add(relative2);
|
|
6721
|
-
});
|
|
6722
|
-
}).transform((entry) => entry.files ? {
|
|
6723
|
-
...entry,
|
|
6724
|
-
files: entry.files.map((file) => ({
|
|
6725
|
-
...file,
|
|
6726
|
-
path: resolvePackageFilePath(entry.name, file.path)
|
|
6727
|
-
}))
|
|
6728
|
-
} : entry);
|
|
6729
|
-
function parseSkillsCatalogDocument(json2) {
|
|
6730
|
-
if (typeof json2 != "object" || json2 === null || Array.isArray(json2)) return null;
|
|
6731
|
-
let doc = json2;
|
|
6732
|
-
if (doc.schema !== void 0 && doc.schema !== 1 || !Array.isArray(doc.skills)) return null;
|
|
6733
|
-
let entries = [], seen = /* @__PURE__ */ new Set(), dropped = 0;
|
|
6734
|
-
for (let raw of doc.skills) {
|
|
6735
|
-
let result = SkillCatalogEntrySchema.safeParse(raw);
|
|
6736
|
-
if (!result.success || seen.has(result.data.name)) {
|
|
6737
|
-
dropped++;
|
|
6738
|
-
continue;
|
|
6739
|
-
}
|
|
6740
|
-
seen.add(result.data.name), entries.push(result.data);
|
|
6741
|
-
}
|
|
6742
|
-
return {
|
|
6743
|
-
entries,
|
|
6744
|
-
publisher: typeof doc.publisher == "string" ? doc.publisher : void 0,
|
|
6745
|
-
repository: typeof doc.repository == "string" ? doc.repository : void 0,
|
|
6746
|
-
dropped
|
|
6747
|
-
};
|
|
6748
|
-
}
|
|
6749
|
-
|
|
6750
6670
|
// src/main/tui/skills/catalog.ts
|
|
6751
|
-
var { guardedFetch
|
|
6671
|
+
var { guardedFetch } = cjs(guarded_fetch_exports), { parseSkillsCatalogDocument, MAX_CATALOG_BYTES, MAX_SKILL_PACKAGE_BYTES } = cjs(skills_catalog_schema_exports), { normalizeCatalogSources: normalizeCatalogSources2 } = cjs(skills_panel_exports), SKILLS_FETCH_TIMEOUT_MS = 1e4, CATALOG_SOURCES_SETTING = "skillCatalogSources";
|
|
6752
6672
|
async function fetchCatalogDocument(url2) {
|
|
6753
6673
|
if (typeof url2 != "string" || !/^https:\/\//.test(url2)) return { ok: !1, error: "Catalog URL must be https" };
|
|
6754
|
-
let body = await
|
|
6674
|
+
let body = await guardedFetch(url2, { maxBytes: MAX_CATALOG_BYTES, timeoutMs: SKILLS_FETCH_TIMEOUT_MS });
|
|
6755
6675
|
if ("error" in body) return { ok: !1, error: body.error };
|
|
6756
6676
|
let json2;
|
|
6757
6677
|
try {
|
|
@@ -6759,12 +6679,12 @@ async function fetchCatalogDocument(url2) {
|
|
|
6759
6679
|
} catch {
|
|
6760
6680
|
return { ok: !1, error: "Catalog is not valid JSON" };
|
|
6761
6681
|
}
|
|
6762
|
-
let parsed =
|
|
6682
|
+
let parsed = parseSkillsCatalogDocument(json2);
|
|
6763
6683
|
return parsed ? { ok: !0, entries: parsed.entries, publisher: parsed.publisher, dropped: parsed.dropped } : { ok: !1, error: "Unrecognized catalog schema" };
|
|
6764
6684
|
}
|
|
6765
6685
|
async function fetchSkillText(url2) {
|
|
6766
6686
|
if (typeof url2 != "string" || !/^https:\/\//.test(url2)) return { ok: !1, error: "Package URL must be https" };
|
|
6767
|
-
let body = await
|
|
6687
|
+
let body = await guardedFetch(url2, { maxBytes: MAX_SKILL_PACKAGE_BYTES, timeoutMs: SKILLS_FETCH_TIMEOUT_MS });
|
|
6768
6688
|
return "error" in body ? { ok: !1, error: body.error } : body.bytes.subarray(0, 8192).includes(0) ? { ok: !1, error: "SKILL.md is not text" } : { ok: !0, content: body.bytes.toString("utf8") };
|
|
6769
6689
|
}
|
|
6770
6690
|
var DEFAULT_SEAMS = { catalog: fetchCatalogDocument, text: fetchSkillText }, seams2 = DEFAULT_SEAMS;
|
|
@@ -6798,7 +6718,7 @@ var {
|
|
|
6798
6718
|
parseSkillsRegistry: parseSkillsRegistry2,
|
|
6799
6719
|
sanitizeDisplayText: sanitizeDisplayText2,
|
|
6800
6720
|
skillProblems: skillProblems2
|
|
6801
|
-
} = cjs(skills_panel_exports), { splitSkillDocument: splitSkillDocument2 } = cjs(skill_preview_exports), { SKILL_NAME
|
|
6721
|
+
} = 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);
|
|
6802
6722
|
function parseAddTarget2(raw) {
|
|
6803
6723
|
let value = (raw ?? "").trim().replace(/^(["'])(.*)\1$/, "$2");
|
|
6804
6724
|
if (!value) return { kind: "catalog", query: "" };
|
|
@@ -6849,7 +6769,7 @@ function settleOverrides(overrides, registryText) {
|
|
|
6849
6769
|
function tokenLabel(tokens) {
|
|
6850
6770
|
return tokens == null ? "" : tokens >= 1e3 ? `~${(tokens / 1e3).toFixed(tokens >= 1e4 ? 0 : 1)}k tok` : `~${tokens} tok`;
|
|
6851
6771
|
}
|
|
6852
|
-
var safe = (value) => sanitizeDisplayText2(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 &&
|
|
6772
|
+
var safe = (value) => sanitizeDisplayText2(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);
|
|
6853
6773
|
function manifestProblem(manifest) {
|
|
6854
6774
|
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;
|
|
6855
6775
|
}
|
|
@@ -6917,7 +6837,7 @@ function exactEntry(entries, query) {
|
|
|
6917
6837
|
import { promises as fs3 } from "node:fs";
|
|
6918
6838
|
import { homedir as homedir2 } from "node:os";
|
|
6919
6839
|
import { basename as basename2, dirname, join as join3, relative, resolve as resolve2, sep } from "node:path";
|
|
6920
|
-
var { SKILLS_REGISTRY_PATH: SKILLS_REGISTRY_PATH3, SKILLS_STATE_PATH: SKILLS_STATE_PATH2, mergeDisabledList: mergeDisabledList2, parseSkillsRegistry: parseSkillsRegistry3 } = cjs(skills_panel_exports), { MAX_PACKAGE_FILES
|
|
6840
|
+
var { SKILLS_REGISTRY_PATH: SKILLS_REGISTRY_PATH3, SKILLS_STATE_PATH: SKILLS_STATE_PATH2, mergeDisabledList: mergeDisabledList2, parseSkillsRegistry: parseSkillsRegistry3 } = cjs(skills_panel_exports), { MAX_PACKAGE_FILES, MAX_SKILL_PACKAGE_BYTES: MAX_SKILL_PACKAGE_BYTES2, resolvePackageFilePath } = cjs(skills_catalog_schema_exports), errorText2 = (err) => err instanceof Error ? err.message : String(err), isNotFound = (err) => err?.status === 404;
|
|
6921
6841
|
async function must(result, what) {
|
|
6922
6842
|
let outcome = await result;
|
|
6923
6843
|
if (outcome && outcome.success === !1) throw new Error(`${what} was refused (protected file?)`);
|
|
@@ -7045,7 +6965,7 @@ async function readLocalPackage(input, cwd = process.cwd()) {
|
|
|
7045
6965
|
try {
|
|
7046
6966
|
let manifestStat = await fs3.stat(manifestPath);
|
|
7047
6967
|
if (!manifestStat.isFile()) return { ok: !1, error: `${manifestPath} is not a file` };
|
|
7048
|
-
if (manifestStat.size >
|
|
6968
|
+
if (manifestStat.size > MAX_SKILL_PACKAGE_BYTES2) return { ok: !1, error: `SKILL.md is over ${Math.round(MAX_SKILL_PACKAGE_BYTES2 / 1024)} KB` };
|
|
7049
6969
|
manifestBytes = await fs3.readFile(manifestPath);
|
|
7050
6970
|
} catch {
|
|
7051
6971
|
return { ok: !1, error: stat.isDirectory() ? `No SKILL.md in ${target2}` : `Cannot read ${target2}` };
|
|
@@ -7077,24 +6997,24 @@ async function readLocalPackage(input, cwd = process.cwd()) {
|
|
|
7077
6997
|
if (!entry.isFile()) continue;
|
|
7078
6998
|
let rel = relative(target2, full).split(sep).join("/");
|
|
7079
6999
|
if (rel === "SKILL.md") continue;
|
|
7080
|
-
let path =
|
|
7000
|
+
let path = resolvePackageFilePath(identity.name, rel);
|
|
7081
7001
|
if (!path) {
|
|
7082
7002
|
warnings.push(`${rel}: skipped (not a package path)`);
|
|
7083
7003
|
continue;
|
|
7084
7004
|
}
|
|
7085
|
-
if (resources.length >=
|
|
7005
|
+
if (resources.length >= MAX_PACKAGE_FILES) {
|
|
7086
7006
|
skippedOver++;
|
|
7087
7007
|
continue;
|
|
7088
7008
|
}
|
|
7089
|
-
if ((await fs3.stat(full)).size >
|
|
7090
|
-
warnings.push(`${rel}: skipped (over ${Math.round(
|
|
7009
|
+
if ((await fs3.stat(full)).size > MAX_SKILL_PACKAGE_BYTES2) {
|
|
7010
|
+
warnings.push(`${rel}: skipped (over ${Math.round(MAX_SKILL_PACKAGE_BYTES2 / 1024)} KB)`);
|
|
7091
7011
|
continue;
|
|
7092
7012
|
}
|
|
7093
7013
|
let bytes = await fs3.readFile(full);
|
|
7094
7014
|
resources.push(bytes.subarray(0, 8192).includes(0) ? { path, contentBase64: bytes.toString("base64") } : { path, content: bytes.toString("utf-8") });
|
|
7095
7015
|
}
|
|
7096
7016
|
};
|
|
7097
|
-
await walk(target2, 0), skippedOver && warnings.push(`${skippedOver} more file${skippedOver === 1 ? "" : "s"} skipped (a package ships at most ${
|
|
7017
|
+
await walk(target2, 0), skippedOver && warnings.push(`${skippedOver} more file${skippedOver === 1 ? "" : "s"} skipped (a package ships at most ${MAX_PACKAGE_FILES} beside SKILL.md)`);
|
|
7098
7018
|
}
|
|
7099
7019
|
return {
|
|
7100
7020
|
ok: !0,
|
|
@@ -7423,7 +7343,7 @@ function SkillDoc({ manifest, width, height }) {
|
|
|
7423
7343
|
var import_react24 = __toESM(require_react(), 1);
|
|
7424
7344
|
|
|
7425
7345
|
// src/main/tui/context/model.ts
|
|
7426
|
-
var { resolveLoopThreshold } = cjs(context_breakdown_exports), CONTEXT_OVERLAY = "context";
|
|
7346
|
+
var { resolveLoopThreshold, calibrationNote } = cjs(context_breakdown_exports), CONTEXT_OVERLAY = "context";
|
|
7427
7347
|
function openContext(store, props) {
|
|
7428
7348
|
store.actions.pushOverlay({ kind: CONTEXT_OVERLAY, props: { ...props } });
|
|
7429
7349
|
}
|
|
@@ -7446,6 +7366,9 @@ var SOURCE_TEXT = {
|
|
|
7446
7366
|
function thresholdText(r, fmt) {
|
|
7447
7367
|
return `auto-compacts at ${fmt(r.compactThreshold)} (${SOURCE_TEXT[r.compactThresholdSource]})`;
|
|
7448
7368
|
}
|
|
7369
|
+
function calibrationText(cal, approx, fmt) {
|
|
7370
|
+
return calibrationNote(cal, fmt, approx);
|
|
7371
|
+
}
|
|
7449
7372
|
function contextRows(categories, expanded) {
|
|
7450
7373
|
let rows = [];
|
|
7451
7374
|
for (let category of categories) {
|
|
@@ -7592,7 +7515,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7592
7515
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Box_default, { marginTop: 1, flexDirection: "column", height: Math.min(rows.length, rowsHeight), children: shown.map((row4, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RowLine, { row: row4, selectedId: selected?.id, total, labelWidth, rowBar, theme: theme2 }, `${start + i}`)) }),
|
|
7593
7516
|
rows.length > rowsHeight ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { color: theme2.color.dim, children: `${start + 1}-${Math.min(rows.length, start + rowsHeight)} of ${rows.length} rows` }) : null,
|
|
7594
7517
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { color: theme2.color.muted, wrap: "truncate-end", children: selected ? `${selected.label}: ${selected.note}` : "" }) }),
|
|
7595
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { color: theme2.color.dim, wrap: "truncate-end", children: s.compacting ? `Compacting ${s.loop}${g.ellipsis}` : s.loading ? `Re-measuring${g.ellipsis}` : s.measuredAt ? `Measured ${formatClock(s.measuredAt)} ${g.sep}
|
|
7518
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { color: theme2.color.dim, wrap: "truncate-end", children: s.compacting ? `Compacting ${s.loop}${g.ellipsis}` : s.loading ? `Re-measuring${g.ellipsis}` : s.measuredAt ? `Measured ${formatClock(s.measuredAt)} ${g.sep} ${calibrationText(s.data?.breakdown?.calibration, g.approx, formatCount)}` : "" })
|
|
7596
7519
|
] });
|
|
7597
7520
|
}
|
|
7598
7521
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Modal, { title: `Context ${g.sep} ${truncate(header2, inner - 12)}`, width: dialogWidth, hints, onClose: close, children: body });
|
|
@@ -7600,7 +7523,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7600
7523
|
function RowLine({ row: row4, selectedId, total, labelWidth, rowBar, theme: theme2 }) {
|
|
7601
7524
|
let g = theme2.glyph, share = (tokens) => total > 0 ? `${Math.round(tokens / total * 100)}%` : "0%";
|
|
7602
7525
|
if (row4.kind === "category") {
|
|
7603
|
-
let c = row4.category, isSel = c.id === selectedId, label2 = `${row4.expandable ? row4.expanded ? g.expanded : g.collapsed : " "} ${c.label}${c.count !== void 0 ? ` (${c.count})` : ""}`, bar = barText(c.tokens, total, rowBar, theme2.ascii);
|
|
7526
|
+
let c = row4.category, isSel = c.id === selectedId, label2 = `${row4.expandable ? row4.expanded ? g.expanded : g.collapsed : " "} ${c.label}${c.count !== void 0 ? ` (${c.count})` : ""}${c.basis !== "measured" ? ` ${g.approx}` : ""}`, bar = barText(c.tokens, total, rowBar, theme2.ascii);
|
|
7604
7527
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Text, { wrap: "truncate-end", inverse: theme2.mono && isSel, bold: isSel, children: [
|
|
7605
7528
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Text, { color: isSel ? theme2.color.accent : theme2.color.dim, children: [
|
|
7606
7529
|
isSel ? g.pointer : " ",
|
|
@@ -8011,7 +7934,7 @@ var RUNTIME_VIEW = "runtime", RUNTIME_TABS = [
|
|
|
8011
7934
|
{ id: "status", title: "Status", description: "Daemon health, version, uptime and every agent\u2019s loops" },
|
|
8012
7935
|
{ id: "folders", title: "Folders", description: "Tracked agent folders: Enter its agents (review, load, errors), a add, d stop tracking, r rescan" },
|
|
8013
7936
|
{ id: "identity", title: "Identity", description: "Owner identity: status; Enter to create, restore, unlock or lock" },
|
|
8014
|
-
{ id: "auth", title: "Sign-in", description: "Provider sign-ins (ChatGPT, Grok) and API-key providers; Enter to sign in" },
|
|
7937
|
+
{ id: "auth", title: "Sign-in", description: "Provider sign-ins (ChatGPT, Grok, Claude) and API-key providers; Enter to sign in" },
|
|
8015
7938
|
{ id: "providers", title: "Providers", description: "LLM providers and which agents use them" },
|
|
8016
7939
|
{ id: "usage", title: "Usage", description: "Token usage across agents, by model" },
|
|
8017
7940
|
{ id: "network", title: "Network", description: "Mesh, LAN, WebSocket; m mesh on/off, s server start/stop" },
|
|
@@ -8486,14 +8409,14 @@ var REPORTS = {
|
|
|
8486
8409
|
title: "Auth",
|
|
8487
8410
|
async load(client) {
|
|
8488
8411
|
let d = await client.authStatus(), lines = [heading("Subscription sign-ins")];
|
|
8489
|
-
for (let [name, status] of [["chatgpt", d.chatgpt], ["grok", d.grok]]) {
|
|
8490
|
-
let s = status ?? {};
|
|
8491
|
-
lines.push(indent([{ text: name.padEnd(9), tone: "key" },
|
|
8412
|
+
for (let [name, status] of [["chatgpt", d.chatgpt], ["grok", d.grok], ["claude", d.claude]]) {
|
|
8413
|
+
let s = status ?? {}, state = s.authenticated ? { text: "signed in", tone: "success" } : s.installed === !1 ? { text: "Claude Code not installed", tone: "warn" } : { text: "not signed in", tone: "muted" }, extra = [s.email ? String(s.email) : "", s.plan ? `${String(s.plan)} plan` : "", s.installed === !1 && s.installUrl ? String(s.installUrl) : ""].filter(Boolean).join(" \xB7 ");
|
|
8414
|
+
lines.push(indent([{ text: name.padEnd(9), tone: "key" }, state, { text: extra ? ` ${extra}` : "", tone: "muted" }]));
|
|
8492
8415
|
}
|
|
8493
8416
|
return lines.push(blank(), heading("API-key providers")), lines.push(...tableLines(
|
|
8494
8417
|
["id", "type", "key", "stored in"],
|
|
8495
8418
|
d.providers.map((p) => [p.id, p.type, p.hasApiKey ? "set" : "missing", p.credentialStorage])
|
|
8496
|
-
).map(indent)), lines.push(blank(), heading("Sign in or out")), lines.push(indent(plain("Enter opens the sign-in dialog \xB7 /login chatgpt \xB7 /login grok \xB7 /logout <chatgpt|grok>", "accent"))), lines.push(indent(plain("From a shell: adf auth login <chatgpt|grok>", "muted"))), lines.push(indent(plain("API keys: Studio settings, stored by the daemon (never shown here).", "muted"))), { data: redactSecrets(d), lines };
|
|
8419
|
+
).map(indent)), lines.push(blank(), heading("Sign in or out")), lines.push(indent(plain("Enter opens the sign-in dialog \xB7 /login chatgpt \xB7 /login grok \xB7 /login claude \xB7 /logout <chatgpt|grok|claude>", "accent"))), lines.push(indent(plain("From a shell: adf auth login <chatgpt|grok|claude>", "muted"))), lines.push(indent(plain("API keys: Studio settings, stored by the daemon (never shown here).", "muted"))), { data: redactSecrets(d), lines };
|
|
8497
8420
|
}
|
|
8498
8421
|
},
|
|
8499
8422
|
network: {
|
|
@@ -8900,15 +8823,14 @@ function folderAgentsSummary(agents) {
|
|
|
8900
8823
|
}
|
|
8901
8824
|
async function loadFolderAgent(store, agent2, options = {}) {
|
|
8902
8825
|
try {
|
|
8903
|
-
options.accept
|
|
8904
|
-
let ref = await store.client.load(agent2.filePath, !0), name = ref.config?.handle || ref.config?.name || agent2.name, started = "";
|
|
8826
|
+
let accepted = options.accept ? await store.client.acceptReview(agent2.filePath) : null, ref = await store.client.load(agent2.filePath, !0), name = ref.config?.handle || ref.config?.name || agent2.name, started = "";
|
|
8905
8827
|
if (agent2.autostart)
|
|
8906
8828
|
try {
|
|
8907
8829
|
await store.client.start(ref.id), started = " and started it";
|
|
8908
8830
|
} catch (err) {
|
|
8909
8831
|
started = ` (start failed: ${err instanceof Error ? err.message : String(err)})`;
|
|
8910
8832
|
}
|
|
8911
|
-
return store.actions.toast(`${options.accept ? "Reviewed and loaded" : "Loaded"} ${name}${started}`, started.startsWith(" (") ? "warn" : "success",
|
|
8833
|
+
return store.actions.toast(`${options.accept ? "Reviewed and loaded" : "Loaded"} ${name}${started}${lockedNote(accepted?.lockedFields)}`, started.startsWith(" (") ? "warn" : "success", 6e3), writeFolders(store, {}, !0), await store.actions.refreshAgents(), store.actions.refreshTracked(), { ok: !0, agentId: ref.id };
|
|
8912
8834
|
} catch (err) {
|
|
8913
8835
|
err instanceof DaemonError && err.unreachable && store.dispatch({ type: "daemon/reachable", reachable: !1 });
|
|
8914
8836
|
let error = err instanceof DaemonError && err.status === 403 ? "It needs review first." : err instanceof Error ? err.message : String(err);
|
|
@@ -10107,7 +10029,10 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10107
10029
|
g.dot,
|
|
10108
10030
|
" "
|
|
10109
10031
|
] }),
|
|
10110
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.
|
|
10032
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { width: w - 2, flexDirection: "column", children: [
|
|
10033
|
+
item.text ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Markdown, { text: item.text, color: theme2.color.assistant }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { children: " " }),
|
|
10034
|
+
item.interrupted ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: theme2.color.dim, children: "[interrupted]" }) : null
|
|
10035
|
+
] })
|
|
10111
10036
|
] });
|
|
10112
10037
|
case "thinking": {
|
|
10113
10038
|
let open2 = expanded || showThinking, lines = lineCount(item.text);
|
|
@@ -10131,7 +10056,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10131
10056
|
case "tool":
|
|
10132
10057
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToolBody, { item, w, expanded });
|
|
10133
10058
|
case "hil": {
|
|
10134
|
-
let tone = item.status === "pending" ? theme2.color.warn : item.status === "approved" ? theme2.color.success : theme2.color.error;
|
|
10059
|
+
let tone = item.status === "pending" ? theme2.color.warn : item.status === "approved" || item.status === "completed" ? theme2.color.success : theme2.color.error;
|
|
10135
10060
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", width: w, borderStyle: theme2.ascii ? "classic" : "single", borderLeft: !0, borderRight: !1, borderTop: !1, borderBottom: !1, borderColor: tone, paddingLeft: 1, children: [
|
|
10136
10061
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
10137
10062
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { bold: !0, color: tone, children: [
|
|
@@ -11663,7 +11588,7 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
11663
11588
|
import { promises as fs4, rmSync, statSync as statSync3 } from "node:fs";
|
|
11664
11589
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
11665
11590
|
import { join as join4 } from "node:path";
|
|
11666
|
-
var copies = /* @__PURE__ */ new Map(), dirs = /* @__PURE__ */ new Set(), exitHook = !1, copyKey = (agentId, target2) => `${agentId}\0${targetKey(target2)}`, errorText5 = (err) => err instanceof Error ? err.message : String(err), bytesOf = (loaded) => loaded.binary ? Buffer.from(loaded.bytes ?? new Uint8Array()) : Buffer.from(loaded.text ?? "", "utf-8");
|
|
11591
|
+
var { openBrowser: openBrowser2 } = cjs(auth_flow_exports), copies = /* @__PURE__ */ new Map(), dirs = /* @__PURE__ */ new Set(), exitHook = !1, copyKey = (agentId, target2) => `${agentId}\0${targetKey(target2)}`, errorText5 = (err) => err instanceof Error ? err.message : String(err), bytesOf = (loaded) => loaded.binary ? Buffer.from(loaded.bytes ?? new Uint8Array()) : Buffer.from(loaded.text ?? "", "utf-8");
|
|
11667
11592
|
function externalCopy(agentId, target2) {
|
|
11668
11593
|
return copies.get(copyKey(agentId, target2));
|
|
11669
11594
|
}
|
|
@@ -11694,7 +11619,7 @@ async function openExternal(deps, target2) {
|
|
|
11694
11619
|
}
|
|
11695
11620
|
copies.set(copyKey(agentId, target2), { agentId, target: target2, file, original: bytes, binary: loaded.binary, mime: loaded.mime, mtimeMs: (await fs4.stat(file)).mtimeMs });
|
|
11696
11621
|
}
|
|
11697
|
-
return (deps.open ??
|
|
11622
|
+
return (deps.open ?? openBrowser2)(file), actions4.toast(`Opened ${label2} in the default app \u2014 after saving there, press s to save it back (${file})`, "info", 8e3), !0;
|
|
11698
11623
|
}
|
|
11699
11624
|
async function saveBackExternal(deps, target2) {
|
|
11700
11625
|
let { client, actions: actions4, agentId, agentLabel: agentLabel5 } = deps, label2 = targetLabel(target2), copy = externalCopy(agentId, target2);
|
|
@@ -11708,14 +11633,14 @@ async function saveBackExternal(deps, target2) {
|
|
|
11708
11633
|
}
|
|
11709
11634
|
if (edited.equals(copy.original))
|
|
11710
11635
|
return copy.mtimeMs = (await fs4.stat(copy.file)).mtimeMs, actions4.toast(`No changes to ${label2}`, "info"), "unchanged";
|
|
11711
|
-
let concurrent = null;
|
|
11636
|
+
let concurrent = null, baseRevision;
|
|
11712
11637
|
try {
|
|
11713
11638
|
let current = await loadTarget(client, agentId, target2);
|
|
11714
|
-
bytesOf(current).equals(copy.original) || (concurrent = "changed in the agent since you opened it");
|
|
11639
|
+
baseRevision = current.revision, bytesOf(current).equals(copy.original) || (concurrent = "changed in the agent since you opened it");
|
|
11715
11640
|
} catch (err) {
|
|
11716
11641
|
concurrent = err.status === 404 ? "was deleted since you opened it" : `could not be re-checked (${errorText5(err)})`;
|
|
11717
11642
|
}
|
|
11718
|
-
|
|
11643
|
+
if (!await actions4.confirm({
|
|
11719
11644
|
title: concurrent ? `Concurrent change: ${label2}` : `Save ${label2}`,
|
|
11720
11645
|
message: [
|
|
11721
11646
|
concurrent ? `WARNING: ${label2} ${concurrent}. Writing replaces that version.` : null,
|
|
@@ -11725,7 +11650,9 @@ async function saveBackExternal(deps, target2) {
|
|
|
11725
11650
|
confirmLabel: concurrent ? "Overwrite" : "Write",
|
|
11726
11651
|
cancelLabel: "Cancel",
|
|
11727
11652
|
danger: !!concurrent
|
|
11728
|
-
})
|
|
11653
|
+
})) return "discarded";
|
|
11654
|
+
let written = copy.binary && target2.kind === "file" ? await actions4.run(`Write ${label2}`, (c) => c.writeFile(agentId, target2.path, { contentBase64: edited.toString("base64"), ...copy.mime ? { mimeType: copy.mime } : {} }).then(() => !0)) : await writeOverConflicts(actions4, label2, copy.file, (base2) => actions4.run(`Write ${label2}`, (c) => writeOver(() => writeTarget(c, agentId, target2, edited.toString("utf-8"), base2))), baseRevision);
|
|
11655
|
+
return written === "reloaded" ? "discarded" : written ? (copy.original = edited, copy.mtimeMs = (await fs4.stat(copy.file)).mtimeMs, actions4.toast(`Saved ${label2} from the app`, "success"), "written") : (actions4.toast(`Write failed. Your copy is still at ${copy.file}`, "error", 12e3), "failed");
|
|
11729
11656
|
}
|
|
11730
11657
|
|
|
11731
11658
|
// src/main/tui/views/files/FilesTab.tsx
|
|
@@ -14558,8 +14485,8 @@ var TOOL_GROUPS = [
|
|
|
14558
14485
|
off: "nobody: no inbound messages, sends still allowed",
|
|
14559
14486
|
directory: "only ancestor-directory agents on this runtime",
|
|
14560
14487
|
localhost: "any agent on this machine",
|
|
14561
|
-
lan: "any agent on
|
|
14562
|
-
public: "any agent
|
|
14488
|
+
lan: "any agent on an allowed network",
|
|
14489
|
+
public: "any agent that reaches this computer, also only on an allowed network"
|
|
14563
14490
|
}, SEND_MODES = ["proactive", "respond_only", "listen_only"], SEND_MODE_HINTS = {
|
|
14564
14491
|
proactive: "can send anytime",
|
|
14565
14492
|
respond_only: "sends only when a message triggered the turn",
|
|
@@ -14571,8 +14498,6 @@ function triState(items, pred) {
|
|
|
14571
14498
|
return n === 0 ? "none" : n === items.length ? "all" : "mixed";
|
|
14572
14499
|
}
|
|
14573
14500
|
function groupBlocked(config2, groupId) {
|
|
14574
|
-
let triggers = config2.triggers;
|
|
14575
|
-
if (groupId === "messaging" && !triggers?.on_inbox?.enabled) return "needs messaging (the on_inbox trigger)";
|
|
14576
14501
|
if (groupId === "inbox" && config2.messaging?.inbox_mode !== !0) return "needs inbox mode (Settings \u203A Inbox mode)";
|
|
14577
14502
|
}
|
|
14578
14503
|
function mcpServers(config2) {
|
|
@@ -14729,6 +14654,26 @@ function setMainThreshold(config2, value) {
|
|
|
14729
14654
|
let next = clone(config2), context = { ...next.context ?? {} };
|
|
14730
14655
|
return value === null ? delete context.compact_threshold : context.compact_threshold = value, next.context = context, { ok: !0, config: next, message: value === null ? `main compacts at the default (${formatTokens2(mainThreshold(next).value)})` : `main compacts at ${formatTokens2(value)} tokens` };
|
|
14731
14656
|
}
|
|
14657
|
+
function requestMediaLimitOf(config2) {
|
|
14658
|
+
let files2 = config2.context?.max_request_media_files, mb = config2.context?.max_request_media_mb;
|
|
14659
|
+
return {
|
|
14660
|
+
files: typeof files2 == "number" && files2 > 0 ? files2 : 20,
|
|
14661
|
+
mb: typeof mb == "number" && mb > 0 ? mb : 20,
|
|
14662
|
+
set: typeof files2 == "number" && files2 > 0 || typeof mb == "number" && mb > 0
|
|
14663
|
+
};
|
|
14664
|
+
}
|
|
14665
|
+
function setRequestMediaLimit(config2, value) {
|
|
14666
|
+
let next = clone(config2), context = { ...next.context ?? {} };
|
|
14667
|
+
delete context.max_request_media_files, delete context.max_request_media_mb, value && (context.max_request_media_files = value.files, context.max_request_media_mb = value.mb), next.context = context;
|
|
14668
|
+
let now = requestMediaLimitOf(next);
|
|
14669
|
+
return { ok: !0, config: next, message: `Requests carry at most ${now.files} files, ${now.mb} MB${value ? "" : " (default)"}` };
|
|
14670
|
+
}
|
|
14671
|
+
function parseMediaLimit(args) {
|
|
14672
|
+
if (args.length === 1 && args[0].toLowerCase() === "default") return { ok: !0, value: null };
|
|
14673
|
+
if (args.length !== 2) return { ok: !1, error: "Give files and MB, or default" };
|
|
14674
|
+
let [files2, mb] = args.map((a) => Number(a));
|
|
14675
|
+
return [files2, mb].every((n) => Number.isInteger(n) && n > 0) ? { ok: !0, value: { files: files2, mb } } : { ok: !1, error: "Files and MB must be positive whole numbers" };
|
|
14676
|
+
}
|
|
14732
14677
|
function parseThreshold(text) {
|
|
14733
14678
|
let raw = text.trim().toLowerCase().replace(/[,_\s]/g, "");
|
|
14734
14679
|
if (!raw || raw === "default" || raw === "inherit" || raw === "0") return { ok: !0, value: null };
|
|
@@ -14835,6 +14780,15 @@ function settingRows(config2, extras = {}) {
|
|
|
14835
14780
|
value: `main at ${formatTokens2(main.value)}${main.source === "default" ? " (default)" : ""}${typeof used == "number" ? ` \xB7 in use ${formatTokens2(used)} (${Math.round(used / main.value * 100)}%)` : ""}`,
|
|
14836
14781
|
hint: (config2.loops ?? []).length ? `inner loops: ${(config2.loops ?? []).map((l) => `${l.name} ${l.compact_threshold != null ? formatTokens2(l.compact_threshold) : "inherit"}`).join(", ")}` : "History is summarized when the context reaches this size",
|
|
14837
14782
|
...lock(["context"])
|
|
14783
|
+
});
|
|
14784
|
+
let media2 = requestMediaLimitOf(config2);
|
|
14785
|
+
rows.push({
|
|
14786
|
+
id: "media",
|
|
14787
|
+
label: "Media",
|
|
14788
|
+
kind: "dialog",
|
|
14789
|
+
value: `${media2.files} files, ${media2.mb} MB per request${media2.set ? "" : " (default)"}`,
|
|
14790
|
+
hint: "Past either, the oldest files are left out until half remains \xB7 /media <files> <MB> | default",
|
|
14791
|
+
...lock(["context"])
|
|
14838
14792
|
}), rows.push({
|
|
14839
14793
|
id: "autonomous",
|
|
14840
14794
|
label: "Autonomous",
|
|
@@ -14929,6 +14883,9 @@ async function actOnSetting(actions4, agentId, row4, config2) {
|
|
|
14929
14883
|
case "compaction":
|
|
14930
14884
|
actions4.pushOverlay({ kind: COMPACTION_OVERLAY, props: { agentId } });
|
|
14931
14885
|
return;
|
|
14886
|
+
case "media":
|
|
14887
|
+
actions4.toast("Set with /media <files> <MB>, or /media default", "info", 3e3);
|
|
14888
|
+
return;
|
|
14932
14889
|
case "visibility":
|
|
14933
14890
|
case "send":
|
|
14934
14891
|
actions4.pushOverlay({ kind: CHOICE_OVERLAY, props: { agentId, setting: row4.id } });
|
|
@@ -15302,6 +15259,24 @@ var inspect = {
|
|
|
15302
15259
|
}
|
|
15303
15260
|
await applyThreshold(ctx.store, ctx.agentId, ctx.loop, parsed.value);
|
|
15304
15261
|
}
|
|
15262
|
+
}, media = {
|
|
15263
|
+
name: "media",
|
|
15264
|
+
args: "[<files> <MB>|default]",
|
|
15265
|
+
description: "Request media limit of the selected agent: most files and MB one request carries (default 20, 20). Past either, the oldest are left out until half remains",
|
|
15266
|
+
available: (scope) => !!scope.agentId,
|
|
15267
|
+
complete: (partial) => ["default"].filter((v) => v.startsWith(partial.trim())),
|
|
15268
|
+
run: async (ctx) => {
|
|
15269
|
+
if (!ctx.agentId) {
|
|
15270
|
+
ctx.print("No agent selected", "warn");
|
|
15271
|
+
return;
|
|
15272
|
+
}
|
|
15273
|
+
let parsed = parseMediaLimit(ctx.args);
|
|
15274
|
+
if (!parsed.ok) {
|
|
15275
|
+
ctx.print(`${parsed.error}. Usage: /media <files> <MB> | default`, "warn");
|
|
15276
|
+
return;
|
|
15277
|
+
}
|
|
15278
|
+
await applyChange(ctx.actions, ctx.agentId, (cfg) => setRequestMediaLimit(cfg, parsed.value), "Media");
|
|
15279
|
+
}
|
|
15305
15280
|
}, TASK_FILTER_ARGS = TASK_FILTERS, tasks = {
|
|
15306
15281
|
name: "tasks",
|
|
15307
15282
|
args: `[${TASK_FILTERS.join("|")}]`,
|
|
@@ -15354,7 +15329,7 @@ var inspect = {
|
|
|
15354
15329
|
patchInspectState(ctx.actions, ctx.state(), { tab: t.id }), ctx.actions.setView(INSPECT_VIEW);
|
|
15355
15330
|
}
|
|
15356
15331
|
}))
|
|
15357
|
-
], inspectCommands = { commands: [inspect, model, config, tasks, instructions, tools, compaction], actions: actions2 };
|
|
15332
|
+
], inspectCommands = { commands: [inspect, model, config, tasks, instructions, tools, compaction, media], actions: actions2 };
|
|
15358
15333
|
|
|
15359
15334
|
// src/main/tui/views/inspect/EventsTab.tsx
|
|
15360
15335
|
var import_react51 = __toESM(require_react(), 1);
|
|
@@ -15613,6 +15588,9 @@ function typeColor(theme2, type) {
|
|
|
15613
15588
|
// src/main/tui/views/inspect/ConfigTab.tsx
|
|
15614
15589
|
var import_react52 = __toESM(require_react(), 1);
|
|
15615
15590
|
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
15591
|
+
import { promises as fs5 } from "node:fs";
|
|
15592
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
15593
|
+
import { join as join5 } from "node:path";
|
|
15616
15594
|
async function editConfigFlow(agentId, label2, actions4, suspend, edit = (text) => editText(text, { filename: `${label2}.config.json` })) {
|
|
15617
15595
|
let original = await actions4.loadConfig(agentId);
|
|
15618
15596
|
if (!original) return "failed";
|
|
@@ -15644,10 +15622,10 @@ Edit again? Discard drops your edit.`,
|
|
|
15644
15622
|
}
|
|
15645
15623
|
if (check.changedKeys.length === 0)
|
|
15646
15624
|
return actions4.toast("Config unchanged (formatting only), nothing saved", "info"), "unchanged";
|
|
15647
|
-
let
|
|
15648
|
-
if (!
|
|
15649
|
-
let theirs = changedKeysBetween(original, fresh);
|
|
15650
|
-
|
|
15625
|
+
let freshResult = await actions4.run("Re-check config", (c) => c.config(agentId));
|
|
15626
|
+
if (!freshResult) return "failed";
|
|
15627
|
+
let fresh = freshResult.config, baseRevision = revisionOf(freshResult), theirs = changedKeysBetween(original, fresh);
|
|
15628
|
+
if (theirs.length > 0 && !await actions4.confirm({
|
|
15651
15629
|
title: `Config of ${label2} changed on the daemon`,
|
|
15652
15630
|
message: `While you were editing, these keys changed on the daemon: ${theirs.join(", ")}.
|
|
15653
15631
|
Saving your copy reverts them${theirs.includes("loops") ? " (a loop added meanwhile would be removed and archived)" : ""}.
|
|
@@ -15656,14 +15634,24 @@ Warning: ${check.warnings.join("; ")}` : ""}`,
|
|
|
15656
15634
|
confirmLabel: "Overwrite",
|
|
15657
15635
|
cancelLabel: "Discard",
|
|
15658
15636
|
danger: !0
|
|
15659
|
-
})
|
|
15637
|
+
}))
|
|
15638
|
+
return actions4.toast("Config edit discarded (the daemon copy changed meanwhile)", "warn"), "discarded";
|
|
15639
|
+
if (changedKeysBetween(fresh, check.config).length === 0)
|
|
15640
|
+
return actions4.toast("Config already matches the daemon, nothing saved", "info"), "unchanged";
|
|
15641
|
+
if (!(theirs.length > 0 || await actions4.confirm({
|
|
15660
15642
|
title: `Save config of ${label2}?`,
|
|
15661
15643
|
message: `Changed: ${check.changedKeys.join(", ")}${check.warnings.length ? `
|
|
15662
15644
|
Warning: ${check.warnings.join("; ")}` : ""}`,
|
|
15663
15645
|
confirmLabel: "Save",
|
|
15664
15646
|
cancelLabel: "Discard",
|
|
15665
15647
|
danger: check.warnings.length > 0
|
|
15666
|
-
})
|
|
15648
|
+
})))
|
|
15649
|
+
return actions4.toast("Config edit discarded", "warn"), "discarded";
|
|
15650
|
+
let keepCopy = async () => {
|
|
15651
|
+
let file = join5(tmpdir4(), `adf-tui-${label2.replace(/[^\w.-]+/g, "_")}.config-${Date.now()}.json`);
|
|
15652
|
+
return await fs5.writeFile(file, result.text ?? "", "utf-8"), file;
|
|
15653
|
+
}, saved = await writeOverConflicts(actions4, `Config of ${label2}`, keepCopy, (base2) => actions4.run("Save config", (c) => writeOver(() => c.request("PUT", `/agents/${encodeURIComponent(agentId)}/config`, { body: check.config, ...base2 !== void 0 ? { query: { baseRevision: base2 } } : {} }))), baseRevision);
|
|
15654
|
+
return saved === "reloaded" ? (await actions4.loadConfig(agentId), "discarded") : saved ? (actions4.toast(`Config of ${label2} saved (${check.changedKeys.join(", ")})`, "success"), await actions4.loadConfig(agentId), "saved") : "failed";
|
|
15667
15655
|
}
|
|
15668
15656
|
}
|
|
15669
15657
|
function ConfigTab({ agentId, label: label2, width, height, focused }) {
|