@cydm/pie 1.0.47 → 1.0.48
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/cli.js +349 -131
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -218,7 +218,10 @@ Pie uses a hierarchical slash-command menu. The current built-in commands includ
|
|
|
218
218
|
| `pie doctor [--json]` | Diagnose local config, model setup, writable paths, browser automation, and Unity bridge hints |
|
|
219
219
|
| `pie models init` | Create a starter `~/.pie/models.json` |
|
|
220
220
|
| `pie models validate` | Validate `~/.pie/models.json` |
|
|
221
|
-
| `pie permissions` | Explain tool and shell safety defaults |
|
|
221
|
+
| `pie permissions` | Explain tool and shell safety defaults (`--json` returns the structured safety model) |
|
|
222
|
+
| `pie capabilities [--json]` | Report the command surface, flags, exit codes, and output schema for agents |
|
|
223
|
+
| `pie sessions list/read/rename/rewind/fork` | Inspect and manage stored sessions non-interactively (each supports `--json` and `--help`) |
|
|
224
|
+
| `pie extensions list/enable/disable` | Inspect and toggle extensions non-interactively |
|
|
222
225
|
| `/sessions/compact` | Summarize history and create a compact checkpoint |
|
|
223
226
|
| `/sessions/new` | Start a new session |
|
|
224
227
|
| `/sessions/resume` | Resume a different session |
|
|
@@ -355,6 +358,23 @@ pie "summarize this file" --json-output
|
|
|
355
358
|
pie "continue previous task" --session-id my-session
|
|
356
359
|
```
|
|
357
360
|
|
|
361
|
+
### Machine-Readable Output (Agents And Hosts)
|
|
362
|
+
|
|
363
|
+
Every management command (`sessions`, `doctor`, `models`, `extensions`, `permissions`, `capabilities`) emits one compact JSON envelope when given `--json`:
|
|
364
|
+
|
|
365
|
+
```json
|
|
366
|
+
{"v":1,"ok":true,"kind":"sessions.list","data":[...],"meta":{"count":10,"total":42,"nextCursor":"..."},"help":["..."]}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
- `v` is a constant output-schema generation marker; `kind` identifies the command.
|
|
370
|
+
- `meta` carries pagination (`nextCursor`) and aggregates; `help[]` lists concrete next steps when they exist and never duplicates large payloads.
|
|
371
|
+
- Errors are structured on stdout: `{"v":1,"ok":false,"kind":"...","error":{"code":"session_not_found","message":"...","hint":"..."}}`.
|
|
372
|
+
- Exit codes: `0` success, `1` business failure, `2` usage error. Unknown flags fail loudly; every subcommand supports `--help`.
|
|
373
|
+
- `sessions list --json` defaults to the current project (`--all` lists every project). Rows are minimal (`id`, `name`, `updatedAt`, `count`) with `--fields` and `--full` opt-ins; `sessions read` truncates content by default with the same opt-ins.
|
|
374
|
+
- JSONL protocol mode (`--json-events`) identifies entries by `entryId` only (the legacy `checkpointId` alias is gone) and caps large tool results and turn summaries by default; pass `--event-detail full` for untruncated payloads. Truncation always carries `truncated`/`fullLength` markers.
|
|
375
|
+
|
|
376
|
+
Run `pie capabilities --json` to discover the full command surface, flags, and exit-code contract programmatically.
|
|
377
|
+
|
|
358
378
|
## Terminal Notes
|
|
359
379
|
|
|
360
380
|
For the best multiline editing experience, use a terminal with good modified-key support, such as:
|
package/dist/cli.js
CHANGED
|
@@ -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, ""));
|
|
@@ -51847,6 +51855,13 @@ var Editor = class {
|
|
|
51847
51855
|
autocompleteState = null;
|
|
51848
51856
|
autocompletePrefix = "";
|
|
51849
51857
|
autocompleteMaxVisible = 5;
|
|
51858
|
+
/**
|
|
51859
|
+
* Whether the user moved the autocomplete selection (arrows/paging).
|
|
51860
|
+
* A bare "/" + Enter still submits the slash itself (root command menu),
|
|
51861
|
+
* but once the user has actively highlighted an item, Enter must accept
|
|
51862
|
+
* that selection instead of re-opening the same menu.
|
|
51863
|
+
*/
|
|
51864
|
+
autocompleteListTouched = false;
|
|
51850
51865
|
// Paste tracking for large pastes
|
|
51851
51866
|
pastes = /* @__PURE__ */ new Map();
|
|
51852
51867
|
pasteCounter = 0;
|
|
@@ -52083,6 +52098,12 @@ var Editor = class {
|
|
|
52083
52098
|
return;
|
|
52084
52099
|
}
|
|
52085
52100
|
if (kb.matches(data, "selectUp") || kb.matches(data, "selectDown")) {
|
|
52101
|
+
this.autocompleteListTouched = true;
|
|
52102
|
+
this.autocompleteList.handleInput(data);
|
|
52103
|
+
return;
|
|
52104
|
+
}
|
|
52105
|
+
if (kb.matches(data, "cursorLeft") || kb.matches(data, "cursorRight") || kb.matches(data, "pageUp") || kb.matches(data, "pageDown")) {
|
|
52106
|
+
this.autocompleteListTouched = true;
|
|
52086
52107
|
this.autocompleteList.handleInput(data);
|
|
52087
52108
|
return;
|
|
52088
52109
|
}
|
|
@@ -52108,7 +52129,7 @@ var Editor = class {
|
|
|
52108
52129
|
}
|
|
52109
52130
|
if (kb.matches(data, "selectConfirm")) {
|
|
52110
52131
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
52111
|
-
const isBareSlashSubmit = this.state.lines.length === 1 && currentLine === "/" && this.state.cursorCol === 1;
|
|
52132
|
+
const isBareSlashSubmit = !this.autocompleteListTouched && this.state.lines.length === 1 && currentLine === "/" && this.state.cursorCol === 1;
|
|
52112
52133
|
if (isBareSlashSubmit) {
|
|
52113
52134
|
this.cancelAutocomplete();
|
|
52114
52135
|
} else {
|
|
@@ -53128,12 +53149,29 @@ var Editor = class {
|
|
|
53128
53149
|
);
|
|
53129
53150
|
if (suggestions && suggestions.items.length > 0) {
|
|
53130
53151
|
this.autocompletePrefix = suggestions.prefix;
|
|
53131
|
-
this.
|
|
53152
|
+
this.autocompleteListTouched = false;
|
|
53153
|
+
this.autocompleteList = new SelectList(
|
|
53154
|
+
suggestions.items,
|
|
53155
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53156
|
+
this.theme.selectList
|
|
53157
|
+
);
|
|
53132
53158
|
this.autocompleteState = "regular";
|
|
53133
53159
|
} else {
|
|
53134
53160
|
this.cancelAutocomplete();
|
|
53135
53161
|
}
|
|
53136
53162
|
}
|
|
53163
|
+
/**
|
|
53164
|
+
* Visible autocomplete rows, scaled with terminal height so tall screens
|
|
53165
|
+
* show the full command list instead of paginating five rows at a time.
|
|
53166
|
+
* Floor: the configured max (default 5). Ceiling: ~45% of rows, capped at
|
|
53167
|
+
* 20 so a huge terminal never dedicates half the screen to suggestions.
|
|
53168
|
+
*/
|
|
53169
|
+
computeAutocompleteMaxVisible(itemCount) {
|
|
53170
|
+
const rows = this.tui.terminal.rows;
|
|
53171
|
+
const heightScaled = Number.isFinite(rows) ? Math.floor(rows * 0.45) : this.autocompleteMaxVisible;
|
|
53172
|
+
const desired = Math.max(this.autocompleteMaxVisible, Math.min(heightScaled, 20));
|
|
53173
|
+
return Math.max(1, Math.min(desired, Math.max(itemCount, 1)));
|
|
53174
|
+
}
|
|
53137
53175
|
handleTabCompletion() {
|
|
53138
53176
|
if (!this.autocompleteProvider) return;
|
|
53139
53177
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
@@ -53183,7 +53221,12 @@ var Editor = class {
|
|
|
53183
53221
|
return;
|
|
53184
53222
|
}
|
|
53185
53223
|
this.autocompletePrefix = suggestions.prefix;
|
|
53186
|
-
this.
|
|
53224
|
+
this.autocompleteListTouched = false;
|
|
53225
|
+
this.autocompleteList = new SelectList(
|
|
53226
|
+
suggestions.items,
|
|
53227
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53228
|
+
this.theme.selectList
|
|
53229
|
+
);
|
|
53187
53230
|
this.autocompleteState = "force";
|
|
53188
53231
|
} else {
|
|
53189
53232
|
this.cancelAutocomplete();
|
|
@@ -53193,6 +53236,7 @@ var Editor = class {
|
|
|
53193
53236
|
this.autocompleteState = null;
|
|
53194
53237
|
this.autocompleteList = void 0;
|
|
53195
53238
|
this.autocompletePrefix = "";
|
|
53239
|
+
this.autocompleteListTouched = false;
|
|
53196
53240
|
}
|
|
53197
53241
|
isShowingAutocomplete() {
|
|
53198
53242
|
return this.autocompleteState !== null;
|
|
@@ -53210,7 +53254,11 @@ var Editor = class {
|
|
|
53210
53254
|
);
|
|
53211
53255
|
if (suggestions && suggestions.items.length > 0) {
|
|
53212
53256
|
this.autocompletePrefix = suggestions.prefix;
|
|
53213
|
-
this.autocompleteList = new SelectList(
|
|
53257
|
+
this.autocompleteList = new SelectList(
|
|
53258
|
+
suggestions.items,
|
|
53259
|
+
this.computeAutocompleteMaxVisible(suggestions.items.length),
|
|
53260
|
+
this.theme.selectList
|
|
53261
|
+
);
|
|
53214
53262
|
} else {
|
|
53215
53263
|
this.cancelAutocomplete();
|
|
53216
53264
|
}
|
|
@@ -55394,6 +55442,17 @@ var SettingsList = class {
|
|
|
55394
55442
|
item.currentValue = newValue;
|
|
55395
55443
|
}
|
|
55396
55444
|
}
|
|
55445
|
+
/**
|
|
55446
|
+
* Move the selection to an item by id (respects the active filter).
|
|
55447
|
+
* Used when a command targets a specific row (e.g. /settings/theme).
|
|
55448
|
+
*/
|
|
55449
|
+
focusItemById(id) {
|
|
55450
|
+
const displayItems = this.searchEnabled ? this.filteredItems : this.items;
|
|
55451
|
+
const index = displayItems.findIndex((item) => item.id === id);
|
|
55452
|
+
if (index >= 0) {
|
|
55453
|
+
this.selectedIndex = index;
|
|
55454
|
+
}
|
|
55455
|
+
}
|
|
55397
55456
|
invalidate() {
|
|
55398
55457
|
this.submenuComponent?.invalidate?.();
|
|
55399
55458
|
}
|
|
@@ -62341,6 +62400,9 @@ var SettingsSelectorComponent = class extends Container {
|
|
|
62341
62400
|
{ enableSearch: true }
|
|
62342
62401
|
);
|
|
62343
62402
|
this.addChild(this.settingsList);
|
|
62403
|
+
if (config.focusItem) {
|
|
62404
|
+
this.settingsList.focusItemById(config.focusItem);
|
|
62405
|
+
}
|
|
62344
62406
|
}
|
|
62345
62407
|
getSettingsList() {
|
|
62346
62408
|
return this.settingsList;
|
|
@@ -62447,36 +62509,6 @@ function selectRuntimeExtensionWinners(infos) {
|
|
|
62447
62509
|
}
|
|
62448
62510
|
return reversed.reverse();
|
|
62449
62511
|
}
|
|
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
62512
|
function unidentifiedLabel(info) {
|
|
62481
62513
|
const parentName = path23.basename(path23.dirname(info.entryPath));
|
|
62482
62514
|
const fileName = path23.basename(info.entryPath);
|
|
@@ -62497,37 +62529,41 @@ var ExtensionEnablementSelectorComponent = class extends Container {
|
|
|
62497
62529
|
0
|
|
62498
62530
|
));
|
|
62499
62531
|
this.addChild(new Spacer(1));
|
|
62532
|
+
const identityById = /* @__PURE__ */ new Map();
|
|
62533
|
+
const lastPersistedValue = /* @__PURE__ */ new Map();
|
|
62500
62534
|
const items = selectRuntimeExtensionWinners(infos).map((info, index) => {
|
|
62501
62535
|
const identity = info.identity;
|
|
62502
62536
|
const descriptionParts = [`Source: ${info.source}`];
|
|
62503
62537
|
if (info.description) descriptionParts.push(info.description);
|
|
62504
62538
|
if (!identity) descriptionParts.push("No stable identity; this entry is read-only.");
|
|
62539
|
+
const id = identity ?? `unidentified:${index}`;
|
|
62540
|
+
if (identity) {
|
|
62541
|
+
identityById.set(id, identity);
|
|
62542
|
+
lastPersistedValue.set(id, info.enabled ? "on" : "off");
|
|
62543
|
+
}
|
|
62505
62544
|
const item = {
|
|
62506
|
-
id
|
|
62545
|
+
id,
|
|
62507
62546
|
label: identity ?? unidentifiedLabel(info),
|
|
62508
62547
|
description: descriptionParts.join(" \xB7 "),
|
|
62509
62548
|
currentValue: info.enabled ? "on" : "off"
|
|
62510
62549
|
};
|
|
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
|
-
}
|
|
62550
|
+
if (identity) item.values = ["on", "off"];
|
|
62524
62551
|
return item;
|
|
62525
62552
|
});
|
|
62526
62553
|
this.settingsList = new SettingsList(
|
|
62527
62554
|
items,
|
|
62528
62555
|
10,
|
|
62529
62556
|
getSettingsListTheme(),
|
|
62530
|
-
() => {
|
|
62557
|
+
(id, newValue) => {
|
|
62558
|
+
const identity = identityById.get(id);
|
|
62559
|
+
if (!identity) return;
|
|
62560
|
+
const previous = lastPersistedValue.get(id) ?? "on";
|
|
62561
|
+
const accepted = callbacks.onToggle(identity, newValue === "on");
|
|
62562
|
+
if (accepted === false) {
|
|
62563
|
+
this.settingsList.updateValue(id, previous);
|
|
62564
|
+
return;
|
|
62565
|
+
}
|
|
62566
|
+
lastPersistedValue.set(id, newValue);
|
|
62531
62567
|
},
|
|
62532
62568
|
callbacks.onCancel,
|
|
62533
62569
|
{ enableSearch: true }
|
|
@@ -62587,9 +62623,9 @@ function createExtensionSelector(host, scope, onCancel) {
|
|
|
62587
62623
|
return new ExtensionEnablementSelectorComponent(infos, scope, {
|
|
62588
62624
|
onToggle: (identity, enabled) => {
|
|
62589
62625
|
const outcome = trySetExtensionEnabled(host, identity, enabled, scope);
|
|
62590
|
-
if (!outcome) return
|
|
62626
|
+
if (!outcome) return false;
|
|
62591
62627
|
host.showStatus(outcome.message);
|
|
62592
|
-
return
|
|
62628
|
+
return true;
|
|
62593
62629
|
},
|
|
62594
62630
|
onCancel
|
|
62595
62631
|
});
|
|
@@ -62679,16 +62715,21 @@ var BUILTIN_SLASH_COMMANDS = [
|
|
|
62679
62715
|
{ name: "debugs/context", description: "Append a context summary to ~/.pie/logs/pie-cli.log" },
|
|
62680
62716
|
{ name: "debugs/package", description: "Append a package summary to ~/.pie/logs/pie-cli.log" },
|
|
62681
62717
|
{ name: "settings/quit", description: "Exit Pie" },
|
|
62682
|
-
{ name: "skills", description: "
|
|
62683
|
-
{ name: "skills/list", description: "List available skills" },
|
|
62718
|
+
{ name: "skills", description: "Manage skills: list, toggle enable/disable, invoke" },
|
|
62719
|
+
{ name: "skills/list", description: "List available skills (plain text)" },
|
|
62720
|
+
{ name: "skills/create", description: "Create a new skill from a template" },
|
|
62684
62721
|
{ name: "skills/enable", description: "Enable a skill by name" },
|
|
62685
62722
|
{ name: "skills/disable", description: "Disable a skill by name" },
|
|
62686
62723
|
{ name: "skills/reload", description: "Reload skills from disk" },
|
|
62687
62724
|
{ name: "skills/use", description: "Use a skill" },
|
|
62688
62725
|
{ name: "tools", description: "List tools and manage enable/disable toggles" },
|
|
62726
|
+
{ name: "tools/list", description: "List runtime tools and their state (plain text)" },
|
|
62689
62727
|
{ name: "tools/enable", description: "Enable a tool by name" },
|
|
62690
62728
|
{ name: "tools/disable", description: "Disable a tool by name" },
|
|
62691
|
-
{ name: "tools/subagent", description: "Spawn subagents in parallel to handle tasks" }
|
|
62729
|
+
{ name: "tools/subagent", description: "Spawn subagents in parallel to handle tasks" },
|
|
62730
|
+
{ name: "files/upload", description: "Attach a file to the conversation" },
|
|
62731
|
+
{ name: "files/upload-pic", description: "Attach an image to the conversation" },
|
|
62732
|
+
{ name: "files/upload-video", description: "Attach a video to the conversation" }
|
|
62692
62733
|
];
|
|
62693
62734
|
|
|
62694
62735
|
// src/commands/interactive-debug-commands.ts
|
|
@@ -65261,6 +65302,81 @@ function errorMessage2(error) {
|
|
|
65261
65302
|
return error instanceof Error ? error.message : String(error);
|
|
65262
65303
|
}
|
|
65263
65304
|
function handleSkillsCommand(host) {
|
|
65305
|
+
host.showSelector((done) => {
|
|
65306
|
+
const settingsManager = host.options.settingsManager;
|
|
65307
|
+
const discovered = listDiscoveredSkills(host);
|
|
65308
|
+
const items = discovered.map((skill) => ({
|
|
65309
|
+
id: `skill:${skill.name}`,
|
|
65310
|
+
label: skill.name,
|
|
65311
|
+
description: `${skill.description} \xB7 Source: ${skill.source ?? "unknown"}`,
|
|
65312
|
+
currentValue: settingsManager.isSkillEnabled(skill.name) ? "on" : "off",
|
|
65313
|
+
values: ["on", "off"]
|
|
65314
|
+
}));
|
|
65315
|
+
const settingsList = new SettingsList(
|
|
65316
|
+
items,
|
|
65317
|
+
12,
|
|
65318
|
+
{
|
|
65319
|
+
label: (text, selected) => selected ? theme.fg("accent", text) : theme.fg("text", text),
|
|
65320
|
+
value: (text, selected) => selected ? theme.fg("accent", text) : theme.fg("accent", text),
|
|
65321
|
+
description: (text) => theme.fg("muted", text),
|
|
65322
|
+
cursor: "> ",
|
|
65323
|
+
hint: (text) => theme.fg("dim", text)
|
|
65324
|
+
},
|
|
65325
|
+
(id, newValue) => {
|
|
65326
|
+
const name = id.slice("skill:".length);
|
|
65327
|
+
const enabled = newValue === "on";
|
|
65328
|
+
try {
|
|
65329
|
+
settingsManager.setSkillEnabled(name, enabled);
|
|
65330
|
+
} catch (error) {
|
|
65331
|
+
host.showError(`Failed to update skill "${name}": ${errorMessage2(error)}`);
|
|
65332
|
+
return;
|
|
65333
|
+
}
|
|
65334
|
+
applyReloadedSkills(host, discoverSkills(host));
|
|
65335
|
+
host.showStatus(`Skill "${name}" ${enabled ? "enabled" : "disabled"} (reloaded).`);
|
|
65336
|
+
},
|
|
65337
|
+
() => done(),
|
|
65338
|
+
{ enableSearch: true }
|
|
65339
|
+
);
|
|
65340
|
+
const component = {
|
|
65341
|
+
render: (width) => [
|
|
65342
|
+
theme.bold(theme.fg("accent", "Skills")),
|
|
65343
|
+
"",
|
|
65344
|
+
theme.fg("muted", "Enter/Space toggles \xB7 changes apply immediately \xB7 Esc to close"),
|
|
65345
|
+
theme.fg("dim", `Usage: /skills/skill:<name> <your request> (${discovered.length} discovered)`),
|
|
65346
|
+
"",
|
|
65347
|
+
...settingsList.render(width)
|
|
65348
|
+
],
|
|
65349
|
+
handleInput: (data) => settingsList.handleInput(data),
|
|
65350
|
+
invalidate: () => settingsList.invalidate()
|
|
65351
|
+
};
|
|
65352
|
+
return { component, focus: settingsList };
|
|
65353
|
+
});
|
|
65354
|
+
}
|
|
65355
|
+
function discoverSkills(host) {
|
|
65356
|
+
const builtinDir = path25.join(getBuiltinDir(), "skills");
|
|
65357
|
+
const userDir = path25.join(os7.homedir(), ".pie", "skills");
|
|
65358
|
+
const projectDir = path25.join(process.cwd(), ".pie", "skills");
|
|
65359
|
+
return loadSkills({ dirs: buildSkillDirs({ builtinDir, userDir, projectDir, cwd: process.cwd() }) });
|
|
65360
|
+
}
|
|
65361
|
+
function listDiscoveredSkills(host) {
|
|
65362
|
+
return discoverSkills(host).skills;
|
|
65363
|
+
}
|
|
65364
|
+
function applyReloadedSkills(host, result) {
|
|
65365
|
+
host.skills = result.skills.filter((skill) => host.options.settingsManager.isSkillEnabled(skill.name));
|
|
65366
|
+
host.skillsSection = formatSkillsForPrompt(host.skills);
|
|
65367
|
+
host.applyRuntimeToolMode(host.allTools.length > 0 ? host.allTools : host.agent.state.tools);
|
|
65368
|
+
host.updateSystemPromptTools();
|
|
65369
|
+
for (const skill of host.skills) {
|
|
65370
|
+
const skillPath = ["skills", `skill:${skill.name}`];
|
|
65371
|
+
if (!commandTree.find(skillPath)) {
|
|
65372
|
+
commandTree.register(skillPath, {
|
|
65373
|
+
description: skill.description,
|
|
65374
|
+
handler: (_2, args) => host.handleSkillInvoke(skill.name, args || "")
|
|
65375
|
+
});
|
|
65376
|
+
}
|
|
65377
|
+
}
|
|
65378
|
+
}
|
|
65379
|
+
function handleSkillsListCommand(host) {
|
|
65264
65380
|
host.chatContainer.addChild(new Spacer(1));
|
|
65265
65381
|
host.chatContainer.addChild(new Text(theme.bold("Available Skills"), 1, 0));
|
|
65266
65382
|
if (host.skills.length === 0) {
|
|
@@ -65417,7 +65533,12 @@ async function handleSkillToggleCommand(host, args, enabled) {
|
|
|
65417
65533
|
host.ui.requestRender();
|
|
65418
65534
|
}
|
|
65419
65535
|
async function handleSkillsCreate(host, args) {
|
|
65420
|
-
|
|
65536
|
+
const debugLog2 = (message) => {
|
|
65537
|
+
if (process.env.PIE_VERBOSE) {
|
|
65538
|
+
console.error(`[SkillsCreate] ${message}`);
|
|
65539
|
+
}
|
|
65540
|
+
};
|
|
65541
|
+
debugLog2(`Called with args: "${args}"`);
|
|
65421
65542
|
try {
|
|
65422
65543
|
const trimmed = args.trim();
|
|
65423
65544
|
if (!trimmed) {
|
|
@@ -65448,7 +65569,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65448
65569
|
description = descPart.replace(/^["']|["']$/g, "");
|
|
65449
65570
|
}
|
|
65450
65571
|
}
|
|
65451
|
-
|
|
65572
|
+
debugLog2(`Parsed name: "${name}", description: "${description}"`);
|
|
65452
65573
|
if (!name) {
|
|
65453
65574
|
host.showSkillCreatePrompt();
|
|
65454
65575
|
return;
|
|
@@ -65464,7 +65585,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65464
65585
|
const skillsDir = path25.join(os7.homedir(), ".pie", "skills");
|
|
65465
65586
|
const skillDir = path25.join(skillsDir, name);
|
|
65466
65587
|
const skillFile = path25.join(skillDir, "SKILL.md");
|
|
65467
|
-
|
|
65588
|
+
debugLog2(`Creating at: ${skillFile}`);
|
|
65468
65589
|
if (fs23.existsSync(skillDir)) {
|
|
65469
65590
|
host.showError(`Skill "${name}" already exists at ${skillDir}`);
|
|
65470
65591
|
return;
|
|
@@ -65472,7 +65593,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65472
65593
|
fs23.mkdirSync(skillDir, { recursive: true });
|
|
65473
65594
|
const template = createSkillTemplate(name, description);
|
|
65474
65595
|
fs23.writeFileSync(skillFile, template, "utf-8");
|
|
65475
|
-
|
|
65596
|
+
debugLog2("Successfully created skill");
|
|
65476
65597
|
host.chatContainer.addChild(new Spacer(1));
|
|
65477
65598
|
host.chatContainer.addChild(new Text(theme.fg("accent", `\u2713 Created skill: ${name}`), 1, 0));
|
|
65478
65599
|
host.chatContainer.addChild(new Text(theme.fg("dim", ` Location: ${skillFile}`), 1, 0));
|
|
@@ -65481,7 +65602,7 @@ async function handleSkillsCreate(host, args) {
|
|
|
65481
65602
|
host.chatContainer.addChild(new Spacer(1));
|
|
65482
65603
|
host.ui.requestRender();
|
|
65483
65604
|
} catch (err) {
|
|
65484
|
-
|
|
65605
|
+
debugLog2(`Error: ${errorMessage2(err)}`);
|
|
65485
65606
|
host.showError(`Failed to create skill: ${errorMessage2(err)}`);
|
|
65486
65607
|
}
|
|
65487
65608
|
}
|
|
@@ -65556,6 +65677,67 @@ function collectKnownToolNames(host) {
|
|
|
65556
65677
|
const disabled = disabledNames.filter((name) => !liveNames.includes(name));
|
|
65557
65678
|
return { active: [...liveNames].sort(), disabled: [...disabled].sort() };
|
|
65558
65679
|
}
|
|
65680
|
+
function showToolsManager(host) {
|
|
65681
|
+
host.showSelector((done) => {
|
|
65682
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65683
|
+
const settingsManager = host.options.settingsManager;
|
|
65684
|
+
const items = [
|
|
65685
|
+
...active.map((name) => ({
|
|
65686
|
+
id: `tool:${name}`,
|
|
65687
|
+
label: name,
|
|
65688
|
+
description: "Runtime agent tool",
|
|
65689
|
+
currentValue: settingsManager.isToolEnabled(name) ? "on" : "off",
|
|
65690
|
+
values: ["on", "off"]
|
|
65691
|
+
})),
|
|
65692
|
+
...disabled.map((name) => ({
|
|
65693
|
+
id: `tool:${name}`,
|
|
65694
|
+
label: name,
|
|
65695
|
+
description: "Not loaded this session (start with it enabled to use it)",
|
|
65696
|
+
currentValue: "off",
|
|
65697
|
+
values: ["on", "off"]
|
|
65698
|
+
}))
|
|
65699
|
+
];
|
|
65700
|
+
const settingsList = new SettingsList(
|
|
65701
|
+
items,
|
|
65702
|
+
14,
|
|
65703
|
+
getSettingsListTheme(),
|
|
65704
|
+
(_id, newValue) => {
|
|
65705
|
+
const name = _id.slice("tool:".length);
|
|
65706
|
+
const enabled = newValue === "on";
|
|
65707
|
+
try {
|
|
65708
|
+
settingsManager.setToolEnabled(name, enabled);
|
|
65709
|
+
} catch (error) {
|
|
65710
|
+
host.showError(`Failed to update tool "${name}": ${errorMessage3(error)}`);
|
|
65711
|
+
return;
|
|
65712
|
+
}
|
|
65713
|
+
host.applyRuntimeToolMode();
|
|
65714
|
+
host.showStatus(
|
|
65715
|
+
enabled ? `Tool "${name}" enabled (active now).` : `Tool "${name}" disabled (removed from this session).`
|
|
65716
|
+
);
|
|
65717
|
+
},
|
|
65718
|
+
() => done(),
|
|
65719
|
+
{ enableSearch: true }
|
|
65720
|
+
);
|
|
65721
|
+
const component = {
|
|
65722
|
+
render: (width) => [
|
|
65723
|
+
...renderHeader(width),
|
|
65724
|
+
...settingsList.render(width)
|
|
65725
|
+
],
|
|
65726
|
+
handleInput: (data) => settingsList.handleInput(data),
|
|
65727
|
+
invalidate: () => settingsList.invalidate()
|
|
65728
|
+
};
|
|
65729
|
+
return { component, focus: settingsList };
|
|
65730
|
+
});
|
|
65731
|
+
}
|
|
65732
|
+
function renderHeader(width) {
|
|
65733
|
+
const lines = [];
|
|
65734
|
+
lines.push(theme.bold(theme.fg("accent", "Tools")));
|
|
65735
|
+
lines.push("");
|
|
65736
|
+
lines.push(theme.fg("muted", "Enter/Space toggles \xB7 changes apply immediately \xB7 Esc to close"));
|
|
65737
|
+
const hint = "Usage: /tools/enable <name> | /tools/disable <name>";
|
|
65738
|
+
if (width > 20) lines.push(theme.fg("dim", hint));
|
|
65739
|
+
return lines;
|
|
65740
|
+
}
|
|
65559
65741
|
function handleToolsCommand(host, args) {
|
|
65560
65742
|
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
65561
65743
|
const subcommand = parts[0];
|
|
@@ -65565,8 +65747,8 @@ function handleToolsCommand(host, args) {
|
|
|
65565
65747
|
host.showError(`Usage: /tools ${subcommand} <tool-name>`);
|
|
65566
65748
|
return;
|
|
65567
65749
|
}
|
|
65568
|
-
const { active
|
|
65569
|
-
if (!
|
|
65750
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65751
|
+
if (!active.includes(name) && !disabled.includes(name)) {
|
|
65570
65752
|
host.showError(`Tool not found: ${name}. Use /tools to list tool names.`);
|
|
65571
65753
|
return;
|
|
65572
65754
|
}
|
|
@@ -65577,38 +65759,42 @@ function handleToolsCommand(host, args) {
|
|
|
65577
65759
|
host.showError(`Failed to update tool "${name}": ${errorMessage3(error)}`);
|
|
65578
65760
|
return;
|
|
65579
65761
|
}
|
|
65762
|
+
host.applyRuntimeToolMode();
|
|
65580
65763
|
host.chatContainer.addChild(new Spacer(1));
|
|
65581
65764
|
host.chatContainer.addChild(new Text(
|
|
65582
|
-
theme.fg("accent", `Tool "${name}" ${enabled ? "enabled" : "disabled"} in ~/.pie/settings.json
|
|
65765
|
+
theme.fg("accent", `Tool "${name}" ${enabled ? "enabled" : "disabled"} in ~/.pie/settings.json (applied now).`),
|
|
65583
65766
|
1,
|
|
65584
65767
|
0
|
|
65585
65768
|
));
|
|
65586
65769
|
host.ui.requestRender();
|
|
65587
65770
|
return;
|
|
65588
65771
|
}
|
|
65589
|
-
if (subcommand) {
|
|
65590
|
-
|
|
65772
|
+
if (subcommand === "list") {
|
|
65773
|
+
const { active, disabled } = collectKnownToolNames(host);
|
|
65774
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
65775
|
+
host.chatContainer.addChild(new Text(theme.bold("Tools"), 1, 0));
|
|
65776
|
+
if (active.length === 0 && disabled.length === 0) {
|
|
65777
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", " No tools available."), 1, 0));
|
|
65778
|
+
}
|
|
65779
|
+
for (const name of active) {
|
|
65780
|
+
const state = host.options.settingsManager.isToolEnabled(name) ? "enabled" : "disabled (removed from this session)";
|
|
65781
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: ${state}`), 1, 0));
|
|
65782
|
+
}
|
|
65783
|
+
for (const name of disabled) {
|
|
65784
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", ` \u2022 ${name}: disabled (/tools/enable ${name})`), 1, 0));
|
|
65785
|
+
}
|
|
65786
|
+
host.ui.requestRender();
|
|
65591
65787
|
return;
|
|
65592
65788
|
}
|
|
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));
|
|
65789
|
+
if (subcommand) {
|
|
65790
|
+
host.showError("Usage: /tools [list | enable|disable <tool-name>]");
|
|
65791
|
+
return;
|
|
65604
65792
|
}
|
|
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();
|
|
65793
|
+
showToolsManager(host);
|
|
65608
65794
|
}
|
|
65609
65795
|
|
|
65610
65796
|
// src/commands/interactive-command-handlers.ts
|
|
65611
|
-
function showSettingsSelector(host) {
|
|
65797
|
+
function showSettingsSelector(host, focusItem) {
|
|
65612
65798
|
host.showSelector((done) => {
|
|
65613
65799
|
const currentModelId = host.options.model?.id || "unknown";
|
|
65614
65800
|
const currentProvider = host.options.model?.provider || "unknown";
|
|
@@ -65624,7 +65810,8 @@ function showSettingsSelector(host) {
|
|
|
65624
65810
|
yoloMode: host.yoloMode,
|
|
65625
65811
|
calmMode: host.calmMode,
|
|
65626
65812
|
notificationsBell: host.options.settingsManager.getBellNotificationsEnabled(),
|
|
65627
|
-
notificationsDesktop: host.options.settingsManager.getDesktopNotificationsEnabled()
|
|
65813
|
+
notificationsDesktop: host.options.settingsManager.getDesktopNotificationsEnabled(),
|
|
65814
|
+
focusItem
|
|
65628
65815
|
},
|
|
65629
65816
|
{
|
|
65630
65817
|
onThinkingLevelChange: (level) => {
|
|
@@ -66012,7 +66199,19 @@ async function handleClearCommand(host) {
|
|
|
66012
66199
|
host.syncSessionModelMetadata();
|
|
66013
66200
|
host.planModeEnabled = false;
|
|
66014
66201
|
host.pendingPlanModeTransition = null;
|
|
66015
|
-
host.
|
|
66202
|
+
const contextUsage = host.calculateContextUsage();
|
|
66203
|
+
const contextWindow = host.options.model?.contextWindow ?? 0;
|
|
66204
|
+
host.footer.setState({
|
|
66205
|
+
planMode: false,
|
|
66206
|
+
status: "ready",
|
|
66207
|
+
inputTokens: contextUsage.input,
|
|
66208
|
+
outputTokens: contextUsage.output,
|
|
66209
|
+
cacheRead: contextUsage.cacheRead,
|
|
66210
|
+
cacheWrite: contextUsage.cacheWrite,
|
|
66211
|
+
cost: contextUsage.cost,
|
|
66212
|
+
contextPercent: contextWindow > 0 && contextUsage.tokens !== null ? contextUsage.tokens / contextWindow * 100 : 0,
|
|
66213
|
+
contextWindow
|
|
66214
|
+
});
|
|
66016
66215
|
host.updateTerminalTitle();
|
|
66017
66216
|
host.chatContainer.clear();
|
|
66018
66217
|
host.streamingComponent = void 0;
|
|
@@ -66193,7 +66392,7 @@ function registerBuiltinCommands(host) {
|
|
|
66193
66392
|
});
|
|
66194
66393
|
commandTree.register(["settings", "theme"], {
|
|
66195
66394
|
description: "Change theme",
|
|
66196
|
-
handler: () => host.showSettingsSelector()
|
|
66395
|
+
handler: () => host.showSettingsSelector("theme")
|
|
66197
66396
|
});
|
|
66198
66397
|
commandTree.register(["settings", "thinking"], {
|
|
66199
66398
|
description: "Set thinking level (off/minimal/low/medium/high/xhigh)",
|
|
@@ -66223,14 +66422,22 @@ function registerBuiltinCommands(host) {
|
|
|
66223
66422
|
description: "Disable an extension by identity (writes settings)",
|
|
66224
66423
|
handler: (_2, args) => host.handleExtensionsCommand(`disable ${args || ""}`)
|
|
66225
66424
|
});
|
|
66226
|
-
commandTree.register(["skills"
|
|
66227
|
-
description: "
|
|
66425
|
+
commandTree.register(["skills"], {
|
|
66426
|
+
description: "Manage skills: list, toggle enable/disable, invoke",
|
|
66228
66427
|
handler: () => host.handleSkillsCommand()
|
|
66229
66428
|
});
|
|
66429
|
+
commandTree.register(["skills", "list"], {
|
|
66430
|
+
description: "List available skills (plain text)",
|
|
66431
|
+
handler: () => host.handleSkillsListCommand()
|
|
66432
|
+
});
|
|
66230
66433
|
commandTree.register(["skills", "use"], {
|
|
66231
66434
|
description: "Use a skill",
|
|
66232
66435
|
handler: (_2, args) => host.handleSkillCommand(args || "")
|
|
66233
66436
|
});
|
|
66437
|
+
commandTree.register(["skills", "create"], {
|
|
66438
|
+
description: "Create a new skill from a template",
|
|
66439
|
+
handler: (_2, args) => host.handleSkillsCreate(args || "")
|
|
66440
|
+
});
|
|
66234
66441
|
commandTree.register(["skills", "reload"], {
|
|
66235
66442
|
description: "Reload skills from disk",
|
|
66236
66443
|
handler: async () => {
|
|
@@ -66259,12 +66466,16 @@ function registerBuiltinCommands(host) {
|
|
|
66259
66466
|
description: "List runtime tools and manage enable/disable toggles",
|
|
66260
66467
|
handler: (_2, args) => host.handleToolsCommand(args || "")
|
|
66261
66468
|
});
|
|
66469
|
+
commandTree.register(["tools", "list"], {
|
|
66470
|
+
description: "List runtime tools and their state (plain text)",
|
|
66471
|
+
handler: (_2, args) => host.handleToolsCommand(args ? `list ${args}` : "list")
|
|
66472
|
+
});
|
|
66262
66473
|
commandTree.register(["tools", "enable"], {
|
|
66263
|
-
description: "Enable a tool by name (writes settings;
|
|
66474
|
+
description: "Enable a tool by name (writes settings; applies now)",
|
|
66264
66475
|
handler: (_2, args) => host.handleToolsCommand(`enable ${args || ""}`)
|
|
66265
66476
|
});
|
|
66266
66477
|
commandTree.register(["tools", "disable"], {
|
|
66267
|
-
description: "Disable a tool by name (writes settings;
|
|
66478
|
+
description: "Disable a tool by name (writes settings; applies now)",
|
|
66268
66479
|
handler: (_2, args) => host.handleToolsCommand(`disable ${args || ""}`)
|
|
66269
66480
|
});
|
|
66270
66481
|
commandTree.register(["debugs", "cache-test"], {
|
|
@@ -71635,9 +71846,12 @@ var InteractiveMode = class {
|
|
|
71635
71846
|
const rebuilt = this.rebuildSkillAwareTools(completeToolSet);
|
|
71636
71847
|
const currentTools = this.extensionRunner ? wrapToolsWithExtensions(rebuilt.currentTools, this.extensionRunner) : rebuilt.currentTools;
|
|
71637
71848
|
const originalTools = this.extensionRunner ? wrapToolsWithExtensions(rebuilt.originalTools, this.extensionRunner) : rebuilt.originalTools;
|
|
71638
|
-
const activeTools =
|
|
71639
|
-
|
|
71640
|
-
|
|
71849
|
+
const activeTools = filterEnabledTools(
|
|
71850
|
+
selectToolsForRuntimeMode(
|
|
71851
|
+
currentTools,
|
|
71852
|
+
this.planModeEnabled ? "plan" : "normal"
|
|
71853
|
+
),
|
|
71854
|
+
this.options.settingsManager
|
|
71641
71855
|
);
|
|
71642
71856
|
this.agent.setTools(activeTools);
|
|
71643
71857
|
this.allTools = [...currentTools];
|
|
@@ -71648,7 +71862,8 @@ var InteractiveMode = class {
|
|
|
71648
71862
|
planMode: this.planModeEnabled ? "planning" : "off",
|
|
71649
71863
|
filesystemScope: this.yoloMode ? "all" : "workspace",
|
|
71650
71864
|
toolCount: activeTools.length,
|
|
71651
|
-
availableToolCount: currentTools.length
|
|
71865
|
+
availableToolCount: currentTools.length,
|
|
71866
|
+
disabledToolCount: this.options.settingsManager.getDisabledTools().length
|
|
71652
71867
|
});
|
|
71653
71868
|
}
|
|
71654
71869
|
noteRuntimeModeChanged(trigger) {
|
|
@@ -71901,8 +72116,8 @@ var InteractiveMode = class {
|
|
|
71901
72116
|
async selectMentionOption(option) {
|
|
71902
72117
|
return selectMentionOption(this.filePipelineHost, option);
|
|
71903
72118
|
}
|
|
71904
|
-
showSettingsSelector() {
|
|
71905
|
-
return showSettingsSelector(this);
|
|
72119
|
+
showSettingsSelector(focusItem) {
|
|
72120
|
+
return showSettingsSelector(this, focusItem);
|
|
71906
72121
|
}
|
|
71907
72122
|
async handleModelCommand(searchTerm) {
|
|
71908
72123
|
return handleModelCommand(this, searchTerm);
|
|
@@ -72013,6 +72228,9 @@ var InteractiveMode = class {
|
|
|
72013
72228
|
handleSkillsCommand() {
|
|
72014
72229
|
return handleSkillsCommand(this);
|
|
72015
72230
|
}
|
|
72231
|
+
handleSkillsListCommand() {
|
|
72232
|
+
return handleSkillsListCommand(this);
|
|
72233
|
+
}
|
|
72016
72234
|
handleSkillCommand(name) {
|
|
72017
72235
|
return handleSkillCommand(this, name);
|
|
72018
72236
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cydm/pie",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.48",
|
|
4
4
|
"description": "Pie AI Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"test": "npm run test:offline",
|
|
19
19
|
"pretest:offline": "npm run build --workspace @pie/agent-framework && npm run build --workspace @pie/shared-headless-capabilities && npm run build",
|
|
20
20
|
"posttest:offline": "node --test --import tsx test/remote-model-catalog.test.ts",
|
|
21
|
-
"test:offline": "node --test --import tsx test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-extension.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/hierarchical-command-system.test.ts test/extensions-enablement.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/calm-mode.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/daily-agent-smoke.terminal.test.ts",
|
|
21
|
+
"test:offline": "node --test --import tsx test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-extension.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/hierarchical-command-system.test.ts test/extensions-enablement.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/calm-mode.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts",
|
|
22
22
|
"test:all": "npm run test:offline && npm run test:terminal:vitest",
|
|
23
23
|
"test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/viewport-position-final.test.ts test/resume-header.terminal.test.ts --no-file-parallelism",
|
|
24
24
|
"test:todo-tui": "PIE_REAL_TODO_TUI=1 node --test --import tsx test/todo-closure.terminal.test.ts",
|