@agentdocumentformat/cli 0.7.8 → 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-7RIIOHJJ.mjs → App-A5GUFCFJ.mjs} +279 -293
- 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-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-G6PH7RPW.mjs → chunk-LCMANRYY.mjs} +3 -3
- package/dist/chunks/{chunk-ZESQMP66.mjs → chunk-LGL6ML37.mjs} +3 -3
- 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-HSBV6YFU.mjs → chunk-YRMKSHW3.mjs} +614 -92
- 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-NMFIAR7Z.mjs → cli-I47IFDHJ.mjs} +797 -56
- package/dist/chunks/{commands-KPJWFRUE.mjs → commands-E4EQUHE5.mjs} +4 -3
- package/dist/chunks/{daemon-YDIK3AAM.mjs → daemon-FQ5BV3AP.mjs} +82058 -63958
- 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/{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-O77NTGLP.mjs → pipeline-executor-FD4FBWQA.mjs} +6 -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-UQJLK7XI.mjs → tui-SPSPDADM.mjs} +17 -14
- package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
- package/dist/chunks/{whatsapp-AJMRQBT7.mjs → whatsapp-YJFFVN4Q.mjs} +9 -9
- 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-Y2QA53AN.mjs +0 -259
- package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
- package/dist/chunks/{telegram-2EFGKIVK.mjs → telegram-JYY2VDTI.mjs} +5 -5
|
@@ -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,36 +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";
|
|
153
|
+
} from "./chunk-GAZO6UMI.mjs";
|
|
144
154
|
import {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
} from "./chunk-
|
|
149
|
-
import
|
|
150
|
-
|
|
151
|
-
} from "./chunk-SGUTYISF.mjs";
|
|
152
|
-
import {
|
|
153
|
-
getPrefs,
|
|
154
|
-
savePrefs
|
|
155
|
-
} from "./chunk-5QU5VY7N.mjs";
|
|
156
|
-
import {
|
|
157
|
-
checkFetchTarget,
|
|
158
|
-
context_breakdown_exports
|
|
159
|
-
} from "./chunk-Y2QA53AN.mjs";
|
|
160
|
-
import "./chunk-2NAP2ZF7.mjs";
|
|
161
|
-
import "./chunk-5PO5PKRV.mjs";
|
|
162
|
-
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";
|
|
163
161
|
import {
|
|
164
162
|
Box_default,
|
|
165
163
|
Text,
|
|
@@ -176,7 +174,7 @@ import {
|
|
|
176
174
|
ThemeContext,
|
|
177
175
|
stateColor,
|
|
178
176
|
useTheme
|
|
179
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-NZLEPJ5M.mjs";
|
|
180
178
|
import {
|
|
181
179
|
isMouseGarbage,
|
|
182
180
|
lastRawInput,
|
|
@@ -192,21 +190,24 @@ import {
|
|
|
192
190
|
import {
|
|
193
191
|
require_react
|
|
194
192
|
} from "./chunk-6GJ4QHRI.mjs";
|
|
193
|
+
import {
|
|
194
|
+
ADF_SKILLS_REGISTRY_URL
|
|
195
|
+
} from "./chunk-LCMANRYY.mjs";
|
|
195
196
|
import "./chunk-UYY5M2PB.mjs";
|
|
196
|
-
import "./chunk-
|
|
197
|
-
import "./chunk-
|
|
198
|
-
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";
|
|
199
205
|
import {
|
|
200
206
|
require_dist
|
|
201
207
|
} from "./chunk-APHX6HSV.mjs";
|
|
202
|
-
import
|
|
203
|
-
|
|
204
|
-
} from "./chunk-ZJKXHM4Q.mjs";
|
|
208
|
+
import "./chunk-NZO5O4VN.mjs";
|
|
209
|
+
import "./chunk-ZJKXHM4Q.mjs";
|
|
205
210
|
import "./chunk-RIX34QHC.mjs";
|
|
206
|
-
import {
|
|
207
|
-
ADF_SKILLS_REGISTRY_URL
|
|
208
|
-
} from "./chunk-G6PH7RPW.mjs";
|
|
209
|
-
import "./chunk-CD3ATSXE.mjs";
|
|
210
211
|
import {
|
|
211
212
|
__export,
|
|
212
213
|
__toESM
|
|
@@ -510,10 +511,10 @@ function TextInput(props) {
|
|
|
510
511
|
var import_react3 = __toESM(require_react(), 1);
|
|
511
512
|
|
|
512
513
|
// src/main/tui/auth/model.ts
|
|
513
|
-
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.";
|
|
514
515
|
function subscriptionOfType(type, id) {
|
|
515
516
|
let t = `${type ?? ""} ${id ?? ""}`.toLowerCase();
|
|
516
|
-
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;
|
|
517
518
|
}
|
|
518
519
|
function statusOf(auth, provider) {
|
|
519
520
|
let value = auth?.[provider];
|
|
@@ -540,9 +541,14 @@ function formatExpiry(expiresAt, now = Date.now()) {
|
|
|
540
541
|
}
|
|
541
542
|
function describeStatus(status) {
|
|
542
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}` : "";
|
|
543
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 };
|
|
544
550
|
let expiry = formatExpiry(status.expiresAt);
|
|
545
|
-
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 };
|
|
546
552
|
}
|
|
547
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 };
|
|
548
554
|
}
|
|
@@ -1039,6 +1045,9 @@ function completePath(input, options = {}) {
|
|
|
1039
1045
|
}
|
|
1040
1046
|
return { value: dirPart + (common.length > base2.length ? common : base2), candidates };
|
|
1041
1047
|
}
|
|
1048
|
+
function lockedNote(fields) {
|
|
1049
|
+
return fields && fields.length > 0 ? `; locked against agent edits: ${fields.join(", ")}` : "";
|
|
1050
|
+
}
|
|
1042
1051
|
|
|
1043
1052
|
// src/main/tui/views/fleet/data.ts
|
|
1044
1053
|
var import_react4 = __toESM(require_react(), 1);
|
|
@@ -1252,13 +1261,14 @@ ${bits}` : "";
|
|
|
1252
1261
|
if (!await store.actions.confirm({
|
|
1253
1262
|
title: "Review required",
|
|
1254
1263
|
message: `${filePath} has not been reviewed on this daemon.${summary}
|
|
1255
|
-
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.`,
|
|
1256
1265
|
confirmLabel: "Accept + load",
|
|
1257
1266
|
danger: !0
|
|
1258
1267
|
}))
|
|
1259
1268
|
return store.actions.toast("Not loaded (review declined)", "warn"), !1;
|
|
1260
1269
|
try {
|
|
1261
|
-
|
|
1270
|
+
let accepted = await store.client.acceptReview(filePath);
|
|
1271
|
+
return store.actions.toast(`Review accepted for ${filePath}${lockedNote(accepted.lockedFields)}`, "success", 6e3), !0;
|
|
1262
1272
|
} catch (err) {
|
|
1263
1273
|
return failure(store, null, "Accept review", err), !1;
|
|
1264
1274
|
}
|
|
@@ -3832,7 +3842,7 @@ function wakesText(timers, now = Date.now(), sep4 = "\xB7") {
|
|
|
3832
3842
|
}
|
|
3833
3843
|
|
|
3834
3844
|
// src/main/tui/auth/flow.ts
|
|
3835
|
-
var { loginChatGpt, loginGrok, openBrowser
|
|
3845
|
+
var { loginChatGpt, loginClaude, loginGrok, openBrowser } = cjs(auth_flow_exports), seams = { openBrowser };
|
|
3836
3846
|
function openUrl(url2) {
|
|
3837
3847
|
seams.openBrowser(url2);
|
|
3838
3848
|
}
|
|
@@ -3845,7 +3855,7 @@ async function signIn(client, provider, signal, handlers) {
|
|
|
3845
3855
|
startCallbackServer: seams.startCallbackServer
|
|
3846
3856
|
};
|
|
3847
3857
|
try {
|
|
3848
|
-
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) });
|
|
3849
3859
|
} catch (err) {
|
|
3850
3860
|
return signal.aborted ? { ok: !1, error: "Sign-in cancelled", cancelled: !0 } : { ok: !1, error: err instanceof Error ? err.message : String(err) };
|
|
3851
3861
|
}
|
|
@@ -3854,14 +3864,15 @@ async function signIn(client, provider, signal, handlers) {
|
|
|
3854
3864
|
// src/main/tui/auth/AuthDialog.tsx
|
|
3855
3865
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
3856
3866
|
function AuthDialog({ overlay, close, width }) {
|
|
3857
|
-
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));
|
|
3858
3868
|
(0, import_react15.useEffect)(() => (store.actions.refreshAuth(), props.login && start(props.login), () => abort.current?.abort()), []);
|
|
3859
3869
|
let start = (provider) => {
|
|
3860
3870
|
abort.current?.abort();
|
|
3861
3871
|
let ctrl = new AbortController();
|
|
3862
|
-
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, {
|
|
3863
3873
|
onChatGpt: (info) => setFlow({ kind: "running", provider, url: info.authUrl, relay: info.mode === "relay" ? info.redirectUri : void 0 }),
|
|
3864
|
-
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 })
|
|
3865
3876
|
}).then((outcome) => {
|
|
3866
3877
|
if (ctrl.signal.aborted && !outcome.ok) return;
|
|
3867
3878
|
abort.current = null, store.actions.refreshAuth();
|
|
@@ -3870,6 +3881,12 @@ function AuthDialog({ overlay, close, width }) {
|
|
|
3870
3881
|
});
|
|
3871
3882
|
}, cancel = () => {
|
|
3872
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;
|
|
3873
3890
|
}, copyUrl = (url2) => {
|
|
3874
3891
|
url2 && copyToClipboard(url2).then((ok) => setNote(ok ? "URL copied to the clipboard." : "Could not copy; select the URL with the mouse instead."));
|
|
3875
3892
|
};
|
|
@@ -3894,25 +3911,30 @@ function AuthDialog({ overlay, close, width }) {
|
|
|
3894
3911
|
} else (input === "n" || key.escape) && setFlow({ kind: "list" });
|
|
3895
3912
|
return !0;
|
|
3896
3913
|
case "running":
|
|
3897
|
-
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);
|
|
3898
3915
|
case "done":
|
|
3899
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);
|
|
3900
3917
|
}
|
|
3901
3918
|
}, { layer: "overlay" });
|
|
3902
3919
|
let noteLine = note ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, wrap: "wrap", children: note }) : null;
|
|
3903
3920
|
if (flow.kind === "running" || flow.kind === "done") {
|
|
3904
|
-
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" }];
|
|
3905
3922
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Modal, { title: `Sign in to ${label2}`, width: dialogWidth, hints: hints2, children: [
|
|
3906
|
-
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,
|
|
3907
3925
|
code ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Box_default, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [
|
|
3908
3926
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.muted, children: "Enter this code in the browser:" }),
|
|
3909
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) }) })
|
|
3910
3928
|
] }) : null,
|
|
3911
3929
|
url2 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3912
|
-
/* @__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:" }),
|
|
3913
3931
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { color: theme2.color.info, wrap: "wrap", children: url2 })
|
|
3914
3932
|
] }) : null,
|
|
3915
|
-
|
|
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,
|
|
3916
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: [
|
|
3917
3939
|
theme2.glyph.check,
|
|
3918
3940
|
" Signed in to ",
|
|
@@ -4484,8 +4506,8 @@ var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1), MODEL_OVERLAY = "i
|
|
|
4484
4506
|
function providerChoices(providers, auth) {
|
|
4485
4507
|
return providers.map((p) => {
|
|
4486
4508
|
let type = String(p.type ?? ""), id = String(p.id ?? ""), name = String(p.name ?? id);
|
|
4487
|
-
if (type === "chatgpt-subscription" || type === "grok-subscription") {
|
|
4488
|
-
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;
|
|
4489
4511
|
return { id, name, type, access: signedIn?.authenticated ? "signed in" : "not signed in (/login)", ready: !!signedIn?.authenticated };
|
|
4490
4512
|
}
|
|
4491
4513
|
if (p.hasApiKey === !0) return { id, name, type, access: "key set", ready: !0 };
|
|
@@ -4633,14 +4655,14 @@ var { normalizeAuthProvider } = cjs(auth_flow_exports);
|
|
|
4633
4655
|
function openAuth(actions4, props = {}) {
|
|
4634
4656
|
actions4.pushOverlay({ kind: AUTH_OVERLAY, props: { ...props } });
|
|
4635
4657
|
}
|
|
4636
|
-
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 = {
|
|
4637
4659
|
name: "auth",
|
|
4638
|
-
description: "Provider sign-in: ChatGPT and
|
|
4660
|
+
description: "Provider sign-in: ChatGPT, Grok and Claude status, sign in, sign out",
|
|
4639
4661
|
run: (ctx) => openAuth(ctx.actions)
|
|
4640
4662
|
}, loginCommand = {
|
|
4641
4663
|
name: "login",
|
|
4642
|
-
args: "[chatgpt|grok]",
|
|
4643
|
-
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)",
|
|
4644
4666
|
complete,
|
|
4645
4667
|
run: (ctx) => {
|
|
4646
4668
|
if (!ctx.args[0]) {
|
|
@@ -4649,29 +4671,30 @@ var complete = (partial) => ["chatgpt", "grok"].filter((v) => v.startsWith(parti
|
|
|
4649
4671
|
}
|
|
4650
4672
|
let provider = normalizeAuthProvider(ctx.args[0]);
|
|
4651
4673
|
if (!provider) {
|
|
4652
|
-
ctx.print("Usage: /login [chatgpt|grok]", "warn");
|
|
4674
|
+
ctx.print("Usage: /login [chatgpt|grok|claude]", "warn");
|
|
4653
4675
|
return;
|
|
4654
4676
|
}
|
|
4655
4677
|
openAuth(ctx.actions, { login: provider });
|
|
4656
4678
|
}
|
|
4657
4679
|
}, logoutCommand = {
|
|
4658
4680
|
name: "logout",
|
|
4659
|
-
args: "<chatgpt|grok>",
|
|
4660
|
-
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)",
|
|
4661
4683
|
complete,
|
|
4662
4684
|
run: async (ctx) => {
|
|
4663
4685
|
let provider = normalizeAuthProvider(ctx.args[0]);
|
|
4664
4686
|
if (!provider) {
|
|
4665
|
-
ctx.print("Usage: /logout <chatgpt|grok>", "warn");
|
|
4687
|
+
ctx.print("Usage: /logout <chatgpt|grok|claude>", "warn");
|
|
4666
4688
|
return;
|
|
4667
4689
|
}
|
|
4668
|
-
let label2 = SUBSCRIPTION_LABELS[provider];
|
|
4669
|
-
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);
|
|
4670
4692
|
}
|
|
4671
4693
|
}, authActions = [
|
|
4672
|
-
{ 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) },
|
|
4673
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" }) },
|
|
4674
|
-
{ 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" }) }
|
|
4675
4698
|
];
|
|
4676
4699
|
|
|
4677
4700
|
// src/main/tui/setup/ProviderDialog.tsx
|
|
@@ -5535,7 +5558,7 @@ async function editText(text, options = {}) {
|
|
|
5535
5558
|
var schemaParse = null;
|
|
5536
5559
|
async function loadSchema() {
|
|
5537
5560
|
if (schemaParse) return schemaParse;
|
|
5538
|
-
let schema = cjs(await import("./adf-schema-
|
|
5561
|
+
let schema = cjs(await import("./adf-schema-YJSGLMA4.mjs")).AgentConfigSchema;
|
|
5539
5562
|
return schemaParse = (value) => schema.safeParse(value), schemaParse;
|
|
5540
5563
|
}
|
|
5541
5564
|
function changedKeysBetween(a, b) {
|
|
@@ -5740,6 +5763,10 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5740
5763
|
}, openReview = async (id, back) => {
|
|
5741
5764
|
let r = await act("Review", back, () => store.client.templateReview(id));
|
|
5742
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
|
+
}
|
|
5743
5770
|
if (!r.needsReview) {
|
|
5744
5771
|
await refresh2(), done(`${label2(id)} is already reviewed`, back);
|
|
5745
5772
|
return;
|
|
@@ -5883,7 +5910,7 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5883
5910
|
}
|
|
5884
5911
|
if (step.kind === "review")
|
|
5885
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: [
|
|
5886
|
-
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" }),
|
|
5887
5914
|
errorLine
|
|
5888
5915
|
] });
|
|
5889
5916
|
if (step.kind === "files") {
|
|
@@ -6484,20 +6511,62 @@ function describeDiff(before, after, preview = 6) {
|
|
|
6484
6511
|
return diff.changes.length > preview && lines.push(` \u2026 ${diff.changes.length - preview} more changed lines`), { summary, lines };
|
|
6485
6512
|
}
|
|
6486
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
|
+
|
|
6487
6555
|
// src/main/tui/views/files/io.ts
|
|
6488
6556
|
async function loadTarget(client, agentId, target2) {
|
|
6489
6557
|
if (target2.kind === "document" || target2.kind === "mind") {
|
|
6490
|
-
let
|
|
6491
|
-
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) };
|
|
6492
6560
|
}
|
|
6493
|
-
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) };
|
|
6494
6562
|
if (file.encoding === "base64")
|
|
6495
6563
|
return { ...base2, binary: !0, bytes: Buffer.from(file.content_base64 ?? "", "base64") };
|
|
6496
6564
|
let text = file.content ?? "";
|
|
6497
6565
|
return looksBinary(text) ? { ...base2, binary: !0, bytes: Buffer.from(text, "utf-8") } : { ...base2, text, binary: !1 };
|
|
6498
6566
|
}
|
|
6499
|
-
async function writeTarget(client, agentId, target2, text) {
|
|
6500
|
-
|
|
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 } }));
|
|
6501
6570
|
}
|
|
6502
6571
|
var pathCache = /* @__PURE__ */ new Map();
|
|
6503
6572
|
function cacheFiles(agentId, files2) {
|
|
@@ -6549,13 +6618,13 @@ async function editTarget(deps, target2, options = {}) {
|
|
|
6549
6618
|
}
|
|
6550
6619
|
if (original.charCodeAt(0) !== 65279 && (edited = stripBom2(edited)), edited === original && !options.create)
|
|
6551
6620
|
return await cleanup(), actions4.toast(`No changes to ${label2}`, "info"), "unchanged";
|
|
6552
|
-
let concurrent = null;
|
|
6621
|
+
let concurrent = null, baseRevision = options.create ? "absent" : void 0;
|
|
6553
6622
|
if (options.create)
|
|
6554
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");
|
|
6555
6624
|
else
|
|
6556
6625
|
try {
|
|
6557
6626
|
let current = await loadTarget(client, agentId, target2);
|
|
6558
|
-
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})`);
|
|
6559
6628
|
} catch (err) {
|
|
6560
6629
|
concurrent = err.status === 404 ? "was deleted while you were editing" : `could not be re-checked (${err instanceof Error ? err.message : String(err)})`;
|
|
6561
6630
|
}
|
|
@@ -6565,195 +6634,44 @@ async function editTarget(deps, target2, options = {}) {
|
|
|
6565
6634
|
...diff.lines
|
|
6566
6635
|
].filter((line) => line !== null).join(`
|
|
6567
6636
|
`);
|
|
6568
|
-
|
|
6637
|
+
if (!await actions4.confirm({
|
|
6569
6638
|
title: concurrent ? `Concurrent change: ${label2}` : `${options.create ? "Create" : "Save"} ${label2}`,
|
|
6570
6639
|
message,
|
|
6571
6640
|
confirmLabel: concurrent ? "Overwrite" : options.create ? "Create" : "Write",
|
|
6572
6641
|
cancelLabel: "Discard",
|
|
6573
6642
|
danger: !!concurrent
|
|
6574
|
-
})
|
|
6575
|
-
}
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
var guarded_fetch_exports = {};
|
|
6579
|
-
__export(guarded_fetch_exports, {
|
|
6580
|
-
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
6581
|
-
MAX_FETCH_REDIRECTS: () => MAX_FETCH_REDIRECTS,
|
|
6582
|
-
daemonGuardPort: () => daemonGuardPort,
|
|
6583
|
-
guardedFetch: () => guardedFetch,
|
|
6584
|
-
isFetchFailure: () => isFetchFailure
|
|
6585
|
-
});
|
|
6586
|
-
var DEFAULT_DAEMON_PORT = 7385, MAX_FETCH_REDIRECTS = 3;
|
|
6587
|
-
function daemonGuardPort() {
|
|
6588
|
-
return Number(process.env.ADF_DAEMON_PORT) || DEFAULT_DAEMON_PORT;
|
|
6589
|
-
}
|
|
6590
|
-
function isFetchFailure(result) {
|
|
6591
|
-
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");
|
|
6592
6647
|
}
|
|
6593
|
-
async function
|
|
6594
|
-
let
|
|
6595
|
-
if (!body) return Buffer.alloc(0);
|
|
6596
|
-
if (typeof body.getReader != "function") {
|
|
6597
|
-
let bytes = Buffer.from(new Uint8Array(await response.arrayBuffer()));
|
|
6598
|
-
return bytes.length > maxBytes ? { error: `exceeds ${maxBytes} bytes` } : bytes;
|
|
6599
|
-
}
|
|
6600
|
-
let reader2 = body.getReader(), chunks = [], total = 0;
|
|
6648
|
+
async function writeOverConflicts(actions4, label2, file, write2, baseRevision) {
|
|
6649
|
+
let base2 = baseRevision;
|
|
6601
6650
|
for (; ; ) {
|
|
6602
|
-
let
|
|
6603
|
-
if (
|
|
6604
|
-
if (
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
}
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
}
|
|
6617
|
-
async function guardedFetch(url2, options) {
|
|
6618
|
-
let { maxBytes, timeoutMs } = options, maxRedirects = options.maxRedirects ?? MAX_FETCH_REDIRECTS, daemonPort = daemonGuardPort(), current;
|
|
6619
|
-
try {
|
|
6620
|
-
current = new URL(url2).toString();
|
|
6621
|
-
} catch {
|
|
6622
|
-
return { error: `invalid URL: ${String(url2).slice(0, 200)}` };
|
|
6623
|
-
}
|
|
6624
|
-
let controller = new AbortController(), timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
6625
|
-
try {
|
|
6626
|
-
for (let hop = 0; ; hop++) {
|
|
6627
|
-
let protocol = new URL(current).protocol;
|
|
6628
|
-
if (protocol !== "https:")
|
|
6629
|
-
return { error: `only https URLs may be fetched (got "${protocol}")` };
|
|
6630
|
-
let blocked = await checkFetchTarget(current, { allowLocal: !1, daemonPort });
|
|
6631
|
-
if (blocked) return { error: blocked };
|
|
6632
|
-
let response = await fetch(current, { signal: controller.signal, redirect: "manual" });
|
|
6633
|
-
if (response.status >= 300 && response.status <= 399) {
|
|
6634
|
-
let location = response.headers.get("location");
|
|
6635
|
-
if (!location) return { error: `redirect without a location header (HTTP ${response.status})` };
|
|
6636
|
-
if (hop >= maxRedirects) return { error: `too many redirects (>${maxRedirects})` };
|
|
6637
|
-
try {
|
|
6638
|
-
await response.body?.cancel();
|
|
6639
|
-
} catch {
|
|
6640
|
-
}
|
|
6641
|
-
try {
|
|
6642
|
-
current = new URL(location, current).toString();
|
|
6643
|
-
} catch {
|
|
6644
|
-
return { error: `redirect to an unusable location: ${location.slice(0, 200)}` };
|
|
6645
|
-
}
|
|
6646
|
-
continue;
|
|
6647
|
-
}
|
|
6648
|
-
if (!response.ok) return { error: `HTTP ${response.status} ${response.statusText}`.trim() };
|
|
6649
|
-
let lengthHeader = response.headers.get("content-length"), declared = lengthHeader === null ? NaN : Number(lengthHeader);
|
|
6650
|
-
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
6651
|
-
try {
|
|
6652
|
-
await response.body?.cancel();
|
|
6653
|
-
} catch {
|
|
6654
|
-
}
|
|
6655
|
-
return { error: `exceeds ${maxBytes} bytes` };
|
|
6656
|
-
}
|
|
6657
|
-
let bytes = await readCapped(response, maxBytes);
|
|
6658
|
-
return Buffer.isBuffer(bytes) ? { bytes, contentType: response.headers.get("content-type") ?? "" } : bytes;
|
|
6659
|
-
}
|
|
6660
|
-
} catch (err) {
|
|
6661
|
-
let message = err instanceof Error ? err.message : String(err);
|
|
6662
|
-
return { error: err instanceof Error && err.name === "AbortError" ? `request timed out after ${timeoutMs}ms` : message };
|
|
6663
|
-
} finally {
|
|
6664
|
-
clearTimeout(timer);
|
|
6665
|
-
}
|
|
6666
|
-
}
|
|
6667
|
-
|
|
6668
|
-
// src/shared/schemas/skills-catalog.schema.ts
|
|
6669
|
-
var skills_catalog_schema_exports = {};
|
|
6670
|
-
__export(skills_catalog_schema_exports, {
|
|
6671
|
-
MAX_CATALOG_BYTES: () => MAX_CATALOG_BYTES,
|
|
6672
|
-
MAX_PACKAGE_FILES: () => MAX_PACKAGE_FILES,
|
|
6673
|
-
MAX_SKILL_PACKAGE_BYTES: () => MAX_SKILL_PACKAGE_BYTES,
|
|
6674
|
-
SKILL_NAME: () => SKILL_NAME,
|
|
6675
|
-
SkillCatalogEntrySchema: () => SkillCatalogEntrySchema,
|
|
6676
|
-
parseSkillsCatalogDocument: () => parseSkillsCatalogDocument,
|
|
6677
|
-
resolvePackageFilePath: () => resolvePackageFilePath
|
|
6678
|
-
});
|
|
6679
|
-
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";
|
|
6680
|
-
function resolvePackageFilePath(name, raw) {
|
|
6681
|
-
if (typeof raw != "string") return null;
|
|
6682
|
-
let directory = `skills/${name}/`, candidate = raw.trim().replace(/\\/g, "/");
|
|
6683
|
-
if (!candidate) return null;
|
|
6684
|
-
for (; candidate.startsWith("./"); ) candidate = candidate.slice(2);
|
|
6685
|
-
if (candidate.startsWith("/")) return null;
|
|
6686
|
-
let relative2 = candidate.startsWith(directory) ? candidate.slice(directory.length) : candidate;
|
|
6687
|
-
return !relative2 || relative2.split("/").some((segment) => segment === "." || segment === ".." || !PATH_SEGMENT.test(segment)) || relative2 === "SKILL.md" ? null : relative2;
|
|
6688
|
-
}
|
|
6689
|
-
var SkillPackageFileSchema = external_exports.object({
|
|
6690
|
-
path: external_exports.string().min(1).refine(safeText, UNSAFE_TEXT_MESSAGE),
|
|
6691
|
-
raw_url: external_exports.string().url()
|
|
6692
|
-
}), SkillCatalogEntrySchema = external_exports.object({
|
|
6693
|
-
name: external_exports.string().regex(SKILL_NAME),
|
|
6694
|
-
description: external_exports.string().min(1).max(500).refine(safeText, UNSAFE_TEXT_MESSAGE),
|
|
6695
|
-
/** Path inside the publishing repo — display only. */
|
|
6696
|
-
path: external_exports.string().min(1).refine(safeText, UNSAFE_TEXT_MESSAGE).optional(),
|
|
6697
|
-
/** Where the SKILL.md body is fetched from on install. */
|
|
6698
|
-
raw_url: external_exports.string().url(),
|
|
6699
|
-
/** Resources installed beside SKILL.md, package-relative after parsing. */
|
|
6700
|
-
files: external_exports.array(SkillPackageFileSchema).max(MAX_PACKAGE_FILES).optional()
|
|
6701
|
-
}).superRefine((entry, ctx) => {
|
|
6702
|
-
if (!entry.files) return;
|
|
6703
|
-
let seen = /* @__PURE__ */ new Set();
|
|
6704
|
-
entry.files.forEach((file, index) => {
|
|
6705
|
-
let relative2 = resolvePackageFilePath(entry.name, file.path);
|
|
6706
|
-
if (!relative2) {
|
|
6707
|
-
ctx.addIssue({
|
|
6708
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6709
|
-
path: ["files", index, "path"],
|
|
6710
|
-
message: `must stay inside skills/${entry.name}/ and cannot be SKILL.md`
|
|
6711
|
-
});
|
|
6712
|
-
return;
|
|
6713
|
-
}
|
|
6714
|
-
if (seen.has(relative2)) {
|
|
6715
|
-
ctx.addIssue({
|
|
6716
|
-
code: external_exports.ZodIssueCode.custom,
|
|
6717
|
-
path: ["files", index, "path"],
|
|
6718
|
-
message: "duplicate package path"
|
|
6719
|
-
});
|
|
6720
|
-
return;
|
|
6721
|
-
}
|
|
6722
|
-
seen.add(relative2);
|
|
6723
|
-
});
|
|
6724
|
-
}).transform((entry) => entry.files ? {
|
|
6725
|
-
...entry,
|
|
6726
|
-
files: entry.files.map((file) => ({
|
|
6727
|
-
...file,
|
|
6728
|
-
path: resolvePackageFilePath(entry.name, file.path)
|
|
6729
|
-
}))
|
|
6730
|
-
} : entry);
|
|
6731
|
-
function parseSkillsCatalogDocument(json2) {
|
|
6732
|
-
if (typeof json2 != "object" || json2 === null || Array.isArray(json2)) return null;
|
|
6733
|
-
let doc = json2;
|
|
6734
|
-
if (doc.schema !== void 0 && doc.schema !== 1 || !Array.isArray(doc.skills)) return null;
|
|
6735
|
-
let entries = [], seen = /* @__PURE__ */ new Set(), dropped = 0;
|
|
6736
|
-
for (let raw of doc.skills) {
|
|
6737
|
-
let result = SkillCatalogEntrySchema.safeParse(raw);
|
|
6738
|
-
if (!result.success || seen.has(result.data.name)) {
|
|
6739
|
-
dropped++;
|
|
6740
|
-
continue;
|
|
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";
|
|
6741
6665
|
}
|
|
6742
|
-
|
|
6666
|
+
base2 = result.stale.revision;
|
|
6743
6667
|
}
|
|
6744
|
-
return {
|
|
6745
|
-
entries,
|
|
6746
|
-
publisher: typeof doc.publisher == "string" ? doc.publisher : void 0,
|
|
6747
|
-
repository: typeof doc.repository == "string" ? doc.repository : void 0,
|
|
6748
|
-
dropped
|
|
6749
|
-
};
|
|
6750
6668
|
}
|
|
6751
6669
|
|
|
6752
6670
|
// src/main/tui/skills/catalog.ts
|
|
6753
|
-
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";
|
|
6754
6672
|
async function fetchCatalogDocument(url2) {
|
|
6755
6673
|
if (typeof url2 != "string" || !/^https:\/\//.test(url2)) return { ok: !1, error: "Catalog URL must be https" };
|
|
6756
|
-
let body = await
|
|
6674
|
+
let body = await guardedFetch(url2, { maxBytes: MAX_CATALOG_BYTES, timeoutMs: SKILLS_FETCH_TIMEOUT_MS });
|
|
6757
6675
|
if ("error" in body) return { ok: !1, error: body.error };
|
|
6758
6676
|
let json2;
|
|
6759
6677
|
try {
|
|
@@ -6761,12 +6679,12 @@ async function fetchCatalogDocument(url2) {
|
|
|
6761
6679
|
} catch {
|
|
6762
6680
|
return { ok: !1, error: "Catalog is not valid JSON" };
|
|
6763
6681
|
}
|
|
6764
|
-
let parsed =
|
|
6682
|
+
let parsed = parseSkillsCatalogDocument(json2);
|
|
6765
6683
|
return parsed ? { ok: !0, entries: parsed.entries, publisher: parsed.publisher, dropped: parsed.dropped } : { ok: !1, error: "Unrecognized catalog schema" };
|
|
6766
6684
|
}
|
|
6767
6685
|
async function fetchSkillText(url2) {
|
|
6768
6686
|
if (typeof url2 != "string" || !/^https:\/\//.test(url2)) return { ok: !1, error: "Package URL must be https" };
|
|
6769
|
-
let body = await
|
|
6687
|
+
let body = await guardedFetch(url2, { maxBytes: MAX_SKILL_PACKAGE_BYTES, timeoutMs: SKILLS_FETCH_TIMEOUT_MS });
|
|
6770
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") };
|
|
6771
6689
|
}
|
|
6772
6690
|
var DEFAULT_SEAMS = { catalog: fetchCatalogDocument, text: fetchSkillText }, seams2 = DEFAULT_SEAMS;
|
|
@@ -6800,7 +6718,7 @@ var {
|
|
|
6800
6718
|
parseSkillsRegistry: parseSkillsRegistry2,
|
|
6801
6719
|
sanitizeDisplayText: sanitizeDisplayText2,
|
|
6802
6720
|
skillProblems: skillProblems2
|
|
6803
|
-
} = 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);
|
|
6804
6722
|
function parseAddTarget2(raw) {
|
|
6805
6723
|
let value = (raw ?? "").trim().replace(/^(["'])(.*)\1$/, "$2");
|
|
6806
6724
|
if (!value) return { kind: "catalog", query: "" };
|
|
@@ -6851,7 +6769,7 @@ function settleOverrides(overrides, registryText) {
|
|
|
6851
6769
|
function tokenLabel(tokens) {
|
|
6852
6770
|
return tokens == null ? "" : tokens >= 1e3 ? `~${(tokens / 1e3).toFixed(tokens >= 1e4 ? 0 : 1)}k tok` : `~${tokens} tok`;
|
|
6853
6771
|
}
|
|
6854
|
-
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);
|
|
6855
6773
|
function manifestProblem(manifest) {
|
|
6856
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;
|
|
6857
6775
|
}
|
|
@@ -6919,7 +6837,7 @@ function exactEntry(entries, query) {
|
|
|
6919
6837
|
import { promises as fs3 } from "node:fs";
|
|
6920
6838
|
import { homedir as homedir2 } from "node:os";
|
|
6921
6839
|
import { basename as basename2, dirname, join as join3, relative, resolve as resolve2, sep } from "node:path";
|
|
6922
|
-
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;
|
|
6923
6841
|
async function must(result, what) {
|
|
6924
6842
|
let outcome = await result;
|
|
6925
6843
|
if (outcome && outcome.success === !1) throw new Error(`${what} was refused (protected file?)`);
|
|
@@ -7047,7 +6965,7 @@ async function readLocalPackage(input, cwd = process.cwd()) {
|
|
|
7047
6965
|
try {
|
|
7048
6966
|
let manifestStat = await fs3.stat(manifestPath);
|
|
7049
6967
|
if (!manifestStat.isFile()) return { ok: !1, error: `${manifestPath} is not a file` };
|
|
7050
|
-
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` };
|
|
7051
6969
|
manifestBytes = await fs3.readFile(manifestPath);
|
|
7052
6970
|
} catch {
|
|
7053
6971
|
return { ok: !1, error: stat.isDirectory() ? `No SKILL.md in ${target2}` : `Cannot read ${target2}` };
|
|
@@ -7079,24 +6997,24 @@ async function readLocalPackage(input, cwd = process.cwd()) {
|
|
|
7079
6997
|
if (!entry.isFile()) continue;
|
|
7080
6998
|
let rel = relative(target2, full).split(sep).join("/");
|
|
7081
6999
|
if (rel === "SKILL.md") continue;
|
|
7082
|
-
let path =
|
|
7000
|
+
let path = resolvePackageFilePath(identity.name, rel);
|
|
7083
7001
|
if (!path) {
|
|
7084
7002
|
warnings.push(`${rel}: skipped (not a package path)`);
|
|
7085
7003
|
continue;
|
|
7086
7004
|
}
|
|
7087
|
-
if (resources.length >=
|
|
7005
|
+
if (resources.length >= MAX_PACKAGE_FILES) {
|
|
7088
7006
|
skippedOver++;
|
|
7089
7007
|
continue;
|
|
7090
7008
|
}
|
|
7091
|
-
if ((await fs3.stat(full)).size >
|
|
7092
|
-
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)`);
|
|
7093
7011
|
continue;
|
|
7094
7012
|
}
|
|
7095
7013
|
let bytes = await fs3.readFile(full);
|
|
7096
7014
|
resources.push(bytes.subarray(0, 8192).includes(0) ? { path, contentBase64: bytes.toString("base64") } : { path, content: bytes.toString("utf-8") });
|
|
7097
7015
|
}
|
|
7098
7016
|
};
|
|
7099
|
-
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)`);
|
|
7100
7018
|
}
|
|
7101
7019
|
return {
|
|
7102
7020
|
ok: !0,
|
|
@@ -7425,7 +7343,7 @@ function SkillDoc({ manifest, width, height }) {
|
|
|
7425
7343
|
var import_react24 = __toESM(require_react(), 1);
|
|
7426
7344
|
|
|
7427
7345
|
// src/main/tui/context/model.ts
|
|
7428
|
-
var { resolveLoopThreshold } = cjs(context_breakdown_exports), CONTEXT_OVERLAY = "context";
|
|
7346
|
+
var { resolveLoopThreshold, calibrationNote } = cjs(context_breakdown_exports), CONTEXT_OVERLAY = "context";
|
|
7429
7347
|
function openContext(store, props) {
|
|
7430
7348
|
store.actions.pushOverlay({ kind: CONTEXT_OVERLAY, props: { ...props } });
|
|
7431
7349
|
}
|
|
@@ -7448,6 +7366,9 @@ var SOURCE_TEXT = {
|
|
|
7448
7366
|
function thresholdText(r, fmt) {
|
|
7449
7367
|
return `auto-compacts at ${fmt(r.compactThreshold)} (${SOURCE_TEXT[r.compactThresholdSource]})`;
|
|
7450
7368
|
}
|
|
7369
|
+
function calibrationText(cal, approx, fmt) {
|
|
7370
|
+
return calibrationNote(cal, fmt, approx);
|
|
7371
|
+
}
|
|
7451
7372
|
function contextRows(categories, expanded) {
|
|
7452
7373
|
let rows = [];
|
|
7453
7374
|
for (let category of categories) {
|
|
@@ -7594,7 +7515,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7594
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}`)) }),
|
|
7595
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,
|
|
7596
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}` : "" }) }),
|
|
7597
|
-
/* @__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)}` : "" })
|
|
7598
7519
|
] });
|
|
7599
7520
|
}
|
|
7600
7521
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Modal, { title: `Context ${g.sep} ${truncate(header2, inner - 12)}`, width: dialogWidth, hints, onClose: close, children: body });
|
|
@@ -7602,7 +7523,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7602
7523
|
function RowLine({ row: row4, selectedId, total, labelWidth, rowBar, theme: theme2 }) {
|
|
7603
7524
|
let g = theme2.glyph, share = (tokens) => total > 0 ? `${Math.round(tokens / total * 100)}%` : "0%";
|
|
7604
7525
|
if (row4.kind === "category") {
|
|
7605
|
-
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);
|
|
7606
7527
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Text, { wrap: "truncate-end", inverse: theme2.mono && isSel, bold: isSel, children: [
|
|
7607
7528
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Text, { color: isSel ? theme2.color.accent : theme2.color.dim, children: [
|
|
7608
7529
|
isSel ? g.pointer : " ",
|
|
@@ -8013,7 +7934,7 @@ var RUNTIME_VIEW = "runtime", RUNTIME_TABS = [
|
|
|
8013
7934
|
{ id: "status", title: "Status", description: "Daemon health, version, uptime and every agent\u2019s loops" },
|
|
8014
7935
|
{ id: "folders", title: "Folders", description: "Tracked agent folders: Enter its agents (review, load, errors), a add, d stop tracking, r rescan" },
|
|
8015
7936
|
{ id: "identity", title: "Identity", description: "Owner identity: status; Enter to create, restore, unlock or lock" },
|
|
8016
|
-
{ 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" },
|
|
8017
7938
|
{ id: "providers", title: "Providers", description: "LLM providers and which agents use them" },
|
|
8018
7939
|
{ id: "usage", title: "Usage", description: "Token usage across agents, by model" },
|
|
8019
7940
|
{ id: "network", title: "Network", description: "Mesh, LAN, WebSocket; m mesh on/off, s server start/stop" },
|
|
@@ -8488,14 +8409,14 @@ var REPORTS = {
|
|
|
8488
8409
|
title: "Auth",
|
|
8489
8410
|
async load(client) {
|
|
8490
8411
|
let d = await client.authStatus(), lines = [heading("Subscription sign-ins")];
|
|
8491
|
-
for (let [name, status] of [["chatgpt", d.chatgpt], ["grok", d.grok]]) {
|
|
8492
|
-
let s = status ?? {};
|
|
8493
|
-
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" }]));
|
|
8494
8415
|
}
|
|
8495
8416
|
return lines.push(blank(), heading("API-key providers")), lines.push(...tableLines(
|
|
8496
8417
|
["id", "type", "key", "stored in"],
|
|
8497
8418
|
d.providers.map((p) => [p.id, p.type, p.hasApiKey ? "set" : "missing", p.credentialStorage])
|
|
8498
|
-
).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 };
|
|
8499
8420
|
}
|
|
8500
8421
|
},
|
|
8501
8422
|
network: {
|
|
@@ -8902,15 +8823,14 @@ function folderAgentsSummary(agents) {
|
|
|
8902
8823
|
}
|
|
8903
8824
|
async function loadFolderAgent(store, agent2, options = {}) {
|
|
8904
8825
|
try {
|
|
8905
|
-
options.accept
|
|
8906
|
-
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 = "";
|
|
8907
8827
|
if (agent2.autostart)
|
|
8908
8828
|
try {
|
|
8909
8829
|
await store.client.start(ref.id), started = " and started it";
|
|
8910
8830
|
} catch (err) {
|
|
8911
8831
|
started = ` (start failed: ${err instanceof Error ? err.message : String(err)})`;
|
|
8912
8832
|
}
|
|
8913
|
-
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 };
|
|
8914
8834
|
} catch (err) {
|
|
8915
8835
|
err instanceof DaemonError && err.unreachable && store.dispatch({ type: "daemon/reachable", reachable: !1 });
|
|
8916
8836
|
let error = err instanceof DaemonError && err.status === 403 ? "It needs review first." : err instanceof Error ? err.message : String(err);
|
|
@@ -10109,7 +10029,10 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10109
10029
|
g.dot,
|
|
10110
10030
|
" "
|
|
10111
10031
|
] }),
|
|
10112
|
-
/* @__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
|
+
] })
|
|
10113
10036
|
] });
|
|
10114
10037
|
case "thinking": {
|
|
10115
10038
|
let open2 = expanded || showThinking, lines = lineCount(item.text);
|
|
@@ -10133,7 +10056,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10133
10056
|
case "tool":
|
|
10134
10057
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToolBody, { item, w, expanded });
|
|
10135
10058
|
case "hil": {
|
|
10136
|
-
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;
|
|
10137
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: [
|
|
10138
10061
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
10139
10062
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { bold: !0, color: tone, children: [
|
|
@@ -11665,7 +11588,7 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
11665
11588
|
import { promises as fs4, rmSync, statSync as statSync3 } from "node:fs";
|
|
11666
11589
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
11667
11590
|
import { join as join4 } from "node:path";
|
|
11668
|
-
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");
|
|
11669
11592
|
function externalCopy(agentId, target2) {
|
|
11670
11593
|
return copies.get(copyKey(agentId, target2));
|
|
11671
11594
|
}
|
|
@@ -11696,7 +11619,7 @@ async function openExternal(deps, target2) {
|
|
|
11696
11619
|
}
|
|
11697
11620
|
copies.set(copyKey(agentId, target2), { agentId, target: target2, file, original: bytes, binary: loaded.binary, mime: loaded.mime, mtimeMs: (await fs4.stat(file)).mtimeMs });
|
|
11698
11621
|
}
|
|
11699
|
-
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;
|
|
11700
11623
|
}
|
|
11701
11624
|
async function saveBackExternal(deps, target2) {
|
|
11702
11625
|
let { client, actions: actions4, agentId, agentLabel: agentLabel5 } = deps, label2 = targetLabel(target2), copy = externalCopy(agentId, target2);
|
|
@@ -11710,14 +11633,14 @@ async function saveBackExternal(deps, target2) {
|
|
|
11710
11633
|
}
|
|
11711
11634
|
if (edited.equals(copy.original))
|
|
11712
11635
|
return copy.mtimeMs = (await fs4.stat(copy.file)).mtimeMs, actions4.toast(`No changes to ${label2}`, "info"), "unchanged";
|
|
11713
|
-
let concurrent = null;
|
|
11636
|
+
let concurrent = null, baseRevision;
|
|
11714
11637
|
try {
|
|
11715
11638
|
let current = await loadTarget(client, agentId, target2);
|
|
11716
|
-
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");
|
|
11717
11640
|
} catch (err) {
|
|
11718
11641
|
concurrent = err.status === 404 ? "was deleted since you opened it" : `could not be re-checked (${errorText5(err)})`;
|
|
11719
11642
|
}
|
|
11720
|
-
|
|
11643
|
+
if (!await actions4.confirm({
|
|
11721
11644
|
title: concurrent ? `Concurrent change: ${label2}` : `Save ${label2}`,
|
|
11722
11645
|
message: [
|
|
11723
11646
|
concurrent ? `WARNING: ${label2} ${concurrent}. Writing replaces that version.` : null,
|
|
@@ -11727,7 +11650,9 @@ async function saveBackExternal(deps, target2) {
|
|
|
11727
11650
|
confirmLabel: concurrent ? "Overwrite" : "Write",
|
|
11728
11651
|
cancelLabel: "Cancel",
|
|
11729
11652
|
danger: !!concurrent
|
|
11730
|
-
})
|
|
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");
|
|
11731
11656
|
}
|
|
11732
11657
|
|
|
11733
11658
|
// src/main/tui/views/files/FilesTab.tsx
|
|
@@ -14560,8 +14485,8 @@ var TOOL_GROUPS = [
|
|
|
14560
14485
|
off: "nobody: no inbound messages, sends still allowed",
|
|
14561
14486
|
directory: "only ancestor-directory agents on this runtime",
|
|
14562
14487
|
localhost: "any agent on this machine",
|
|
14563
|
-
lan: "any agent on
|
|
14564
|
-
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"
|
|
14565
14490
|
}, SEND_MODES = ["proactive", "respond_only", "listen_only"], SEND_MODE_HINTS = {
|
|
14566
14491
|
proactive: "can send anytime",
|
|
14567
14492
|
respond_only: "sends only when a message triggered the turn",
|
|
@@ -14573,8 +14498,6 @@ function triState(items, pred) {
|
|
|
14573
14498
|
return n === 0 ? "none" : n === items.length ? "all" : "mixed";
|
|
14574
14499
|
}
|
|
14575
14500
|
function groupBlocked(config2, groupId) {
|
|
14576
|
-
let triggers = config2.triggers;
|
|
14577
|
-
if (groupId === "messaging" && !triggers?.on_inbox?.enabled) return "needs messaging (the on_inbox trigger)";
|
|
14578
14501
|
if (groupId === "inbox" && config2.messaging?.inbox_mode !== !0) return "needs inbox mode (Settings \u203A Inbox mode)";
|
|
14579
14502
|
}
|
|
14580
14503
|
function mcpServers(config2) {
|
|
@@ -14731,6 +14654,26 @@ function setMainThreshold(config2, value) {
|
|
|
14731
14654
|
let next = clone(config2), context = { ...next.context ?? {} };
|
|
14732
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` };
|
|
14733
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
|
+
}
|
|
14734
14677
|
function parseThreshold(text) {
|
|
14735
14678
|
let raw = text.trim().toLowerCase().replace(/[,_\s]/g, "");
|
|
14736
14679
|
if (!raw || raw === "default" || raw === "inherit" || raw === "0") return { ok: !0, value: null };
|
|
@@ -14837,6 +14780,15 @@ function settingRows(config2, extras = {}) {
|
|
|
14837
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)}%)` : ""}`,
|
|
14838
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",
|
|
14839
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"])
|
|
14840
14792
|
}), rows.push({
|
|
14841
14793
|
id: "autonomous",
|
|
14842
14794
|
label: "Autonomous",
|
|
@@ -14931,6 +14883,9 @@ async function actOnSetting(actions4, agentId, row4, config2) {
|
|
|
14931
14883
|
case "compaction":
|
|
14932
14884
|
actions4.pushOverlay({ kind: COMPACTION_OVERLAY, props: { agentId } });
|
|
14933
14885
|
return;
|
|
14886
|
+
case "media":
|
|
14887
|
+
actions4.toast("Set with /media <files> <MB>, or /media default", "info", 3e3);
|
|
14888
|
+
return;
|
|
14934
14889
|
case "visibility":
|
|
14935
14890
|
case "send":
|
|
14936
14891
|
actions4.pushOverlay({ kind: CHOICE_OVERLAY, props: { agentId, setting: row4.id } });
|
|
@@ -15304,6 +15259,24 @@ var inspect = {
|
|
|
15304
15259
|
}
|
|
15305
15260
|
await applyThreshold(ctx.store, ctx.agentId, ctx.loop, parsed.value);
|
|
15306
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
|
+
}
|
|
15307
15280
|
}, TASK_FILTER_ARGS = TASK_FILTERS, tasks = {
|
|
15308
15281
|
name: "tasks",
|
|
15309
15282
|
args: `[${TASK_FILTERS.join("|")}]`,
|
|
@@ -15356,7 +15329,7 @@ var inspect = {
|
|
|
15356
15329
|
patchInspectState(ctx.actions, ctx.state(), { tab: t.id }), ctx.actions.setView(INSPECT_VIEW);
|
|
15357
15330
|
}
|
|
15358
15331
|
}))
|
|
15359
|
-
], inspectCommands = { commands: [inspect, model, config, tasks, instructions, tools, compaction], actions: actions2 };
|
|
15332
|
+
], inspectCommands = { commands: [inspect, model, config, tasks, instructions, tools, compaction, media], actions: actions2 };
|
|
15360
15333
|
|
|
15361
15334
|
// src/main/tui/views/inspect/EventsTab.tsx
|
|
15362
15335
|
var import_react51 = __toESM(require_react(), 1);
|
|
@@ -15615,6 +15588,9 @@ function typeColor(theme2, type) {
|
|
|
15615
15588
|
// src/main/tui/views/inspect/ConfigTab.tsx
|
|
15616
15589
|
var import_react52 = __toESM(require_react(), 1);
|
|
15617
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";
|
|
15618
15594
|
async function editConfigFlow(agentId, label2, actions4, suspend, edit = (text) => editText(text, { filename: `${label2}.config.json` })) {
|
|
15619
15595
|
let original = await actions4.loadConfig(agentId);
|
|
15620
15596
|
if (!original) return "failed";
|
|
@@ -15646,10 +15622,10 @@ Edit again? Discard drops your edit.`,
|
|
|
15646
15622
|
}
|
|
15647
15623
|
if (check.changedKeys.length === 0)
|
|
15648
15624
|
return actions4.toast("Config unchanged (formatting only), nothing saved", "info"), "unchanged";
|
|
15649
|
-
let
|
|
15650
|
-
if (!
|
|
15651
|
-
let theirs = changedKeysBetween(original, fresh);
|
|
15652
|
-
|
|
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({
|
|
15653
15629
|
title: `Config of ${label2} changed on the daemon`,
|
|
15654
15630
|
message: `While you were editing, these keys changed on the daemon: ${theirs.join(", ")}.
|
|
15655
15631
|
Saving your copy reverts them${theirs.includes("loops") ? " (a loop added meanwhile would be removed and archived)" : ""}.
|
|
@@ -15658,14 +15634,24 @@ Warning: ${check.warnings.join("; ")}` : ""}`,
|
|
|
15658
15634
|
confirmLabel: "Overwrite",
|
|
15659
15635
|
cancelLabel: "Discard",
|
|
15660
15636
|
danger: !0
|
|
15661
|
-
})
|
|
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({
|
|
15662
15642
|
title: `Save config of ${label2}?`,
|
|
15663
15643
|
message: `Changed: ${check.changedKeys.join(", ")}${check.warnings.length ? `
|
|
15664
15644
|
Warning: ${check.warnings.join("; ")}` : ""}`,
|
|
15665
15645
|
confirmLabel: "Save",
|
|
15666
15646
|
cancelLabel: "Discard",
|
|
15667
15647
|
danger: check.warnings.length > 0
|
|
15668
|
-
})
|
|
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";
|
|
15669
15655
|
}
|
|
15670
15656
|
}
|
|
15671
15657
|
function ConfigTab({ agentId, label: label2, width, height, focused }) {
|