@cydm/pie 1.0.48 → 1.0.50

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.
Files changed (29) hide show
  1. package/README.md +1 -1
  2. package/dist/builtin/extensions/ask-user/index.js +2 -9
  3. package/dist/builtin/extensions/ask-user/package.json +0 -7
  4. package/dist/builtin/extensions/changelog/index.js +15 -20
  5. package/dist/builtin/extensions/document-attachments/index.js +0 -1
  6. package/dist/builtin/extensions/document-attachments/package.json +1 -1
  7. package/dist/builtin/extensions/init/index.js +0 -13
  8. package/dist/builtin/extensions/plan-mode/index.js +29 -17
  9. package/dist/builtin/extensions/subagent/index.js +15 -31
  10. package/dist/builtin/extensions/todo/index.js +4 -8
  11. package/dist/builtin/skills/skill-creator/SKILL.md +15 -43
  12. package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +1 -1
  13. package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +2 -2
  14. package/dist/builtin/skills/skill-creator/references/schemas.md +1 -1
  15. package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +1 -1
  16. package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +3 -3
  17. package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +32 -4
  18. package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +1 -1
  19. package/dist/chunks/{chunk-IJMP3JTX.js → chunk-DZS34ACX.js} +230 -46
  20. package/dist/chunks/{chunk-U4B6RJ6Z.js → chunk-XBWFDIAU.js} +1 -1
  21. package/dist/cli.js +127 -80
  22. package/package.json +3 -3
  23. package/dist/builtin/extensions/deploy/index.js +0 -11
  24. package/dist/builtin/extensions/deploy/package.json +0 -11
  25. package/dist/builtin/extensions/files/index.js +0 -10
  26. package/dist/builtin/extensions/files/package.json +0 -14
  27. package/dist/builtin/extensions/kimi-attachments/index.js +0 -47
  28. package/dist/builtin/extensions/kimi-attachments/package.json +0 -11
  29. package/dist/builtin/skills/skill-creator/scripts/claude_cli.mjs +0 -115
package/dist/cli.js CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
3
+ import {
4
+ resolveCliProjectRoot
5
+ } from "./chunks/chunk-WLFOBECN.js";
3
6
  import {
4
7
  VERSION,
5
8
  cleanupBashOutputArtifacts,
@@ -19,7 +22,7 @@ import {
19
22
  getThemesDir,
20
23
  migrateConfigFromAgentDir,
21
24
  truncateHeadTail
22
- } from "./chunks/chunk-U4B6RJ6Z.js";
25
+ } from "./chunks/chunk-XBWFDIAU.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-IJMP3JTX.js";
76
+ } from "./chunks/chunk-DZS34ACX.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,
@@ -51855,13 +51855,6 @@ var Editor = class {
51855
51855
  autocompleteState = null;
51856
51856
  autocompletePrefix = "";
51857
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;
51865
51858
  // Paste tracking for large pastes
51866
51859
  pastes = /* @__PURE__ */ new Map();
51867
51860
  pasteCounter = 0;
@@ -52098,12 +52091,10 @@ var Editor = class {
52098
52091
  return;
52099
52092
  }
52100
52093
  if (kb.matches(data, "selectUp") || kb.matches(data, "selectDown")) {
52101
- this.autocompleteListTouched = true;
52102
52094
  this.autocompleteList.handleInput(data);
52103
52095
  return;
52104
52096
  }
52105
52097
  if (kb.matches(data, "cursorLeft") || kb.matches(data, "cursorRight") || kb.matches(data, "pageUp") || kb.matches(data, "pageDown")) {
52106
- this.autocompleteListTouched = true;
52107
52098
  this.autocompleteList.handleInput(data);
52108
52099
  return;
52109
52100
  }
@@ -52128,32 +52119,26 @@ var Editor = class {
52128
52119
  return;
52129
52120
  }
52130
52121
  if (kb.matches(data, "selectConfirm")) {
52131
- const currentLine = this.state.lines[this.state.cursorLine] || "";
52132
- const isBareSlashSubmit = !this.autocompleteListTouched && this.state.lines.length === 1 && currentLine === "/" && this.state.cursorCol === 1;
52133
- if (isBareSlashSubmit) {
52134
- this.cancelAutocomplete();
52135
- } else {
52136
- const selected = this.autocompleteList.getSelectedItem();
52137
- if (selected && this.autocompleteProvider) {
52138
- this.pushUndoSnapshot();
52139
- this.lastAction = null;
52140
- const result = this.autocompleteProvider.applyCompletion(
52141
- this.state.lines,
52142
- this.state.cursorLine,
52143
- this.state.cursorCol,
52144
- selected,
52145
- this.autocompletePrefix
52146
- );
52147
- this.state.lines = result.lines;
52148
- this.state.cursorLine = result.cursorLine;
52149
- this.setCursorCol(result.cursorCol);
52150
- if (this.autocompletePrefix.startsWith("/")) {
52151
- this.cancelAutocomplete();
52152
- } else {
52153
- this.cancelAutocomplete();
52154
- if (this.onChange) this.onChange(this.getText());
52155
- return;
52156
- }
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;
52157
52142
  }
52158
52143
  }
52159
52144
  }
@@ -53149,7 +53134,6 @@ var Editor = class {
53149
53134
  );
53150
53135
  if (suggestions && suggestions.items.length > 0) {
53151
53136
  this.autocompletePrefix = suggestions.prefix;
53152
- this.autocompleteListTouched = false;
53153
53137
  this.autocompleteList = new SelectList(
53154
53138
  suggestions.items,
53155
53139
  this.computeAutocompleteMaxVisible(suggestions.items.length),
@@ -53221,7 +53205,6 @@ var Editor = class {
53221
53205
  return;
53222
53206
  }
53223
53207
  this.autocompletePrefix = suggestions.prefix;
53224
- this.autocompleteListTouched = false;
53225
53208
  this.autocompleteList = new SelectList(
53226
53209
  suggestions.items,
53227
53210
  this.computeAutocompleteMaxVisible(suggestions.items.length),
@@ -53236,7 +53219,6 @@ var Editor = class {
53236
53219
  this.autocompleteState = null;
53237
53220
  this.autocompleteList = void 0;
53238
53221
  this.autocompletePrefix = "";
53239
- this.autocompleteListTouched = false;
53240
53222
  }
53241
53223
  isShowingAutocomplete() {
53242
53224
  return this.autocompleteState !== null;
@@ -62729,7 +62711,12 @@ var BUILTIN_SLASH_COMMANDS = [
62729
62711
  { name: "tools/subagent", description: "Spawn subagents in parallel to handle tasks" },
62730
62712
  { name: "files/upload", description: "Attach a file to the conversation" },
62731
62713
  { name: "files/upload-pic", description: "Attach an image to the conversation" },
62732
- { name: "files/upload-video", description: "Attach a video 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" }
62733
62720
  ];
62734
62721
 
62735
62722
  // src/commands/interactive-debug-commands.ts
@@ -65305,6 +65292,7 @@ function handleSkillsCommand(host) {
65305
65292
  host.showSelector((done) => {
65306
65293
  const settingsManager = host.options.settingsManager;
65307
65294
  const discovered = listDiscoveredSkills(host);
65295
+ const lastPersisted = /* @__PURE__ */ new Map();
65308
65296
  const items = discovered.map((skill) => ({
65309
65297
  id: `skill:${skill.name}`,
65310
65298
  label: skill.name,
@@ -65312,25 +65300,23 @@ function handleSkillsCommand(host) {
65312
65300
  currentValue: settingsManager.isSkillEnabled(skill.name) ? "on" : "off",
65313
65301
  values: ["on", "off"]
65314
65302
  }));
65303
+ for (const item of items) lastPersisted.set(item.id, item.currentValue);
65315
65304
  const settingsList = new SettingsList(
65316
65305
  items,
65317
65306
  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
- },
65307
+ getSettingsListTheme(),
65325
65308
  (id, newValue) => {
65326
65309
  const name = id.slice("skill:".length);
65327
65310
  const enabled = newValue === "on";
65311
+ const previous = lastPersisted.get(id) ?? "on";
65328
65312
  try {
65329
65313
  settingsManager.setSkillEnabled(name, enabled);
65330
65314
  } catch (error) {
65315
+ settingsList.updateValue(id, previous);
65331
65316
  host.showError(`Failed to update skill "${name}": ${errorMessage2(error)}`);
65332
65317
  return;
65333
65318
  }
65319
+ lastPersisted.set(id, newValue);
65334
65320
  applyReloadedSkills(host, discoverSkills(host));
65335
65321
  host.showStatus(`Skill "${name}" ${enabled ? "enabled" : "disabled"} (reloaded).`);
65336
65322
  },
@@ -65628,23 +65614,8 @@ async function handleSkillsReload(host) {
65628
65614
  host.chatContainer.addChild(new Text(theme.fg("accent", "Reloading skills..."), 1, 0));
65629
65615
  host.ui.requestRender();
65630
65616
  try {
65631
- const builtinDir = path25.join(getBuiltinDir(), "skills");
65632
- const userDir = path25.join(os7.homedir(), ".pie", "skills");
65633
- const projectDir = path25.join(process.cwd(), ".pie", "skills");
65634
- const result = loadSkills({ dirs: buildSkillDirs({ builtinDir, userDir, projectDir, cwd: process.cwd() }) });
65635
- host.skills = result.skills.filter((skill) => host.options.settingsManager.isSkillEnabled(skill.name));
65636
- host.skillsSection = formatSkillsForPrompt(host.skills);
65637
- host.applyRuntimeToolMode(host.allTools.length > 0 ? host.allTools : host.agent.state.tools);
65638
- host.updateSystemPromptTools();
65639
- for (const skill of host.skills) {
65640
- const skillPath = ["skills", `skill:${skill.name}`];
65641
- if (!commandTree.find(skillPath)) {
65642
- commandTree.register(skillPath, {
65643
- description: skill.description,
65644
- handler: (_2, args) => host.handleSkillInvoke(skill.name, args || "")
65645
- });
65646
- }
65647
- }
65617
+ const result = discoverSkills(host);
65618
+ applyReloadedSkills(host, result);
65648
65619
  const builtinCount = host.skills.filter((s) => s.source === "builtin").length;
65649
65620
  const userCount = host.skills.filter((s) => s.source === "user" || s.source === "user-agents").length;
65650
65621
  const projectCount = host.skills.filter((s) => s.source === "project" || s.source === "project-agents").length;
@@ -65677,10 +65648,18 @@ function collectKnownToolNames(host) {
65677
65648
  const disabled = disabledNames.filter((name) => !liveNames.includes(name));
65678
65649
  return { active: [...liveNames].sort(), disabled: [...disabled].sort() };
65679
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
+ }
65680
65658
  function showToolsManager(host) {
65681
65659
  host.showSelector((done) => {
65682
65660
  const { active, disabled } = collectKnownToolNames(host);
65683
65661
  const settingsManager = host.options.settingsManager;
65662
+ const lastPersisted = /* @__PURE__ */ new Map();
65684
65663
  const items = [
65685
65664
  ...active.map((name) => ({
65686
65665
  id: `tool:${name}`,
@@ -65692,28 +65671,30 @@ function showToolsManager(host) {
65692
65671
  ...disabled.map((name) => ({
65693
65672
  id: `tool:${name}`,
65694
65673
  label: name,
65695
- description: "Not loaded this session (start with it enabled to use it)",
65674
+ description: "Not loaded this session (starts enabled next launch)",
65696
65675
  currentValue: "off",
65697
65676
  values: ["on", "off"]
65698
65677
  }))
65699
65678
  ];
65679
+ for (const item of items) lastPersisted.set(item.id, item.currentValue);
65700
65680
  const settingsList = new SettingsList(
65701
65681
  items,
65702
65682
  14,
65703
65683
  getSettingsListTheme(),
65704
- (_id, newValue) => {
65705
- const name = _id.slice("tool:".length);
65684
+ (id, newValue) => {
65685
+ const name = id.slice("tool:".length);
65706
65686
  const enabled = newValue === "on";
65687
+ const previous = lastPersisted.get(id) ?? "off";
65707
65688
  try {
65708
65689
  settingsManager.setToolEnabled(name, enabled);
65709
65690
  } catch (error) {
65691
+ settingsList.updateValue(id, previous);
65710
65692
  host.showError(`Failed to update tool "${name}": ${errorMessage3(error)}`);
65711
65693
  return;
65712
65694
  }
65695
+ lastPersisted.set(id, newValue);
65713
65696
  host.applyRuntimeToolMode();
65714
- host.showStatus(
65715
- enabled ? `Tool "${name}" enabled (active now).` : `Tool "${name}" disabled (removed from this session).`
65716
- );
65697
+ host.showStatus(describeToggleEffect(host, name, enabled));
65717
65698
  },
65718
65699
  () => done(),
65719
65700
  { enableSearch: true }
@@ -65733,7 +65714,7 @@ function renderHeader(width) {
65733
65714
  const lines = [];
65734
65715
  lines.push(theme.bold(theme.fg("accent", "Tools")));
65735
65716
  lines.push("");
65736
- lines.push(theme.fg("muted", "Enter/Space toggles \xB7 changes apply immediately \xB7 Esc to close"));
65717
+ lines.push(theme.fg("muted", "Enter/Space toggles \xB7 live tools apply immediately \xB7 Esc to close"));
65737
65718
  const hint = "Usage: /tools/enable <name> | /tools/disable <name>";
65738
65719
  if (width > 20) lines.push(theme.fg("dim", hint));
65739
65720
  return lines;
@@ -65762,7 +65743,7 @@ function handleToolsCommand(host, args) {
65762
65743
  host.applyRuntimeToolMode();
65763
65744
  host.chatContainer.addChild(new Spacer(1));
65764
65745
  host.chatContainer.addChild(new Text(
65765
- theme.fg("accent", `Tool "${name}" ${enabled ? "enabled" : "disabled"} in ~/.pie/settings.json (applied now).`),
65746
+ theme.fg("accent", describeToggleEffect(host, name, enabled)),
65766
65747
  1,
65767
65748
  0
65768
65749
  ));
@@ -66471,7 +66452,7 @@ function registerBuiltinCommands(host) {
66471
66452
  handler: (_2, args) => host.handleToolsCommand(args ? `list ${args}` : "list")
66472
66453
  });
66473
66454
  commandTree.register(["tools", "enable"], {
66474
- description: "Enable a tool by name (writes settings; applies now)",
66455
+ description: "Enable a tool by name (writes settings; live tools apply now)",
66475
66456
  handler: (_2, args) => host.handleToolsCommand(`enable ${args || ""}`)
66476
66457
  });
66477
66458
  commandTree.register(["tools", "disable"], {
@@ -66633,6 +66614,7 @@ function ringTerminalBell(options = {}) {
66633
66614
  function ringTurnSettledBell(host) {
66634
66615
  if ((host.agentSessionController?.pendingMessageCount ?? 0) > 0) return;
66635
66616
  if (host.executionState.read().awaitingContinuation) return;
66617
+ if (host.peekTodoAutoContinuePrompt?.()) return;
66636
66618
  host.ringAttentionBell?.("turn-settled");
66637
66619
  }
66638
66620
  function attentionMessage(reason) {
@@ -70275,12 +70257,19 @@ function clearContinuationTimeout(host, reason) {
70275
70257
  function isWaitingForUserInteraction(host) {
70276
70258
  return host.activeInteractionCount > 0;
70277
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
+ }
70278
70267
  function getTodoAutoContinueMessage(host) {
70268
+ const prompt = peekTodoAutoContinuePrompt(host);
70279
70269
  if (isWaitingForUserInteraction(host)) return { reason: "waiting_for_user_interaction" };
70280
70270
  if (host.submitLock || host.isProcessing || host.isInterrupting || host.isCompacting) return { reason: "host_busy" };
70281
70271
  const hasTodoTool = (host.agent?.state?.tools ?? []).some((tool) => tool.name === "manage_todo_list");
70282
70272
  if (!hasTodoTool) return { reason: "todo_tool_unavailable" };
70283
- const prompt = host.executionState.takeTodoClosureFollowUp();
70284
70273
  if (!prompt) return { reason: "no_active_todo_follow_up" };
70285
70274
  host.logDebug("todo_closure:follow_up", {
70286
70275
  textPreview: prompt.slice(0, 120),
@@ -71317,11 +71306,14 @@ async function restoreExtensionProviderCredentials(modelRegistry) {
71317
71306
  }
71318
71307
 
71319
71308
  // src/attachments/resolver.ts
71309
+ var PROVIDER_SOURCE = "(provider)";
71320
71310
  var AttachmentResolver = class {
71321
- constructor(extensions) {
71311
+ constructor(extensions, builtInHandlers = []) {
71322
71312
  this.extensions = extensions;
71313
+ this.builtInHandlers = builtInHandlers;
71323
71314
  }
71324
71315
  extensions;
71316
+ builtInHandlers;
71325
71317
  findHandler(model, attachment) {
71326
71318
  const candidate = this.collectCandidates(model, attachment)[0];
71327
71319
  if (!candidate) return void 0;
@@ -71346,6 +71338,15 @@ var AttachmentResolver = class {
71346
71338
  }
71347
71339
  collectCandidates(model, attachment) {
71348
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
+ }
71349
71350
  for (const extension of this.extensions) {
71350
71351
  for (const handler of extension.attachmentHandlers.values()) {
71351
71352
  if (!handler.matches(model, attachment)) continue;
@@ -71368,6 +71369,48 @@ var AttachmentResolver = class {
71368
71369
  }
71369
71370
  };
71370
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
+
71371
71414
  // src/app/runtime-composition-pipeline.ts
71372
71415
  var CLI_COMPOSITION_STEP_ORDER = [
71373
71416
  "model_config",
@@ -71518,7 +71561,7 @@ async function loadInteractiveExtensions(host) {
71518
71561
  buildExtensionLoadOptions(host.options.settingsManager, host.options.extensionFlags)
71519
71562
  );
71520
71563
  host.extensions = extensions;
71521
- host.attachmentResolver = new AttachmentResolver(extensions);
71564
+ host.attachmentResolver = new AttachmentResolver(extensions, providerAttachmentHandlers);
71522
71565
  host.extensionRunner = new ExtensionRunner(
71523
71566
  extensions,
71524
71567
  extensionActions,
@@ -71690,6 +71733,10 @@ var InteractiveMode = class {
71690
71733
  getTodoAutoContinueMessage() {
71691
71734
  return getTodoAutoContinueMessage(this.continuationHost);
71692
71735
  }
71736
+ /** Side-effect-free todo auto-continue prediction for the turn-settled bell. */
71737
+ peekTodoAutoContinuePrompt() {
71738
+ return peekTodoAutoContinuePrompt(this.continuationHost);
71739
+ }
71693
71740
  appendWarningSummary(message) {
71694
71741
  return appendWarningSummary(this.continuationHost, message);
71695
71742
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,9 +18,9 @@
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/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts",
21
+ "test:offline": "node --test --import tsx test/builtin-extensions.test.ts 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-provider.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 test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts",
22
22
  "test:all": "npm run test:offline && npm run test:terminal:vitest",
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",
23
+ "test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/footer-plan-mode.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",
25
25
  "test:daily-tui": "npm run test:daily-tui:quick",
26
26
  "test:daily-tui:quick": "PIE_REAL_DAILY_TUI=1 PIE_DAILY_TUI_LEVEL=quick node --test --import tsx test/daily-agent-smoke.terminal.test.ts",
@@ -1,11 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import "../../../chunks/chunk-LZQXQOPJ.js";
3
-
4
- // builtin/extensions/deploy/index.ts
5
- function deployExtension(ctx) {
6
- ctx.log("Deploy extension loaded");
7
- ctx.log("Deploy extension ready");
8
- }
9
- export {
10
- deployExtension as default
11
- };
@@ -1,11 +0,0 @@
1
- {
2
- "name": "@pie/extension-deploy",
3
- "version": "1.0.0",
4
- "description": "Deployment assistance commands",
5
- "main": "index.ts",
6
- "type": "module",
7
- "pie": {
8
- "name": "deploy",
9
- "main": "index.ts"
10
- }
11
- }
@@ -1,10 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import "../../../chunks/chunk-LZQXQOPJ.js";
3
-
4
- // builtin/extensions/files/index.ts
5
- function filesExtension(ctx) {
6
- ctx.log("Files extension loaded");
7
- }
8
- export {
9
- filesExtension as default
10
- };
@@ -1,14 +0,0 @@
1
- {
2
- "name": "@pie/extension-files",
3
- "version": "1.0.0",
4
- "description": "File browser with git status support",
5
- "main": "index.ts",
6
- "type": "module",
7
- "pie": {
8
- "name": "files",
9
- "main": "index.ts"
10
- },
11
- "keywords": ["pie", "extension", "files", "git"],
12
- "author": "Pie Team",
13
- "license": "MIT"
14
- }
@@ -1,47 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import "../../../chunks/chunk-LZQXQOPJ.js";
3
-
4
- // builtin/extensions/kimi-attachments/index.ts
5
- function isKimiAttachmentPlatform(model) {
6
- return model.attachmentPlatform === "kimi" || model.filePlatform === "kimi";
7
- }
8
- function getModality(mimeType) {
9
- if (mimeType.startsWith("image/")) return "image";
10
- if (mimeType.startsWith("video/")) return "video";
11
- return "file";
12
- }
13
- function kimiAttachmentsExtension(ctx) {
14
- ctx.log("Kimi attachment extension loaded");
15
- ctx.registerAttachmentHandler({
16
- name: "kimi-native-attachments",
17
- priority: 100,
18
- matches(model, attachment) {
19
- return isKimiAttachmentPlatform(model) && Boolean(attachment.fileId) && getModality(attachment.mimeType) !== "file";
20
- },
21
- async prepare(_model, attachment, prepareCtx) {
22
- const fileId = attachment.fileId;
23
- if (!fileId) {
24
- return {
25
- items: [{ type: "text", text: `[${attachment.id}]` }],
26
- warnings: ["\u9644\u4EF6\u7F3A\u5C11 fileId\uFF0C\u65E0\u6CD5\u8D70 Kimi \u539F\u751F\u5F15\u7528"]
27
- };
28
- }
29
- const modality = getModality(attachment.mimeType);
30
- const url = `ms://${fileId}`;
31
- prepareCtx.log(`Kimi handler prepared ${modality} reference for ${attachment.id}`);
32
- return {
33
- items: [
34
- {
35
- type: "file-ref",
36
- mimeType: attachment.mimeType,
37
- url,
38
- modality
39
- }
40
- ]
41
- };
42
- }
43
- });
44
- }
45
- export {
46
- kimiAttachmentsExtension as default
47
- };
@@ -1,11 +0,0 @@
1
- {
2
- "name": "@pie/extension-kimi-attachments",
3
- "version": "1.0.0",
4
- "description": "Kimi file upload attachment handlers",
5
- "main": "index.ts",
6
- "type": "module",
7
- "pie": {
8
- "name": "kimi-attachments",
9
- "main": "index.ts"
10
- }
11
- }