@cydm/pie 1.0.47 → 1.0.49
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 +21 -1
- package/dist/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +2 -2
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/chunks/{chunk-IJMP3JTX.js → chunk-7RYOIXA2.js} +212 -43
- package/dist/chunks/{chunk-U4B6RJ6Z.js → chunk-J6PEH6ST.js} +1 -1
- package/dist/cli.js +446 -181
- package/package.json +2 -2
- package/dist/builtin/extensions/kimi-attachments/index.js +0 -47
- package/dist/builtin/extensions/kimi-attachments/package.json +0 -11
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,10 @@ import {
|
|
|
19
19
|
getThemesDir,
|
|
20
20
|
migrateConfigFromAgentDir,
|
|
21
21
|
truncateHeadTail
|
|
22
|
-
} from "./chunks/chunk-
|
|
22
|
+
} from "./chunks/chunk-J6PEH6ST.js";
|
|
23
|
+
import {
|
|
24
|
+
resolveCliProjectRoot
|
|
25
|
+
} from "./chunks/chunk-WLFOBECN.js";
|
|
23
26
|
import {
|
|
24
27
|
AGENTS_CONTEXT_FILE_NAME,
|
|
25
28
|
AgentSessionController,
|
|
@@ -70,7 +73,7 @@ import {
|
|
|
70
73
|
setExtensionEnabledInSettings,
|
|
71
74
|
shouldPreserveExecutionStateForUserText,
|
|
72
75
|
supersedeExecutionState
|
|
73
|
-
} from "./chunks/chunk-
|
|
76
|
+
} from "./chunks/chunk-7RYOIXA2.js";
|
|
74
77
|
import "./chunks/chunk-FKAO25XH.js";
|
|
75
78
|
import {
|
|
76
79
|
Deref,
|
|
@@ -108,9 +111,6 @@ import {
|
|
|
108
111
|
sortToolModelCandidatesByCapability,
|
|
109
112
|
type_exports
|
|
110
113
|
} from "./chunks/chunk-K6ZOCJ4V.js";
|
|
111
|
-
import {
|
|
112
|
-
resolveCliProjectRoot
|
|
113
|
-
} from "./chunks/chunk-WLFOBECN.js";
|
|
114
114
|
import {
|
|
115
115
|
__commonJS,
|
|
116
116
|
__require,
|
|
@@ -51654,6 +51654,33 @@ var SelectList = class {
|
|
|
51654
51654
|
}
|
|
51655
51655
|
invalidate() {
|
|
51656
51656
|
}
|
|
51657
|
+
/**
|
|
51658
|
+
* Lay out one item row: label (left column) + description (right column).
|
|
51659
|
+
*
|
|
51660
|
+
* The label column is sized from the actual labels and the available
|
|
51661
|
+
* width. The previous fixed 30-column cap truncated long commands (e.g.
|
|
51662
|
+
* /skills/skill:terminal-pty-testing) even on wide terminals.
|
|
51663
|
+
*/
|
|
51664
|
+
renderLabelParts(prefix, displayValue, descriptionSingleLine, useDescriptionColumn, labelColumnWidth, width) {
|
|
51665
|
+
const prefixWidth = visibleWidth(prefix);
|
|
51666
|
+
if (useDescriptionColumn && descriptionSingleLine) {
|
|
51667
|
+
const truncatedValue = truncateToWidth(displayValue, labelColumnWidth, "");
|
|
51668
|
+
const valueWidth = visibleWidth(truncatedValue);
|
|
51669
|
+
const spacing = " ".repeat(Math.max(1, labelColumnWidth - valueWidth + 2));
|
|
51670
|
+
const descriptionStart = prefixWidth + valueWidth + spacing.length;
|
|
51671
|
+
const remainingWidth = width - descriptionStart - 2;
|
|
51672
|
+
if (remainingWidth > 10) {
|
|
51673
|
+
return {
|
|
51674
|
+
value: truncatedValue,
|
|
51675
|
+
spacing,
|
|
51676
|
+
desc: truncateToWidth(descriptionSingleLine, remainingWidth, "")
|
|
51677
|
+
};
|
|
51678
|
+
}
|
|
51679
|
+
return { value: truncateToWidth(displayValue, width - prefixWidth - 2, ""), spacing: "", desc: "" };
|
|
51680
|
+
}
|
|
51681
|
+
const maxWidth = width - prefixWidth - 2;
|
|
51682
|
+
return { value: truncateToWidth(displayValue, maxWidth, ""), spacing: "", desc: "" };
|
|
51683
|
+
}
|
|
51657
51684
|
render(width) {
|
|
51658
51685
|
const lines = [];
|
|
51659
51686
|
if (this.filteredItems.length === 0) {
|
|
@@ -51661,54 +51688,35 @@ var SelectList = class {
|
|
|
51661
51688
|
return lines;
|
|
51662
51689
|
}
|
|
51663
51690
|
const { startIndex, endIndex } = this.getVisibleRange();
|
|
51691
|
+
const useDescriptionColumn = this.filteredItems.some((item) => item.description) && width > 40;
|
|
51692
|
+
let labelColumnWidth = 0;
|
|
51693
|
+
if (useDescriptionColumn) {
|
|
51694
|
+
const maxLabelWidth = Math.max(
|
|
51695
|
+
...this.filteredItems.map((item) => visibleWidth(item.label || item.value))
|
|
51696
|
+
);
|
|
51697
|
+
labelColumnWidth = Math.max(8, Math.min(maxLabelWidth, Math.floor(width * 0.45)));
|
|
51698
|
+
}
|
|
51664
51699
|
for (let i = startIndex; i < endIndex; i++) {
|
|
51665
51700
|
const item = this.filteredItems[i];
|
|
51666
51701
|
if (!item) continue;
|
|
51667
51702
|
const isSelected = i === this.selectedIndex;
|
|
51668
51703
|
const descriptionSingleLine = item.description ? normalizeToSingleLine(item.description) : void 0;
|
|
51704
|
+
const displayValue = item.label || item.value;
|
|
51669
51705
|
let line = "";
|
|
51670
51706
|
if (isSelected) {
|
|
51671
|
-
const
|
|
51672
|
-
|
|
51673
|
-
|
|
51674
|
-
|
|
51675
|
-
|
|
51676
|
-
|
|
51677
|
-
const spacing = " ".repeat(Math.max(1, 32 - valueWidth));
|
|
51678
|
-
const descriptionStart = prefixWidth + valueWidth + spacing.length;
|
|
51679
|
-
const remainingWidth = width - descriptionStart - 2;
|
|
51680
|
-
if (remainingWidth > 10) {
|
|
51681
|
-
const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
|
|
51682
|
-
line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncatedValue}${spacing}${truncatedDesc}`), width, "");
|
|
51683
|
-
} else {
|
|
51684
|
-
const maxWidth = width - prefixWidth - 2;
|
|
51685
|
-
line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`), width, "");
|
|
51686
|
-
}
|
|
51687
|
-
} else {
|
|
51688
|
-
const maxWidth = width - prefixWidth - 2;
|
|
51689
|
-
line = truncateToWidth(this.theme.selectedText(`\u2192 ${truncateToWidth(displayValue, maxWidth, "")}`), width, "");
|
|
51690
|
-
}
|
|
51707
|
+
const parts = this.renderLabelParts("\u2192 ", displayValue, descriptionSingleLine, useDescriptionColumn, labelColumnWidth, width);
|
|
51708
|
+
line = truncateToWidth(
|
|
51709
|
+
this.theme.selectedText(`\u2192 ${parts.value}${parts.spacing}${parts.desc}`),
|
|
51710
|
+
width,
|
|
51711
|
+
""
|
|
51712
|
+
);
|
|
51691
51713
|
} else {
|
|
51692
|
-
const
|
|
51693
|
-
|
|
51694
|
-
|
|
51695
|
-
|
|
51696
|
-
const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "");
|
|
51697
|
-
const valueWidth = visibleWidth(truncatedValue);
|
|
51698
|
-
const spacing = " ".repeat(Math.max(1, 32 - valueWidth));
|
|
51699
|
-
const descriptionStart = prefix.length + valueWidth + spacing.length;
|
|
51700
|
-
const remainingWidth = width - descriptionStart - 2;
|
|
51701
|
-
if (remainingWidth > 10) {
|
|
51702
|
-
const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
|
|
51703
|
-
const descText = this.theme.description(spacing + truncatedDesc);
|
|
51704
|
-
line = truncateToWidth(prefix + truncatedValue + descText, width, "");
|
|
51705
|
-
} else {
|
|
51706
|
-
const maxWidth = width - prefix.length - 2;
|
|
51707
|
-
line = truncateToWidth(prefix + truncateToWidth(displayValue, maxWidth, ""), width, "");
|
|
51708
|
-
}
|
|
51714
|
+
const parts = this.renderLabelParts(" ", displayValue, descriptionSingleLine, useDescriptionColumn, labelColumnWidth, width);
|
|
51715
|
+
if (parts.desc) {
|
|
51716
|
+
const descText = this.theme.description(parts.spacing + parts.desc);
|
|
51717
|
+
line = truncateToWidth(" " + parts.value + descText, width, "");
|
|
51709
51718
|
} else {
|
|
51710
|
-
|
|
51711
|
-
line = truncateToWidth(prefix + truncateToWidth(displayValue, maxWidth, ""), width, "");
|
|
51719
|
+
line = truncateToWidth(" " + parts.value, width, "");
|
|
51712
51720
|
}
|
|
51713
51721
|
}
|
|
51714
51722
|
lines.push(truncateToWidth(line, width, ""));
|
|
@@ -52086,6 +52094,10 @@ var Editor = class {
|
|
|
52086
52094
|
this.autocompleteList.handleInput(data);
|
|
52087
52095
|
return;
|
|
52088
52096
|
}
|
|
52097
|
+
if (kb.matches(data, "cursorLeft") || kb.matches(data, "cursorRight") || kb.matches(data, "pageUp") || kb.matches(data, "pageDown")) {
|
|
52098
|
+
this.autocompleteList.handleInput(data);
|
|
52099
|
+
return;
|
|
52100
|
+
}
|
|
52089
52101
|
if (kb.matches(data, "tab")) {
|
|
52090
52102
|
const selected = this.autocompleteList.getSelectedItem();
|
|
52091
52103
|
if (selected && this.autocompleteProvider) {
|
|
@@ -52107,32 +52119,26 @@ var Editor = class {
|
|
|
52107
52119
|
return;
|
|
52108
52120
|
}
|
|
52109
52121
|
if (kb.matches(data, "selectConfirm")) {
|
|
52110
|
-
const
|
|
52111
|
-
|
|
52112
|
-
|
|
52113
|
-
this.
|
|
52114
|
-
|
|
52115
|
-
|
|
52116
|
-
|
|
52117
|
-
this.
|
|
52118
|
-
|
|
52119
|
-
|
|
52120
|
-
|
|
52121
|
-
|
|
52122
|
-
|
|
52123
|
-
|
|
52124
|
-
|
|
52125
|
-
);
|
|
52126
|
-
|
|
52127
|
-
this.
|
|
52128
|
-
this.
|
|
52129
|
-
|
|
52130
|
-
this.cancelAutocomplete();
|
|
52131
|
-
} else {
|
|
52132
|
-
this.cancelAutocomplete();
|
|
52133
|
-
if (this.onChange) this.onChange(this.getText());
|
|
52134
|
-
return;
|
|
52135
|
-
}
|
|
52122
|
+
const selected = this.autocompleteList.getSelectedItem();
|
|
52123
|
+
if (selected && this.autocompleteProvider) {
|
|
52124
|
+
this.pushUndoSnapshot();
|
|
52125
|
+
this.lastAction = null;
|
|
52126
|
+
const result = this.autocompleteProvider.applyCompletion(
|
|
52127
|
+
this.state.lines,
|
|
52128
|
+
this.state.cursorLine,
|
|
52129
|
+
this.state.cursorCol,
|
|
52130
|
+
selected,
|
|
52131
|
+
this.autocompletePrefix
|
|
52132
|
+
);
|
|
52133
|
+
this.state.lines = result.lines;
|
|
52134
|
+
this.state.cursorLine = result.cursorLine;
|
|
52135
|
+
this.setCursorCol(result.cursorCol);
|
|
52136
|
+
if (this.autocompletePrefix.startsWith("/")) {
|
|
52137
|
+
this.cancelAutocomplete();
|
|
52138
|
+
} else {
|
|
52139
|
+
this.cancelAutocomplete();
|
|
52140
|
+
if (this.onChange) this.onChange(this.getText());
|
|
52141
|
+
return;
|
|
52136
52142
|
}
|
|
52137
52143
|
}
|
|
52138
52144
|
}
|
|
@@ -53128,12 +53134,28 @@ var Editor = class {
|
|
|
53128
53134
|
);
|
|
53129
53135
|
if (suggestions && suggestions.items.length > 0) {
|
|
53130
53136
|
this.autocompletePrefix = suggestions.prefix;
|
|
53131
|
-
this.autocompleteList = new SelectList(
|
|
53137
|
+
this.autocompleteList = new SelectList(
|
|
53138
|
+
suggestions.items,
|
|
53139
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53140
|
+
this.theme.selectList
|
|
53141
|
+
);
|
|
53132
53142
|
this.autocompleteState = "regular";
|
|
53133
53143
|
} else {
|
|
53134
53144
|
this.cancelAutocomplete();
|
|
53135
53145
|
}
|
|
53136
53146
|
}
|
|
53147
|
+
/**
|
|
53148
|
+
* Visible autocomplete rows, scaled with terminal height so tall screens
|
|
53149
|
+
* show the full command list instead of paginating five rows at a time.
|
|
53150
|
+
* Floor: the configured max (default 5). Ceiling: ~45% of rows, capped at
|
|
53151
|
+
* 20 so a huge terminal never dedicates half the screen to suggestions.
|
|
53152
|
+
*/
|
|
53153
|
+
computeAutocompleteMaxVisible(itemCount) {
|
|
53154
|
+
const rows = this.tui.terminal.rows;
|
|
53155
|
+
const heightScaled = Number.isFinite(rows) ? Math.floor(rows * 0.45) : this.autocompleteMaxVisible;
|
|
53156
|
+
const desired = Math.max(this.autocompleteMaxVisible, Math.min(heightScaled, 20));
|
|
53157
|
+
return Math.max(1, Math.min(desired, Math.max(itemCount, 1)));
|
|
53158
|
+
}
|
|
53137
53159
|
handleTabCompletion() {
|
|
53138
53160
|
if (!this.autocompleteProvider) return;
|
|
53139
53161
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
@@ -53183,7 +53205,11 @@ var Editor = class {
|
|
|
53183
53205
|
return;
|
|
53184
53206
|
}
|
|
53185
53207
|
this.autocompletePrefix = suggestions.prefix;
|
|
53186
|
-
this.autocompleteList = new SelectList(
|
|
53208
|
+
this.autocompleteList = new SelectList(
|
|
53209
|
+
suggestions.items,
|
|
53210
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53211
|
+
this.theme.selectList
|
|
53212
|
+
);
|
|
53187
53213
|
this.autocompleteState = "force";
|
|
53188
53214
|
} else {
|
|
53189
53215
|
this.cancelAutocomplete();
|
|
@@ -53210,7 +53236,11 @@ var Editor = class {
|
|
|
53210
53236
|
);
|
|
53211
53237
|
if (suggestions && suggestions.items.length > 0) {
|
|
53212
53238
|
this.autocompletePrefix = suggestions.prefix;
|
|
53213
|
-
this.autocompleteList = new SelectList(
|
|
53239
|
+
this.autocompleteList = new SelectList(
|
|
53240
|
+
suggestions.items,
|
|
53241
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53242
|
+
this.theme.selectList
|
|
53243
|
+
);
|
|
53214
53244
|
} else {
|
|
53215
53245
|
this.cancelAutocomplete();
|
|
53216
53246
|
}
|
|
@@ -55394,6 +55424,17 @@ var SettingsList = class {
|
|
|
55394
55424
|
item.currentValue = newValue;
|
|
55395
55425
|
}
|
|
55396
55426
|
}
|
|
55427
|
+
/**
|
|
55428
|
+
* Move the selection to an item by id (respects the active filter).
|
|
55429
|
+
* Used when a command targets a specific row (e.g. /settings/theme).
|
|
55430
|
+
*/
|
|
55431
|
+
focusItemById(id) {
|
|
55432
|
+
const displayItems = this.searchEnabled ? this.filteredItems : this.items;
|
|
55433
|
+
const index = displayItems.findIndex((item) => item.id === id);
|
|
55434
|
+
if (index >= 0) {
|
|
55435
|
+
this.selectedIndex = index;
|
|
55436
|
+
}
|
|
55437
|
+
}
|
|
55397
55438
|
invalidate() {
|
|
55398
55439
|
this.submenuComponent?.invalidate?.();
|
|
55399
55440
|
}
|
|
@@ -62341,6 +62382,9 @@ var SettingsSelectorComponent = class extends Container {
|
|
|
62341
62382
|
{ enableSearch: true }
|
|
62342
62383
|
);
|
|
62343
62384
|
this.addChild(this.settingsList);
|
|
62385
|
+
if (config.focusItem) {
|
|
62386
|
+
this.settingsList.focusItemById(config.focusItem);
|
|
62387
|
+
}
|
|
62344
62388
|
}
|
|
62345
62389
|
getSettingsList() {
|
|
62346
62390
|
return this.settingsList;
|
|
@@ -62447,36 +62491,6 @@ function selectRuntimeExtensionWinners(infos) {
|
|
|
62447
62491
|
}
|
|
62448
62492
|
return reversed.reverse();
|
|
62449
62493
|
}
|
|
62450
|
-
var ExtensionStateSubmenu = class extends Container {
|
|
62451
|
-
selectList;
|
|
62452
|
-
constructor(identity, currentValue, scope, onSelect, onCommitted, onCancel) {
|
|
62453
|
-
super();
|
|
62454
|
-
this.addChild(new Text(theme.bold(theme.fg("accent", identity)), 0, 0));
|
|
62455
|
-
this.addChild(new Spacer(1));
|
|
62456
|
-
const settingsPath = scope === "project" ? "./.pie/settings.json" : "~/.pie/settings.json";
|
|
62457
|
-
this.addChild(new Text(theme.fg("muted", `Save an override in ${settingsPath}`), 0, 0));
|
|
62458
|
-
this.addChild(new Spacer(1));
|
|
62459
|
-
const options = [
|
|
62460
|
-
{ value: "on", label: "On", description: "Enable on next start" },
|
|
62461
|
-
{ value: "off", label: "Off", description: "Disable on next start" }
|
|
62462
|
-
];
|
|
62463
|
-
this.selectList = new SelectList(options, options.length, getSelectListTheme());
|
|
62464
|
-
this.selectList.setSelectedIndex(currentValue === "off" ? 1 : 0);
|
|
62465
|
-
this.selectList.onSelect = (item) => {
|
|
62466
|
-
const effective = onSelect(item.value === "on");
|
|
62467
|
-
if (effective !== void 0) {
|
|
62468
|
-
onCommitted(effective);
|
|
62469
|
-
}
|
|
62470
|
-
};
|
|
62471
|
-
this.selectList.onCancel = onCancel;
|
|
62472
|
-
this.addChild(this.selectList);
|
|
62473
|
-
this.addChild(new Spacer(1));
|
|
62474
|
-
this.addChild(new Text(theme.fg("dim", " Enter to select \xB7 Esc to go back"), 0, 0));
|
|
62475
|
-
}
|
|
62476
|
-
handleInput(data) {
|
|
62477
|
-
this.selectList.handleInput(data);
|
|
62478
|
-
}
|
|
62479
|
-
};
|
|
62480
62494
|
function unidentifiedLabel(info) {
|
|
62481
62495
|
const parentName = path23.basename(path23.dirname(info.entryPath));
|
|
62482
62496
|
const fileName = path23.basename(info.entryPath);
|
|
@@ -62497,37 +62511,41 @@ var ExtensionEnablementSelectorComponent = class extends Container {
|
|
|
62497
62511
|
0
|
|
62498
62512
|
));
|
|
62499
62513
|
this.addChild(new Spacer(1));
|
|
62514
|
+
const identityById = /* @__PURE__ */ new Map();
|
|
62515
|
+
const lastPersistedValue = /* @__PURE__ */ new Map();
|
|
62500
62516
|
const items = selectRuntimeExtensionWinners(infos).map((info, index) => {
|
|
62501
62517
|
const identity = info.identity;
|
|
62502
62518
|
const descriptionParts = [`Source: ${info.source}`];
|
|
62503
62519
|
if (info.description) descriptionParts.push(info.description);
|
|
62504
62520
|
if (!identity) descriptionParts.push("No stable identity; this entry is read-only.");
|
|
62521
|
+
const id = identity ?? `unidentified:${index}`;
|
|
62522
|
+
if (identity) {
|
|
62523
|
+
identityById.set(id, identity);
|
|
62524
|
+
lastPersistedValue.set(id, info.enabled ? "on" : "off");
|
|
62525
|
+
}
|
|
62505
62526
|
const item = {
|
|
62506
|
-
id
|
|
62527
|
+
id,
|
|
62507
62528
|
label: identity ?? unidentifiedLabel(info),
|
|
62508
62529
|
description: descriptionParts.join(" \xB7 "),
|
|
62509
62530
|
currentValue: info.enabled ? "on" : "off"
|
|
62510
62531
|
};
|
|
62511
|
-
if (identity)
|
|
62512
|
-
item.submenu = (currentValue, done) => {
|
|
62513
|
-
const submenu = new ExtensionStateSubmenu(
|
|
62514
|
-
identity,
|
|
62515
|
-
currentValue,
|
|
62516
|
-
scope,
|
|
62517
|
-
(enabled) => callbacks.onToggle(identity, enabled),
|
|
62518
|
-
(effectiveEnabled) => done(effectiveEnabled ? "on" : "off"),
|
|
62519
|
-
() => done()
|
|
62520
|
-
);
|
|
62521
|
-
return submenu;
|
|
62522
|
-
};
|
|
62523
|
-
}
|
|
62532
|
+
if (identity) item.values = ["on", "off"];
|
|
62524
62533
|
return item;
|
|
62525
62534
|
});
|
|
62526
62535
|
this.settingsList = new SettingsList(
|
|
62527
62536
|
items,
|
|
62528
62537
|
10,
|
|
62529
62538
|
getSettingsListTheme(),
|
|
62530
|
-
() => {
|
|
62539
|
+
(id, newValue) => {
|
|
62540
|
+
const identity = identityById.get(id);
|
|
62541
|
+
if (!identity) return;
|
|
62542
|
+
const previous = lastPersistedValue.get(id) ?? "on";
|
|
62543
|
+
const accepted = callbacks.onToggle(identity, newValue === "on");
|
|
62544
|
+
if (accepted === false) {
|
|
62545
|
+
this.settingsList.updateValue(id, previous);
|
|
62546
|
+
return;
|
|
62547
|
+
}
|
|
62548
|
+
lastPersistedValue.set(id, newValue);
|
|
62531
62549
|
},
|
|
62532
62550
|
callbacks.onCancel,
|
|
62533
62551
|
{ enableSearch: true }
|
|
@@ -62587,9 +62605,9 @@ function createExtensionSelector(host, scope, onCancel) {
|
|
|
62587
62605
|
return new ExtensionEnablementSelectorComponent(infos, scope, {
|
|
62588
62606
|
onToggle: (identity, enabled) => {
|
|
62589
62607
|
const outcome = trySetExtensionEnabled(host, identity, enabled, scope);
|
|
62590
|
-
if (!outcome) return
|
|
62608
|
+
if (!outcome) return false;
|
|
62591
62609
|
host.showStatus(outcome.message);
|
|
62592
|
-
return
|
|
62610
|
+
return true;
|
|
62593
62611
|
},
|
|
62594
62612
|
onCancel
|
|
62595
62613
|
});
|
|
@@ -62679,16 +62697,26 @@ var BUILTIN_SLASH_COMMANDS = [
|
|
|
62679
62697
|
{ name: "debugs/context", description: "Append a context summary to ~/.pie/logs/pie-cli.log" },
|
|
62680
62698
|
{ name: "debugs/package", description: "Append a package summary to ~/.pie/logs/pie-cli.log" },
|
|
62681
62699
|
{ name: "settings/quit", description: "Exit Pie" },
|
|
62682
|
-
{ name: "skills", description: "
|
|
62683
|
-
{ name: "skills/list", description: "List available skills" },
|
|
62700
|
+
{ name: "skills", description: "Manage skills: list, toggle enable/disable, invoke" },
|
|
62701
|
+
{ name: "skills/list", description: "List available skills (plain text)" },
|
|
62702
|
+
{ name: "skills/create", description: "Create a new skill from a template" },
|
|
62684
62703
|
{ name: "skills/enable", description: "Enable a skill by name" },
|
|
62685
62704
|
{ name: "skills/disable", description: "Disable a skill by name" },
|
|
62686
62705
|
{ name: "skills/reload", description: "Reload skills from disk" },
|
|
62687
62706
|
{ name: "skills/use", description: "Use a skill" },
|
|
62688
62707
|
{ name: "tools", description: "List tools and manage enable/disable toggles" },
|
|
62708
|
+
{ name: "tools/list", description: "List runtime tools and their state (plain text)" },
|
|
62689
62709
|
{ name: "tools/enable", description: "Enable a tool by name" },
|
|
62690
62710
|
{ name: "tools/disable", description: "Disable a tool by name" },
|
|
62691
|
-
{ name: "tools/subagent", description: "Spawn subagents in parallel to handle tasks" }
|
|
62711
|
+
{ name: "tools/subagent", description: "Spawn subagents in parallel to handle tasks" },
|
|
62712
|
+
{ name: "files/upload", description: "Attach a file to the conversation" },
|
|
62713
|
+
{ name: "files/upload-pic", description: "Attach an image to the conversation" },
|
|
62714
|
+
{ name: "files/upload-video", description: "Attach a video to the conversation" },
|
|
62715
|
+
{ name: "files/list", description: "List uploaded files" },
|
|
62716
|
+
{ name: "files/status", description: "Check file status" },
|
|
62717
|
+
{ name: "files/refresh", description: "Refresh expired files" },
|
|
62718
|
+
{ name: "files/delete", description: "Delete a file" },
|
|
62719
|
+
{ name: "files/stats", description: "Show file statistics" }
|
|
62692
62720
|
];
|
|
62693
62721
|
|
|
62694
62722
|
// src/commands/interactive-debug-commands.ts
|
|
@@ -65261,6 +65289,80 @@ function errorMessage2(error) {
|
|
|
65261
65289
|
return error instanceof Error ? error.message : String(error);
|
|
65262
65290
|
}
|
|
65263
65291
|
function handleSkillsCommand(host) {
|
|
65292
|
+
host.showSelector((done) => {
|
|
65293
|
+
const settingsManager = host.options.settingsManager;
|
|
65294
|
+
const discovered = listDiscoveredSkills(host);
|
|
65295
|
+
const lastPersisted = /* @__PURE__ */ new Map();
|
|
65296
|
+
const items = discovered.map((skill) => ({
|
|
65297
|
+
id: `skill:${skill.name}`,
|
|
65298
|
+
label: skill.name,
|
|
65299
|
+
description: `${skill.description} \xB7 Source: ${skill.source ?? "unknown"}`,
|
|
65300
|
+
currentValue: settingsManager.isSkillEnabled(skill.name) ? "on" : "off",
|
|
65301
|
+
values: ["on", "off"]
|
|
65302
|
+
}));
|
|
65303
|
+
for (const item of items) lastPersisted.set(item.id, item.currentValue);
|
|
65304
|
+
const settingsList = new SettingsList(
|
|
65305
|
+
items,
|
|
65306
|
+
12,
|
|
65307
|
+
getSettingsListTheme(),
|
|
65308
|
+
(id, newValue) => {
|
|
65309
|
+
const name = id.slice("skill:".length);
|
|
65310
|
+
const enabled = newValue === "on";
|
|
65311
|
+
const previous = lastPersisted.get(id) ?? "on";
|
|
65312
|
+
try {
|
|
65313
|
+
settingsManager.setSkillEnabled(name, enabled);
|
|
65314
|
+
} catch (error) {
|
|
65315
|
+
settingsList.updateValue(id, previous);
|
|
65316
|
+
host.showError(`Failed to update skill "${name}": ${errorMessage2(error)}`);
|
|
65317
|
+
return;
|
|
65318
|
+
}
|
|
65319
|
+
lastPersisted.set(id, newValue);
|
|
65320
|
+
applyReloadedSkills(host, discoverSkills(host));
|
|
65321
|
+
host.showStatus(`Skill "${name}" ${enabled ? "enabled" : "disabled"} (reloaded).`);
|
|
65322
|
+
},
|
|
65323
|
+
() => done(),
|
|
65324
|
+
{ enableSearch: true }
|
|
65325
|
+
);
|
|
65326
|
+
const component = {
|
|
65327
|
+
render: (width) => [
|
|
65328
|
+
theme.bold(theme.fg("accent", "Skills")),
|
|
65329
|
+
"",
|
|
65330
|
+
theme.fg("muted", "Enter/Space toggles \xB7 changes apply immediately \xB7 Esc to close"),
|
|
65331
|
+
theme.fg("dim", `Usage: /skills/skill:<name> <your request> (${discovered.length} discovered)`),
|
|
65332
|
+
"",
|
|
65333
|
+
...settingsList.render(width)
|
|
65334
|
+
],
|
|
65335
|
+
handleInput: (data) => settingsList.handleInput(data),
|
|
65336
|
+
invalidate: () => settingsList.invalidate()
|
|
65337
|
+
};
|
|
65338
|
+
return { component, focus: settingsList };
|
|
65339
|
+
});
|
|
65340
|
+
}
|
|
65341
|
+
function discoverSkills(host) {
|
|
65342
|
+
const builtinDir = path25.join(getBuiltinDir(), "skills");
|
|
65343
|
+
const userDir = path25.join(os7.homedir(), ".pie", "skills");
|
|
65344
|
+
const projectDir = path25.join(process.cwd(), ".pie", "skills");
|
|
65345
|
+
return loadSkills({ dirs: buildSkillDirs({ builtinDir, userDir, projectDir, cwd: process.cwd() }) });
|
|
65346
|
+
}
|
|
65347
|
+
function listDiscoveredSkills(host) {
|
|
65348
|
+
return discoverSkills(host).skills;
|
|
65349
|
+
}
|
|
65350
|
+
function applyReloadedSkills(host, result) {
|
|
65351
|
+
host.skills = result.skills.filter((skill) => host.options.settingsManager.isSkillEnabled(skill.name));
|
|
65352
|
+
host.skillsSection = formatSkillsForPrompt(host.skills);
|
|
65353
|
+
host.applyRuntimeToolMode(host.allTools.length > 0 ? host.allTools : host.agent.state.tools);
|
|
65354
|
+
host.updateSystemPromptTools();
|
|
65355
|
+
for (const skill of host.skills) {
|
|
65356
|
+
const skillPath = ["skills", `skill:${skill.name}`];
|
|
65357
|
+
if (!commandTree.find(skillPath)) {
|
|
65358
|
+
commandTree.register(skillPath, {
|
|
65359
|
+
description: skill.description,
|
|
65360
|
+
handler: (_2, args) => host.handleSkillInvoke(skill.name, args || "")
|
|
65361
|
+
});
|
|
65362
|
+
}
|
|
65363
|
+
}
|
|
65364
|
+
}
|
|
65365
|
+
function handleSkillsListCommand(host) {
|
|
65264
65366
|
host.chatContainer.addChild(new Spacer(1));
|
|
65265
65367
|
host.chatContainer.addChild(new Text(theme.bold("Available Skills"), 1, 0));
|
|
65266
65368
|
if (host.skills.length === 0) {
|
|
@@ -65417,7 +65519,12 @@ async function handleSkillToggleCommand(host, args, enabled) {
|
|
|
65417
65519
|
host.ui.requestRender();
|
|
65418
65520
|
}
|
|
65419
65521
|
async function handleSkillsCreate(host, args) {
|
|
65420
|
-
|
|
65522
|
+
const debugLog2 = (message) => {
|
|
65523
|
+
if (process.env.PIE_VERBOSE) {
|
|
65524
|
+
console.error(`[SkillsCreate] ${message}`);
|
|
65525
|
+
}
|
|
65526
|
+
};
|
|
65527
|
+
debugLog2(`Called with args: "${args}"`);
|
|
65421
65528
|
try {
|
|
65422
65529
|
const trimmed = args.trim();
|
|
65423
65530
|
if (!trimmed) {
|
|
@@ -65448,7 +65555,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65448
65555
|
description = descPart.replace(/^["']|["']$/g, "");
|
|
65449
65556
|
}
|
|
65450
65557
|
}
|
|
65451
|
-
|
|
65558
|
+
debugLog2(`Parsed name: "${name}", description: "${description}"`);
|
|
65452
65559
|
if (!name) {
|
|
65453
65560
|
host.showSkillCreatePrompt();
|
|
65454
65561
|
return;
|
|
@@ -65464,7 +65571,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65464
65571
|
const skillsDir = path25.join(os7.homedir(), ".pie", "skills");
|
|
65465
65572
|
const skillDir = path25.join(skillsDir, name);
|
|
65466
65573
|
const skillFile = path25.join(skillDir, "SKILL.md");
|
|
65467
|
-
|
|
65574
|
+
debugLog2(`Creating at: ${skillFile}`);
|
|
65468
65575
|
if (fs23.existsSync(skillDir)) {
|
|
65469
65576
|
host.showError(`Skill "${name}" already exists at ${skillDir}`);
|
|
65470
65577
|
return;
|
|
@@ -65472,7 +65579,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65472
65579
|
fs23.mkdirSync(skillDir, { recursive: true });
|
|
65473
65580
|
const template = createSkillTemplate(name, description);
|
|
65474
65581
|
fs23.writeFileSync(skillFile, template, "utf-8");
|
|
65475
|
-
|
|
65582
|
+
debugLog2("Successfully created skill");
|
|
65476
65583
|
host.chatContainer.addChild(new Spacer(1));
|
|
65477
65584
|
host.chatContainer.addChild(new Text(theme.fg("accent", `\u2713 Created skill: ${name}`), 1, 0));
|
|
65478
65585
|
host.chatContainer.addChild(new Text(theme.fg("dim", ` Location: ${skillFile}`), 1, 0));
|
|
@@ -65481,7 +65588,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65481
65588
|
host.chatContainer.addChild(new Spacer(1));
|
|
65482
65589
|
host.ui.requestRender();
|
|
65483
65590
|
} catch (err) {
|
|
65484
|
-
|
|
65591
|
+
debugLog2(`Error: ${errorMessage2(err)}`);
|
|
65485
65592
|
host.showError(`Failed to create skill: ${errorMessage2(err)}`);
|
|
65486
65593
|
}
|
|
65487
65594
|
}
|
|
@@ -65507,23 +65614,8 @@ async function handleSkillsReload(host) {
|
|
|
65507
65614
|
host.chatContainer.addChild(new Text(theme.fg("accent", "Reloading skills..."), 1, 0));
|
|
65508
65615
|
host.ui.requestRender();
|
|
65509
65616
|
try {
|
|
65510
|
-
const
|
|
65511
|
-
|
|
65512
|
-
const projectDir = path25.join(process.cwd(), ".pie", "skills");
|
|
65513
|
-
const result = loadSkills({ dirs: buildSkillDirs({ builtinDir, userDir, projectDir, cwd: process.cwd() }) });
|
|
65514
|
-
host.skills = result.skills.filter((skill) => host.options.settingsManager.isSkillEnabled(skill.name));
|
|
65515
|
-
host.skillsSection = formatSkillsForPrompt(host.skills);
|
|
65516
|
-
host.applyRuntimeToolMode(host.allTools.length > 0 ? host.allTools : host.agent.state.tools);
|
|
65517
|
-
host.updateSystemPromptTools();
|
|
65518
|
-
for (const skill of host.skills) {
|
|
65519
|
-
const skillPath = ["skills", `skill:${skill.name}`];
|
|
65520
|
-
if (!commandTree.find(skillPath)) {
|
|
65521
|
-
commandTree.register(skillPath, {
|
|
65522
|
-
description: skill.description,
|
|
65523
|
-
handler: (_2, args) => host.handleSkillInvoke(skill.name, args || "")
|
|
65524
|
-
});
|
|
65525
|
-
}
|
|
65526
|
-
}
|
|
65617
|
+
const result = discoverSkills(host);
|
|
65618
|
+
applyReloadedSkills(host, result);
|
|
65527
65619
|
const builtinCount = host.skills.filter((s) => s.source === "builtin").length;
|
|
65528
65620
|
const userCount = host.skills.filter((s) => s.source === "user" || s.source === "user-agents").length;
|
|
65529
65621
|
const projectCount = host.skills.filter((s) => s.source === "project" || s.source === "project-agents").length;
|
|
@@ -65556,6 +65648,77 @@ function collectKnownToolNames(host) {
|
|
|
65556
65648
|
const disabled = disabledNames.filter((name) => !liveNames.includes(name));
|
|
65557
65649
|
return { active: [...liveNames].sort(), disabled: [...disabled].sort() };
|
|
65558
65650
|
}
|
|
65651
|
+
function describeToggleEffect(host, name, enabled) {
|
|
65652
|
+
const loaded = collectKnownToolNames(host).active.includes(name);
|
|
65653
|
+
if (enabled) {
|
|
65654
|
+
return loaded ? `Tool "${name}" enabled (active now).` : `Tool "${name}" enabled in ~/.pie/settings.json (loads on next start \u2014 it was not loaded this session).`;
|
|
65655
|
+
}
|
|
65656
|
+
return loaded ? `Tool "${name}" disabled (removed from this session).` : `Tool "${name}" disabled in ~/.pie/settings.json.`;
|
|
65657
|
+
}
|
|
65658
|
+
function showToolsManager(host) {
|
|
65659
|
+
host.showSelector((done) => {
|
|
65660
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65661
|
+
const settingsManager = host.options.settingsManager;
|
|
65662
|
+
const lastPersisted = /* @__PURE__ */ new Map();
|
|
65663
|
+
const items = [
|
|
65664
|
+
...active.map((name) => ({
|
|
65665
|
+
id: `tool:${name}`,
|
|
65666
|
+
label: name,
|
|
65667
|
+
description: "Runtime agent tool",
|
|
65668
|
+
currentValue: settingsManager.isToolEnabled(name) ? "on" : "off",
|
|
65669
|
+
values: ["on", "off"]
|
|
65670
|
+
})),
|
|
65671
|
+
...disabled.map((name) => ({
|
|
65672
|
+
id: `tool:${name}`,
|
|
65673
|
+
label: name,
|
|
65674
|
+
description: "Not loaded this session (starts enabled next launch)",
|
|
65675
|
+
currentValue: "off",
|
|
65676
|
+
values: ["on", "off"]
|
|
65677
|
+
}))
|
|
65678
|
+
];
|
|
65679
|
+
for (const item of items) lastPersisted.set(item.id, item.currentValue);
|
|
65680
|
+
const settingsList = new SettingsList(
|
|
65681
|
+
items,
|
|
65682
|
+
14,
|
|
65683
|
+
getSettingsListTheme(),
|
|
65684
|
+
(id, newValue) => {
|
|
65685
|
+
const name = id.slice("tool:".length);
|
|
65686
|
+
const enabled = newValue === "on";
|
|
65687
|
+
const previous = lastPersisted.get(id) ?? "off";
|
|
65688
|
+
try {
|
|
65689
|
+
settingsManager.setToolEnabled(name, enabled);
|
|
65690
|
+
} catch (error) {
|
|
65691
|
+
settingsList.updateValue(id, previous);
|
|
65692
|
+
host.showError(`Failed to update tool "${name}": ${errorMessage3(error)}`);
|
|
65693
|
+
return;
|
|
65694
|
+
}
|
|
65695
|
+
lastPersisted.set(id, newValue);
|
|
65696
|
+
host.applyRuntimeToolMode();
|
|
65697
|
+
host.showStatus(describeToggleEffect(host, name, enabled));
|
|
65698
|
+
},
|
|
65699
|
+
() => done(),
|
|
65700
|
+
{ enableSearch: true }
|
|
65701
|
+
);
|
|
65702
|
+
const component = {
|
|
65703
|
+
render: (width) => [
|
|
65704
|
+
...renderHeader(width),
|
|
65705
|
+
...settingsList.render(width)
|
|
65706
|
+
],
|
|
65707
|
+
handleInput: (data) => settingsList.handleInput(data),
|
|
65708
|
+
invalidate: () => settingsList.invalidate()
|
|
65709
|
+
};
|
|
65710
|
+
return { component, focus: settingsList };
|
|
65711
|
+
});
|
|
65712
|
+
}
|
|
65713
|
+
function renderHeader(width) {
|
|
65714
|
+
const lines = [];
|
|
65715
|
+
lines.push(theme.bold(theme.fg("accent", "Tools")));
|
|
65716
|
+
lines.push("");
|
|
65717
|
+
lines.push(theme.fg("muted", "Enter/Space toggles \xB7 live tools apply immediately \xB7 Esc to close"));
|
|
65718
|
+
const hint = "Usage: /tools/enable <name> | /tools/disable <name>";
|
|
65719
|
+
if (width > 20) lines.push(theme.fg("dim", hint));
|
|
65720
|
+
return lines;
|
|
65721
|
+
}
|
|
65559
65722
|
function handleToolsCommand(host, args) {
|
|
65560
65723
|
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
65561
65724
|
const subcommand = parts[0];
|
|
@@ -65565,8 +65728,8 @@ function handleToolsCommand(host, args) {
|
|
|
65565
65728
|
host.showError(`Usage: /tools ${subcommand} <tool-name>`);
|
|
65566
65729
|
return;
|
|
65567
65730
|
}
|
|
65568
|
-
const { active
|
|
65569
|
-
if (!
|
|
65731
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65732
|
+
if (!active.includes(name) && !disabled.includes(name)) {
|
|
65570
65733
|
host.showError(`Tool not found: ${name}. Use /tools to list tool names.`);
|
|
65571
65734
|
return;
|
|
65572
65735
|
}
|
|
@@ -65577,38 +65740,42 @@ function handleToolsCommand(host, args) {
|
|
|
65577
65740
|
host.showError(`Failed to update tool "${name}": ${errorMessage3(error)}`);
|
|
65578
65741
|
return;
|
|
65579
65742
|
}
|
|
65743
|
+
host.applyRuntimeToolMode();
|
|
65580
65744
|
host.chatContainer.addChild(new Spacer(1));
|
|
65581
65745
|
host.chatContainer.addChild(new Text(
|
|
65582
|
-
theme.fg("accent",
|
|
65746
|
+
theme.fg("accent", describeToggleEffect(host, name, enabled)),
|
|
65583
65747
|
1,
|
|
65584
65748
|
0
|
|
65585
65749
|
));
|
|
65586
65750
|
host.ui.requestRender();
|
|
65587
65751
|
return;
|
|
65588
65752
|
}
|
|
65589
|
-
if (subcommand) {
|
|
65590
|
-
|
|
65753
|
+
if (subcommand === "list") {
|
|
65754
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65755
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
65756
|
+
host.chatContainer.addChild(new Text(theme.bold("Tools"), 1, 0));
|
|
65757
|
+
if (active.length === 0 && disabled.length === 0) {
|
|
65758
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", " No tools available."), 1, 0));
|
|
65759
|
+
}
|
|
65760
|
+
for (const name of active) {
|
|
65761
|
+
const state = host.options.settingsManager.isToolEnabled(name) ? "enabled" : "disabled (removed from this session)";
|
|
65762
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: ${state}`), 1, 0));
|
|
65763
|
+
}
|
|
65764
|
+
for (const name of disabled) {
|
|
65765
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: disabled (/tools/enable ${name})`), 1, 0));
|
|
65766
|
+
}
|
|
65767
|
+
host.ui.requestRender();
|
|
65591
65768
|
return;
|
|
65592
65769
|
}
|
|
65593
|
-
|
|
65594
|
-
|
|
65595
|
-
|
|
65596
|
-
if (active.length === 0 && disabled.length === 0) {
|
|
65597
|
-
host.chatContainer.addChild(new Text(theme.fg("dim", " No tools available."), 1, 0));
|
|
65598
|
-
}
|
|
65599
|
-
for (const name of active) {
|
|
65600
|
-
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: enabled`), 1, 0));
|
|
65601
|
-
}
|
|
65602
|
-
for (const name of disabled) {
|
|
65603
|
-
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: disabled (/tools/enable ${name})`), 1, 0));
|
|
65770
|
+
if (subcommand) {
|
|
65771
|
+
host.showError("Usage: /tools [list | enable|disable <tool-name>]");
|
|
65772
|
+
return;
|
|
65604
65773
|
}
|
|
65605
|
-
host
|
|
65606
|
-
host.chatContainer.addChild(new Text(theme.fg("dim", "Usage: /tools/enable <name> | /tools/disable <name> (takes effect on next start)"), 1, 0));
|
|
65607
|
-
host.ui.requestRender();
|
|
65774
|
+
showToolsManager(host);
|
|
65608
65775
|
}
|
|
65609
65776
|
|
|
65610
65777
|
// src/commands/interactive-command-handlers.ts
|
|
65611
|
-
function showSettingsSelector(host) {
|
|
65778
|
+
function showSettingsSelector(host, focusItem) {
|
|
65612
65779
|
host.showSelector((done) => {
|
|
65613
65780
|
const currentModelId = host.options.model?.id || "unknown";
|
|
65614
65781
|
const currentProvider = host.options.model?.provider || "unknown";
|
|
@@ -65624,7 +65791,8 @@ function showSettingsSelector(host) {
|
|
|
65624
65791
|
yoloMode: host.yoloMode,
|
|
65625
65792
|
calmMode: host.calmMode,
|
|
65626
65793
|
notificationsBell: host.options.settingsManager.getBellNotificationsEnabled(),
|
|
65627
|
-
notificationsDesktop: host.options.settingsManager.getDesktopNotificationsEnabled()
|
|
65794
|
+
notificationsDesktop: host.options.settingsManager.getDesktopNotificationsEnabled(),
|
|
65795
|
+
focusItem
|
|
65628
65796
|
},
|
|
65629
65797
|
{
|
|
65630
65798
|
onThinkingLevelChange: (level) => {
|
|
@@ -66012,7 +66180,19 @@ async function handleClearCommand(host) {
|
|
|
66012
66180
|
host.syncSessionModelMetadata();
|
|
66013
66181
|
host.planModeEnabled = false;
|
|
66014
66182
|
host.pendingPlanModeTransition = null;
|
|
66015
|
-
host.
|
|
66183
|
+
const contextUsage = host.calculateContextUsage();
|
|
66184
|
+
const contextWindow = host.options.model?.contextWindow ?? 0;
|
|
66185
|
+
host.footer.setState({
|
|
66186
|
+
planMode: false,
|
|
66187
|
+
status: "ready",
|
|
66188
|
+
inputTokens: contextUsage.input,
|
|
66189
|
+
outputTokens: contextUsage.output,
|
|
66190
|
+
cacheRead: contextUsage.cacheRead,
|
|
66191
|
+
cacheWrite: contextUsage.cacheWrite,
|
|
66192
|
+
cost: contextUsage.cost,
|
|
66193
|
+
contextPercent: contextWindow > 0 && contextUsage.tokens !== null ? contextUsage.tokens / contextWindow * 100 : 0,
|
|
66194
|
+
contextWindow
|
|
66195
|
+
});
|
|
66016
66196
|
host.updateTerminalTitle();
|
|
66017
66197
|
host.chatContainer.clear();
|
|
66018
66198
|
host.streamingComponent = void 0;
|
|
@@ -66193,7 +66373,7 @@ function registerBuiltinCommands(host) {
|
|
|
66193
66373
|
});
|
|
66194
66374
|
commandTree.register(["settings", "theme"], {
|
|
66195
66375
|
description: "Change theme",
|
|
66196
|
-
handler: () => host.showSettingsSelector()
|
|
66376
|
+
handler: () => host.showSettingsSelector("theme")
|
|
66197
66377
|
});
|
|
66198
66378
|
commandTree.register(["settings", "thinking"], {
|
|
66199
66379
|
description: "Set thinking level (off/minimal/low/medium/high/xhigh)",
|
|
@@ -66223,14 +66403,22 @@ function registerBuiltinCommands(host) {
|
|
|
66223
66403
|
description: "Disable an extension by identity (writes settings)",
|
|
66224
66404
|
handler: (_2, args) => host.handleExtensionsCommand(`disable ${args || ""}`)
|
|
66225
66405
|
});
|
|
66226
|
-
commandTree.register(["skills"
|
|
66227
|
-
description: "
|
|
66406
|
+
commandTree.register(["skills"], {
|
|
66407
|
+
description: "Manage skills: list, toggle enable/disable, invoke",
|
|
66228
66408
|
handler: () => host.handleSkillsCommand()
|
|
66229
66409
|
});
|
|
66410
|
+
commandTree.register(["skills", "list"], {
|
|
66411
|
+
description: "List available skills (plain text)",
|
|
66412
|
+
handler: () => host.handleSkillsListCommand()
|
|
66413
|
+
});
|
|
66230
66414
|
commandTree.register(["skills", "use"], {
|
|
66231
66415
|
description: "Use a skill",
|
|
66232
66416
|
handler: (_2, args) => host.handleSkillCommand(args || "")
|
|
66233
66417
|
});
|
|
66418
|
+
commandTree.register(["skills", "create"], {
|
|
66419
|
+
description: "Create a new skill from a template",
|
|
66420
|
+
handler: (_2, args) => host.handleSkillsCreate(args || "")
|
|
66421
|
+
});
|
|
66234
66422
|
commandTree.register(["skills", "reload"], {
|
|
66235
66423
|
description: "Reload skills from disk",
|
|
66236
66424
|
handler: async () => {
|
|
@@ -66259,12 +66447,16 @@ function registerBuiltinCommands(host) {
|
|
|
66259
66447
|
description: "List runtime tools and manage enable/disable toggles",
|
|
66260
66448
|
handler: (_2, args) => host.handleToolsCommand(args || "")
|
|
66261
66449
|
});
|
|
66450
|
+
commandTree.register(["tools", "list"], {
|
|
66451
|
+
description: "List runtime tools and their state (plain text)",
|
|
66452
|
+
handler: (_2, args) => host.handleToolsCommand(args ? `list ${args}` : "list")
|
|
66453
|
+
});
|
|
66262
66454
|
commandTree.register(["tools", "enable"], {
|
|
66263
|
-
description: "Enable a tool by name (writes settings;
|
|
66455
|
+
description: "Enable a tool by name (writes settings; live tools apply now)",
|
|
66264
66456
|
handler: (_2, args) => host.handleToolsCommand(`enable ${args || ""}`)
|
|
66265
66457
|
});
|
|
66266
66458
|
commandTree.register(["tools", "disable"], {
|
|
66267
|
-
description: "Disable a tool by name (writes settings;
|
|
66459
|
+
description: "Disable a tool by name (writes settings; applies now)",
|
|
66268
66460
|
handler: (_2, args) => host.handleToolsCommand(`disable ${args || ""}`)
|
|
66269
66461
|
});
|
|
66270
66462
|
commandTree.register(["debugs", "cache-test"], {
|
|
@@ -66422,6 +66614,7 @@ function ringTerminalBell(options = {}) {
|
|
|
66422
66614
|
function ringTurnSettledBell(host) {
|
|
66423
66615
|
if ((host.agentSessionController?.pendingMessageCount ?? 0) > 0) return;
|
|
66424
66616
|
if (host.executionState.read().awaitingContinuation) return;
|
|
66617
|
+
if (host.peekTodoAutoContinuePrompt?.()) return;
|
|
66425
66618
|
host.ringAttentionBell?.("turn-settled");
|
|
66426
66619
|
}
|
|
66427
66620
|
function attentionMessage(reason) {
|
|
@@ -70064,12 +70257,19 @@ function clearContinuationTimeout(host, reason) {
|
|
|
70064
70257
|
function isWaitingForUserInteraction(host) {
|
|
70065
70258
|
return host.activeInteractionCount > 0;
|
|
70066
70259
|
}
|
|
70260
|
+
function peekTodoAutoContinuePrompt(host) {
|
|
70261
|
+
if (isWaitingForUserInteraction(host)) return void 0;
|
|
70262
|
+
if (host.submitLock || host.isProcessing || host.isInterrupting || host.isCompacting) return void 0;
|
|
70263
|
+
const hasTodoTool = (host.agent?.state?.tools ?? []).some((tool) => tool.name === "manage_todo_list");
|
|
70264
|
+
if (!hasTodoTool) return void 0;
|
|
70265
|
+
return host.executionState.takeTodoClosureFollowUp() || void 0;
|
|
70266
|
+
}
|
|
70067
70267
|
function getTodoAutoContinueMessage(host) {
|
|
70268
|
+
const prompt = peekTodoAutoContinuePrompt(host);
|
|
70068
70269
|
if (isWaitingForUserInteraction(host)) return { reason: "waiting_for_user_interaction" };
|
|
70069
70270
|
if (host.submitLock || host.isProcessing || host.isInterrupting || host.isCompacting) return { reason: "host_busy" };
|
|
70070
70271
|
const hasTodoTool = (host.agent?.state?.tools ?? []).some((tool) => tool.name === "manage_todo_list");
|
|
70071
70272
|
if (!hasTodoTool) return { reason: "todo_tool_unavailable" };
|
|
70072
|
-
const prompt = host.executionState.takeTodoClosureFollowUp();
|
|
70073
70273
|
if (!prompt) return { reason: "no_active_todo_follow_up" };
|
|
70074
70274
|
host.logDebug("todo_closure:follow_up", {
|
|
70075
70275
|
textPreview: prompt.slice(0, 120),
|
|
@@ -71106,11 +71306,14 @@ async function restoreExtensionProviderCredentials(modelRegistry) {
|
|
|
71106
71306
|
}
|
|
71107
71307
|
|
|
71108
71308
|
// src/attachments/resolver.ts
|
|
71309
|
+
var PROVIDER_SOURCE = "(provider)";
|
|
71109
71310
|
var AttachmentResolver = class {
|
|
71110
|
-
constructor(extensions) {
|
|
71311
|
+
constructor(extensions, builtInHandlers = []) {
|
|
71111
71312
|
this.extensions = extensions;
|
|
71313
|
+
this.builtInHandlers = builtInHandlers;
|
|
71112
71314
|
}
|
|
71113
71315
|
extensions;
|
|
71316
|
+
builtInHandlers;
|
|
71114
71317
|
findHandler(model, attachment) {
|
|
71115
71318
|
const candidate = this.collectCandidates(model, attachment)[0];
|
|
71116
71319
|
if (!candidate) return void 0;
|
|
@@ -71135,6 +71338,15 @@ var AttachmentResolver = class {
|
|
|
71135
71338
|
}
|
|
71136
71339
|
collectCandidates(model, attachment) {
|
|
71137
71340
|
const matches = [];
|
|
71341
|
+
for (const handler of this.builtInHandlers) {
|
|
71342
|
+
if (!handler.matches(model, attachment)) continue;
|
|
71343
|
+
matches.push({
|
|
71344
|
+
handlerName: handler.name,
|
|
71345
|
+
extensionPath: PROVIDER_SOURCE,
|
|
71346
|
+
priority: handler.priority ?? 0,
|
|
71347
|
+
prepare: handler.prepare.bind(handler)
|
|
71348
|
+
});
|
|
71349
|
+
}
|
|
71138
71350
|
for (const extension of this.extensions) {
|
|
71139
71351
|
for (const handler of extension.attachmentHandlers.values()) {
|
|
71140
71352
|
if (!handler.matches(model, attachment)) continue;
|
|
@@ -71157,6 +71369,48 @@ var AttachmentResolver = class {
|
|
|
71157
71369
|
}
|
|
71158
71370
|
};
|
|
71159
71371
|
|
|
71372
|
+
// src/attachments/provider-handlers.ts
|
|
71373
|
+
function getModality(mimeType) {
|
|
71374
|
+
if (mimeType.startsWith("image/")) return "image";
|
|
71375
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
71376
|
+
return "file";
|
|
71377
|
+
}
|
|
71378
|
+
function isKimiAttachmentPlatform(model) {
|
|
71379
|
+
return model.attachmentPlatform === "kimi" || model.filePlatform === "kimi";
|
|
71380
|
+
}
|
|
71381
|
+
var kimiNativeAttachmentHandler = {
|
|
71382
|
+
name: "kimi-native-attachments",
|
|
71383
|
+
priority: 100,
|
|
71384
|
+
matches(model, attachment) {
|
|
71385
|
+
return isKimiAttachmentPlatform(model) && Boolean(attachment.fileId) && getModality(attachment.mimeType) !== "file";
|
|
71386
|
+
},
|
|
71387
|
+
async prepare(_model, attachment, ctx) {
|
|
71388
|
+
const fileId = attachment.fileId;
|
|
71389
|
+
if (!fileId) {
|
|
71390
|
+
return {
|
|
71391
|
+
items: [{ type: "text", text: `[${attachment.id}]` }],
|
|
71392
|
+
warnings: ["\u9644\u4EF6\u7F3A\u5C11 fileId\uFF0C\u65E0\u6CD5\u8D70 Kimi \u539F\u751F\u5F15\u7528"]
|
|
71393
|
+
};
|
|
71394
|
+
}
|
|
71395
|
+
const modality = getModality(attachment.mimeType);
|
|
71396
|
+
const url = `ms://${fileId}`;
|
|
71397
|
+
ctx.log(`Kimi handler prepared ${modality} reference for ${attachment.id}`);
|
|
71398
|
+
return {
|
|
71399
|
+
items: [
|
|
71400
|
+
{
|
|
71401
|
+
type: "file-ref",
|
|
71402
|
+
mimeType: attachment.mimeType,
|
|
71403
|
+
url,
|
|
71404
|
+
modality
|
|
71405
|
+
}
|
|
71406
|
+
]
|
|
71407
|
+
};
|
|
71408
|
+
}
|
|
71409
|
+
};
|
|
71410
|
+
var providerAttachmentHandlers = [
|
|
71411
|
+
kimiNativeAttachmentHandler
|
|
71412
|
+
];
|
|
71413
|
+
|
|
71160
71414
|
// src/app/runtime-composition-pipeline.ts
|
|
71161
71415
|
var CLI_COMPOSITION_STEP_ORDER = [
|
|
71162
71416
|
"model_config",
|
|
@@ -71307,7 +71561,7 @@ async function loadInteractiveExtensions(host) {
|
|
|
71307
71561
|
buildExtensionLoadOptions(host.options.settingsManager, host.options.extensionFlags)
|
|
71308
71562
|
);
|
|
71309
71563
|
host.extensions = extensions;
|
|
71310
|
-
host.attachmentResolver = new AttachmentResolver(extensions);
|
|
71564
|
+
host.attachmentResolver = new AttachmentResolver(extensions, providerAttachmentHandlers);
|
|
71311
71565
|
host.extensionRunner = new ExtensionRunner(
|
|
71312
71566
|
extensions,
|
|
71313
71567
|
extensionActions,
|
|
@@ -71479,6 +71733,10 @@ var InteractiveMode = class {
|
|
|
71479
71733
|
getTodoAutoContinueMessage() {
|
|
71480
71734
|
return getTodoAutoContinueMessage(this.continuationHost);
|
|
71481
71735
|
}
|
|
71736
|
+
/** Side-effect-free todo auto-continue prediction for the turn-settled bell. */
|
|
71737
|
+
peekTodoAutoContinuePrompt() {
|
|
71738
|
+
return peekTodoAutoContinuePrompt(this.continuationHost);
|
|
71739
|
+
}
|
|
71482
71740
|
appendWarningSummary(message) {
|
|
71483
71741
|
return appendWarningSummary(this.continuationHost, message);
|
|
71484
71742
|
}
|
|
@@ -71635,9 +71893,12 @@ var InteractiveMode = class {
|
|
|
71635
71893
|
const rebuilt = this.rebuildSkillAwareTools(completeToolSet);
|
|
71636
71894
|
const currentTools = this.extensionRunner ? wrapToolsWithExtensions(rebuilt.currentTools, this.extensionRunner) : rebuilt.currentTools;
|
|
71637
71895
|
const originalTools = this.extensionRunner ? wrapToolsWithExtensions(rebuilt.originalTools, this.extensionRunner) : rebuilt.originalTools;
|
|
71638
|
-
const activeTools =
|
|
71639
|
-
|
|
71640
|
-
|
|
71896
|
+
const activeTools = filterEnabledTools(
|
|
71897
|
+
selectToolsForRuntimeMode(
|
|
71898
|
+
currentTools,
|
|
71899
|
+
this.planModeEnabled ? "plan" : "normal"
|
|
71900
|
+
),
|
|
71901
|
+
this.options.settingsManager
|
|
71641
71902
|
);
|
|
71642
71903
|
this.agent.setTools(activeTools);
|
|
71643
71904
|
this.allTools = [...currentTools];
|
|
@@ -71648,7 +71909,8 @@ var InteractiveMode = class {
|
|
|
71648
71909
|
planMode: this.planModeEnabled ? "planning" : "off",
|
|
71649
71910
|
filesystemScope: this.yoloMode ? "all" : "workspace",
|
|
71650
71911
|
toolCount: activeTools.length,
|
|
71651
|
-
availableToolCount: currentTools.length
|
|
71912
|
+
availableToolCount: currentTools.length,
|
|
71913
|
+
disabledToolCount: this.options.settingsManager.getDisabledTools().length
|
|
71652
71914
|
});
|
|
71653
71915
|
}
|
|
71654
71916
|
noteRuntimeModeChanged(trigger) {
|
|
@@ -71901,8 +72163,8 @@ var InteractiveMode = class {
|
|
|
71901
72163
|
async selectMentionOption(option) {
|
|
71902
72164
|
return selectMentionOption(this.filePipelineHost, option);
|
|
71903
72165
|
}
|
|
71904
|
-
showSettingsSelector() {
|
|
71905
|
-
return showSettingsSelector(this);
|
|
72166
|
+
showSettingsSelector(focusItem) {
|
|
72167
|
+
return showSettingsSelector(this, focusItem);
|
|
71906
72168
|
}
|
|
71907
72169
|
async handleModelCommand(searchTerm) {
|
|
71908
72170
|
return handleModelCommand(this, searchTerm);
|
|
@@ -72013,6 +72275,9 @@ var InteractiveMode = class {
|
|
|
72013
72275
|
handleSkillsCommand() {
|
|
72014
72276
|
return handleSkillsCommand(this);
|
|
72015
72277
|
}
|
|
72278
|
+
handleSkillsListCommand() {
|
|
72279
|
+
return handleSkillsListCommand(this);
|
|
72280
|
+
}
|
|
72016
72281
|
handleSkillCommand(name) {
|
|
72017
72282
|
return handleSkillCommand(this, name);
|
|
72018
72283
|
}
|