@namzu/cli 12.1.0 → 13.0.0

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 (199) hide show
  1. package/README.md +25 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +119 -60
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/acp.d.ts +24 -8
  6. package/dist/commands/acp.d.ts.map +1 -1
  7. package/dist/commands/acp.js +221 -80
  8. package/dist/commands/acp.js.map +1 -1
  9. package/dist/commands/drain.d.ts.map +1 -1
  10. package/dist/commands/drain.js +45 -9
  11. package/dist/commands/drain.js.map +1 -1
  12. package/dist/commands/prior-messages.d.ts +11 -0
  13. package/dist/commands/prior-messages.d.ts.map +1 -0
  14. package/dist/commands/prior-messages.js +280 -0
  15. package/dist/commands/prior-messages.js.map +1 -0
  16. package/dist/commands/resume.d.ts.map +1 -1
  17. package/dist/commands/resume.js +21 -19
  18. package/dist/commands/resume.js.map +1 -1
  19. package/dist/commands/run-stream.d.ts +5 -3
  20. package/dist/commands/run-stream.d.ts.map +1 -1
  21. package/dist/commands/run-stream.js +66 -62
  22. package/dist/commands/run-stream.js.map +1 -1
  23. package/dist/commands/run.d.ts.map +1 -1
  24. package/dist/commands/run.js +50 -37
  25. package/dist/commands/run.js.map +1 -1
  26. package/dist/config/debug.d.ts +55 -0
  27. package/dist/config/debug.d.ts.map +1 -0
  28. package/dist/config/debug.js +126 -0
  29. package/dist/config/debug.js.map +1 -0
  30. package/dist/config/load.d.ts +88 -4
  31. package/dist/config/load.d.ts.map +1 -1
  32. package/dist/config/load.js +386 -56
  33. package/dist/config/load.js.map +1 -1
  34. package/dist/config/schema.d.ts +87 -5
  35. package/dist/config/schema.d.ts.map +1 -1
  36. package/dist/config/schema.js +5 -5
  37. package/dist/config/schema.js.map +1 -1
  38. package/dist/config/trusted-project-context.d.ts +11 -0
  39. package/dist/config/trusted-project-context.d.ts.map +1 -0
  40. package/dist/config/trusted-project-context.js +28 -0
  41. package/dist/config/trusted-project-context.js.map +1 -0
  42. package/dist/context/project-path.d.ts +3 -0
  43. package/dist/context/project-path.d.ts.map +1 -0
  44. package/dist/context/project-path.js +16 -0
  45. package/dist/context/project-path.js.map +1 -0
  46. package/dist/context/project-tracker.d.ts +30 -0
  47. package/dist/context/project-tracker.d.ts.map +1 -0
  48. package/dist/context/project-tracker.js +217 -0
  49. package/dist/context/project-tracker.js.map +1 -0
  50. package/dist/context/sandbox.d.ts +29 -9
  51. package/dist/context/sandbox.d.ts.map +1 -1
  52. package/dist/context/sandbox.js +8 -0
  53. package/dist/context/sandbox.js.map +1 -1
  54. package/dist/exit-codes.d.ts +5 -4
  55. package/dist/exit-codes.d.ts.map +1 -1
  56. package/dist/exit-codes.js +5 -4
  57. package/dist/exit-codes.js.map +1 -1
  58. package/dist/index.d.ts +2 -2
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +2 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/integrations/clipboard/text.d.ts +43 -0
  63. package/dist/integrations/clipboard/text.d.ts.map +1 -0
  64. package/dist/integrations/clipboard/text.js +43 -0
  65. package/dist/integrations/clipboard/text.js.map +1 -0
  66. package/dist/integrations/mcp/servers.d.ts +9 -0
  67. package/dist/integrations/mcp/servers.d.ts.map +1 -1
  68. package/dist/integrations/mcp/servers.js +11 -4
  69. package/dist/integrations/mcp/servers.js.map +1 -1
  70. package/dist/integrations/notifications/terminal.d.ts +32 -0
  71. package/dist/integrations/notifications/terminal.d.ts.map +1 -0
  72. package/dist/integrations/notifications/terminal.js +46 -0
  73. package/dist/integrations/notifications/terminal.js.map +1 -0
  74. package/dist/integrations/plugins/runtime.d.ts +17 -0
  75. package/dist/integrations/plugins/runtime.d.ts.map +1 -0
  76. package/dist/integrations/plugins/runtime.js +100 -0
  77. package/dist/integrations/plugins/runtime.js.map +1 -0
  78. package/dist/integrations/providers/credential-store.d.ts +17 -0
  79. package/dist/integrations/providers/credential-store.d.ts.map +1 -1
  80. package/dist/integrations/providers/credential-store.js +114 -2
  81. package/dist/integrations/providers/credential-store.js.map +1 -1
  82. package/dist/integrations/providers/index.d.ts +2 -2
  83. package/dist/integrations/providers/index.d.ts.map +1 -1
  84. package/dist/integrations/providers/index.js +2 -2
  85. package/dist/integrations/providers/index.js.map +1 -1
  86. package/dist/integrations/providers/keychain.d.ts +0 -13
  87. package/dist/integrations/providers/keychain.d.ts.map +1 -1
  88. package/dist/integrations/providers/keychain.js +0 -76
  89. package/dist/integrations/providers/keychain.js.map +1 -1
  90. package/dist/integrations/providers/oauth.d.ts +45 -16
  91. package/dist/integrations/providers/oauth.d.ts.map +1 -1
  92. package/dist/integrations/providers/oauth.js +170 -43
  93. package/dist/integrations/providers/oauth.js.map +1 -1
  94. package/dist/integrations/providers/subscription-login.d.ts +2 -0
  95. package/dist/integrations/providers/subscription-login.d.ts.map +1 -1
  96. package/dist/integrations/providers/subscription-login.js +117 -14
  97. package/dist/integrations/providers/subscription-login.js.map +1 -1
  98. package/dist/integrations/sessions/store.d.ts +111 -1
  99. package/dist/integrations/sessions/store.d.ts.map +1 -1
  100. package/dist/integrations/sessions/store.js +400 -7
  101. package/dist/integrations/sessions/store.js.map +1 -1
  102. package/dist/integrations/sessions/transcript-export.d.ts +25 -0
  103. package/dist/integrations/sessions/transcript-export.d.ts.map +1 -0
  104. package/dist/integrations/sessions/transcript-export.js +441 -0
  105. package/dist/integrations/sessions/transcript-export.js.map +1 -0
  106. package/dist/integrations/sessions/turn-evidence.d.ts +138 -0
  107. package/dist/integrations/sessions/turn-evidence.d.ts.map +1 -0
  108. package/dist/integrations/sessions/turn-evidence.js +506 -0
  109. package/dist/integrations/sessions/turn-evidence.js.map +1 -0
  110. package/dist/integrations/subagents/runtime.d.ts +7 -12
  111. package/dist/integrations/subagents/runtime.d.ts.map +1 -1
  112. package/dist/integrations/subagents/runtime.js +19 -10
  113. package/dist/integrations/subagents/runtime.js.map +1 -1
  114. package/dist/integrations/trust/store.d.ts.map +1 -1
  115. package/dist/integrations/trust/store.js +27 -13
  116. package/dist/integrations/trust/store.js.map +1 -1
  117. package/dist/permissions/canonical-project.d.ts +9 -0
  118. package/dist/permissions/canonical-project.d.ts.map +1 -0
  119. package/dist/permissions/canonical-project.js +13 -0
  120. package/dist/permissions/canonical-project.js.map +1 -0
  121. package/dist/permissions/checks.d.ts +65 -0
  122. package/dist/permissions/checks.d.ts.map +1 -0
  123. package/dist/permissions/checks.js +122 -0
  124. package/dist/permissions/checks.js.map +1 -0
  125. package/dist/permissions/headless-trust.d.ts +9 -5
  126. package/dist/permissions/headless-trust.d.ts.map +1 -1
  127. package/dist/permissions/headless-trust.js +18 -4
  128. package/dist/permissions/headless-trust.js.map +1 -1
  129. package/dist/permissions/rules.d.ts +16 -7
  130. package/dist/permissions/rules.d.ts.map +1 -1
  131. package/dist/permissions/rules.js +78 -13
  132. package/dist/permissions/rules.js.map +1 -1
  133. package/dist/tui/App.d.ts +5 -2
  134. package/dist/tui/App.d.ts.map +1 -1
  135. package/dist/tui/App.js +1555 -143
  136. package/dist/tui/App.js.map +1 -1
  137. package/dist/tui/Composer.d.ts +14 -3
  138. package/dist/tui/Composer.d.ts.map +1 -1
  139. package/dist/tui/Composer.js +53 -15
  140. package/dist/tui/Composer.js.map +1 -1
  141. package/dist/tui/EditPromptPicker.d.ts +8 -0
  142. package/dist/tui/EditPromptPicker.d.ts.map +1 -0
  143. package/dist/tui/EditPromptPicker.js +18 -0
  144. package/dist/tui/EditPromptPicker.js.map +1 -0
  145. package/dist/tui/LiveActivity.d.ts.map +1 -1
  146. package/dist/tui/LiveActivity.js +2 -1
  147. package/dist/tui/LiveActivity.js.map +1 -1
  148. package/dist/tui/Markdown.d.ts.map +1 -1
  149. package/dist/tui/Markdown.js +2 -1
  150. package/dist/tui/Markdown.js.map +1 -1
  151. package/dist/tui/PermissionOverlay.d.ts.map +1 -1
  152. package/dist/tui/PermissionOverlay.js +7 -1
  153. package/dist/tui/PermissionOverlay.js.map +1 -1
  154. package/dist/tui/Picker.d.ts +4 -4
  155. package/dist/tui/Picker.d.ts.map +1 -1
  156. package/dist/tui/Picker.js +86 -7
  157. package/dist/tui/Picker.js.map +1 -1
  158. package/dist/tui/ResumePicker.d.ts.map +1 -1
  159. package/dist/tui/ResumePicker.js +1 -1
  160. package/dist/tui/ResumePicker.js.map +1 -1
  161. package/dist/tui/Transcript.d.ts +4 -2
  162. package/dist/tui/Transcript.d.ts.map +1 -1
  163. package/dist/tui/Transcript.js +31 -5
  164. package/dist/tui/Transcript.js.map +1 -1
  165. package/dist/tui/agent.d.ts +123 -19
  166. package/dist/tui/agent.d.ts.map +1 -1
  167. package/dist/tui/agent.js +665 -143
  168. package/dist/tui/agent.js.map +1 -1
  169. package/dist/tui/compact-transcript.d.ts +24 -0
  170. package/dist/tui/compact-transcript.d.ts.map +1 -0
  171. package/dist/tui/compact-transcript.js +46 -0
  172. package/dist/tui/compact-transcript.js.map +1 -0
  173. package/dist/tui/conversation-history.d.ts +33 -0
  174. package/dist/tui/conversation-history.d.ts.map +1 -0
  175. package/dist/tui/conversation-history.js +42 -0
  176. package/dist/tui/conversation-history.js.map +1 -0
  177. package/dist/tui/edit-prompts.d.ts +23 -0
  178. package/dist/tui/edit-prompts.d.ts.map +1 -0
  179. package/dist/tui/edit-prompts.js +35 -0
  180. package/dist/tui/edit-prompts.js.map +1 -0
  181. package/dist/tui/live-window.d.ts +3 -1
  182. package/dist/tui/live-window.d.ts.map +1 -1
  183. package/dist/tui/live-window.js +20 -8
  184. package/dist/tui/live-window.js.map +1 -1
  185. package/dist/tui/slashCommands.d.ts +178 -9
  186. package/dist/tui/slashCommands.d.ts.map +1 -1
  187. package/dist/tui/slashCommands.js +339 -15
  188. package/dist/tui/slashCommands.js.map +1 -1
  189. package/dist/tui/terminal-display.d.ts +12 -0
  190. package/dist/tui/terminal-display.d.ts.map +1 -0
  191. package/dist/tui/terminal-display.js +65 -0
  192. package/dist/tui/terminal-display.js.map +1 -0
  193. package/dist/tui/types.d.ts +14 -2
  194. package/dist/tui/types.d.ts.map +1 -1
  195. package/dist/tui/workspace-diff.d.ts +40 -0
  196. package/dist/tui/workspace-diff.d.ts.map +1 -0
  197. package/dist/tui/workspace-diff.js +101 -0
  198. package/dist/tui/workspace-diff.js.map +1 -0
  199. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB,eAAO,MAAM,SAAS,IAAI,CAAA;AAC1B,eAAO,MAAM,cAAc,IAAI,CAAA;AAC/B,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAClC,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,MAAM,MAAM,WAAW,GACpB,OAAO,OAAO,GACd,OAAO,SAAS,GAChB,OAAO,cAAc,GACrB,OAAO,UAAU,GACjB,OAAO,gBAAgB,GACvB,OAAO,mBAAmB,GAC1B,OAAO,cAAc,GACrB,OAAO,eAAe,CAAA"}
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB,eAAO,MAAM,SAAS,IAAI,CAAA;AAC1B,eAAO,MAAM,cAAc,IAAI,CAAA;AAC/B,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAClC,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,MAAM,MAAM,WAAW,GACpB,OAAO,OAAO,GACd,OAAO,SAAS,GAChB,OAAO,cAAc,GACrB,OAAO,UAAU,GACjB,OAAO,gBAAgB,GACvB,OAAO,mBAAmB,GAC1B,OAAO,cAAc,GACrB,OAAO,eAAe,CAAA"}
@@ -37,10 +37,11 @@
37
37
  * nothing else is. A caller who cannot tell them
38
38
  * apart matches on the message string, and then
39
39
  * the message can never be reworded.
40
- * 78 EXIT_BAD_CONFIG — sysexits EX_CONFIG; a config file is present and
41
- * its contents could not be established, so the
42
- * run refused to start rather than continue with
43
- * settings it failed to read. Distinct from 2 for
40
+ * 78 EXIT_BAD_CONFIG — sysexits EX_CONFIG; a config source is present
41
+ * and cannot be read or contains a known setting
42
+ * with an invalid value, so the run refuses rather
43
+ * than silently substituting another setting.
44
+ * Distinct from 2 for
44
45
  * the reason 2 is distinct from 0: "namzu is not
45
46
  * configured here" and "your configuration is
46
47
  * unreadable" are fixed by opposite actions, and a
@@ -1 +1 @@
1
- {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAA;AACxB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAA;AAC1B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAClC,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAA;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAA;AACxB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAA;AAC1B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAClC,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAA;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA"}
package/dist/index.d.ts CHANGED
@@ -12,6 +12,6 @@ export { runCli, type RunCliOptions } from './cli.js';
12
12
  export type { CommandContext, CommandDef, CommandHandler, CommandHandlerArgs, } from './commands/types.js';
13
13
  export { registerAll, registerCommand, type RegisterOptions, } from './commands/registry.js';
14
14
  export { createFormatter, type FormatName, type Formatter, type FormatterOptions, isFormatName, } from './output/index.js';
15
- export { ConfigLoadError, loadConfig, loadConfigWithProvenance, type ConfigProvenance, type ConfigSource, type LoadConfigOptions, } from './config/load.js';
16
- export { DEFAULT_CONFIG, type NamzuCliConfig } from './config/schema.js';
15
+ export { ConfigLoadError, ConfigValueError, loadConfig, loadConfigWithProvenance, type ConfigProvenance, type ConfigSource, type ConfigValueSource, type LoadConfigOptions, } from './config/load.js';
16
+ export { DEFAULT_CONFIG, type NamzuCliConfig, type PluginConfig, type PluginScope, type TerminalNotificationEvent, type TerminalNotificationMethod, type TuiConfig, } from './config/schema.js';
17
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACN,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,SAAS,GACT,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,EACN,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EACN,KAAK,eAAe,EACpB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAGvD,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EACX,cAAc,EACd,UAAU,EACV,cAAc,EACd,kBAAkB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACN,WAAW,EACX,eAAe,EACf,KAAK,eAAe,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACN,eAAe,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,YAAY,GACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,GACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACN,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,SAAS,GACT,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,EACN,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EACN,KAAK,eAAe,EACpB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAGvD,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EACX,cAAc,EACd,UAAU,EACV,cAAc,EACd,kBAAkB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACN,WAAW,EACX,eAAe,EACf,KAAK,eAAe,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACN,eAAe,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,YAAY,GACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,SAAS,GACd,MAAM,oBAAoB,CAAA"}
package/dist/index.js CHANGED
@@ -12,6 +12,6 @@ export { runDoctorCommand } from './commands/doctor.js';
12
12
  export { runCli } from './cli.js';
13
13
  export { registerAll, registerCommand, } from './commands/registry.js';
14
14
  export { createFormatter, isFormatName, } from './output/index.js';
15
- export { ConfigLoadError, loadConfig, loadConfigWithProvenance, } from './config/load.js';
16
- export { DEFAULT_CONFIG } from './config/schema.js';
15
+ export { ConfigLoadError, ConfigValueError, loadConfig, loadConfigWithProvenance, } from './config/load.js';
16
+ export { DEFAULT_CONFIG, } from './config/schema.js';
17
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,iEAAiE;AACjE,OAAO,EACN,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,SAAS,GACT,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACN,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAEN,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,yCAAyC;AACzC,OAAO,EAAE,MAAM,EAAsB,MAAM,UAAU,CAAA;AAOrD,OAAO,EACN,WAAW,EACX,eAAe,GAEf,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACN,eAAe,EAIf,YAAY,GACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,eAAe,EACf,UAAU,EACV,wBAAwB,GAIxB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,iEAAiE;AACjE,OAAO,EACN,oBAAoB,EACpB,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,SAAS,GACT,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACN,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAEN,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,yCAAyC;AACzC,OAAO,EAAE,MAAM,EAAsB,MAAM,UAAU,CAAA;AAOrD,OAAO,EACN,WAAW,EACX,eAAe,GAEf,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACN,eAAe,EAIf,YAAY,GACZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,wBAAwB,GAKxB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,cAAc,GAOd,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Ask an interactive terminal to place text on its clipboard via OSC 52.
3
+ *
4
+ * This deliberately does not spawn a platform clipboard command. `/copy` is a
5
+ * TUI operation, not permission to run arbitrary host code outside the agent's
6
+ * sandbox and approval path. The escape payload is base64, so model-authored
7
+ * control characters cannot terminate the sequence and inject another one.
8
+ *
9
+ * OSC 52 has no portable acknowledgement. A successful write proves only that
10
+ * the complete request reached Ink's stdout; a terminal, multiplexer or remote
11
+ * hop may still ignore it. The result therefore says `request-sent`, never
12
+ * `copied`, and the caller must preserve that distinction in its message.
13
+ */
14
+ /**
15
+ * Bound the raw UTF-8 text before base64 expands it by roughly one third.
16
+ *
17
+ * Terminal limits vary and cannot be negotiated. Refusing above a stated cap
18
+ * is honest; truncating would put something on the clipboard that is not the
19
+ * answer the operator asked for.
20
+ */
21
+ export declare const MAX_CLIPBOARD_TEXT_BYTES = 100000;
22
+ export interface TerminalClipboardOutput {
23
+ /** Whether Ink is attached to an interactive terminal. */
24
+ readonly isTTY?: boolean;
25
+ /** Ink's stdout writer, which preserves the frame around out-of-band output. */
26
+ readonly write: (data: string) => void;
27
+ }
28
+ export type ClipboardWriteResult = {
29
+ readonly kind: 'request-sent';
30
+ readonly bytes: number;
31
+ } | {
32
+ readonly kind: 'unavailable';
33
+ readonly detail: string;
34
+ } | {
35
+ readonly kind: 'too-large';
36
+ readonly bytes: number;
37
+ readonly limit: number;
38
+ } | {
39
+ readonly kind: 'write-failed';
40
+ readonly detail: string;
41
+ };
42
+ export declare function writeClipboardText(text: string, output: TerminalClipboardOutput): ClipboardWriteResult;
43
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/integrations/clipboard/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,SAAU,CAAA;AAE/C,MAAM,WAAW,uBAAuB;IACvC,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7D,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,uBAAuB,GAC7B,oBAAoB,CAqBtB"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Ask an interactive terminal to place text on its clipboard via OSC 52.
3
+ *
4
+ * This deliberately does not spawn a platform clipboard command. `/copy` is a
5
+ * TUI operation, not permission to run arbitrary host code outside the agent's
6
+ * sandbox and approval path. The escape payload is base64, so model-authored
7
+ * control characters cannot terminate the sequence and inject another one.
8
+ *
9
+ * OSC 52 has no portable acknowledgement. A successful write proves only that
10
+ * the complete request reached Ink's stdout; a terminal, multiplexer or remote
11
+ * hop may still ignore it. The result therefore says `request-sent`, never
12
+ * `copied`, and the caller must preserve that distinction in its message.
13
+ */
14
+ /**
15
+ * Bound the raw UTF-8 text before base64 expands it by roughly one third.
16
+ *
17
+ * Terminal limits vary and cannot be negotiated. Refusing above a stated cap
18
+ * is honest; truncating would put something on the clipboard that is not the
19
+ * answer the operator asked for.
20
+ */
21
+ export const MAX_CLIPBOARD_TEXT_BYTES = 100_000;
22
+ export function writeClipboardText(text, output) {
23
+ if (!output.isTTY) {
24
+ return { kind: 'unavailable', detail: 'stdout is not an interactive terminal' };
25
+ }
26
+ const bytes = Buffer.byteLength(text, 'utf8');
27
+ if (bytes > MAX_CLIPBOARD_TEXT_BYTES) {
28
+ return { kind: 'too-large', bytes, limit: MAX_CLIPBOARD_TEXT_BYTES };
29
+ }
30
+ try {
31
+ const encoded = Buffer.from(text, 'utf8').toString('base64');
32
+ // `c` selects the clipboard; BEL terminates the OSC control sequence.
33
+ output.write(`\x1b]52;c;${encoded}\x07`);
34
+ return { kind: 'request-sent', bytes };
35
+ }
36
+ catch (err) {
37
+ return {
38
+ kind: 'write-failed',
39
+ detail: err instanceof Error ? err.message : String(err),
40
+ };
41
+ }
42
+ }
43
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/integrations/clipboard/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAA;AAe/C,MAAM,UAAU,kBAAkB,CACjC,IAAY,EACZ,MAA+B;IAE/B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAA;IAChF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAC7C,IAAI,KAAK,GAAG,wBAAwB,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAA;IACrE,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAC5D,sEAAsE;QACtE,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,MAAM,CAAC,CAAA;QACxC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAA;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO;YACN,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAA;IACF,CAAC;AACF,CAAC"}
@@ -78,6 +78,15 @@ export type McpServersConfig = Readonly<Record<string, McpServerSpec>>;
78
78
  export interface ConnectedMcpServer {
79
79
  readonly name: string;
80
80
  readonly toolCount: number;
81
+ /**
82
+ * What this server actually contributes, by tool name.
83
+ *
84
+ * Carried from the listing rather than recovered later. The names arrive
85
+ * prefixed with the server's own (`mcp_tickets_create`), so a caller COULD
86
+ * split them back apart — but that turns an encoding this file owns into a
87
+ * format two places have to agree about, and the list is free right here.
88
+ */
89
+ readonly tools: readonly string[];
81
90
  }
82
91
  export interface FailedMcpServer {
83
92
  readonly name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAEN,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,OAAQ,CAAA;AAErC,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACnD;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAwBhG;AAkBD,wBAAsB,iBAAiB,CACtC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,aAAa,CAAC,CAmExB"}
1
+ {"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAEN,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,OAAQ,CAAA;AAErC,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACnD;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAwBhG;AAkBD,wBAAsB,iBAAiB,CACtC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,aAAa,CAAC,CA0ExB"}
@@ -118,10 +118,17 @@ export async function connectMcpServers(config, options) {
118
118
  try {
119
119
  await withDeadline(client.connect(), CONNECT_TIMEOUT_MS, `server "${name}"`);
120
120
  const listed = await withDeadline(client.listTools(), CONNECT_TIMEOUT_MS, `server "${name}" listing its tools`);
121
- for (const tool of listed) {
122
- tools.push(mcpToolToToolDefinition(tool, client, name));
123
- }
124
- connected.push({ name, toolCount: listed.length });
121
+ // Adapted once, then read twice. Adapting a second time to collect
122
+ // the names would build a parallel set of definitions bound to the
123
+ // same client — cheap today and exactly the kind of duplicate a
124
+ // future adapter with a side effect turns into a bug.
125
+ const adapted = listed.map((tool) => mcpToolToToolDefinition(tool, client, name));
126
+ tools.push(...adapted);
127
+ connected.push({
128
+ name,
129
+ toolCount: adapted.length,
130
+ tools: adapted.map((tool) => tool.name),
131
+ });
125
132
  clients.push(client);
126
133
  }
127
134
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { TerminalNotificationEvent, TerminalNotificationMethod } from '../../config/schema.js';
2
+ /** A semantic TUI moment, before it is rendered for a terminal protocol. */
3
+ export type TerminalNotification = {
4
+ readonly kind: 'approval-required';
5
+ } | {
6
+ readonly kind: 'turn-settled';
7
+ readonly outcome: 'completed' | 'stopped' | 'failed';
8
+ };
9
+ export interface TerminalNotificationOutput {
10
+ readonly isTTY?: boolean;
11
+ readonly write: (data: string) => void;
12
+ }
13
+ export type TerminalNotificationResult = {
14
+ readonly kind: 'request-sent';
15
+ } | {
16
+ readonly kind: 'unavailable';
17
+ readonly detail: string;
18
+ } | {
19
+ readonly kind: 'write-failed';
20
+ readonly detail: string;
21
+ };
22
+ /** Whether one configured setting includes this semantic event. */
23
+ export declare function terminalNotificationEnabled(setting: boolean | readonly TerminalNotificationEvent[] | undefined, notification: TerminalNotification): boolean;
24
+ /**
25
+ * Send one fixed, content-free notification request through Ink's stdout.
26
+ *
27
+ * Neither protocol acknowledges that a terminal displayed anything. Success
28
+ * therefore means only that the request was written, never that a desktop
29
+ * notification appeared or a bell was audible.
30
+ */
31
+ export declare function writeTerminalNotification(notification: TerminalNotification, method: TerminalNotificationMethod, output: TerminalNotificationOutput): TerminalNotificationResult;
32
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../../src/integrations/notifications/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAA;AAEnG,4EAA4E;AAC5E,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAA;CAAE,GACtC;IACA,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAA;CACnD,CAAA;AAEJ,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,MAAM,0BAA0B,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7D,mEAAmE;AACnE,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,OAAO,GAAG,SAAS,yBAAyB,EAAE,GAAG,SAAS,EACnE,YAAY,EAAE,oBAAoB,GAChC,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACxC,YAAY,EAAE,oBAAoB,EAClC,MAAM,EAAE,0BAA0B,EAClC,MAAM,EAAE,0BAA0B,GAChC,0BAA0B,CAe5B"}
@@ -0,0 +1,46 @@
1
+ /** Whether one configured setting includes this semantic event. */
2
+ export function terminalNotificationEnabled(setting, notification) {
3
+ if (setting === true)
4
+ return true;
5
+ if (!Array.isArray(setting))
6
+ return false;
7
+ return setting.includes(notification.kind);
8
+ }
9
+ /**
10
+ * Send one fixed, content-free notification request through Ink's stdout.
11
+ *
12
+ * Neither protocol acknowledges that a terminal displayed anything. Success
13
+ * therefore means only that the request was written, never that a desktop
14
+ * notification appeared or a bell was audible.
15
+ */
16
+ export function writeTerminalNotification(notification, method, output) {
17
+ if (!output.isTTY) {
18
+ return { kind: 'unavailable', detail: 'stdout is not an interactive terminal' };
19
+ }
20
+ try {
21
+ if (method === 'bel')
22
+ output.write('\x07');
23
+ else
24
+ output.write(`\x1b]9;${notificationText(notification)}\x07`);
25
+ return { kind: 'request-sent' };
26
+ }
27
+ catch (err) {
28
+ return {
29
+ kind: 'write-failed',
30
+ detail: err instanceof Error ? err.message : String(err),
31
+ };
32
+ }
33
+ }
34
+ function notificationText(notification) {
35
+ if (notification.kind === 'approval-required')
36
+ return 'Namzu: approval required';
37
+ switch (notification.outcome) {
38
+ case 'completed':
39
+ return 'Namzu: turn completed';
40
+ case 'stopped':
41
+ return 'Namzu: turn needs attention';
42
+ case 'failed':
43
+ return 'Namzu: turn failed';
44
+ }
45
+ }
46
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../../src/integrations/notifications/terminal.ts"],"names":[],"mappings":"AAoBA,mEAAmE;AACnE,MAAM,UAAU,2BAA2B,CAC1C,OAAmE,EACnE,YAAkC;IAElC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CACxC,YAAkC,EAClC,MAAkC,EAClC,MAAkC;IAElC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAA;IAChF,CAAC;IAED,IAAI,CAAC;QACJ,IAAI,MAAM,KAAK,KAAK;YAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;;YACrC,MAAM,CAAC,KAAK,CAAC,UAAU,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QACjE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAA;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO;YACN,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAA;IACF,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,YAAkC;IAC3D,IAAI,YAAY,CAAC,IAAI,KAAK,mBAAmB;QAAE,OAAO,0BAA0B,CAAA;IAChF,QAAQ,YAAY,CAAC,OAAO,EAAE,CAAC;QAC9B,KAAK,WAAW;YACf,OAAO,uBAAuB,CAAA;QAC/B,KAAK,SAAS;YACb,OAAO,6BAA6B,CAAA;QACrC,KAAK,QAAQ;YACZ,OAAO,oBAAoB,CAAA;IAC7B,CAAC;AACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { PluginLifecycleManager, SkillRegistry, type ToolRegistry } from '@namzu/sdk';
2
+ import type { PluginConfig } from '../../config/schema.js';
3
+ export interface CliPluginRuntime {
4
+ readonly manager: PluginLifecycleManager;
5
+ readonly skills: SkillRegistry;
6
+ readonly pluginCount: number;
7
+ close(): Promise<void>;
8
+ }
9
+ /**
10
+ * Build the executable extension runtime owned by one agent session.
11
+ *
12
+ * The exact `enabled === true` check is the default-off boundary. Nothing in
13
+ * the plugin directories is discovered, read, or imported on every other
14
+ * value. Callers invoke this only after project trust has pinned `cwd`.
15
+ */
16
+ export declare function createCliPluginRuntime(config: PluginConfig | undefined, tools: ToolRegistry, cwd: string): Promise<CliPluginRuntime | undefined>;
17
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/plugins/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,sBAAsB,EAEtB,aAAa,EAEb,KAAK,YAAY,EAEjB,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,wBAAwB,CAAA;AAGvE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAMD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC3C,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAmFvC"}
@@ -0,0 +1,100 @@
1
+ import { homedir } from 'node:os';
2
+ import { PluginLifecycleManager, PluginRegistry, SkillRegistry, SkillTool, discoverAllPluginDirs, } from '@namzu/sdk';
3
+ import { cliLogger } from '../../logging.js';
4
+ function message(error) {
5
+ return error instanceof Error ? error.message : String(error);
6
+ }
7
+ /**
8
+ * Build the executable extension runtime owned by one agent session.
9
+ *
10
+ * The exact `enabled === true` check is the default-off boundary. Nothing in
11
+ * the plugin directories is discovered, read, or imported on every other
12
+ * value. Callers invoke this only after project trust has pinned `cwd`.
13
+ */
14
+ export async function createCliPluginRuntime(config, tools, cwd) {
15
+ if (config?.enabled !== true)
16
+ return undefined;
17
+ const log = cliLogger();
18
+ const plugins = new PluginRegistry();
19
+ const skills = new SkillRegistry(log);
20
+ const manager = new PluginLifecycleManager({
21
+ pluginRegistry: plugins,
22
+ toolRegistry: tools,
23
+ skillRegistry: skills,
24
+ scopeRoots: { project: cwd, user: homedir() },
25
+ log,
26
+ ...(config.hookTimeoutMs !== undefined ? { hookTimeoutMs: config.hookTimeoutMs } : {}),
27
+ });
28
+ const allowedScopes = config.allowedScopes ?? ['project', 'user'];
29
+ const discovered = await discoverAllPluginDirs(cwd, {
30
+ enabled: true,
31
+ autoDiscovery: config.autoDiscovery ?? true,
32
+ allowedScopes,
33
+ log,
34
+ });
35
+ const installed = [];
36
+ let ownsSkillTool = false;
37
+ try {
38
+ for (const scope of allowedScopes) {
39
+ const dirs = [...discovered[scope]].sort((a, b) => a.localeCompare(b));
40
+ for (const dir of dirs) {
41
+ const plugin = await manager.install(dir, scope);
42
+ installed.push(plugin);
43
+ await manager.enable(plugin.id);
44
+ }
45
+ }
46
+ if (skills.size > 0 && !tools.has(SkillTool.name)) {
47
+ tools.register(SkillTool);
48
+ ownsSkillTool = true;
49
+ }
50
+ }
51
+ catch (error) {
52
+ if (ownsSkillTool)
53
+ tools.unregister(SkillTool.name);
54
+ const cleanupErrors = [];
55
+ for (const plugin of [...installed].reverse()) {
56
+ try {
57
+ await manager.uninstall(plugin.id);
58
+ }
59
+ catch (cleanupError) {
60
+ cleanupErrors.push(cleanupError);
61
+ }
62
+ }
63
+ const cleanupSuffix = cleanupErrors.length === 0
64
+ ? ''
65
+ : ` Cleanup also failed: ${cleanupErrors.map(message).join('; ')}`;
66
+ throw new Error(`Plugin runtime could not start: ${message(error)}.${cleanupSuffix}`, {
67
+ cause: error,
68
+ });
69
+ }
70
+ let closePromise;
71
+ return {
72
+ manager,
73
+ skills,
74
+ pluginCount: installed.length,
75
+ close() {
76
+ if (closePromise)
77
+ return closePromise;
78
+ closePromise = (async () => {
79
+ const errors = [];
80
+ if (ownsSkillTool) {
81
+ tools.unregister(SkillTool.name);
82
+ ownsSkillTool = false;
83
+ }
84
+ for (const plugin of [...installed].reverse()) {
85
+ try {
86
+ await manager.uninstall(plugin.id);
87
+ }
88
+ catch (error) {
89
+ errors.push(error);
90
+ }
91
+ }
92
+ if (errors.length > 0) {
93
+ throw new AggregateError(errors, 'One or more plugins could not be uninstalled.');
94
+ }
95
+ })();
96
+ return closePromise;
97
+ },
98
+ };
99
+ }
100
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/integrations/plugins/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEjC,OAAO,EACN,sBAAsB,EACtB,cAAc,EACd,aAAa,EACb,SAAS,EAET,qBAAqB,GACrB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAS5C,SAAS,OAAO,CAAC,KAAc;IAC9B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,MAAgC,EAChC,KAAmB,EACnB,GAAW;IAEX,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAE9C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;IACvB,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC;QAC1C,cAAc,EAAE,OAAO;QACvB,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,MAAM;QACrB,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC7C,GAAG;QACH,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtF,CAAC,CAAA;IACF,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAK,CAAC,SAAS,EAAE,MAAM,CAAW,CAAA;IAC5E,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE;QACnD,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,aAAa;QACb,GAAG;KACH,CAAC,CAAA;IACF,MAAM,SAAS,GAA6D,EAAE,CAAA;IAC9E,IAAI,aAAa,GAAG,KAAK,CAAA;IAEzB,IAAI,CAAC;QACJ,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;YACtE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAoB,CAAC,CAAA;gBAC/D,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACtB,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAChC,CAAC;QACF,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YACzB,aAAa,GAAG,IAAI,CAAA;QACrB,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,aAAa;YAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACnD,MAAM,aAAa,GAAc,EAAE,CAAA;QACnC,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACJ,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACvB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YACjC,CAAC;QACF,CAAC;QACD,MAAM,aAAa,GAClB,aAAa,CAAC,MAAM,KAAK,CAAC;YACzB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,yBAAyB,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QACpE,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,KAAK,CAAC,IAAI,aAAa,EAAE,EAAE;YACrF,KAAK,EAAE,KAAK;SACZ,CAAC,CAAA;IACH,CAAC;IAED,IAAI,YAAuC,CAAA;IAC3C,OAAO;QACN,OAAO;QACP,MAAM;QACN,WAAW,EAAE,SAAS,CAAC,MAAM;QAC7B,KAAK;YACJ,IAAI,YAAY;gBAAE,OAAO,YAAY,CAAA;YACrC,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,MAAM,MAAM,GAAc,EAAE,CAAA;gBAC5B,IAAI,aAAa,EAAE,CAAC;oBACnB,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;oBAChC,aAAa,GAAG,KAAK,CAAA;gBACtB,CAAC;gBACD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC/C,IAAI,CAAC;wBACJ,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;oBACnC,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;oBACnB,CAAC;gBACF,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,+CAA+C,CAAC,CAAA;gBAClF,CAAC;YACF,CAAC,CAAC,EAAE,CAAA;YACJ,OAAO,YAAY,CAAA;QACpB,CAAC;KACD,CAAA;AACF,CAAC"}
@@ -47,6 +47,13 @@ export declare const CREDENTIALS_FILE_VERSION: 1;
47
47
  export declare class CredentialStoreError extends Error {
48
48
  readonly name = "CredentialStoreError";
49
49
  }
50
+ export type ConditionalCredentialWrite = {
51
+ readonly replaced: true;
52
+ readonly current: AgentOAuthCredential;
53
+ } | {
54
+ readonly replaced: false;
55
+ readonly current: AgentOAuthCredential | null;
56
+ };
50
57
  export declare function credentialsPath(home?: string): string;
51
58
  /**
52
59
  * The stored subscription credential, or `null` when there is none.
@@ -68,6 +75,16 @@ export declare function readStoredSubscriptionCredential(home?: string): AgentOA
68
75
  * removes.
69
76
  */
70
77
  export declare function writeStoredSubscriptionCredential(cred: AgentOAuthCredential, home?: string): string;
78
+ /**
79
+ * Replace exactly the credential a refresh was derived from.
80
+ *
81
+ * Comparison and rename happen under the same store-owned cross-process lock.
82
+ * A changed record is returned to the caller and is never overwritten. This is
83
+ * the durable authority boundary a post-network plain reread cannot provide:
84
+ * without the lock, another writer can still rotate the credential between
85
+ * the comparison and the rename.
86
+ */
87
+ export declare function replaceStoredSubscriptionCredential(expected: AgentOAuthCredential, replacement: AgentOAuthCredential, home?: string): ConditionalCredentialWrite;
71
88
  /** Remove the stored credential. Absence is success. */
72
89
  export declare function clearStoredSubscriptionCredential(home?: string): void;
73
90
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../../src/integrations/providers/credential-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAiBH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAKzD,eAAO,MAAM,wBAAwB,EAAG,CAAU,CAAA;AAElD,wFAAwF;AACxF,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,SAAkB,IAAI,0BAAyB;CAC/C;AAED,wBAAgB,eAAe,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC/C,IAAI,GAAE,MAAkB,GACtB,oBAAoB,GAAG,IAAI,CA2B7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAChD,IAAI,EAAE,oBAAoB,EAC1B,IAAI,GAAE,MAAkB,GACtB,MAAM,CAiDR;AAED,wDAAwD;AACxD,wBAAgB,iCAAiC,CAAC,IAAI,GAAE,MAAkB,GAAG,IAAI,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMpE;AAgDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBvD;AAED,qFAAqF;AACrF,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAc9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAoCjF"}
1
+ {"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../../src/integrations/providers/credential-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAoBH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAKzD,eAAO,MAAM,wBAAwB,EAAG,CAAU,CAAA;AAElD,wFAAwF;AACxF,qBAAa,oBAAqB,SAAQ,KAAK;IAC9C,SAAkB,IAAI,0BAAyB;CAC/C;AAED,MAAM,MAAM,0BAA0B,GACnC;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAA;CAAE,CAAA;AAE9E,wBAAgB,eAAe,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC/C,IAAI,GAAE,MAAkB,GACtB,oBAAoB,GAAG,IAAI,CA2B7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAChD,IAAI,EAAE,oBAAoB,EAC1B,IAAI,GAAE,MAAkB,GACtB,MAAM,CAIR;AAED;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CAClD,QAAQ,EAAE,oBAAoB,EAC9B,WAAW,EAAE,oBAAoB,EACjC,IAAI,GAAE,MAAkB,GACtB,0BAA0B,CAS5B;AAsDD,wDAAwD;AACxD,wBAAgB,iCAAiC,CAAC,IAAI,GAAE,MAAkB,GAAG,IAAI,CAIhF;AA+FD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMpE;AAgDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBvD;AAED,qFAAqF;AACrF,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAc9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAoCjF"}
@@ -43,7 +43,7 @@
43
43
  */
44
44
  import { execFileSync } from 'node:child_process';
45
45
  import { randomBytes } from 'node:crypto';
46
- import { closeSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, writeSync, } from 'node:fs';
46
+ import { closeSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, writeSync, } from 'node:fs';
47
47
  import { homedir, platform, tmpdir } from 'node:os';
48
48
  import { dirname, join } from 'node:path';
49
49
  const FILE_MODE = 0o600;
@@ -110,6 +110,29 @@ export function readStoredSubscriptionCredential(home = homedir()) {
110
110
  export function writeStoredSubscriptionCredential(cred, home = homedir()) {
111
111
  const path = credentialsPath(home);
112
112
  mkdirSync(dirname(path), { recursive: true, mode: DIR_MODE });
113
+ return withCredentialStoreLock(path, () => writeStoredSubscriptionCredentialUnlocked(cred, path));
114
+ }
115
+ /**
116
+ * Replace exactly the credential a refresh was derived from.
117
+ *
118
+ * Comparison and rename happen under the same store-owned cross-process lock.
119
+ * A changed record is returned to the caller and is never overwritten. This is
120
+ * the durable authority boundary a post-network plain reread cannot provide:
121
+ * without the lock, another writer can still rotate the credential between
122
+ * the comparison and the rename.
123
+ */
124
+ export function replaceStoredSubscriptionCredential(expected, replacement, home = homedir()) {
125
+ const path = credentialsPath(home);
126
+ mkdirSync(dirname(path), { recursive: true, mode: DIR_MODE });
127
+ return withCredentialStoreLock(path, () => {
128
+ const current = readStoredSubscriptionCredential(home);
129
+ if (!sameCredential(current, expected))
130
+ return { replaced: false, current };
131
+ writeStoredSubscriptionCredentialUnlocked(replacement, path);
132
+ return { replaced: true, current: replacement };
133
+ });
134
+ }
135
+ function writeStoredSubscriptionCredentialUnlocked(cred, path) {
113
136
  const tmp = `${path}.tmp.${process.pid}.${randomBytes(6).toString('hex')}`;
114
137
  const body = `${JSON.stringify({
115
138
  version: CREDENTIALS_FILE_VERSION,
@@ -152,7 +175,96 @@ export function writeStoredSubscriptionCredential(cred, home = homedir()) {
152
175
  }
153
176
  /** Remove the stored credential. Absence is success. */
154
177
  export function clearStoredSubscriptionCredential(home = homedir()) {
155
- rmSync(credentialsPath(home), { force: true });
178
+ const path = credentialsPath(home);
179
+ mkdirSync(dirname(path), { recursive: true, mode: DIR_MODE });
180
+ withCredentialStoreLock(path, () => rmSync(path, { force: true }));
181
+ }
182
+ function sameCredential(left, right) {
183
+ if (!left)
184
+ return false;
185
+ if (left.accessToken !== right.accessToken ||
186
+ left.refreshToken !== right.refreshToken ||
187
+ left.expiresAt !== right.expiresAt) {
188
+ return false;
189
+ }
190
+ const leftScopes = left.scopes ?? [];
191
+ const rightScopes = right.scopes ?? [];
192
+ return (leftScopes.length === rightScopes.length &&
193
+ leftScopes.every((scope, index) => scope === rightScopes[index]));
194
+ }
195
+ /**
196
+ * Run one synchronous store mutation with cross-process exclusion.
197
+ *
198
+ * The lock is held only across local read/rename work, never across a network
199
+ * request. A dead owner can leave a complete lock behind. It is deliberately
200
+ * not stolen automatically: pathname-based stale reclamation cannot prove it
201
+ * is unlinking the inode it inspected, so a delayed reclaimer can delete a new
202
+ * owner's lock and admit two writers. A present lock is a refusal until an
203
+ * operator proves no process owns the store and removes it.
204
+ */
205
+ function withCredentialStoreLock(path, operation) {
206
+ const lockPath = `${path}.lock`;
207
+ const token = `${process.pid}:${Date.now()}:${randomBytes(12).toString('hex')}`;
208
+ const published = publishLockAtomically(lockPath, token);
209
+ if (!published.acquired) {
210
+ throw new CredentialStoreError(`could not acquire the credential-store lock for ${path}: another owner or an unrecovered process lock is present (${published.error instanceof Error ? published.error.message : String(published.error)}). Refusing concurrent mutation; after proving no Namzu process is using this credential store, remove ${lockPath} and retry.`);
211
+ }
212
+ try {
213
+ return operation();
214
+ }
215
+ finally {
216
+ // Do not remove a successor's lock if an external actor replaced the file.
217
+ try {
218
+ if (readFileSync(lockPath, 'utf8') === token)
219
+ rmSync(lockPath, { force: true });
220
+ }
221
+ catch {
222
+ // The mutation already has its result. A missing/replaced lock is not
223
+ // evidence that the credential itself failed to publish.
224
+ }
225
+ }
226
+ }
227
+ /**
228
+ * Publish a complete owner record at the canonical name in one filesystem op.
229
+ *
230
+ * Creating the canonical file and then writing its token has a fatal crash
231
+ * window: an empty lock names no owner and can never be reclaimed safely. The
232
+ * candidate is completed and synced first; `linkSync` is the exclusive claim.
233
+ * A pre-link crash can leave candidate debris, but it never blocks the store.
234
+ */
235
+ function publishLockAtomically(lockPath, token) {
236
+ const candidatePath = `${lockPath}.candidate.${process.pid}.${randomBytes(12).toString('hex')}`;
237
+ let fd;
238
+ try {
239
+ fd = openSync(candidatePath, 'wx', FILE_MODE);
240
+ writeFileSync(fd, token, 'utf8');
241
+ fsyncSync(fd);
242
+ closeSync(fd);
243
+ fd = undefined;
244
+ }
245
+ catch (error) {
246
+ if (fd !== undefined)
247
+ closeSync(fd);
248
+ rmSync(candidatePath, { force: true });
249
+ throw new CredentialStoreError(`could not prepare the credential-store lock: ${error instanceof Error ? error.message : String(error)}`);
250
+ }
251
+ try {
252
+ linkSync(candidatePath, lockPath);
253
+ return { acquired: true };
254
+ }
255
+ catch (error) {
256
+ return { acquired: false, error };
257
+ }
258
+ finally {
259
+ try {
260
+ rmSync(candidatePath, { force: true });
261
+ }
262
+ catch {
263
+ // Candidate debris is non-canonical and cannot block another owner.
264
+ // Once the hard link succeeds, cleanup must not erase that acquisition
265
+ // result and skip the token-checked canonical release path.
266
+ }
267
+ }
156
268
  }
157
269
  /**
158
270
  * Make `path` readable and writable by its owner and by nobody else, and