zidane 5.6.3 → 5.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.d.ts +158 -3
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +3 -3
- package/dist/{index-DKpXHp1c.d.ts → index-8mn3PIaa.d.ts} +24 -1
- package/dist/{index-DKpXHp1c.d.ts.map → index-8mn3PIaa.d.ts.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/{login-YckkS-Bq.js → login-Btpliwct.js} +2 -2
- package/dist/{login-YckkS-Bq.js.map → login-Btpliwct.js.map} +1 -1
- package/dist/{presets-ZT3TJDEb.js → presets-BXmWG3kd.js} +2 -2
- package/dist/{presets-ZT3TJDEb.js.map → presets-BXmWG3kd.js.map} +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/{tools-Bgx8OBqK.js → tools-FerA0zSl.js} +72 -9
- package/dist/tools-FerA0zSl.js.map +1 -0
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-CtSVZeBi.d.ts → transcript-anchors-C5Sp1Snh.d.ts} +256 -18
- package/dist/transcript-anchors-C5Sp1Snh.d.ts.map +1 -0
- package/dist/tui.d.ts +47 -2
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +456 -175
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-CH7rnULP.js → turn-operations-D-OQYUgS.js} +524 -125
- package/dist/turn-operations-D-OQYUgS.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/docs/CHAT.md +52 -20
- package/docs/TUI.md +5 -5
- package/package.json +1 -1
- package/dist/tools-Bgx8OBqK.js.map +0 -1
- package/dist/transcript-anchors-CtSVZeBi.d.ts.map +0 -1
- package/dist/turn-operations-CH7rnULP.js.map +0 -1
package/dist/tui.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { A as resolvePersistDir, B as formatTaskStatus, H as previewLine, I as ageString, L as compactPath, O as cleanupPersistedSession, R as fmtTokens, U as shortId, V as formatTaskSummary, j as resolveTasksDir, p as createAgent, z as formatDuration } from "./tools-
|
|
1
|
+
import { A as getSafelist, Ar as setProviderCredential, At as SETTINGS_TOGGLES, B as oauthUsesManualCodePaste, Bn as KEYBINDING_KEY_COL_WIDTH, Br as modelSupportsReasoning, Cn as extractEditPayload, Cr as shouldAutoCompact, Ct as buildHints, D as useSafeModeQueue, Di as buildBuildSystem, Dn as summarizeEditPayload, Dt as DEFAULT_SETTINGS, E as useSafeModeActions, Et as useEnabledToggleSet, F as suggestSafelistEntry, Fn as stripEditOutcomesAnnotation, G as indexOfEntry, Gn as matchesBinding, Gr as discoverAgentsMd, Gt as useDiscovery, H as supportsOAuth, Hn as formatBindingForDisplay, In as summarizeOutcomes, It as resolveChipColor, J as discoverProjectMcps, Jt as useConfig, K as buildMcpServers, Kt as useDiscoveryOptional, L as splitPromptSegments, Lt as resolveTheme, Mn as parseEditOutcomesFromResult, Mt as clampFps, Nn as resolveApprovalForPayload, Nt as useSettings, Oi as buildPlanSystem, Ot as SETTINGS_CATEGORIES, Pn as rewriteMultiEditHeader, Qn as uniqueSkillNamesFromReferences, Qt as EDIT_TOOL_NAMES, R as formatPathForCwd, Rn as KEYBINDING_DEFS, Rr as getContextWindow, Sr as AUTO_COMPACT_MIN_GROWTH_FRACTION, St as generateSessionTitle, T as SafeModeProvider, Tn as previewEditPayload, Tt as listProjectFiles, U as buildModelCatalog, Un as groupBindings, Ut as createDiscoverySlot, V as runOAuthLogin, Vn as ensureKeybindingsFile, W as filterModelCatalog, Wn as keybindingsPath, Wr as piIdOf, Wt as DiscoveryProvider, Yt as resolveConfig, Z as createFileMcpCredentialStore, Zn as createSkillsCompletionProvider, _ as turnContextSize, _n as updateToolEventOutcomes, _t as EMPTY_HINTS, a as computeTurnAnchors, an as lastContextSizeFromTurns, at as splitMarkdownCodeBlocks, b as defaultSkillScanPaths, bn as buildUnifiedDiff, bt as truncateTrailing, c as formatToolCall, cn as marginTopFor, cr as buildLinearRamp, d as useSelectStyle, dn as stripSpawnTokensLine, dr as bootTick, ei as accentColor, en as deriveSessionTitle, er as createFilesCompletionProvider, et as McpAuthProvider, f as useSurfaces, fn as sumRunCosts, fr as buildUpdateHint, ft as makeRequestInteraction, g as finalizeStreamingMarkdownForOwner, gi as useActiveTodos, gn as turnSelectionOwnership, gt as useInteractionsQueue, h as finalizeStreamingMarkdown, hn as toolResultText, ht as useInteractionsActions, i as turnAsText, in as isVisible, j as isOnSafelist, jn as mergeApprovalAndBodyOutcomes, jt as SettingsProvider, k as addToSafelist, ki as envSection, kn as buildEditOutcomesAnnotation, kt as SETTINGS_CHOICES, l as ThemeProvider, lr as tryOpenBrowser, lt as buildResumedToolResultsTurn, m as useTheme, mn as toolCallPreview, n as deleteTurnSafely, nn as isEditErrorResult, nt as useMcpAuthState, o as TOOL_DISPLAY, oi as TODO_STATUS_GLYPHS, on as listSessionMeta, or as useCompletion, pr as useUpdateCheck, pt as pendingInteractionsFromTurns, qr as findGitRoot, qt as ConfigProvider, r as truncateTurnsAt, rn as isTurnHighlighted, rt as getMcpAuthStatus, s as displayNameFor, sr as blendHsl, st as InteractionsProvider, tn as eventsFromTurns, tt as useMcpAuthDispatch, u as useColors, un as selectableTurnIds, ut as createInteractionTools, v as useStreamBuffer, vt as clipHintsToWidth, w as writeSessionExport, wn as filetypeFromPath, wr as detectAuth, x as discoverProjectSkills, y as buildSkillsConfig, yn as buildContextualDiff, yt as hintsLength, z as fetchOAuthRedirect } from "./turn-operations-D-OQYUgS.js";
|
|
2
|
+
import { A as resolvePersistDir, B as formatTaskStatus, H as previewLine, I as ageString, L as compactPath, O as cleanupPersistedSession, R as fmtTokens, U as shortId, V as formatTaskSummary, j as resolveTasksDir, p as createAgent, z as formatDuration } from "./tools-FerA0zSl.js";
|
|
3
3
|
import { n as createProcessContext } from "./contexts-BOtMvzli.js";
|
|
4
4
|
import { c as errorMessage } from "./errors-DdZXnyXE.js";
|
|
5
5
|
import { s as McpOAuthProvider, t as connectMcpServers } from "./mcp-ngMS0S6N.js";
|
|
6
|
-
import { C as summaryToTurn, a as selectFilesFromSession, r as buildPostCompactAttachments, s as compactConversation, t as loginMcpServer } from "./login-
|
|
6
|
+
import { C as summaryToTurn, a as selectFilesFromSession, r as buildPostCompactAttachments, s as compactConversation, t as loginMcpServer } from "./login-Btpliwct.js";
|
|
7
7
|
import { n as formatTokenUsage } from "./stats-Lc3zL3RM.js";
|
|
8
8
|
import { n as loadSession, t as createSession } from "./session-BoEW_wCR.js";
|
|
9
9
|
import { createTuiStore } from "./session/sqlite.js";
|
|
@@ -2017,7 +2017,7 @@ MarkdownBlock.displayName = "MarkdownBlock";
|
|
|
2017
2017
|
const TOOL_RESULT_MAX_LINES = 6;
|
|
2018
2018
|
function ToolResultBlock({ text, indent }) {
|
|
2019
2019
|
const COLOR = useColors();
|
|
2020
|
-
const rawLines = text.split("\n");
|
|
2020
|
+
const rawLines = stripAnsiSequences(text).split("\n");
|
|
2021
2021
|
let end = rawLines.length;
|
|
2022
2022
|
while (end > 0 && rawLines[end - 1].trim() === "") end--;
|
|
2023
2023
|
if (end === 0) return null;
|
|
@@ -3142,23 +3142,7 @@ function EffortRow({ level, isCurrent, isFocused, highlightBg }) {
|
|
|
3142
3142
|
}
|
|
3143
3143
|
//#endregion
|
|
3144
3144
|
//#region src/tui/keybindings-modal.tsx
|
|
3145
|
-
/**
|
|
3146
|
-
* Fixed column width for the rendered key — derived once from
|
|
3147
|
-
* {@link KEYBINDING_DEFS} so adding an action with a wider default spec
|
|
3148
|
-
* (`ctrl+shift+x`, etc.) automatically grows the column instead of
|
|
3149
|
-
* truncating the label. Falls back to a sensible minimum so empty /
|
|
3150
|
-
* one-glyph defaults don't collapse the layout.
|
|
3151
|
-
*/
|
|
3152
|
-
const KEY_COL_WIDTH = (() => {
|
|
3153
|
-
let max = 8;
|
|
3154
|
-
for (const def of KEYBINDING_DEFS) {
|
|
3155
|
-
const width = formatBindingForDisplay(def.default).length;
|
|
3156
|
-
if (width > max) max = width;
|
|
3157
|
-
}
|
|
3158
|
-
return max + 2;
|
|
3159
|
-
})();
|
|
3160
3145
|
function KeybindingsModal({ bindings, filePath, onEditFile, onClose }) {
|
|
3161
|
-
const COLOR = useColors();
|
|
3162
3146
|
const SURFACE = useSurfaces();
|
|
3163
3147
|
const { height: termHeight } = useTerminalDimensions();
|
|
3164
3148
|
const scrollRef = useRef(null);
|
|
@@ -3192,24 +3176,77 @@ function KeybindingsModal({ bindings, filePath, onEditFile, onClose }) {
|
|
|
3192
3176
|
flexGrow: 1,
|
|
3193
3177
|
flexShrink: 1
|
|
3194
3178
|
},
|
|
3195
|
-
children:
|
|
3196
|
-
style: {
|
|
3197
|
-
flexDirection: "column",
|
|
3198
|
-
flexShrink: 0,
|
|
3199
|
-
marginTop: sectionIdx === 0 ? 0 : 1
|
|
3200
|
-
},
|
|
3201
|
-
children: [/* @__PURE__ */ jsx(SectionHeader, { label: section.group }), section.rows.map((row) => /* @__PURE__ */ jsx(BindingRow, {
|
|
3202
|
-
def: row.def,
|
|
3203
|
-
spec: row.spec
|
|
3204
|
-
}, row.def.action))]
|
|
3205
|
-
}, section.group))
|
|
3179
|
+
children: /* @__PURE__ */ jsx(KeybindingsCatalog, { sections })
|
|
3206
3180
|
})
|
|
3207
|
-
}), /* @__PURE__ */ jsx(
|
|
3181
|
+
}), /* @__PURE__ */ jsx(KeybindingsEditFileButton, {
|
|
3208
3182
|
filePath,
|
|
3209
|
-
highlightBg: SURFACE.selection
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3183
|
+
highlightBg: SURFACE.selection
|
|
3184
|
+
})]
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
function KeybindingsCatalog({ sections }) {
|
|
3188
|
+
return /* @__PURE__ */ jsx("box", {
|
|
3189
|
+
style: { flexDirection: "column" },
|
|
3190
|
+
children: sections.map((section, sectionIdx) => /* @__PURE__ */ jsxs("box", {
|
|
3191
|
+
style: {
|
|
3192
|
+
flexDirection: "column",
|
|
3193
|
+
flexShrink: 0,
|
|
3194
|
+
marginTop: sectionIdx === 0 ? 0 : 1
|
|
3195
|
+
},
|
|
3196
|
+
children: [/* @__PURE__ */ jsx(SectionHeader, { label: section.group }), section.rows.map((row) => /* @__PURE__ */ jsx(BindingRow, {
|
|
3197
|
+
def: row.def,
|
|
3198
|
+
spec: row.spec
|
|
3199
|
+
}, row.def.action))]
|
|
3200
|
+
}, section.group))
|
|
3201
|
+
});
|
|
3202
|
+
}
|
|
3203
|
+
/**
|
|
3204
|
+
* Highlighted "Edit keybindings file" button. Used as the standalone
|
|
3205
|
+
* modal's pinned footer AND as the Settings-modal Keybindings tab's
|
|
3206
|
+
* pinned action row. Activation is the caller's responsibility (the
|
|
3207
|
+
* standalone modal uses its own `useKeyboard`; the Settings modal
|
|
3208
|
+
* routes `↵` through its top-level handler).
|
|
3209
|
+
*/
|
|
3210
|
+
function KeybindingsEditFileButton({ filePath, highlightBg }) {
|
|
3211
|
+
const COLOR = useColors();
|
|
3212
|
+
const display = filePath ? compactPath(filePath) : "~/.zidane/keybindings.json";
|
|
3213
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
3214
|
+
style: {
|
|
3215
|
+
flexShrink: 0,
|
|
3216
|
+
flexDirection: "column",
|
|
3217
|
+
paddingLeft: 1,
|
|
3218
|
+
paddingRight: 1,
|
|
3219
|
+
backgroundColor: highlightBg
|
|
3220
|
+
},
|
|
3221
|
+
children: [/* @__PURE__ */ jsxs("text", {
|
|
3222
|
+
wrapMode: "none",
|
|
3223
|
+
children: [
|
|
3224
|
+
/* @__PURE__ */ jsx("span", {
|
|
3225
|
+
fg: COLOR.brand,
|
|
3226
|
+
children: "▶ "
|
|
3227
|
+
}),
|
|
3228
|
+
/* @__PURE__ */ jsx("span", {
|
|
3229
|
+
fg: COLOR.brand,
|
|
3230
|
+
children: "Edit keybindings file"
|
|
3231
|
+
}),
|
|
3232
|
+
/* @__PURE__ */ jsx("span", {
|
|
3233
|
+
fg: COLOR.mute,
|
|
3234
|
+
children: " "
|
|
3235
|
+
}),
|
|
3236
|
+
/* @__PURE__ */ jsx("span", {
|
|
3237
|
+
fg: COLOR.brand,
|
|
3238
|
+
children: "›"
|
|
3239
|
+
})
|
|
3240
|
+
]
|
|
3241
|
+
}), /* @__PURE__ */ jsxs("text", {
|
|
3242
|
+
wrapMode: "none",
|
|
3243
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
3244
|
+
fg: COLOR.mute,
|
|
3245
|
+
children: " "
|
|
3246
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
3247
|
+
fg: COLOR.dim,
|
|
3248
|
+
children: `${display} — restart to apply changes`
|
|
3249
|
+
})]
|
|
3213
3250
|
})]
|
|
3214
3251
|
});
|
|
3215
3252
|
}
|
|
@@ -3232,7 +3269,7 @@ function SectionHeader({ label }) {
|
|
|
3232
3269
|
function BindingRow({ def, spec }) {
|
|
3233
3270
|
const COLOR = useColors();
|
|
3234
3271
|
const display = formatBindingForDisplay(spec);
|
|
3235
|
-
const keyText = (display || "—").padEnd(
|
|
3272
|
+
const keyText = (display || "—").padEnd(KEYBINDING_KEY_COL_WIDTH, " ");
|
|
3236
3273
|
return /* @__PURE__ */ jsxs("box", {
|
|
3237
3274
|
style: {
|
|
3238
3275
|
flexDirection: "column",
|
|
@@ -3252,7 +3289,7 @@ function BindingRow({ def, spec }) {
|
|
|
3252
3289
|
}), /* @__PURE__ */ jsx("box", {
|
|
3253
3290
|
style: {
|
|
3254
3291
|
flexShrink: 0,
|
|
3255
|
-
paddingLeft:
|
|
3292
|
+
paddingLeft: KEYBINDING_KEY_COL_WIDTH
|
|
3256
3293
|
},
|
|
3257
3294
|
children: /* @__PURE__ */ jsx("text", {
|
|
3258
3295
|
wrapMode: "word",
|
|
@@ -3262,48 +3299,6 @@ function BindingRow({ def, spec }) {
|
|
|
3262
3299
|
})]
|
|
3263
3300
|
});
|
|
3264
3301
|
}
|
|
3265
|
-
function EditFileButton({ filePath, highlightBg, brand, mute, dim }) {
|
|
3266
|
-
const display = filePath ? compactPath(filePath) : "~/.zidane/keybindings.json";
|
|
3267
|
-
return /* @__PURE__ */ jsxs("box", {
|
|
3268
|
-
style: {
|
|
3269
|
-
flexShrink: 0,
|
|
3270
|
-
flexDirection: "column",
|
|
3271
|
-
paddingLeft: 1,
|
|
3272
|
-
paddingRight: 1,
|
|
3273
|
-
backgroundColor: highlightBg
|
|
3274
|
-
},
|
|
3275
|
-
children: [/* @__PURE__ */ jsxs("text", {
|
|
3276
|
-
wrapMode: "none",
|
|
3277
|
-
children: [
|
|
3278
|
-
/* @__PURE__ */ jsx("span", {
|
|
3279
|
-
fg: brand,
|
|
3280
|
-
children: "▶ "
|
|
3281
|
-
}),
|
|
3282
|
-
/* @__PURE__ */ jsx("span", {
|
|
3283
|
-
fg: brand,
|
|
3284
|
-
children: "Edit keybindings file"
|
|
3285
|
-
}),
|
|
3286
|
-
/* @__PURE__ */ jsx("span", {
|
|
3287
|
-
fg: mute,
|
|
3288
|
-
children: " "
|
|
3289
|
-
}),
|
|
3290
|
-
/* @__PURE__ */ jsx("span", {
|
|
3291
|
-
fg: brand,
|
|
3292
|
-
children: "›"
|
|
3293
|
-
})
|
|
3294
|
-
]
|
|
3295
|
-
}), /* @__PURE__ */ jsxs("text", {
|
|
3296
|
-
wrapMode: "none",
|
|
3297
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3298
|
-
fg: mute,
|
|
3299
|
-
children: " "
|
|
3300
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
3301
|
-
fg: dim,
|
|
3302
|
-
children: `${display} — restart to apply changes`
|
|
3303
|
-
})]
|
|
3304
|
-
})]
|
|
3305
|
-
});
|
|
3306
|
-
}
|
|
3307
3302
|
function CountsBadge$1({ count }) {
|
|
3308
3303
|
const COLOR = useColors();
|
|
3309
3304
|
return /* @__PURE__ */ jsxs("text", {
|
|
@@ -3324,36 +3319,6 @@ function CountsBadge$1({ count }) {
|
|
|
3324
3319
|
]
|
|
3325
3320
|
});
|
|
3326
3321
|
}
|
|
3327
|
-
/**
|
|
3328
|
-
* Walk `KEYBINDING_DEFS` in order and bucket rows into contiguous
|
|
3329
|
-
* sections by `group`. Preserves catalog order — if two actions in the
|
|
3330
|
-
* same group are split by an entry from another group, they'd render
|
|
3331
|
-
* as two separate sections with the same header (catalog order wins
|
|
3332
|
-
* over "merge same-group entries" so the on-screen story matches the
|
|
3333
|
-
* on-disk file).
|
|
3334
|
-
*/
|
|
3335
|
-
function groupBindings(bindings) {
|
|
3336
|
-
const sections = [];
|
|
3337
|
-
for (const def of KEYBINDING_DEFS) {
|
|
3338
|
-
const last = sections[sections.length - 1];
|
|
3339
|
-
const spec = bindings[def.action] ?? "";
|
|
3340
|
-
if (last && last.group === def.group) {
|
|
3341
|
-
last.rows.push({
|
|
3342
|
-
def,
|
|
3343
|
-
spec
|
|
3344
|
-
});
|
|
3345
|
-
continue;
|
|
3346
|
-
}
|
|
3347
|
-
sections.push({
|
|
3348
|
-
group: def.group,
|
|
3349
|
-
rows: [{
|
|
3350
|
-
def,
|
|
3351
|
-
spec
|
|
3352
|
-
}]
|
|
3353
|
-
});
|
|
3354
|
-
}
|
|
3355
|
-
return sections;
|
|
3356
|
-
}
|
|
3357
3322
|
//#endregion
|
|
3358
3323
|
//#region src/tui/model-picker.tsx
|
|
3359
3324
|
/**
|
|
@@ -7999,22 +7964,22 @@ function statusColor(status, COLOR) {
|
|
|
7999
7964
|
}
|
|
8000
7965
|
//#endregion
|
|
8001
7966
|
//#region src/tui/settings-modal.tsx
|
|
8002
|
-
const TAB_ORDER = [
|
|
8003
|
-
"general",
|
|
8004
|
-
"skills",
|
|
8005
|
-
"mcps"
|
|
8006
|
-
];
|
|
8007
7967
|
const TAB_LABELS = {
|
|
8008
|
-
|
|
7968
|
+
...Object.fromEntries(SETTINGS_CATEGORIES.map((c) => [c.id, c.label])),
|
|
7969
|
+
keybindings: "Keybindings",
|
|
7970
|
+
authentication: "Authentication",
|
|
8009
7971
|
skills: "Skills",
|
|
8010
7972
|
mcps: "MCP servers"
|
|
8011
7973
|
};
|
|
7974
|
+
function isCategoryTab(id) {
|
|
7975
|
+
return id !== "skills" && id !== "mcps" && id !== "keybindings" && id !== "authentication";
|
|
7976
|
+
}
|
|
8012
7977
|
function anchorIdFor(index) {
|
|
8013
7978
|
return `settings-row-${index}`;
|
|
8014
7979
|
}
|
|
8015
7980
|
const COL_TITLE = " ";
|
|
8016
7981
|
const SPACER_CHECKBOX_WIDTH = " ";
|
|
8017
|
-
function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCatalogProp, mcpsErrors: mcpsErrorsProp, actions } = {}) {
|
|
7982
|
+
function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCatalogProp, mcpsErrors: mcpsErrorsProp, keybindings, keybindingsPath, authentication, actions } = {}) {
|
|
8018
7983
|
const COLOR = useColors();
|
|
8019
7984
|
const SURFACE = useSurfaces();
|
|
8020
7985
|
const { settings, toggle: toggleBoolean, setSetting } = useSettings();
|
|
@@ -8035,13 +8000,19 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8035
8000
|
keyOf: (m) => m.config.name,
|
|
8036
8001
|
settingKey: "enabledMcps"
|
|
8037
8002
|
});
|
|
8038
|
-
const
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
mcps
|
|
8043
|
-
|
|
8003
|
+
const tabOrder = useMemo(() => {
|
|
8004
|
+
const tabs = [...SETTINGS_CATEGORIES.map((c) => c.id)];
|
|
8005
|
+
if (keybindings) tabs.push("keybindings");
|
|
8006
|
+
if (authentication) tabs.push("authentication");
|
|
8007
|
+
tabs.push("skills", "mcps");
|
|
8008
|
+
return tabs;
|
|
8009
|
+
}, [keybindings, authentication]);
|
|
8010
|
+
const [activeTab, setActiveTab] = useState(tabOrder[0]);
|
|
8011
|
+
const [cursorByTab, setCursorByTab] = useState(() => Object.fromEntries(tabOrder.map((id) => [id, 0])));
|
|
8044
8012
|
const [query, setQuery] = useState("");
|
|
8013
|
+
useEffect(() => {
|
|
8014
|
+
if (!tabOrder.includes(activeTab)) setActiveTab(tabOrder[0]);
|
|
8015
|
+
}, [tabOrder, activeTab]);
|
|
8045
8016
|
useEffect(() => {
|
|
8046
8017
|
inputRef.current?.focus();
|
|
8047
8018
|
}, []);
|
|
@@ -8055,15 +8026,17 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8055
8026
|
...c
|
|
8056
8027
|
}));
|
|
8057
8028
|
const acts = [];
|
|
8058
|
-
if (actions?.onOpenKeybindings) acts.push({
|
|
8029
|
+
if (actions?.onOpenKeybindings && !keybindings) acts.push({
|
|
8059
8030
|
kind: "action",
|
|
8031
|
+
category: "ui",
|
|
8060
8032
|
id: "keybindings",
|
|
8061
8033
|
label: "Keybindings",
|
|
8062
8034
|
description: "open ~/.zidane/keybindings.json (restart to apply)",
|
|
8063
8035
|
onPick: actions.onOpenKeybindings
|
|
8064
8036
|
});
|
|
8065
|
-
if (actions?.onReauth) acts.push({
|
|
8037
|
+
if (actions?.onReauth && !authentication) acts.push({
|
|
8066
8038
|
kind: "action",
|
|
8039
|
+
category: "agent",
|
|
8067
8040
|
id: "reauth",
|
|
8068
8041
|
label: "Authentication",
|
|
8069
8042
|
description: "switch provider, add another, or re-authenticate",
|
|
@@ -8074,14 +8047,29 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8074
8047
|
...choices,
|
|
8075
8048
|
...acts
|
|
8076
8049
|
];
|
|
8077
|
-
}, [
|
|
8078
|
-
|
|
8050
|
+
}, [
|
|
8051
|
+
actions,
|
|
8052
|
+
keybindings,
|
|
8053
|
+
authentication
|
|
8054
|
+
]);
|
|
8055
|
+
const filteredByCategory = useMemo(() => {
|
|
8056
|
+
const buckets = Object.fromEntries(SETTINGS_CATEGORIES.map((c) => [c.id, []]));
|
|
8057
|
+
for (const it of generalItems) {
|
|
8058
|
+
if (!matchesQuery(generalCorpus(it), query)) continue;
|
|
8059
|
+
buckets[it.category].push(it);
|
|
8060
|
+
}
|
|
8061
|
+
return buckets;
|
|
8062
|
+
}, [generalItems, query]);
|
|
8079
8063
|
const filteredSkills = useMemo(() => skillsCatalog.filter((s) => matchesQuery(skillCorpus(s), query)), [skillsCatalog, query]);
|
|
8080
8064
|
const filteredMcps = useMemo(() => mcpsCatalog.filter((m) => matchesQuery(mcpCorpus(m), query)), [mcpsCatalog, query]);
|
|
8065
|
+
const filteredProviders = useMemo(() => (authentication?.providers ?? []).filter((p) => matchesQuery(providerCorpus(p), query)), [authentication?.providers, query]);
|
|
8066
|
+
const authRowCount = filteredProviders.length + (authentication ? 1 : 0);
|
|
8081
8067
|
const filteredSize = {
|
|
8082
|
-
|
|
8068
|
+
...Object.fromEntries(SETTINGS_CATEGORIES.map((c) => [c.id, filteredByCategory[c.id].length])),
|
|
8083
8069
|
skills: filteredSkills.length,
|
|
8084
|
-
mcps: filteredMcps.length
|
|
8070
|
+
mcps: filteredMcps.length,
|
|
8071
|
+
keybindings: 0,
|
|
8072
|
+
authentication: authRowCount
|
|
8085
8073
|
};
|
|
8086
8074
|
const cursor = Math.min(cursorByTab[activeTab], Math.max(0, filteredSize[activeTab] - 1));
|
|
8087
8075
|
const moveCursor = useCallback((delta) => setCursorByTab((prev) => {
|
|
@@ -8101,6 +8089,7 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8101
8089
|
}));
|
|
8102
8090
|
}, [activeTab]);
|
|
8103
8091
|
useEffect(() => {
|
|
8092
|
+
if (activeTab === "keybindings") return;
|
|
8104
8093
|
const sb = scrollboxRef.current;
|
|
8105
8094
|
if (!sb) return;
|
|
8106
8095
|
const handle = requestAnimationFrame(() => {
|
|
@@ -8112,6 +8101,15 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8112
8101
|
activeTab,
|
|
8113
8102
|
query
|
|
8114
8103
|
]);
|
|
8104
|
+
useEffect(() => {
|
|
8105
|
+
if (activeTab !== "keybindings") return;
|
|
8106
|
+
const sb = scrollboxRef.current;
|
|
8107
|
+
if (!sb) return;
|
|
8108
|
+
const handle = requestAnimationFrame(() => {
|
|
8109
|
+
sb.scrollTo(0);
|
|
8110
|
+
});
|
|
8111
|
+
return () => cancelAnimationFrame(handle);
|
|
8112
|
+
}, [activeTab]);
|
|
8115
8113
|
const focusedMcp = filteredMcps[cursor];
|
|
8116
8114
|
const focusedMcpStatus = focusedMcp ? getMcpAuthStatus(authState, focusedMcp.config.name) : void 0;
|
|
8117
8115
|
const oauthPasteActive = activeTab === "mcps" && focusedMcpStatus?.kind === "authorizing" && !!focusedMcpStatus.url;
|
|
@@ -8123,21 +8121,43 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8123
8121
|
if (oauthPasteActive) return;
|
|
8124
8122
|
if (!key.ctrl && !key.meta && !key.shift && (key.name === "left" || key.name === "right")) {
|
|
8125
8123
|
key.preventDefault();
|
|
8126
|
-
const idx =
|
|
8127
|
-
setActiveTab(key.name === "left" ?
|
|
8124
|
+
const idx = tabOrder.indexOf(activeTab);
|
|
8125
|
+
setActiveTab(key.name === "left" ? tabOrder[(idx - 1 + tabOrder.length) % tabOrder.length] : tabOrder[(idx + 1) % tabOrder.length]);
|
|
8128
8126
|
return;
|
|
8129
8127
|
}
|
|
8130
8128
|
if (key.name === "up" || key.ctrl && key.name === "p") {
|
|
8131
|
-
|
|
8129
|
+
if (activeTab === "keybindings") scrollboxRef.current?.scrollBy(-2);
|
|
8130
|
+
else moveCursor(-1);
|
|
8132
8131
|
return;
|
|
8133
8132
|
}
|
|
8134
8133
|
if (key.name === "down" || key.ctrl && key.name === "n") {
|
|
8135
|
-
|
|
8134
|
+
if (activeTab === "keybindings") scrollboxRef.current?.scrollBy(2);
|
|
8135
|
+
else moveCursor(1);
|
|
8136
|
+
return;
|
|
8137
|
+
}
|
|
8138
|
+
if ((key.name === "pageup" || key.ctrl && key.name === "b") && activeTab === "keybindings") {
|
|
8139
|
+
scrollboxRef.current?.scrollBy(-.5, "viewport");
|
|
8140
|
+
return;
|
|
8141
|
+
}
|
|
8142
|
+
if ((key.name === "pagedown" || key.ctrl && key.name === "f") && activeTab === "keybindings") {
|
|
8143
|
+
scrollboxRef.current?.scrollBy(.5, "viewport");
|
|
8144
|
+
return;
|
|
8145
|
+
}
|
|
8146
|
+
if (key.name === "home" && activeTab === "keybindings") {
|
|
8147
|
+
scrollboxRef.current?.scrollTo(0);
|
|
8148
|
+
return;
|
|
8149
|
+
}
|
|
8150
|
+
if (key.name === "end" && activeTab === "keybindings") {
|
|
8151
|
+
const sb = scrollboxRef.current;
|
|
8152
|
+
if (sb) sb.scrollTo({
|
|
8153
|
+
x: 0,
|
|
8154
|
+
y: sb.scrollHeight
|
|
8155
|
+
});
|
|
8136
8156
|
return;
|
|
8137
8157
|
}
|
|
8138
8158
|
if (key.name === "return") {
|
|
8139
|
-
if (activeTab
|
|
8140
|
-
const it =
|
|
8159
|
+
if (isCategoryTab(activeTab)) {
|
|
8160
|
+
const it = filteredByCategory[activeTab][cursor];
|
|
8141
8161
|
if (!it) return;
|
|
8142
8162
|
if (it.kind === "toggle") toggleBoolean(it.key);
|
|
8143
8163
|
else if (it.kind === "choice") {
|
|
@@ -8156,6 +8176,24 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8156
8176
|
if (activeTab === "mcps") {
|
|
8157
8177
|
const m = filteredMcps[cursor];
|
|
8158
8178
|
if (m) mcpsToggle.toggle(m.config.name);
|
|
8179
|
+
return;
|
|
8180
|
+
}
|
|
8181
|
+
if (activeTab === "keybindings") {
|
|
8182
|
+
actions?.onOpenKeybindings?.();
|
|
8183
|
+
return;
|
|
8184
|
+
}
|
|
8185
|
+
if (activeTab === "authentication") {
|
|
8186
|
+
if (cursor === filteredProviders.length || !filteredProviders[cursor]) {
|
|
8187
|
+
actions?.onReauth?.();
|
|
8188
|
+
return;
|
|
8189
|
+
}
|
|
8190
|
+
const provider = filteredProviders[cursor];
|
|
8191
|
+
if (provider.available && actions?.onPickProvider) {
|
|
8192
|
+
actions.onPickProvider(provider);
|
|
8193
|
+
return;
|
|
8194
|
+
}
|
|
8195
|
+
actions?.onReauth?.();
|
|
8196
|
+
return;
|
|
8159
8197
|
}
|
|
8160
8198
|
return;
|
|
8161
8199
|
}
|
|
@@ -8178,23 +8216,29 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8178
8216
|
if (activeTab === "mcps" && actions?.onRefreshMcps) actions.onRefreshMcps();
|
|
8179
8217
|
}
|
|
8180
8218
|
});
|
|
8219
|
+
const totalsByCategory = useMemo(() => {
|
|
8220
|
+
const t = Object.fromEntries(SETTINGS_CATEGORIES.map((c) => [c.id, 0]));
|
|
8221
|
+
for (const it of generalItems) t[it.category]++;
|
|
8222
|
+
return t;
|
|
8223
|
+
}, [generalItems]);
|
|
8181
8224
|
return /* @__PURE__ */ jsxs(Modal, {
|
|
8182
8225
|
title: "settings",
|
|
8183
|
-
maxWidth:
|
|
8226
|
+
maxWidth: 160,
|
|
8184
8227
|
minWidth: 76,
|
|
8185
|
-
maxHeight:
|
|
8228
|
+
maxHeight: 50,
|
|
8186
8229
|
horizontalMargin: 2,
|
|
8187
8230
|
verticalMargin: 1,
|
|
8188
8231
|
children: [
|
|
8189
8232
|
/* @__PURE__ */ jsx("box", {
|
|
8190
8233
|
style: { flexShrink: 0 },
|
|
8191
8234
|
children: /* @__PURE__ */ jsx(TabStrip, {
|
|
8235
|
+
order: tabOrder,
|
|
8192
8236
|
active: activeTab,
|
|
8193
8237
|
counts: {
|
|
8194
|
-
|
|
8195
|
-
current:
|
|
8196
|
-
total:
|
|
8197
|
-
},
|
|
8238
|
+
...Object.fromEntries(SETTINGS_CATEGORIES.map((c) => [c.id, {
|
|
8239
|
+
current: filteredByCategory[c.id].length,
|
|
8240
|
+
total: totalsByCategory[c.id]
|
|
8241
|
+
}])),
|
|
8198
8242
|
skills: {
|
|
8199
8243
|
current: filteredSkills.length,
|
|
8200
8244
|
total: skillsCatalog.length
|
|
@@ -8234,8 +8278,8 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8234
8278
|
},
|
|
8235
8279
|
stickyScroll: false,
|
|
8236
8280
|
children: [
|
|
8237
|
-
activeTab
|
|
8238
|
-
items:
|
|
8281
|
+
isCategoryTab(activeTab) && /* @__PURE__ */ jsx(GeneralList, {
|
|
8282
|
+
items: filteredByCategory[activeTab],
|
|
8239
8283
|
cursor,
|
|
8240
8284
|
highlightBg: SURFACE.selection,
|
|
8241
8285
|
query
|
|
@@ -8257,9 +8301,27 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8257
8301
|
query,
|
|
8258
8302
|
errors: mcpsErrors,
|
|
8259
8303
|
authState
|
|
8304
|
+
}),
|
|
8305
|
+
activeTab === "keybindings" && keybindings && /* @__PURE__ */ jsx(KeybindingsList, {
|
|
8306
|
+
bindings: keybindings,
|
|
8307
|
+
query
|
|
8308
|
+
}),
|
|
8309
|
+
activeTab === "authentication" && authentication && /* @__PURE__ */ jsx(AuthenticationList, {
|
|
8310
|
+
view: authentication,
|
|
8311
|
+
providers: filteredProviders,
|
|
8312
|
+
cursor,
|
|
8313
|
+
highlightBg: SURFACE.selection,
|
|
8314
|
+
query
|
|
8260
8315
|
})
|
|
8261
8316
|
]
|
|
8262
8317
|
}),
|
|
8318
|
+
activeTab === "keybindings" && /* @__PURE__ */ jsx("box", {
|
|
8319
|
+
style: { flexShrink: 0 },
|
|
8320
|
+
children: /* @__PURE__ */ jsx(KeybindingsEditFileButton, {
|
|
8321
|
+
filePath: keybindingsPath,
|
|
8322
|
+
highlightBg: SURFACE.selection
|
|
8323
|
+
})
|
|
8324
|
+
}),
|
|
8263
8325
|
activeTab === "mcps" && focusedMcp && focusedMcpStatus && /* @__PURE__ */ jsx("box", {
|
|
8264
8326
|
style: { flexShrink: 0 },
|
|
8265
8327
|
children: renderMcpDetailPanel(focusedMcp, focusedMcpStatus, COLOR)
|
|
@@ -8277,7 +8339,7 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
8277
8339
|
]
|
|
8278
8340
|
});
|
|
8279
8341
|
}
|
|
8280
|
-
function TabStrip({ active, counts }) {
|
|
8342
|
+
function TabStrip({ order, active, counts }) {
|
|
8281
8343
|
const COLOR = useColors();
|
|
8282
8344
|
const SURFACE = useSurfaces();
|
|
8283
8345
|
return /* @__PURE__ */ jsx("box", {
|
|
@@ -8285,16 +8347,17 @@ function TabStrip({ active, counts }) {
|
|
|
8285
8347
|
flexDirection: "row",
|
|
8286
8348
|
height: 1
|
|
8287
8349
|
},
|
|
8288
|
-
children:
|
|
8350
|
+
children: order.map((id, i) => {
|
|
8289
8351
|
const isActive = id === active;
|
|
8290
8352
|
const label = TAB_LABELS[id];
|
|
8291
|
-
const
|
|
8292
|
-
const
|
|
8353
|
+
const tabCounts = counts[id];
|
|
8354
|
+
const showBadge = !!tabCounts;
|
|
8355
|
+
const badge = tabCounts ? tabCounts.current !== tabCounts.total ? `${tabCounts.current}/${tabCounts.total}` : `${tabCounts.total}` : "";
|
|
8293
8356
|
return /* @__PURE__ */ jsx("box", {
|
|
8294
8357
|
style: {
|
|
8295
8358
|
paddingLeft: 1,
|
|
8296
8359
|
paddingRight: 1,
|
|
8297
|
-
marginRight: i ===
|
|
8360
|
+
marginRight: i === order.length - 1 ? 0 : 1,
|
|
8298
8361
|
backgroundColor: isActive ? SURFACE.selection : void 0
|
|
8299
8362
|
},
|
|
8300
8363
|
children: /* @__PURE__ */ jsxs("text", {
|
|
@@ -8302,7 +8365,7 @@ function TabStrip({ active, counts }) {
|
|
|
8302
8365
|
children: [/* @__PURE__ */ jsx("span", {
|
|
8303
8366
|
fg: isActive ? COLOR.brand : COLOR.dim,
|
|
8304
8367
|
children: label
|
|
8305
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
8368
|
+
}), showBadge && /* @__PURE__ */ jsx("span", {
|
|
8306
8369
|
fg: isActive ? COLOR.brand : COLOR.mute,
|
|
8307
8370
|
children: ` ${badge}`
|
|
8308
8371
|
})]
|
|
@@ -8445,7 +8508,12 @@ function McpsList({ items, enabledSet, totalCount, cursor, highlightBg, query, e
|
|
|
8445
8508
|
fg: COLOR.model,
|
|
8446
8509
|
children: " mcps.json "
|
|
8447
8510
|
}),
|
|
8448
|
-
"
|
|
8511
|
+
"(or",
|
|
8512
|
+
/* @__PURE__ */ jsx("span", {
|
|
8513
|
+
fg: COLOR.model,
|
|
8514
|
+
children: " mcp.json "
|
|
8515
|
+
}),
|
|
8516
|
+
") into",
|
|
8449
8517
|
/* @__PURE__ */ jsx("span", {
|
|
8450
8518
|
fg: COLOR.model,
|
|
8451
8519
|
children: " .zidane/ "
|
|
@@ -8512,6 +8580,179 @@ function McpsList({ items, enabledSet, totalCount, cursor, highlightBg, query, e
|
|
|
8512
8580
|
})]
|
|
8513
8581
|
});
|
|
8514
8582
|
}
|
|
8583
|
+
function KeybindingsList({ bindings, query }) {
|
|
8584
|
+
const sections = useMemo(() => groupBindings(bindings), [bindings]);
|
|
8585
|
+
const filteredSections = useMemo(() => {
|
|
8586
|
+
if (!query.trim()) return sections;
|
|
8587
|
+
return sections.map((section) => ({
|
|
8588
|
+
group: section.group,
|
|
8589
|
+
rows: section.rows.filter((row) => matchesQuery(keybindingCorpus(row), query))
|
|
8590
|
+
})).filter((s) => s.rows.length > 0);
|
|
8591
|
+
}, [sections, query]);
|
|
8592
|
+
if (filteredSections.length === 0) return /* @__PURE__ */ jsx(EmptyRow, { label: `no keybindings match "${query}"` });
|
|
8593
|
+
return /* @__PURE__ */ jsx(KeybindingsCatalog, { sections: filteredSections });
|
|
8594
|
+
}
|
|
8595
|
+
function AuthenticationList({ view, providers, cursor, highlightBg, query }) {
|
|
8596
|
+
const COLOR = useColors();
|
|
8597
|
+
const home = homedir();
|
|
8598
|
+
const totalProviders = view.providers?.length ?? 0;
|
|
8599
|
+
const addRowIndex = providers.length;
|
|
8600
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
8601
|
+
style: { flexDirection: "column" },
|
|
8602
|
+
children: [
|
|
8603
|
+
/* @__PURE__ */ jsxs("box", {
|
|
8604
|
+
style: {
|
|
8605
|
+
flexDirection: "column",
|
|
8606
|
+
flexShrink: 0,
|
|
8607
|
+
paddingLeft: 1,
|
|
8608
|
+
paddingRight: 1
|
|
8609
|
+
},
|
|
8610
|
+
children: [
|
|
8611
|
+
/* @__PURE__ */ jsx("text", {
|
|
8612
|
+
wrapMode: "none",
|
|
8613
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
8614
|
+
fg: COLOR.brand,
|
|
8615
|
+
children: "Current"
|
|
8616
|
+
})
|
|
8617
|
+
}),
|
|
8618
|
+
/* @__PURE__ */ jsxs("text", {
|
|
8619
|
+
wrapMode: "none",
|
|
8620
|
+
children: [
|
|
8621
|
+
/* @__PURE__ */ jsx("span", {
|
|
8622
|
+
fg: COLOR.mute,
|
|
8623
|
+
children: " provider "
|
|
8624
|
+
}),
|
|
8625
|
+
/* @__PURE__ */ jsx("span", {
|
|
8626
|
+
fg: view.currentProviderLabel ? COLOR.accent : COLOR.mute,
|
|
8627
|
+
children: view.currentProviderLabel ?? "— not selected —"
|
|
8628
|
+
}),
|
|
8629
|
+
view.currentProviderKey && view.currentProviderLabel && view.currentProviderKey !== view.currentProviderLabel.toLowerCase() && /* @__PURE__ */ jsx("span", {
|
|
8630
|
+
fg: COLOR.dim,
|
|
8631
|
+
children: ` (${view.currentProviderKey})`
|
|
8632
|
+
})
|
|
8633
|
+
]
|
|
8634
|
+
}),
|
|
8635
|
+
/* @__PURE__ */ jsxs("text", {
|
|
8636
|
+
wrapMode: "none",
|
|
8637
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
8638
|
+
fg: COLOR.mute,
|
|
8639
|
+
children: " model "
|
|
8640
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
8641
|
+
fg: view.currentModel ? COLOR.model : COLOR.mute,
|
|
8642
|
+
children: view.currentModel ?? "— not selected —"
|
|
8643
|
+
})]
|
|
8644
|
+
})
|
|
8645
|
+
]
|
|
8646
|
+
}),
|
|
8647
|
+
/* @__PURE__ */ jsx("box", {
|
|
8648
|
+
style: {
|
|
8649
|
+
flexDirection: "column",
|
|
8650
|
+
flexShrink: 0,
|
|
8651
|
+
marginTop: 1,
|
|
8652
|
+
paddingLeft: 1,
|
|
8653
|
+
paddingRight: 1
|
|
8654
|
+
},
|
|
8655
|
+
children: /* @__PURE__ */ jsxs("text", {
|
|
8656
|
+
wrapMode: "none",
|
|
8657
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
8658
|
+
fg: COLOR.brand,
|
|
8659
|
+
children: "Providers"
|
|
8660
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
8661
|
+
fg: COLOR.mute,
|
|
8662
|
+
children: totalProviders > 0 ? ` ${providers.length}/${totalProviders}` : ""
|
|
8663
|
+
})]
|
|
8664
|
+
})
|
|
8665
|
+
}),
|
|
8666
|
+
totalProviders === 0 && /* @__PURE__ */ jsx("box", {
|
|
8667
|
+
style: {
|
|
8668
|
+
paddingLeft: 3,
|
|
8669
|
+
paddingRight: 1
|
|
8670
|
+
},
|
|
8671
|
+
children: /* @__PURE__ */ jsx("text", {
|
|
8672
|
+
fg: COLOR.mute,
|
|
8673
|
+
children: "No providers registered."
|
|
8674
|
+
})
|
|
8675
|
+
}),
|
|
8676
|
+
totalProviders > 0 && providers.length === 0 && /* @__PURE__ */ jsx(EmptyRow, { label: `no providers match "${query}"` }),
|
|
8677
|
+
providers.map((p, i) => {
|
|
8678
|
+
const isCurrent = view.currentProviderKey === p.key;
|
|
8679
|
+
const focused = i === cursor;
|
|
8680
|
+
const bg = focused ? highlightBg : void 0;
|
|
8681
|
+
const marker = focused ? "▶ " : isCurrent ? "▸ " : " ";
|
|
8682
|
+
const labelColor = focused || isCurrent ? COLOR.brand : p.available ? COLOR.dim : COLOR.mute;
|
|
8683
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
8684
|
+
id: anchorIdFor(i),
|
|
8685
|
+
style: {
|
|
8686
|
+
flexDirection: "column",
|
|
8687
|
+
flexShrink: 0,
|
|
8688
|
+
paddingLeft: 1,
|
|
8689
|
+
paddingRight: 1,
|
|
8690
|
+
backgroundColor: bg
|
|
8691
|
+
},
|
|
8692
|
+
children: [/* @__PURE__ */ jsxs("text", {
|
|
8693
|
+
wrapMode: "none",
|
|
8694
|
+
children: [
|
|
8695
|
+
/* @__PURE__ */ jsx("span", {
|
|
8696
|
+
fg: focused ? COLOR.brand : COLOR.mute,
|
|
8697
|
+
children: marker
|
|
8698
|
+
}),
|
|
8699
|
+
/* @__PURE__ */ jsx("span", {
|
|
8700
|
+
fg: labelColor,
|
|
8701
|
+
children: p.label
|
|
8702
|
+
}),
|
|
8703
|
+
/* @__PURE__ */ jsx("span", {
|
|
8704
|
+
fg: p.available ? COLOR.accent : COLOR.mute,
|
|
8705
|
+
children: p.available ? " ✓ configured" : " · not configured"
|
|
8706
|
+
}),
|
|
8707
|
+
isCurrent && /* @__PURE__ */ jsx("span", {
|
|
8708
|
+
fg: COLOR.mute,
|
|
8709
|
+
children: " (active)"
|
|
8710
|
+
})
|
|
8711
|
+
]
|
|
8712
|
+
}), p.methods.length > 0 && /* @__PURE__ */ jsx("text", {
|
|
8713
|
+
wrapMode: "none",
|
|
8714
|
+
fg: COLOR.mute,
|
|
8715
|
+
children: ` ${p.methods.map((m) => `${m.source}: ${displayPath$1(m.detail, home)}`).join(" · ")}`
|
|
8716
|
+
})]
|
|
8717
|
+
}, p.key);
|
|
8718
|
+
}),
|
|
8719
|
+
/* @__PURE__ */ jsx(AuthAddRow, {
|
|
8720
|
+
anchorIndex: addRowIndex,
|
|
8721
|
+
focused: cursor === addRowIndex,
|
|
8722
|
+
highlightBg
|
|
8723
|
+
})
|
|
8724
|
+
]
|
|
8725
|
+
});
|
|
8726
|
+
}
|
|
8727
|
+
function AuthAddRow({ anchorIndex, focused, highlightBg }) {
|
|
8728
|
+
const COLOR = useColors();
|
|
8729
|
+
const bg = focused ? highlightBg : void 0;
|
|
8730
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
8731
|
+
id: anchorIdFor(anchorIndex),
|
|
8732
|
+
style: {
|
|
8733
|
+
flexDirection: "column",
|
|
8734
|
+
flexShrink: 0,
|
|
8735
|
+
marginTop: 1,
|
|
8736
|
+
paddingLeft: 1,
|
|
8737
|
+
paddingRight: 1,
|
|
8738
|
+
backgroundColor: bg
|
|
8739
|
+
},
|
|
8740
|
+
children: [/* @__PURE__ */ jsxs("text", {
|
|
8741
|
+
wrapMode: "none",
|
|
8742
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
8743
|
+
fg: focused ? COLOR.brand : COLOR.mute,
|
|
8744
|
+
children: focused ? "▶ " : " "
|
|
8745
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
8746
|
+
fg: focused ? COLOR.brand : COLOR.dim,
|
|
8747
|
+
children: "+ add or re-configure a provider"
|
|
8748
|
+
})]
|
|
8749
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
8750
|
+
wrapMode: "none",
|
|
8751
|
+
fg: COLOR.mute,
|
|
8752
|
+
children: " launch the setup wizard"
|
|
8753
|
+
})]
|
|
8754
|
+
});
|
|
8755
|
+
}
|
|
8515
8756
|
function ToggleRow({ id, label, description, enabled, focused, bg }) {
|
|
8516
8757
|
const COLOR = useColors();
|
|
8517
8758
|
return /* @__PURE__ */ jsxs("box", {
|
|
@@ -8656,7 +8897,7 @@ function renderMcpDetailPanel(entry, status, COLOR) {
|
|
|
8656
8897
|
return /* @__PURE__ */ jsx(McpAuthorizingPanel, {
|
|
8657
8898
|
serverName: entry.config.name,
|
|
8658
8899
|
authUrl: status.url,
|
|
8659
|
-
maxLineWidth:
|
|
8900
|
+
maxLineWidth: 154,
|
|
8660
8901
|
inputFocused: true
|
|
8661
8902
|
});
|
|
8662
8903
|
}
|
|
@@ -8742,12 +8983,12 @@ function Hints({ activeTab, focusedMcp, focusedMcpStatus, canRefreshSkills, canR
|
|
|
8742
8983
|
fg: COLOR.warn,
|
|
8743
8984
|
children: "↑↓"
|
|
8744
8985
|
}),
|
|
8745
|
-
" navigate · ",
|
|
8986
|
+
activeTab === "keybindings" ? " scroll · " : " navigate · ",
|
|
8746
8987
|
/* @__PURE__ */ jsx("span", {
|
|
8747
8988
|
fg: COLOR.warn,
|
|
8748
8989
|
children: "↵"
|
|
8749
8990
|
}),
|
|
8750
|
-
activeTab === "
|
|
8991
|
+
isCategoryTab(activeTab) ? " toggle/cycle/select" : activeTab === "keybindings" ? " edit file" : activeTab === "authentication" ? " switch / re-authenticate" : " toggle",
|
|
8751
8992
|
showLogin && /* @__PURE__ */ jsxs("span", { children: [
|
|
8752
8993
|
" · ",
|
|
8753
8994
|
/* @__PURE__ */ jsx("span", {
|
|
@@ -8812,6 +9053,12 @@ function mcpCorpus(m) {
|
|
|
8812
9053
|
(m.config.args ?? []).join(" ")
|
|
8813
9054
|
].join(" ").toLowerCase();
|
|
8814
9055
|
}
|
|
9056
|
+
function keybindingCorpus(row) {
|
|
9057
|
+
return `${row.spec} ${row.def.label} ${row.def.description} ${row.def.action}`.toLowerCase();
|
|
9058
|
+
}
|
|
9059
|
+
function providerCorpus(p) {
|
|
9060
|
+
return `${p.label} ${p.key} ${p.methods.map((m) => `${m.source} ${m.detail}`).join(" ")}`.toLowerCase();
|
|
9061
|
+
}
|
|
8815
9062
|
function mcpDetail(entry) {
|
|
8816
9063
|
const transport = entry.config.transport;
|
|
8817
9064
|
return `${transport} · ${transport === "stdio" ? entry.config.command ?? "" : entry.config.url ?? ""}`;
|
|
@@ -8824,11 +9071,11 @@ function canLogout$1(status) {
|
|
|
8824
9071
|
return status.kind === "authed" || status.kind === "error" || status.kind === "authorizing";
|
|
8825
9072
|
}
|
|
8826
9073
|
function searchPlaceholder(tab) {
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
}
|
|
9074
|
+
if (tab === "skills") return "search skills — name, description…";
|
|
9075
|
+
if (tab === "mcps") return "search MCP servers — name, transport, command/URL…";
|
|
9076
|
+
if (tab === "keybindings") return "search keybindings — action, key, description…";
|
|
9077
|
+
if (tab === "authentication") return "search providers — name, method…";
|
|
9078
|
+
return `search ${TAB_LABELS[tab].toLowerCase()} settings — name, description…`;
|
|
8832
9079
|
}
|
|
8833
9080
|
function displayPath$1(path, home) {
|
|
8834
9081
|
if (home && path.startsWith(`${home}/`)) return `~/${path.slice(home.length + 1)}`;
|
|
@@ -9564,6 +9811,7 @@ function AppShell() {
|
|
|
9564
9811
|
const lastResumedSessionId = initialState.lastSessionId;
|
|
9565
9812
|
const resumeLastSessionOnLaunch = initialState.settings?.resumeLastSession ?? true;
|
|
9566
9813
|
const dataDir = config.paths.userDir;
|
|
9814
|
+
const cacheDir = config.paths.cacheDir;
|
|
9567
9815
|
const [pickedAgent, setPickedAgent] = useState(() => agentRegistry[initialAgentId] ?? Object.values(agentRegistry)[0]);
|
|
9568
9816
|
const pickedAgentRef = useRef(pickedAgent);
|
|
9569
9817
|
const safeModeEnabledRef = useRef(settings.safeMode);
|
|
@@ -9591,6 +9839,10 @@ function AppShell() {
|
|
|
9591
9839
|
useEffect(() => {
|
|
9592
9840
|
allowInteractionRef.current = settings.allowInteraction;
|
|
9593
9841
|
}, [settings.allowInteraction]);
|
|
9842
|
+
const userInstructionsScopeRef = useRef(settings.userInstructionsScope);
|
|
9843
|
+
useEffect(() => {
|
|
9844
|
+
userInstructionsScopeRef.current = settings.userInstructionsScope;
|
|
9845
|
+
}, [settings.userInstructionsScope]);
|
|
9594
9846
|
const autoCompactRef = useRef(settings.autoCompact);
|
|
9595
9847
|
useEffect(() => {
|
|
9596
9848
|
autoCompactRef.current = settings.autoCompact;
|
|
@@ -9987,14 +10239,20 @@ function AppShell() {
|
|
|
9987
10239
|
const allowInteraction = allowInteractionRef.current !== false;
|
|
9988
10240
|
const interactionTools = allowInteraction ? createInteractionTools({ requestInteraction: makeRequestInteraction(interactions) }) : {};
|
|
9989
10241
|
const actualCwd = cwdRef.current;
|
|
10242
|
+
const agentsMd = discoverAgentsMd({
|
|
10243
|
+
cwd: actualCwd,
|
|
10244
|
+
prefix: config.prefix,
|
|
10245
|
+
scope: userInstructionsScopeRef.current
|
|
10246
|
+
});
|
|
9990
10247
|
const envOpts = {
|
|
9991
10248
|
cwd: actualCwd,
|
|
9992
10249
|
...projectDir !== actualCwd ? { projectRoot: projectDir } : {},
|
|
9993
|
-
allowInteraction
|
|
10250
|
+
allowInteraction,
|
|
10251
|
+
...agentsMd.block ? { userInstructions: agentsMd.block } : {}
|
|
9994
10252
|
};
|
|
9995
10253
|
const builtInSystem = profile.id === "build" ? buildBuildSystem(envOpts) : profile.id === "plan" ? buildPlanSystem(envOpts) : null;
|
|
9996
10254
|
const persistDir = resolvePersistDir({
|
|
9997
|
-
userDir:
|
|
10255
|
+
userDir: cacheDir,
|
|
9998
10256
|
sessionId: session.id
|
|
9999
10257
|
});
|
|
10000
10258
|
const persistBehavior = persistToolResultsRef.current === false ? {
|
|
@@ -10002,7 +10260,7 @@ function AppShell() {
|
|
|
10002
10260
|
persistDir
|
|
10003
10261
|
} : { persistDir };
|
|
10004
10262
|
const tasksDir = resolveTasksDir({
|
|
10005
|
-
userDir:
|
|
10263
|
+
userDir: cacheDir,
|
|
10006
10264
|
sessionId: session.id
|
|
10007
10265
|
});
|
|
10008
10266
|
const agent = createAgent({
|
|
@@ -10386,6 +10644,7 @@ function AppShell() {
|
|
|
10386
10644
|
config.prefix,
|
|
10387
10645
|
interactions,
|
|
10388
10646
|
dataDir,
|
|
10647
|
+
cacheDir,
|
|
10389
10648
|
mcpCredentialStore,
|
|
10390
10649
|
registerInFlightTool,
|
|
10391
10650
|
unregisterInFlightTool
|
|
@@ -11191,11 +11450,11 @@ function AppShell() {
|
|
|
11191
11450
|
return;
|
|
11192
11451
|
}
|
|
11193
11452
|
cleanupPersistedSession(resolvePersistDir({
|
|
11194
|
-
userDir:
|
|
11453
|
+
userDir: cacheDir,
|
|
11195
11454
|
sessionId: id
|
|
11196
11455
|
}));
|
|
11197
11456
|
cleanupPersistedSession(resolveTasksDir({
|
|
11198
|
-
userDir:
|
|
11457
|
+
userDir: cacheDir,
|
|
11199
11458
|
sessionId: id
|
|
11200
11459
|
}));
|
|
11201
11460
|
const wasCurrent = id === currentSession?.id;
|
|
@@ -11217,7 +11476,8 @@ function AppShell() {
|
|
|
11217
11476
|
teardown,
|
|
11218
11477
|
refreshSessions,
|
|
11219
11478
|
stateStore,
|
|
11220
|
-
dataDir
|
|
11479
|
+
dataDir,
|
|
11480
|
+
cacheDir
|
|
11221
11481
|
]);
|
|
11222
11482
|
const onGenerateTitle = useCallback(async (sessionId, signal) => {
|
|
11223
11483
|
if (!picked) throw new Error("No provider picked — open the chat screen first.");
|
|
@@ -11535,15 +11795,31 @@ function AppShell() {
|
|
|
11535
11795
|
return;
|
|
11536
11796
|
}
|
|
11537
11797
|
if (matchesBinding(key, keybindings.openSettings) && screen !== "auth") {
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11798
|
+
const allProviders = detectAuth(config.paths.userDir, providerRegistry);
|
|
11799
|
+
const onPickProviderFromSettings = (provider) => {
|
|
11800
|
+
modal.close();
|
|
11801
|
+
onPickProvider(provider);
|
|
11802
|
+
};
|
|
11803
|
+
modal.open(/* @__PURE__ */ jsx(SettingsModal, {
|
|
11804
|
+
keybindings,
|
|
11805
|
+
keybindingsPath: keybindingsPath(config.paths.userDir),
|
|
11806
|
+
authentication: {
|
|
11807
|
+
currentProviderLabel: picked?.provider.label,
|
|
11808
|
+
currentProviderKey: picked?.provider.key,
|
|
11809
|
+
currentModel: picked?.model,
|
|
11810
|
+
providers: allProviders
|
|
11811
|
+
},
|
|
11812
|
+
actions: {
|
|
11813
|
+
onReauth,
|
|
11814
|
+
onPickProvider: onPickProviderFromSettings,
|
|
11815
|
+
onOpenKeybindings: onOpenKeybindingsFile,
|
|
11816
|
+
onLoginMcp,
|
|
11817
|
+
onLogoutMcp,
|
|
11818
|
+
onCancelLoginMcp,
|
|
11819
|
+
onRefreshSkills,
|
|
11820
|
+
onRefreshMcps
|
|
11821
|
+
}
|
|
11822
|
+
}));
|
|
11547
11823
|
return;
|
|
11548
11824
|
}
|
|
11549
11825
|
if (matchesBinding(key, keybindings.openSessionDetails)) {
|
|
@@ -11654,7 +11930,7 @@ function AppShell() {
|
|
|
11654
11930
|
packageName: autoUpdateConfig?.packageName ?? "",
|
|
11655
11931
|
currentVersion: autoUpdateConfig?.currentVersion ?? "",
|
|
11656
11932
|
enabled: !!autoUpdateConfig && settings.checkForUpdates,
|
|
11657
|
-
cacheDir
|
|
11933
|
+
cacheDir,
|
|
11658
11934
|
registry: autoUpdateConfig?.registry,
|
|
11659
11935
|
channel: autoUpdateConfig?.channel,
|
|
11660
11936
|
cacheTtlMs: autoUpdateConfig?.cacheTtlMs
|
|
@@ -12107,7 +12383,12 @@ function McpsSettingsModal({ catalog, errors, onLogin, onLogout, onCancelLogin,
|
|
|
12107
12383
|
fg: COLOR.model,
|
|
12108
12384
|
children: " mcps.json "
|
|
12109
12385
|
}),
|
|
12110
|
-
"
|
|
12386
|
+
"(or",
|
|
12387
|
+
/* @__PURE__ */ jsx("span", {
|
|
12388
|
+
fg: COLOR.model,
|
|
12389
|
+
children: " mcp.json "
|
|
12390
|
+
}),
|
|
12391
|
+
") into",
|
|
12111
12392
|
/* @__PURE__ */ jsx("span", {
|
|
12112
12393
|
fg: COLOR.model,
|
|
12113
12394
|
children: " .zidane/ "
|