@hyperspaceng/neural-coding-agent 0.63.0 → 0.64.1

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 (124) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +3 -3
  3. package/dist/core/agent-session.d.ts +14 -6
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +111 -54
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/auth-storage.d.ts +3 -1
  8. package/dist/core/auth-storage.d.ts.map +1 -1
  9. package/dist/core/auth-storage.js +5 -2
  10. package/dist/core/auth-storage.js.map +1 -1
  11. package/dist/core/compaction/branch-summarization.d.ts +2 -0
  12. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  13. package/dist/core/compaction/branch-summarization.js +2 -2
  14. package/dist/core/compaction/branch-summarization.js.map +1 -1
  15. package/dist/core/compaction/compaction.d.ts +3 -3
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +27 -26
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/export-html/index.d.ts.map +1 -1
  20. package/dist/core/export-html/index.js +5 -4
  21. package/dist/core/export-html/index.js.map +1 -1
  22. package/dist/core/extensions/runner.d.ts +1 -0
  23. package/dist/core/extensions/runner.d.ts.map +1 -1
  24. package/dist/core/extensions/runner.js +4 -0
  25. package/dist/core/extensions/runner.js.map +1 -1
  26. package/dist/core/extensions/types.d.ts +14 -1
  27. package/dist/core/extensions/types.d.ts.map +1 -1
  28. package/dist/core/extensions/types.js.map +1 -1
  29. package/dist/core/model-registry.d.ts +21 -3
  30. package/dist/core/model-registry.d.ts.map +1 -1
  31. package/dist/core/model-registry.js +90 -70
  32. package/dist/core/model-registry.js.map +1 -1
  33. package/dist/core/model-resolver.d.ts.map +1 -1
  34. package/dist/core/model-resolver.js +4 -4
  35. package/dist/core/model-resolver.js.map +1 -1
  36. package/dist/core/package-manager.d.ts.map +1 -1
  37. package/dist/core/package-manager.js +88 -24
  38. package/dist/core/package-manager.js.map +1 -1
  39. package/dist/core/resolve-config-value.d.ts +6 -0
  40. package/dist/core/resolve-config-value.d.ts.map +1 -1
  41. package/dist/core/resolve-config-value.js +37 -5
  42. package/dist/core/resolve-config-value.js.map +1 -1
  43. package/dist/core/sdk.d.ts +2 -2
  44. package/dist/core/sdk.d.ts.map +1 -1
  45. package/dist/core/sdk.js +14 -23
  46. package/dist/core/sdk.js.map +1 -1
  47. package/dist/core/settings-manager.d.ts +2 -0
  48. package/dist/core/settings-manager.d.ts.map +1 -1
  49. package/dist/core/settings-manager.js +3 -0
  50. package/dist/core/settings-manager.js.map +1 -1
  51. package/dist/core/timings.d.ts +1 -0
  52. package/dist/core/timings.d.ts.map +1 -1
  53. package/dist/core/timings.js +6 -0
  54. package/dist/core/timings.js.map +1 -1
  55. package/dist/core/tools/edit-diff.d.ts +23 -1
  56. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  57. package/dist/core/tools/edit-diff.js +150 -57
  58. package/dist/core/tools/edit-diff.js.map +1 -1
  59. package/dist/core/tools/edit.d.ts +13 -11
  60. package/dist/core/tools/edit.d.ts.map +1 -1
  61. package/dist/core/tools/edit.js +55 -77
  62. package/dist/core/tools/edit.js.map +1 -1
  63. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  64. package/dist/core/tools/file-mutation-queue.js +4 -4
  65. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  66. package/dist/core/tools/index.d.ts +9 -6
  67. package/dist/core/tools/index.d.ts.map +1 -1
  68. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  69. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  70. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  71. package/dist/main.d.ts.map +1 -1
  72. package/dist/main.js +29 -11
  73. package/dist/main.js.map +1 -1
  74. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  75. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  76. package/dist/modes/interactive/components/assistant-message.js +14 -3
  77. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  78. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  79. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  80. package/dist/modes/interactive/components/bash-execution.js +18 -5
  81. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  82. package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  83. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  84. package/dist/modes/interactive/components/tool-execution.js +2 -7
  85. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  86. package/dist/modes/interactive/interactive-mode.d.ts +3 -1
  87. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  88. package/dist/modes/interactive/interactive-mode.js +51 -67
  89. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  90. package/dist/modes/print-mode.d.ts +1 -1
  91. package/dist/modes/print-mode.d.ts.map +1 -1
  92. package/dist/modes/print-mode.js +83 -71
  93. package/dist/modes/print-mode.js.map +1 -1
  94. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  95. package/dist/modes/rpc/rpc-mode.js +3 -0
  96. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  97. package/docs/compaction.md +4 -2
  98. package/docs/development.md +3 -1
  99. package/docs/extensions.md +107 -2
  100. package/docs/json.md +5 -2
  101. package/docs/models.md +6 -0
  102. package/docs/rpc.md +32 -9
  103. package/docs/sdk.md +12 -9
  104. package/docs/settings.md +12 -0
  105. package/docs/skills.md +3 -2
  106. package/examples/extensions/README.md +1 -0
  107. package/examples/extensions/custom-compaction.ts +17 -4
  108. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  109. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  110. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  111. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  112. package/examples/extensions/handoff.ts +5 -2
  113. package/examples/extensions/hidden-thinking-label.ts +57 -0
  114. package/examples/extensions/qna.ts +5 -2
  115. package/examples/extensions/sandbox/index.ts +4 -0
  116. package/examples/extensions/summarize.ts +15 -4
  117. package/examples/extensions/trigger-compact.ts +11 -1
  118. package/examples/extensions/with-deps/package-lock.json +2 -2
  119. package/examples/extensions/with-deps/package.json +1 -1
  120. package/examples/sdk/02-custom-model.ts +1 -1
  121. package/examples/sdk/09-api-keys-and-oauth.ts +3 -3
  122. package/examples/sdk/12-full-control.ts +1 -1
  123. package/examples/sdk/README.md +3 -3
  124. package/package.json +5 -4
@@ -74,6 +74,8 @@ export class InteractiveMode {
74
74
  loadingAnimation = undefined;
75
75
  pendingWorkingMessage = undefined;
76
76
  defaultWorkingMessage = "Working...";
77
+ defaultHiddenThinkingLabel = "Thinking...";
78
+ hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
77
79
  lastSigintTime = 0;
78
80
  lastEscapeTime = 0;
79
81
  changelogMarkdown = undefined;
@@ -312,7 +314,8 @@ export class InteractiveMode {
312
314
  hint("app.clipboard.pasteImage", "to paste image"),
313
315
  rawKeyHint("drop files", "to attach"),
314
316
  ].join("\n");
315
- this.builtInHeader = new Text(`${logo}\n${instructions}`, 1, 0);
317
+ const onboarding = theme.fg("dim", `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`);
318
+ this.builtInHeader = new Text(`${logo}\n${instructions}\n\n${onboarding}`, 1, 0);
316
319
  // Setup UI layout
317
320
  this.headerContainer.addChild(new Spacer(1));
318
321
  this.headerContainer.addChild(this.builtInHeader);
@@ -990,6 +993,7 @@ export class InteractiveMode {
990
993
  modelRegistry: this.session.modelRegistry,
991
994
  model: this.session.model,
992
995
  isIdle: () => !this.session.isStreaming,
996
+ signal: this.session.agent.signal,
993
997
  abort: () => this.session.abort(),
994
998
  hasPendingMessages: () => this.session.pendingMessageCount > 0,
995
999
  shutdown: () => {
@@ -999,10 +1003,8 @@ export class InteractiveMode {
999
1003
  compact: (options) => {
1000
1004
  void (async () => {
1001
1005
  try {
1002
- const result = await this.executeCompaction(options?.customInstructions, false);
1003
- if (result) {
1004
- options?.onComplete?.(result);
1005
- }
1006
+ const result = await this.session.compact(options?.customInstructions);
1007
+ options?.onComplete?.(result);
1006
1008
  }
1007
1009
  catch (error) {
1008
1010
  const err = error instanceof Error ? error : new Error(String(error));
@@ -1034,6 +1036,18 @@ export class InteractiveMode {
1034
1036
  this.footerDataProvider.setExtensionStatus(key, text);
1035
1037
  this.ui.requestRender();
1036
1038
  }
1039
+ setHiddenThinkingLabel(label) {
1040
+ this.hiddenThinkingLabel = label ?? this.defaultHiddenThinkingLabel;
1041
+ for (const child of this.chatContainer.children) {
1042
+ if (child instanceof AssistantMessageComponent) {
1043
+ child.setHiddenThinkingLabel(this.hiddenThinkingLabel);
1044
+ }
1045
+ }
1046
+ if (this.streamingComponent) {
1047
+ this.streamingComponent.setHiddenThinkingLabel(this.hiddenThinkingLabel);
1048
+ }
1049
+ this.ui.requestRender();
1050
+ }
1037
1051
  /**
1038
1052
  * Set an extension widget (string array or custom component).
1039
1053
  */
@@ -1105,6 +1119,7 @@ export class InteractiveMode {
1105
1119
  if (this.loadingAnimation) {
1106
1120
  this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`);
1107
1121
  }
1122
+ this.setHiddenThinkingLabel();
1108
1123
  }
1109
1124
  // Maximum total widget lines to prevent viewport overflow
1110
1125
  static MAX_WIDGET_LINES = 10;
@@ -1234,6 +1249,7 @@ export class InteractiveMode {
1234
1249
  this.pendingWorkingMessage = message;
1235
1250
  }
1236
1251
  },
1252
+ setHiddenThinkingLabel: (label) => this.setHiddenThinkingLabel(label),
1237
1253
  setWidget: (key, content, options) => this.setExtensionWidget(key, content, options),
1238
1254
  setFooter: (factory) => this.setExtensionFooter(factory),
1239
1255
  setHeader: (factory) => this.setExtensionHeader(factory),
@@ -1837,6 +1853,10 @@ export class InteractiveMode {
1837
1853
  }
1838
1854
  this.ui.requestRender();
1839
1855
  break;
1856
+ case "queue_update":
1857
+ this.updatePendingMessagesDisplay();
1858
+ this.ui.requestRender();
1859
+ break;
1840
1860
  case "message_start":
1841
1861
  if (event.message.role === "custom") {
1842
1862
  this.addMessageToChat(event.message);
@@ -1848,7 +1868,7 @@ export class InteractiveMode {
1848
1868
  this.ui.requestRender();
1849
1869
  }
1850
1870
  else if (event.message.role === "assistant") {
1851
- this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings());
1871
+ this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel);
1852
1872
  this.streamingMessage = event.message;
1853
1873
  this.chatContainer.addChild(this.streamingComponent);
1854
1874
  this.streamingComponent.updateContent(this.streamingMessage);
@@ -1965,54 +1985,54 @@ export class InteractiveMode {
1965
1985
  await this.checkShutdownRequested();
1966
1986
  this.ui.requestRender();
1967
1987
  break;
1968
- case "auto_compaction_start": {
1988
+ case "compaction_start": {
1969
1989
  // Keep editor active; submissions are queued during compaction.
1970
- // Set up escape to abort auto-compaction
1971
1990
  this.autoCompactionEscapeHandler = this.defaultEditor.onEscape;
1972
1991
  this.defaultEditor.onEscape = () => {
1973
1992
  this.session.abortCompaction();
1974
1993
  };
1975
- // Show compacting indicator with reason
1976
1994
  this.statusContainer.clear();
1977
- const reasonText = event.reason === "overflow" ? "Context overflow detected, " : "";
1978
- this.autoCompactionLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), `${reasonText}Auto-compacting... (${keyText("app.interrupt")} to cancel)`);
1995
+ const cancelHint = `(${keyText("app.interrupt")} to cancel)`;
1996
+ const label = event.reason === "manual"
1997
+ ? `Compacting context... ${cancelHint}`
1998
+ : `${event.reason === "overflow" ? "Context overflow detected, " : ""}Auto-compacting... ${cancelHint}`;
1999
+ this.autoCompactionLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), label);
1979
2000
  this.statusContainer.addChild(this.autoCompactionLoader);
1980
2001
  this.ui.requestRender();
1981
2002
  break;
1982
2003
  }
1983
- case "auto_compaction_end": {
1984
- // Restore escape handler
2004
+ case "compaction_end": {
1985
2005
  if (this.autoCompactionEscapeHandler) {
1986
2006
  this.defaultEditor.onEscape = this.autoCompactionEscapeHandler;
1987
2007
  this.autoCompactionEscapeHandler = undefined;
1988
2008
  }
1989
- // Stop loader
1990
2009
  if (this.autoCompactionLoader) {
1991
2010
  this.autoCompactionLoader.stop();
1992
2011
  this.autoCompactionLoader = undefined;
1993
2012
  this.statusContainer.clear();
1994
2013
  }
1995
- // Handle result
1996
2014
  if (event.aborted) {
1997
- this.showStatus("Auto-compaction cancelled");
2015
+ if (event.reason === "manual") {
2016
+ this.showError("Compaction cancelled");
2017
+ }
2018
+ else {
2019
+ this.showStatus("Auto-compaction cancelled");
2020
+ }
1998
2021
  }
1999
2022
  else if (event.result) {
2000
- // Rebuild chat to show compacted state
2001
2023
  this.chatContainer.clear();
2002
2024
  this.rebuildChatFromMessages();
2003
- // Add compaction component at bottom so user sees it without scrolling
2004
- this.addMessageToChat({
2005
- role: "compactionSummary",
2006
- tokensBefore: event.result.tokensBefore,
2007
- summary: event.result.summary,
2008
- timestamp: Date.now(),
2009
- });
2025
+ this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
2010
2026
  this.footer.invalidate();
2011
2027
  }
2012
2028
  else if (event.errorMessage) {
2013
- // Compaction failed (e.g., quota exceeded, API error)
2014
- this.chatContainer.addChild(new Spacer(1));
2015
- this.chatContainer.addChild(new Text(theme.fg("error", event.errorMessage), 1, 0));
2029
+ if (event.reason === "manual") {
2030
+ this.showError(event.errorMessage);
2031
+ }
2032
+ else {
2033
+ this.chatContainer.addChild(new Spacer(1));
2034
+ this.chatContainer.addChild(new Text(theme.fg("error", event.errorMessage), 1, 0));
2035
+ }
2016
2036
  }
2017
2037
  void this.flushCompactionQueue({ willRetry: event.willRetry });
2018
2038
  this.ui.requestRender();
@@ -2146,7 +2166,7 @@ export class InteractiveMode {
2146
2166
  break;
2147
2167
  }
2148
2168
  case "assistant": {
2149
- const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings());
2169
+ const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel);
2150
2170
  this.chatContainer.addChild(assistantComponent);
2151
2171
  break;
2152
2172
  }
@@ -3852,53 +3872,17 @@ export class InteractiveMode {
3852
3872
  this.showWarning("Nothing to compact (no messages yet)");
3853
3873
  return;
3854
3874
  }
3855
- await this.executeCompaction(customInstructions, false);
3856
- }
3857
- async executeCompaction(customInstructions, isAuto = false) {
3858
- // Stop loading animation
3859
3875
  if (this.loadingAnimation) {
3860
3876
  this.loadingAnimation.stop();
3861
3877
  this.loadingAnimation = undefined;
3862
3878
  }
3863
3879
  this.statusContainer.clear();
3864
- // Set up escape handler during compaction
3865
- const originalOnEscape = this.defaultEditor.onEscape;
3866
- this.defaultEditor.onEscape = () => {
3867
- this.session.abortCompaction();
3868
- };
3869
- // Show compacting status
3870
- this.chatContainer.addChild(new Spacer(1));
3871
- const cancelHint = `(${keyText("app.interrupt")} to cancel)`;
3872
- const label = isAuto ? `Auto-compacting context... ${cancelHint}` : `Compacting context... ${cancelHint}`;
3873
- const compactingLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), label);
3874
- this.statusContainer.addChild(compactingLoader);
3875
- this.ui.requestRender();
3876
- let result;
3877
3880
  try {
3878
- result = await this.session.compact(customInstructions);
3879
- // Rebuild UI
3880
- this.rebuildChatFromMessages();
3881
- // Add compaction component at bottom so user sees it without scrolling
3882
- const msg = createCompactionSummaryMessage(result.summary, result.tokensBefore, new Date().toISOString());
3883
- this.addMessageToChat(msg);
3884
- this.footer.invalidate();
3881
+ await this.session.compact(customInstructions);
3885
3882
  }
3886
- catch (error) {
3887
- const message = error instanceof Error ? error.message : String(error);
3888
- if (message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError")) {
3889
- this.showError("Compaction cancelled");
3890
- }
3891
- else {
3892
- this.showError(`Compaction failed: ${message}`);
3893
- }
3894
- }
3895
- finally {
3896
- compactingLoader.stop();
3897
- this.statusContainer.clear();
3898
- this.defaultEditor.onEscape = originalOnEscape;
3883
+ catch {
3884
+ // Ignore, will be emitted as an event
3899
3885
  }
3900
- void this.flushCompactionQueue({ willRetry: false });
3901
- return result;
3902
3886
  }
3903
3887
  stop() {
3904
3888
  if (this.loadingAnimation) {