@agimon-ai/doompi-ui 0.0.1-alpha.14 → 0.0.1-alpha.16

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 (92) hide show
  1. package/README.md +21 -18
  2. package/dist/_virtual/_rolldown/runtime.cjs +1 -1
  3. package/dist/adapters/pi/extension.cjs +1 -1
  4. package/dist/adapters/pi/extension.cjs.map +1 -1
  5. package/dist/adapters/pi/extension.d.cts.map +1 -1
  6. package/dist/adapters/pi/extension.d.mts.map +1 -1
  7. package/dist/adapters/pi/extension.mjs +1 -1
  8. package/dist/adapters/pi/extension.mjs.map +1 -1
  9. package/dist/components/doomEditor.d.cts +1 -1
  10. package/dist/components/doomEditor.d.mts +1 -1
  11. package/dist/components/doomOverlay.d.cts +1 -1
  12. package/dist/components/doomOverlay.d.mts +1 -1
  13. package/dist/config.cjs +1 -2
  14. package/dist/config.d.cts +2 -5
  15. package/dist/config.d.mts +2 -5
  16. package/dist/config.mjs +1 -2
  17. package/dist/extensions/pi.cjs.map +1 -1
  18. package/dist/extensions/pi.mjs.map +1 -1
  19. package/dist/footer.cjs +1 -2
  20. package/dist/footer.d.cts +2 -5
  21. package/dist/footer.d.mts +2 -5
  22. package/dist/footer.mjs +1 -2
  23. package/dist/harnessMetadata.d.cts +1 -1
  24. package/dist/harnessMetadata.d.mts +1 -1
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.d.cts +3 -15
  27. package/dist/index.d.mts +3 -15
  28. package/dist/index.mjs +1 -1
  29. package/dist/leaderRegistry.d.cts +1 -1
  30. package/dist/leaderRegistry.d.mts +1 -1
  31. package/dist/logSinkTelemetry.d.cts +1 -1
  32. package/dist/logSinkTelemetry.d.mts +1 -1
  33. package/dist/services/leader/leaderRegistry.cjs.map +1 -1
  34. package/dist/services/leader/leaderRegistry.d.cts +4 -4
  35. package/dist/services/leader/leaderRegistry.d.cts.map +1 -1
  36. package/dist/services/leader/leaderRegistry.d.mts +4 -4
  37. package/dist/services/leader/leaderRegistry.d.mts.map +1 -1
  38. package/dist/services/leader/leaderRegistry.mjs.map +1 -1
  39. package/dist/services/tools/toolInventory.cjs +1 -1
  40. package/dist/services/tools/toolInventory.cjs.map +1 -1
  41. package/dist/services/tools/toolInventory.d.cts +13 -2
  42. package/dist/services/tools/toolInventory.d.cts.map +1 -1
  43. package/dist/services/tools/toolInventory.d.mts +13 -2
  44. package/dist/services/tools/toolInventory.d.mts.map +1 -1
  45. package/dist/services/tools/toolInventory.mjs +1 -1
  46. package/dist/services/tools/toolInventory.mjs.map +1 -1
  47. package/dist/skills.cjs +1 -1
  48. package/dist/skills.d.cts +2 -1
  49. package/dist/skills.d.mts +2 -1
  50. package/dist/skills.mjs +1 -1
  51. package/dist/toolInventory.d.cts +1 -1
  52. package/dist/toolInventory.d.mts +1 -1
  53. package/dist/tui/builtinToolRender.cjs +8 -8
  54. package/dist/tui/builtinToolRender.mjs +8 -8
  55. package/dist/tui/configOverlay.cjs.map +1 -1
  56. package/dist/tui/configOverlay.d.cts +0 -0
  57. package/dist/tui/configOverlay.d.cts.map +1 -1
  58. package/dist/tui/configOverlay.d.mts +0 -0
  59. package/dist/tui/configOverlay.d.mts.map +1 -1
  60. package/dist/tui/configOverlay.mjs.map +1 -1
  61. package/dist/tui/doomEditor.cjs +1 -1
  62. package/dist/tui/doomEditor.cjs.map +1 -1
  63. package/dist/tui/doomEditor.d.mts +1 -1
  64. package/dist/tui/doomEditor.mjs +1 -1
  65. package/dist/tui/doomEditor.mjs.map +1 -1
  66. package/dist/tui/doomFooter.cjs +1 -1
  67. package/dist/tui/doomFooter.cjs.map +1 -1
  68. package/dist/tui/doomFooter.d.cts +2 -2
  69. package/dist/tui/doomFooter.d.cts.map +1 -1
  70. package/dist/tui/doomFooter.d.mts +3 -3
  71. package/dist/tui/doomFooter.d.mts.map +1 -1
  72. package/dist/tui/doomFooter.mjs +1 -1
  73. package/dist/tui/doomFooter.mjs.map +1 -1
  74. package/dist/tui/doomHeader.cjs +1 -1
  75. package/dist/tui/doomHeader.cjs.map +1 -1
  76. package/dist/tui/doomHeader.d.mts +1 -1
  77. package/dist/tui/doomHeader.mjs +1 -1
  78. package/dist/tui/doomOverlay.d.mts +1 -1
  79. package/dist/tui/leaderHints.d.mts +1 -1
  80. package/dist/tui/toolChrome.d.mts +1 -1
  81. package/dist/uiState.d.cts +1 -1
  82. package/dist/uiState.d.mts +1 -1
  83. package/package.json +14 -7
  84. package/dist/_virtual/_rolldown/runtime.mjs +0 -1
  85. package/dist/config.cjs.map +0 -1
  86. package/dist/config.d.cts.map +0 -1
  87. package/dist/config.d.mts.map +0 -1
  88. package/dist/config.mjs.map +0 -1
  89. package/dist/footer.cjs.map +0 -1
  90. package/dist/footer.d.cts.map +0 -1
  91. package/dist/footer.d.mts.map +0 -1
  92. package/dist/footer.mjs.map +0 -1
package/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # @agimon-ai/doompi-ui
2
2
 
3
- Doom-inspired interactive UI extension for Pi.
3
+ **Space is a menu only when you are not writing.**
4
4
 
5
- Owns the leader state machine, rendering, conflict handling, and the core key bindings.
6
- Space opens the leader only when the draft is empty, so a half-written prompt is never lost
7
- to a keystroke.
5
+ This is Doompi's TUI: editor, header, modeline, footer, overlays, theme, and the leader-key
6
+ registry that ties its packages together. Pressing `SPC` on an empty draft opens the map;
7
+ pressing it inside a prompt still types a space. No stolen keystrokes and no pile of slash
8
+ commands to memorize.
8
9
 
9
- Part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi), a coding agent that loads
10
- only the skills and tools you name. This package is composed by Doompi and is not usually
11
- installed on its own.
10
+ This is part of [Doompi](https://www.npmjs.com/package/@agimon-ai/doompi). Most users get
11
+ it with the distribution; install it directly when building a Pi extension against the
12
+ Doom UI contracts.
12
13
 
13
14
  ## Install
14
15
 
@@ -18,23 +19,25 @@ npm install @agimon-ai/doompi-ui
18
19
 
19
20
  ## How it loads
20
21
 
21
- Doompi loads this unconditionally. It is core, not a layer, so it does not appear in
22
- `.doom/modes.yaml`: making it optional would only create broken configurations.
23
-
24
- Extension entry: `@agimon-ai/doompi-ui/extensions/pi`
22
+ Doompi loads the UI as core. It is not a layer and does not appear in `.doom/modes.yaml`.
23
+ The bare package name follows its Pi manifest and loads the Pi adapter; the explicit
24
+ `/extensions/pi` subpath does the same job when an adapter path is required.
25
25
 
26
26
  ## Leader
27
27
 
28
- `SPC e c` opens the config panel, once the extension is loaded.
29
-
30
- ## Notes
28
+ - `SPC` opens the leader map when the draft is empty.
29
+ - `SPC e c` opens the Doompi config panel.
30
+ - Other extensions contribute bindings through `@agimon-ai/doompi-ui/leader` instead of
31
+ hardcoding their own key trees.
31
32
 
32
- Other extensions contribute bindings through the public `@agimon-ai/doompi-ui/leader` API
33
- rather than hardcoding chords.
33
+ Conflicts are handled by the registry, so two packages cannot silently claim the same
34
+ chord.
34
35
 
35
- ## Entry points
36
+ ## Public API
36
37
 
37
- 24 subpaths are declared in the `exports` field of `package.json`.
38
+ The package exposes the leader registry, shared UI state, rendering helpers, tool chrome,
39
+ header/footer/editor components, and the Doom Pi dark theme. Use declared exports rather
40
+ than reaching into `dist/`; `package.json` carries the complete list.
38
41
 
39
42
  ## License
40
43
 
@@ -1 +1 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(e,t,n)=>(s(e,t,`default`),n&&s(n,t,`default`)),l=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));exports.__exportAll=o,exports.__reExport=c,exports.__toESM=l;
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
@@ -1,2 +1,2 @@
1
- const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../telemetry/logSinkTelemetry.cjs"),n=require("../../config.cjs"),r=require("../../footer.cjs"),i=require("../../services/state/uiState.cjs"),a=require("../../services/leader/leaderRegistry.cjs"),o=require("../../tui/doomEditor.cjs"),s=require("../../tui/doomFooter.cjs"),c=require("../../tui/doomHeader.cjs"),l=require("../../tui/leaderHints.cjs");require("../../tui/theme.cjs");const u=require("../../tui/configOverlay.cjs"),d=require("../../tui/toolsOverlay.cjs"),f=require("../../services/tools/toolInventory.cjs"),p=require("./toolOverrides.cjs");let m=require("@agimon-ai/doompi-extension-contracts/leader"),h=require("node:path");h=e.__toESM(h,1);let g=require("@agimon-ai/doompi-extension-contracts/mcp-status"),_=require("@agimon-ai/doompi-extension-contracts/mode"),v=require("@agimon-ai/doompi-extension-contracts/protocol");const y=`doom-pi-leader`,b=`belowEditor`,x=`warning`,S=`doom-pi`,C=new Set([`hotkeys`]);function w(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${S} · ${r} · ${h.default.basename(t)||t}`}function T(e,T=t.createUiTelemetry()){p.registerBuiltinToolUi(e,process.cwd());let E=new i.DoomUiState,D=new r.footer_exports.DoomFooterStatusRegistry,O=(0,_.createMinorModeCatalogClient)(),k=new n.config_exports.DoomConfigRegistry,A=new a.DoomLeaderRegistry,j=new Set,M=new Map,N,P,F,I,L,R,z,B,V=new Map,H=0,U=0,W=!1,G,K,q=async()=>{if(G)try{return(await G.request(g.McpStatusQueryProtocol,{},{timeoutMs:250})).servers}catch{return}};e.registerCommand(`tools`,{description:`Browse the tools available in this session`,handler:async(t,n)=>{let r=await q(),i=f.buildToolSources({tools:e.getAllTools(),activeTools:e.getActiveTools(),...r?{mcpServers:r}:{}});await d.openToolsOverlay(n,i)}}),e.registerCommand(`config`,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await u.openConfigOverlay(t,k)}});let J=e=>{for(let n of e){let e=n.bindingId?` (${n.bindingId})`:``,r=`Leader contribution from ${n.source}${e}: ${n.message}`;j.has(r)||(j.add(r),T.recordWarning(t.UI_EVENT.leaderContributionRejected,n.message,{"leader.source":n.source,...n.bindingId?{"leader.binding.id":n.bindingId}:{}}),P?.mode===`tui`&&P.ui.notify(r,x))}},Y=(e,t)=>{let n=Symbol(e.source),r=t?e=>A.registerDeferred(e):e=>A.register(e),i=r(e);if(J(i.diagnostics),!i.accepted)return{update:()=>void 0,dispose:()=>void 0};M.set(e.source,n);let a=!1;return{update(t){a||M.get(e.source)!==n||J(r({source:e.source,bindings:t}).diagnostics)},dispose(){a||(a=!0,M.get(e.source)===n&&(M.delete(e.source),r({source:e.source,bindings:[]})))}}},X=Object.freeze({register(e){let t=Y(e,!1);return()=>t.dispose()}});K=(0,m.installDoomLeaderBootstrapHost)({register:e=>Y(e,!0)}),e.on(`session_start`,(n,r)=>{P=r;let a=++U,u=(0,v.createProtocolRuntime)({bus:e.events,source:`@agimon-ai/doompi-ui`,sessionId:r.sessionManager.getSessionId()});if(G=u,J(A.flush()),F?.(),D.reset(),F=D.bind(u),I?.(),I=O.bind(u),R?.(),k.reset(),R=k.bind(u),z?.(),B?.(),z=u.provide(m.LeaderRegistrationProtocol,({contribution:e,generation:t},n)=>{if(n.source!==e.source)throw Error(`Leader contribution source does not match the registration envelope source.`);let r=`${n.source}:${t}:${++H}`,i={source:e.source,bindings:e.bindings.map(e=>{let[t,...n]=e.path;if(!t)throw Error(`Leader binding '${e.id}' has no path.`);return{...e,path:[t,...n]}})};return V.set(r,X.register(i)),{handleId:r}}),B=u.provide(m.LeaderUnregistrationProtocol,({handleId:e})=>{let t=V.get(e);return t?(V.delete(e),t(),{removed:!0}):{removed:!1}}),W=r.sessionManager.getEntries().some(e=>e.type===`message`),r.mode!==`tui`)return;for(let e of j)r.ui.notify(e,x);let d=process.env.DOOMPI_THEME||`doom-pi-dark`,f=r.ui.setTheme(d);f.success||(r.ui.notify(`Could not apply Doom Pi theme: ${f.error}`,x),T.recordWarning(t.UI_EVENT.themeApplyFailed,f.error??`Unknown theme error`,{"ui.theme":d})),L?.(),L=O.subscribe(()=>E.setModes(i.projectMinorModeRecords(O.list()))),E.setModes(i.projectMinorModeRecords(O.list())),r.ui.setTitle(`${S} · ${h.default.basename(r.cwd)||r.cwd} · pi/coding`),r.ui.setHeader((e,t)=>new c.DoomHeader(t,r.cwd,void 0,r,()=>e.terminal.rows)),r.ui.setFooter((e,t,n)=>(N=n,new s.DoomFooter(e,t,r,n,D,E))),r.ui.setEditorComponent((n,i,s)=>new o.DoomEditor(n,i,s,E,e=>{if(!e.active){r.ui.setWidget(y,void 0,{placement:b});return}r.ui.setWidget(y,(t,n)=>new l.LeaderHints(n,e,r,N,E.getModes()),{placement:b})},void 0,r.ui.theme,{registry:A,isCommandAvailable:t=>C.has(t)||e.getCommands().some(e=>e.name===t),onLeaderAction:(e,t)=>{if(P!==r||U!==a){r.ui.notify(`Leader action ${t} is unavailable.`,x);return}u.notify(m.LeaderActionInvoked,{source:e,action:t})},onUnavailableCommand:e=>{T.recordWarning(t.UI_EVENT.leaderCommandUnavailable,`Leader command /${e} is unavailable.`,{"ui.kind":`command`}),r.ui.notify(`Leader command /${e} is unavailable.`,x)},onUnavailableAction:e=>{T.recordWarning(t.UI_EVENT.leaderActionUnavailable,`Leader action ${e} is unavailable.`,{"ui.kind":`action`}),r.ui.notify(`Leader action ${e} is unavailable.`,x)}})),T.recordEvent(t.UI_EVENT.shellInstalled,{"ui.theme":d,"ui.theme.applied":f.success,"ui.leader.group.count":A.getGroup([])?.options.length??0})}),e.on(`input`,(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||W)return;W=!0;let n=w(e.text,t.cwd);n&&t.ui.setTitle(n)}),e.on(`session_shutdown`,async(e,t)=>{++U,K?.(),K=void 0;for(let e of V.values())e();V.clear(),P=void 0,N=void 0,F?.(),F=void 0,D.reset(),I?.(),I=void 0,L?.(),L=void 0,O.reset(),R?.(),R=void 0,z?.(),z=void 0,B?.(),B=void 0,k.reset(),E.reset(),G=void 0,t.mode===`tui`&&t.ui.setWidget(y,void 0,{placement:b}),await T.shutdown()})}exports.doomPiUiExtension=T;
1
+ const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../services/leader/leaderRegistry.cjs"),n=require("../../services/state/uiState.cjs"),r=require("../../services/tools/toolInventory.cjs"),i=require("../../tui/configOverlay.cjs"),a=require("../../tui/doomEditor.cjs"),o=require("../../tui/doomFooter.cjs"),s=require("../../tui/doomHeader.cjs"),c=require("../../tui/leaderHints.cjs");require("../../tui/theme.cjs");const l=require("../../tui/toolsOverlay.cjs"),u=require("../telemetry/logSinkTelemetry.cjs"),d=require("./extensionName.cjs"),f=require("./toolOverrides.cjs");let p=require("@agimon-ai/doompi-extension-contracts/config"),m=require("node:path");m=e.__toESM(m,1);let h=require("@agimon-ai/doompi-extension-contracts/footer"),g=require("@agimon-ai/doompi-extension-contracts/leader"),_=require("@agimon-ai/doompi-extension-contracts/mcp-status"),v=require("@agimon-ai/doompi-extension-contracts/mode"),y=require("@agimon-ai/doompi-extension-contracts/protocol");const b=`doom-pi-leader`,x=`belowEditor`,S=`warning`,C=`doom-pi`,w=new Set([`hotkeys`]);function T(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${C} · ${r} · ${m.default.basename(t)||t}`}function E(e,E=u.createUiTelemetry()){f.registerBuiltinToolUi(e,process.cwd());let D=new n.DoomUiState,O=new h.DoomFooterStatusRegistry,k=(0,v.createMinorModeCatalogClient)(),A=new p.DoomConfigRegistry,j=new t.DoomLeaderRegistry,M=new Set,N=new Map,P,F,I,L,R,z,B,V,H=new Map,U=0,W=0,G=!1,K,q,J=async()=>{if(K)try{return(await K.request(_.McpStatusQueryProtocol,{},{timeoutMs:250})).servers}catch{return}};e.registerCommand(`tools`,{description:`Browse the tools available in this session`,handler:async(t,n)=>{let i=await J(),a=r.buildToolSources({tools:e.getAllTools(),activeTools:e.getActiveTools(),...i?{mcpServers:i}:{},resolveExtensionName:d.extensionName,resolveExtensionToolSource:d.extensionToolSource});await l.openToolsOverlay(n,a)}}),e.registerCommand(`config`,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await i.openConfigOverlay(t,A)}});let Y=e=>{for(let t of e){let e=t.bindingId?` (${t.bindingId})`:``,n=`Leader contribution from ${t.source}${e}: ${t.message}`;M.has(n)||(M.add(n),E.recordWarning(u.UI_EVENT.leaderContributionRejected,t.message,{"leader.source":t.source,...t.bindingId?{"leader.binding.id":t.bindingId}:{}}),F?.mode===`tui`&&F.ui.notify(n,S))}},X=(e,t)=>{let n=Symbol(e.source),r=t?e=>j.registerDeferred(e):e=>j.register(e),i=r(e);if(Y(i.diagnostics),!i.accepted)return{update:()=>void 0,dispose:()=>void 0};N.set(e.source,n);let a=!1;return{update(t){a||N.get(e.source)!==n||Y(r({source:e.source,bindings:t}).diagnostics)},dispose(){a||(a=!0,N.get(e.source)===n&&(N.delete(e.source),r({source:e.source,bindings:[]})))}}},Z=Object.freeze({register(e){let t=X(e,!1);return()=>t.dispose()}});q=(0,g.installDoomLeaderBootstrapHost)({register:e=>X(e,!0)}),e.on(`session_start`,(t,r)=>{F=r;let i=++W,l=(0,y.createProtocolRuntime)({bus:e.events,source:`@agimon-ai/doompi-ui`,sessionId:r.sessionManager.getSessionId()});if(K=l,Y(j.flush()),I?.(),O.reset(),I=O.bind(l),L?.(),L=k.bind(l),z?.(),A.reset(),z=A.bind(l),B?.(),V?.(),B=l.provide(g.LeaderRegistrationProtocol,({contribution:e,generation:t},n)=>{if(n.source!==e.source)throw Error(`Leader contribution source does not match the registration envelope source.`);let r=`${n.source}:${t}:${++U}`,i={source:e.source,bindings:e.bindings.map(e=>{let[t,...n]=e.path;if(!t)throw Error(`Leader binding '${e.id}' has no path.`);return{...e,path:[t,...n]}})};return H.set(r,Z.register(i)),{handleId:r}}),V=l.provide(g.LeaderUnregistrationProtocol,({handleId:e})=>{let t=H.get(e);return t?(H.delete(e),t(),{removed:!0}):{removed:!1}}),G=r.sessionManager.getEntries().some(e=>e.type===`message`),r.mode!==`tui`)return;for(let e of M)r.ui.notify(e,S);let d=process.env.DOOMPI_THEME||`doom-pi-dark`,f=r.ui.setTheme(d);f.success||(r.ui.notify(`Could not apply Doom Pi theme: ${f.error}`,S),E.recordWarning(u.UI_EVENT.themeApplyFailed,f.error??`Unknown theme error`,{"ui.theme":d})),R?.(),R=k.subscribe(()=>D.setModes(n.projectMinorModeRecords(k.list()))),D.setModes(n.projectMinorModeRecords(k.list())),r.ui.setTitle(`${C} · ${m.default.basename(r.cwd)||r.cwd} · pi/coding`),r.ui.setHeader((e,t)=>new s.DoomHeader(t,r.cwd,void 0,r,()=>e.terminal.rows)),r.ui.setFooter((e,t,n)=>(P=n,new o.DoomFooter(e,t,r,n,O,D))),r.ui.setEditorComponent((t,n,o)=>new a.DoomEditor(t,n,o,D,e=>{if(!e.active){r.ui.setWidget(b,void 0,{placement:x});return}r.ui.setWidget(b,(t,n)=>new c.LeaderHints(n,e,r,P,D.getModes()),{placement:x})},void 0,r.ui.theme,{registry:j,isCommandAvailable:t=>w.has(t)||e.getCommands().some(e=>e.name===t),onLeaderAction:(e,t)=>{if(F!==r||W!==i){r.ui.notify(`Leader action ${t} is unavailable.`,S);return}l.notify(g.LeaderActionInvoked,{source:e,action:t})},onUnavailableCommand:e=>{E.recordWarning(u.UI_EVENT.leaderCommandUnavailable,`Leader command /${e} is unavailable.`,{"ui.kind":`command`}),r.ui.notify(`Leader command /${e} is unavailable.`,S)},onUnavailableAction:e=>{E.recordWarning(u.UI_EVENT.leaderActionUnavailable,`Leader action ${e} is unavailable.`,{"ui.kind":`action`}),r.ui.notify(`Leader action ${e} is unavailable.`,S)}})),E.recordEvent(u.UI_EVENT.shellInstalled,{"ui.theme":d,"ui.theme.applied":f.success,"ui.leader.group.count":j.getGroup([])?.options.length??0})}),e.on(`input`,(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||G)return;G=!0;let n=T(e.text,t.cwd);n&&t.ui.setTitle(n)}),e.on(`session_shutdown`,async(e,t)=>{++W,q?.(),q=void 0;for(let e of H.values())e();H.clear(),F=void 0,P=void 0,I?.(),I=void 0,O.reset(),L?.(),L=void 0,R?.(),R=void 0,k.reset(),z?.(),z=void 0,B?.(),B=void 0,V?.(),V=void 0,A.reset(),D.reset(),K=void 0,t.mode===`tui`&&t.ui.setWidget(b,void 0,{placement:x}),await E.shutdown()})}exports.doomPiUiExtension=E;
2
2
  //# sourceMappingURL=extension.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.cjs","names":["path","createUiTelemetry","DoomUiState","createMinorModeCatalogClient","DoomLeaderRegistry","McpStatusQueryProtocol","buildToolSources","openToolsOverlay","openConfigOverlay","UI_EVENT","installDoomLeaderBootstrapHost","createProtocolRuntime","LeaderRegistrationProtocol","LeaderUnregistrationProtocol","projectMinorModeRecords","DoomHeader","DoomFooter","DoomEditor","LeaderHints","LeaderActionInvoked"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import path from 'node:path';\nimport {\n installDoomLeaderBootstrapHost,\n LeaderActionInvoked,\n type LeaderContribution,\n LeaderRegistrationProtocol,\n LeaderUnregistrationProtocol,\n} from '@agimon-ai/doompi-extension-contracts/leader';\nimport { McpStatusQueryProtocol } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport { createMinorModeCatalogClient } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createProtocolRuntime, type ProtocolRuntime } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\nimport { DoomConfigRegistry } from '../../config.ts';\nimport { DoomFooterStatusRegistry } from '../../footer.ts';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../../services/leader/leaderRegistry.ts';\nimport { DoomUiState, type LeaderSnapshot, projectMinorModeRecords } from '../../services/state/uiState.ts';\nimport { buildToolSources, type McpServerStatus } from '../../services/tools/toolInventory.ts';\nimport { openConfigOverlay } from '../../tui/configOverlay.ts';\nimport { DoomEditor } from '../../tui/doomEditor.ts';\nimport { DoomFooter } from '../../tui/doomFooter.ts';\nimport { DoomHeader } from '../../tui/doomHeader.ts';\nimport { LeaderHints } from '../../tui/leaderHints.ts';\nimport { DEFAULT_THEME_NAME } from '../../tui/theme.ts';\nimport { openToolsOverlay } from '../../tui/toolsOverlay.ts';\nimport { createUiTelemetry, UI_EVENT, type UiTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { registerBuiltinToolUi } from './toolOverrides.ts';\n\nconst LEADER_WIDGET_KEY = 'doom-pi-leader';\nconst TUI_MODE = 'tui';\nconst WIDGET_PLACEMENT = 'belowEditor';\nconst WARNING_STYLE = 'warning';\nconst THEME_ENVIRONMENT_KEY = 'DOOMPI_THEME';\nconst HOTKEYS_COMMAND = 'hotkeys';\nconst TOOLS_COMMAND = 'tools';\nconst CONFIG_COMMAND = 'config';\n/** Short: `/tools` must open promptly whether or not an MCP extension answers. */\nconst MCP_STATUS_TIMEOUT_MS = 250;\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_MESSAGE_ENTRY = 'message';\nconst INPUT_EVENT = 'input';\nconst INTERACTIVE_INPUT_SOURCE = 'interactive';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\nconst TITLE_MESSAGE_MAX_LENGTH = 64;\nconst TITLE_PREFIX = 'doom-pi';\nconst BUILTIN_LEADER_COMMANDS = new Set([HOTKEYS_COMMAND]);\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\nexport function doomPiUiExtension(pi: ExtensionAPI, telemetry: UiTelemetry = createUiTelemetry()): void {\n registerBuiltinToolUi(pi, process.cwd());\n const uiState = new DoomUiState();\n const footerStatusRegistry = new DoomFooterStatusRegistry();\n const modeCatalog = createMinorModeCatalogClient();\n const configRegistry = new DoomConfigRegistry();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n const contributionGenerations = new Map<string, symbol>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let disposeFooterStatuses: (() => void) | undefined;\n let disposeModeCatalogBinding: (() => void) | undefined;\n let disposeModeSubscription: (() => void) | undefined;\n let disposeConfigContributions: (() => void) | undefined;\n let disposeLeaderRegistration: (() => void) | undefined;\n let disposeLeaderUnregistration: (() => void) | undefined;\n const protocolContributions = new Map<string, () => void>();\n let nextProtocolHandle = 0;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let sessionProtocol: ProtocolRuntime | undefined;\n let disposeLeaderBootstrap: (() => void) | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = async (): Promise<readonly McpServerStatus[] | undefined> => {\n if (!sessionProtocol) return undefined;\n try {\n const snapshot = await sessionProtocol.request(McpStatusQueryProtocol, {}, { timeoutMs: MCP_STATUS_TIMEOUT_MS });\n return snapshot.servers;\n } catch {\n return undefined;\n }\n };\n\n pi.registerCommand(TOOLS_COMMAND, {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = await readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n });\n await openToolsOverlay(ctx, sources);\n },\n });\n\n pi.registerCommand(CONFIG_COMMAND, {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, configRegistry);\n },\n });\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) activeContext.ui.notify(message, WARNING_STYLE);\n }\n };\n\n const registerLeaderContribution = (contribution: LeaderContribution, deferred: boolean) => {\n const generation = Symbol(contribution.source);\n const register = deferred\n ? (value: LeaderContribution) => leaderRegistry.registerDeferred(value)\n : (value: LeaderContribution) => leaderRegistry.register(value);\n const result = register(contribution);\n reportDiagnostics(result.diagnostics);\n if (!result.accepted) return { update: () => undefined, dispose: () => undefined };\n contributionGenerations.set(contribution.source, generation);\n let disposed = false;\n return {\n update(bindings: LeaderContribution['bindings']) {\n if (disposed || contributionGenerations.get(contribution.source) !== generation) return;\n reportDiagnostics(register({ source: contribution.source, bindings }).diagnostics);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (contributionGenerations.get(contribution.source) !== generation) return;\n contributionGenerations.delete(contribution.source);\n register({ source: contribution.source, bindings: [] });\n },\n };\n };\n\n const leaderContext = Object.freeze({\n register(contribution: LeaderContribution) {\n const handle = registerLeaderContribution(contribution, false);\n return () => handle.dispose();\n },\n });\n // Installed during the UI factory, before the remaining Doom factories run.\n // Their registrations are validated immediately and rebuilt as one batch at\n // session_start, so the first editor always receives the complete keyspace.\n disposeLeaderBootstrap = installDoomLeaderBootstrapHost({\n register: (contribution) => registerLeaderContribution(contribution, true),\n });\n pi.on(SESSION_START_EVENT, (_event, ctx) => {\n activeContext = ctx;\n const activeGeneration = ++sessionGeneration;\n const protocol = createProtocolRuntime({\n bus: pi.events,\n source: '@agimon-ai/doompi-ui',\n sessionId: ctx.sessionManager.getSessionId(),\n });\n sessionProtocol = protocol;\n reportDiagnostics(leaderRegistry.flush());\n disposeFooterStatuses?.();\n footerStatusRegistry.reset();\n disposeFooterStatuses = footerStatusRegistry.bind(protocol);\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = modeCatalog.bind(protocol);\n // Bound above the TUI-mode guard below, like footer and mode: a headless run\n // still accepts contributions, it just never draws them.\n disposeConfigContributions?.();\n configRegistry.reset();\n disposeConfigContributions = configRegistry.bind(protocol);\n disposeLeaderRegistration?.();\n disposeLeaderUnregistration?.();\n disposeLeaderRegistration = protocol.provide(\n LeaderRegistrationProtocol,\n ({ contribution, generation }, identity) => {\n if (identity.source !== contribution.source) {\n throw new Error('Leader contribution source does not match the registration envelope source.');\n }\n const handleId = `${identity.source}:${generation}:${++nextProtocolHandle}`;\n const typedContribution: LeaderContribution = {\n source: contribution.source,\n bindings: contribution.bindings.map((binding) => {\n const [first, ...rest] = binding.path;\n if (!first) throw new Error(`Leader binding '${binding.id}' has no path.`);\n return { ...binding, path: [first, ...rest] };\n }),\n };\n protocolContributions.set(handleId, leaderContext.register(typedContribution));\n return { handleId };\n },\n );\n disposeLeaderUnregistration = protocol.provide(LeaderUnregistrationProtocol, ({ handleId }) => {\n const dispose = protocolContributions.get(handleId);\n if (!dispose) return { removed: false };\n protocolContributions.delete(handleId);\n dispose();\n return { removed: true };\n });\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) ctx.ui.notify(message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n ctx.ui.notify(`Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n // The modes go into shared state rather than a widget of their own: the\n // editor prints their names beside its badge and the leader panel prints\n // them with their detail, so there is no third surface to paint.\n disposeModeSubscription?.();\n disposeModeSubscription = modeCatalog.subscribe(() =>\n uiState.setModes(projectMinorModeRecords(modeCatalog.list())),\n );\n uiState.setModes(projectMinorModeRecords(modeCatalog.list()));\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, footerStatusRegistry, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) => new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.has(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n protocol.notify(LeaderActionInvoked, { source, action });\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n ctx.ui.notify(`Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n });\n\n pi.on(INPUT_EVENT, (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n });\n\n pi.on(SESSION_SHUTDOWN_EVENT, async (_event, ctx) => {\n ++sessionGeneration;\n disposeLeaderBootstrap?.();\n disposeLeaderBootstrap = undefined;\n for (const dispose of protocolContributions.values()) dispose();\n protocolContributions.clear();\n activeContext = undefined;\n footerData = undefined;\n disposeFooterStatuses?.();\n disposeFooterStatuses = undefined;\n footerStatusRegistry.reset();\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = undefined;\n disposeModeSubscription?.();\n disposeModeSubscription = undefined;\n modeCatalog.reset();\n disposeConfigContributions?.();\n disposeConfigContributions = undefined;\n disposeLeaderRegistration?.();\n disposeLeaderRegistration = undefined;\n disposeLeaderUnregistration?.();\n disposeLeaderUnregistration = undefined;\n configRegistry.reset();\n uiState.reset();\n sessionProtocol = undefined;\n if (ctx.mode === TUI_MODE) ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n await telemetry.shutdown();\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extension.cjs","names":["path","createUiTelemetry","DoomUiState","DoomFooterStatusRegistry","createMinorModeCatalogClient","DoomConfigRegistry","DoomLeaderRegistry","McpStatusQueryProtocol","buildToolSources","extensionName","extensionToolSource","openToolsOverlay","openConfigOverlay","UI_EVENT","installDoomLeaderBootstrapHost","createProtocolRuntime","LeaderRegistrationProtocol","LeaderUnregistrationProtocol","projectMinorModeRecords","DoomHeader","DoomFooter","DoomEditor","LeaderHints","LeaderActionInvoked"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import path from 'node:path';\nimport { DoomConfigRegistry } from '@agimon-ai/doompi-extension-contracts/config';\nimport { DoomFooterStatusRegistry } from '@agimon-ai/doompi-extension-contracts/footer';\nimport {\n installDoomLeaderBootstrapHost,\n LeaderActionInvoked,\n type LeaderContribution,\n LeaderRegistrationProtocol,\n LeaderUnregistrationProtocol,\n} from '@agimon-ai/doompi-extension-contracts/leader';\nimport { McpStatusQueryProtocol } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport { createMinorModeCatalogClient } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createProtocolRuntime, type ProtocolRuntime } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../../services/leader/leaderRegistry.ts';\nimport { DoomUiState, type LeaderSnapshot, projectMinorModeRecords } from '../../services/state/uiState.ts';\nimport { buildToolSources, type McpServerStatus } from '../../services/tools/toolInventory.ts';\nimport { openConfigOverlay } from '../../tui/configOverlay.ts';\nimport { DoomEditor } from '../../tui/doomEditor.ts';\nimport { DoomFooter } from '../../tui/doomFooter.ts';\nimport { DoomHeader } from '../../tui/doomHeader.ts';\nimport { LeaderHints } from '../../tui/leaderHints.ts';\nimport { DEFAULT_THEME_NAME } from '../../tui/theme.ts';\nimport { openToolsOverlay } from '../../tui/toolsOverlay.ts';\nimport { createUiTelemetry, UI_EVENT, type UiTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { extensionName, extensionToolSource } from './extensionName.ts';\nimport { registerBuiltinToolUi } from './toolOverrides.ts';\n\nconst LEADER_WIDGET_KEY = 'doom-pi-leader';\nconst TUI_MODE = 'tui';\nconst WIDGET_PLACEMENT = 'belowEditor';\nconst WARNING_STYLE = 'warning';\nconst THEME_ENVIRONMENT_KEY = 'DOOMPI_THEME';\nconst HOTKEYS_COMMAND = 'hotkeys';\nconst TOOLS_COMMAND = 'tools';\nconst CONFIG_COMMAND = 'config';\n/** Short: `/tools` must open promptly whether or not an MCP extension answers. */\nconst MCP_STATUS_TIMEOUT_MS = 250;\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_MESSAGE_ENTRY = 'message';\nconst INPUT_EVENT = 'input';\nconst INTERACTIVE_INPUT_SOURCE = 'interactive';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\nconst TITLE_MESSAGE_MAX_LENGTH = 64;\nconst TITLE_PREFIX = 'doom-pi';\nconst BUILTIN_LEADER_COMMANDS = new Set([HOTKEYS_COMMAND]);\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\nexport function doomPiUiExtension(pi: ExtensionAPI, telemetry: UiTelemetry = createUiTelemetry()): void {\n registerBuiltinToolUi(pi, process.cwd());\n const uiState = new DoomUiState();\n const footerStatusRegistry = new DoomFooterStatusRegistry();\n const modeCatalog = createMinorModeCatalogClient();\n const configRegistry = new DoomConfigRegistry();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n const contributionGenerations = new Map<string, symbol>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let disposeFooterStatuses: (() => void) | undefined;\n let disposeModeCatalogBinding: (() => void) | undefined;\n let disposeModeSubscription: (() => void) | undefined;\n let disposeConfigContributions: (() => void) | undefined;\n let disposeLeaderRegistration: (() => void) | undefined;\n let disposeLeaderUnregistration: (() => void) | undefined;\n const protocolContributions = new Map<string, () => void>();\n let nextProtocolHandle = 0;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let sessionProtocol: ProtocolRuntime | undefined;\n let disposeLeaderBootstrap: (() => void) | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = async (): Promise<readonly McpServerStatus[] | undefined> => {\n if (!sessionProtocol) return undefined;\n try {\n const snapshot = await sessionProtocol.request(McpStatusQueryProtocol, {}, { timeoutMs: MCP_STATUS_TIMEOUT_MS });\n return snapshot.servers;\n } catch {\n return undefined;\n }\n };\n\n pi.registerCommand(TOOLS_COMMAND, {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = await readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionToolSource: extensionToolSource,\n });\n await openToolsOverlay(ctx, sources);\n },\n });\n\n pi.registerCommand(CONFIG_COMMAND, {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, configRegistry);\n },\n });\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) activeContext.ui.notify(message, WARNING_STYLE);\n }\n };\n\n const registerLeaderContribution = (contribution: LeaderContribution, deferred: boolean) => {\n const generation = Symbol(contribution.source);\n const register = deferred\n ? (value: LeaderContribution) => leaderRegistry.registerDeferred(value)\n : (value: LeaderContribution) => leaderRegistry.register(value);\n const result = register(contribution);\n reportDiagnostics(result.diagnostics);\n if (!result.accepted) return { update: () => undefined, dispose: () => undefined };\n contributionGenerations.set(contribution.source, generation);\n let disposed = false;\n return {\n update(bindings: LeaderContribution['bindings']) {\n if (disposed || contributionGenerations.get(contribution.source) !== generation) return;\n reportDiagnostics(register({ source: contribution.source, bindings }).diagnostics);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (contributionGenerations.get(contribution.source) !== generation) return;\n contributionGenerations.delete(contribution.source);\n register({ source: contribution.source, bindings: [] });\n },\n };\n };\n\n const leaderContext = Object.freeze({\n register(contribution: LeaderContribution) {\n const handle = registerLeaderContribution(contribution, false);\n return () => handle.dispose();\n },\n });\n // Installed during the UI factory, before the remaining Doom factories run.\n // Their registrations are validated immediately and rebuilt as one batch at\n // session_start, so the first editor always receives the complete keyspace.\n disposeLeaderBootstrap = installDoomLeaderBootstrapHost({\n register: (contribution) => registerLeaderContribution(contribution, true),\n });\n pi.on(SESSION_START_EVENT, (_event, ctx) => {\n activeContext = ctx;\n const activeGeneration = ++sessionGeneration;\n const protocol = createProtocolRuntime({\n bus: pi.events,\n source: '@agimon-ai/doompi-ui',\n sessionId: ctx.sessionManager.getSessionId(),\n });\n sessionProtocol = protocol;\n reportDiagnostics(leaderRegistry.flush());\n disposeFooterStatuses?.();\n footerStatusRegistry.reset();\n disposeFooterStatuses = footerStatusRegistry.bind(protocol);\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = modeCatalog.bind(protocol);\n // Bound above the TUI-mode guard below, like footer and mode: a headless run\n // still accepts contributions, it just never draws them.\n disposeConfigContributions?.();\n configRegistry.reset();\n disposeConfigContributions = configRegistry.bind(protocol);\n disposeLeaderRegistration?.();\n disposeLeaderUnregistration?.();\n disposeLeaderRegistration = protocol.provide(\n LeaderRegistrationProtocol,\n ({ contribution, generation }, identity) => {\n if (identity.source !== contribution.source) {\n throw new Error('Leader contribution source does not match the registration envelope source.');\n }\n const handleId = `${identity.source}:${generation}:${++nextProtocolHandle}`;\n const typedContribution: LeaderContribution = {\n source: contribution.source,\n bindings: contribution.bindings.map((binding) => {\n const [first, ...rest] = binding.path;\n if (!first) throw new Error(`Leader binding '${binding.id}' has no path.`);\n return { ...binding, path: [first, ...rest] };\n }),\n };\n protocolContributions.set(handleId, leaderContext.register(typedContribution));\n return { handleId };\n },\n );\n disposeLeaderUnregistration = protocol.provide(LeaderUnregistrationProtocol, ({ handleId }) => {\n const dispose = protocolContributions.get(handleId);\n if (!dispose) return { removed: false };\n protocolContributions.delete(handleId);\n dispose();\n return { removed: true };\n });\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) ctx.ui.notify(message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n ctx.ui.notify(`Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n // The modes go into shared state rather than a widget of their own: the\n // editor prints their names beside its badge and the leader panel prints\n // them with their detail, so there is no third surface to paint.\n disposeModeSubscription?.();\n disposeModeSubscription = modeCatalog.subscribe(() =>\n uiState.setModes(projectMinorModeRecords(modeCatalog.list())),\n );\n uiState.setModes(projectMinorModeRecords(modeCatalog.list()));\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, footerStatusRegistry, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) => new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.has(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n protocol.notify(LeaderActionInvoked, { source, action });\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n ctx.ui.notify(`Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n });\n\n pi.on(INPUT_EVENT, (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n });\n\n pi.on(SESSION_SHUTDOWN_EVENT, async (_event, ctx) => {\n ++sessionGeneration;\n disposeLeaderBootstrap?.();\n disposeLeaderBootstrap = undefined;\n for (const dispose of protocolContributions.values()) dispose();\n protocolContributions.clear();\n activeContext = undefined;\n footerData = undefined;\n disposeFooterStatuses?.();\n disposeFooterStatuses = undefined;\n footerStatusRegistry.reset();\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = undefined;\n disposeModeSubscription?.();\n disposeModeSubscription = undefined;\n modeCatalog.reset();\n disposeConfigContributions?.();\n disposeConfigContributions = undefined;\n disposeLeaderRegistration?.();\n disposeLeaderRegistration = undefined;\n disposeLeaderUnregistration?.();\n disposeLeaderUnregistration = undefined;\n configRegistry.reset();\n uiState.reset();\n sessionProtocol = undefined;\n if (ctx.mode === TUI_MODE) ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n await telemetry.shutdown();\n });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;iBAqDgB,kBAAkB,IAAI,cAAc,YAAW"}
1
+ {"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;iBAsDgB,kBAAkB,IAAI,cAAc,YAAW"}
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;iBAqDgB,kBAAkB,IAAI,cAAc,YAAW"}
1
+ {"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;iBAsDgB,kBAAkB,IAAI,cAAc,YAAW"}
@@ -1,2 +1,2 @@
1
- import{UI_EVENT as e,createUiTelemetry as t}from"../telemetry/logSinkTelemetry.mjs";import{config_exports as n}from"../../config.mjs";import{footer_exports as r}from"../../footer.mjs";import{DoomUiState as i,projectMinorModeRecords as a}from"../../services/state/uiState.mjs";import{DoomLeaderRegistry as o}from"../../services/leader/leaderRegistry.mjs";import{DoomEditor as s}from"../../tui/doomEditor.mjs";import{DoomFooter as c}from"../../tui/doomFooter.mjs";import{DoomHeader as l}from"../../tui/doomHeader.mjs";import{LeaderHints as u}from"../../tui/leaderHints.mjs";import"../../tui/theme.mjs";import{openConfigOverlay as d}from"../../tui/configOverlay.mjs";import{openToolsOverlay as f}from"../../tui/toolsOverlay.mjs";import{buildToolSources as p}from"../../services/tools/toolInventory.mjs";import{registerBuiltinToolUi as m}from"./toolOverrides.mjs";import{LeaderActionInvoked as h,LeaderRegistrationProtocol as g,LeaderUnregistrationProtocol as _,installDoomLeaderBootstrapHost as v}from"@agimon-ai/doompi-extension-contracts/leader";import y from"node:path";import{McpStatusQueryProtocol as b}from"@agimon-ai/doompi-extension-contracts/mcp-status";import{createMinorModeCatalogClient as x}from"@agimon-ai/doompi-extension-contracts/mode";import{createProtocolRuntime as S}from"@agimon-ai/doompi-extension-contracts/protocol";const C=`doom-pi-leader`,w=`belowEditor`,T=`warning`,E=`doom-pi`,D=new Set([`hotkeys`]);function O(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${E} · ${r} · ${y.basename(t)||t}`}function k(k,A=t()){m(k,process.cwd());let j=new i,M=new r.DoomFooterStatusRegistry,N=x(),P=new n.DoomConfigRegistry,F=new o,I=new Set,L=new Map,R,z,B,V,H,U,W,G,K=new Map,q=0,J=0,Y=!1,X,Z,ee=async()=>{if(X)try{return(await X.request(b,{},{timeoutMs:250})).servers}catch{return}};k.registerCommand(`tools`,{description:`Browse the tools available in this session`,handler:async(e,t)=>{let n=await ee(),r=p({tools:k.getAllTools(),activeTools:k.getActiveTools(),...n?{mcpServers:n}:{}});await f(t,r)}}),k.registerCommand(`config`,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await d(t,P)}});let Q=t=>{for(let n of t){let t=n.bindingId?` (${n.bindingId})`:``,r=`Leader contribution from ${n.source}${t}: ${n.message}`;I.has(r)||(I.add(r),A.recordWarning(e.leaderContributionRejected,n.message,{"leader.source":n.source,...n.bindingId?{"leader.binding.id":n.bindingId}:{}}),z?.mode===`tui`&&z.ui.notify(r,T))}},$=(e,t)=>{let n=Symbol(e.source),r=t?e=>F.registerDeferred(e):e=>F.register(e),i=r(e);if(Q(i.diagnostics),!i.accepted)return{update:()=>void 0,dispose:()=>void 0};L.set(e.source,n);let a=!1;return{update(t){a||L.get(e.source)!==n||Q(r({source:e.source,bindings:t}).diagnostics)},dispose(){a||(a=!0,L.get(e.source)===n&&(L.delete(e.source),r({source:e.source,bindings:[]})))}}},te=Object.freeze({register(e){let t=$(e,!1);return()=>t.dispose()}});Z=v({register:e=>$(e,!0)}),k.on(`session_start`,(t,n)=>{z=n;let r=++J,i=S({bus:k.events,source:`@agimon-ai/doompi-ui`,sessionId:n.sessionManager.getSessionId()});if(X=i,Q(F.flush()),B?.(),M.reset(),B=M.bind(i),V?.(),V=N.bind(i),U?.(),P.reset(),U=P.bind(i),W?.(),G?.(),W=i.provide(g,({contribution:e,generation:t},n)=>{if(n.source!==e.source)throw Error(`Leader contribution source does not match the registration envelope source.`);let r=`${n.source}:${t}:${++q}`,i={source:e.source,bindings:e.bindings.map(e=>{let[t,...n]=e.path;if(!t)throw Error(`Leader binding '${e.id}' has no path.`);return{...e,path:[t,...n]}})};return K.set(r,te.register(i)),{handleId:r}}),G=i.provide(_,({handleId:e})=>{let t=K.get(e);return t?(K.delete(e),t(),{removed:!0}):{removed:!1}}),Y=n.sessionManager.getEntries().some(e=>e.type===`message`),n.mode!==`tui`)return;for(let e of I)n.ui.notify(e,T);let o=process.env.DOOMPI_THEME||`doom-pi-dark`,d=n.ui.setTheme(o);d.success||(n.ui.notify(`Could not apply Doom Pi theme: ${d.error}`,T),A.recordWarning(e.themeApplyFailed,d.error??`Unknown theme error`,{"ui.theme":o})),H?.(),H=N.subscribe(()=>j.setModes(a(N.list()))),j.setModes(a(N.list())),n.ui.setTitle(`${E} · ${y.basename(n.cwd)||n.cwd} · pi/coding`),n.ui.setHeader((e,t)=>new l(t,n.cwd,void 0,n,()=>e.terminal.rows)),n.ui.setFooter((e,t,r)=>(R=r,new c(e,t,n,r,M,j))),n.ui.setEditorComponent((t,a,o)=>new s(t,a,o,j,e=>{if(!e.active){n.ui.setWidget(C,void 0,{placement:w});return}n.ui.setWidget(C,(t,r)=>new u(r,e,n,R,j.getModes()),{placement:w})},void 0,n.ui.theme,{registry:F,isCommandAvailable:e=>D.has(e)||k.getCommands().some(t=>t.name===e),onLeaderAction:(e,t)=>{if(z!==n||J!==r){n.ui.notify(`Leader action ${t} is unavailable.`,T);return}i.notify(h,{source:e,action:t})},onUnavailableCommand:t=>{A.recordWarning(e.leaderCommandUnavailable,`Leader command /${t} is unavailable.`,{"ui.kind":`command`}),n.ui.notify(`Leader command /${t} is unavailable.`,T)},onUnavailableAction:t=>{A.recordWarning(e.leaderActionUnavailable,`Leader action ${t} is unavailable.`,{"ui.kind":`action`}),n.ui.notify(`Leader action ${t} is unavailable.`,T)}})),A.recordEvent(e.shellInstalled,{"ui.theme":o,"ui.theme.applied":d.success,"ui.leader.group.count":F.getGroup([])?.options.length??0})}),k.on(`input`,(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||Y)return;Y=!0;let n=O(e.text,t.cwd);n&&t.ui.setTitle(n)}),k.on(`session_shutdown`,async(e,t)=>{++J,Z?.(),Z=void 0;for(let e of K.values())e();K.clear(),z=void 0,R=void 0,B?.(),B=void 0,M.reset(),V?.(),V=void 0,H?.(),H=void 0,N.reset(),U?.(),U=void 0,W?.(),W=void 0,G?.(),G=void 0,P.reset(),j.reset(),X=void 0,t.mode===`tui`&&t.ui.setWidget(C,void 0,{placement:w}),await A.shutdown()})}export{k as doomPiUiExtension};
1
+ import{DoomLeaderRegistry as e}from"../../services/leader/leaderRegistry.mjs";import{DoomUiState as t,projectMinorModeRecords as n}from"../../services/state/uiState.mjs";import{buildToolSources as r}from"../../services/tools/toolInventory.mjs";import{openConfigOverlay as i}from"../../tui/configOverlay.mjs";import{DoomEditor as a}from"../../tui/doomEditor.mjs";import{DoomFooter as o}from"../../tui/doomFooter.mjs";import{DoomHeader as s}from"../../tui/doomHeader.mjs";import{LeaderHints as c}from"../../tui/leaderHints.mjs";import"../../tui/theme.mjs";import{openToolsOverlay as l}from"../../tui/toolsOverlay.mjs";import{UI_EVENT as u,createUiTelemetry as d}from"../telemetry/logSinkTelemetry.mjs";import{extensionName as f,extensionToolSource as p}from"./extensionName.mjs";import{registerBuiltinToolUi as m}from"./toolOverrides.mjs";import{DoomConfigRegistry as ee}from"@agimon-ai/doompi-extension-contracts/config";import h from"node:path";import{DoomFooterStatusRegistry as te}from"@agimon-ai/doompi-extension-contracts/footer";import{LeaderActionInvoked as g,LeaderRegistrationProtocol as _,LeaderUnregistrationProtocol as v,installDoomLeaderBootstrapHost as y}from"@agimon-ai/doompi-extension-contracts/leader";import{McpStatusQueryProtocol as b}from"@agimon-ai/doompi-extension-contracts/mcp-status";import{createMinorModeCatalogClient as x}from"@agimon-ai/doompi-extension-contracts/mode";import{createProtocolRuntime as S}from"@agimon-ai/doompi-extension-contracts/protocol";const C=`doom-pi-leader`,w=`belowEditor`,T=`warning`,E=`doom-pi`,D=new Set([`hotkeys`]);function O(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${E} · ${r} · ${h.basename(t)||t}`}function k(k,A=d()){m(k,process.cwd());let j=new t,M=new te,N=x(),P=new ee,F=new e,I=new Set,L=new Map,R,z,B,V,H,U,W,G,K=new Map,q=0,J=0,Y=!1,X,Z,ne=async()=>{if(X)try{return(await X.request(b,{},{timeoutMs:250})).servers}catch{return}};k.registerCommand(`tools`,{description:`Browse the tools available in this session`,handler:async(e,t)=>{let n=await ne(),i=r({tools:k.getAllTools(),activeTools:k.getActiveTools(),...n?{mcpServers:n}:{},resolveExtensionName:f,resolveExtensionToolSource:p});await l(t,i)}}),k.registerCommand(`config`,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await i(t,P)}});let Q=e=>{for(let t of e){let e=t.bindingId?` (${t.bindingId})`:``,n=`Leader contribution from ${t.source}${e}: ${t.message}`;I.has(n)||(I.add(n),A.recordWarning(u.leaderContributionRejected,t.message,{"leader.source":t.source,...t.bindingId?{"leader.binding.id":t.bindingId}:{}}),z?.mode===`tui`&&z.ui.notify(n,T))}},$=(e,t)=>{let n=Symbol(e.source),r=t?e=>F.registerDeferred(e):e=>F.register(e),i=r(e);if(Q(i.diagnostics),!i.accepted)return{update:()=>void 0,dispose:()=>void 0};L.set(e.source,n);let a=!1;return{update(t){a||L.get(e.source)!==n||Q(r({source:e.source,bindings:t}).diagnostics)},dispose(){a||(a=!0,L.get(e.source)===n&&(L.delete(e.source),r({source:e.source,bindings:[]})))}}},re=Object.freeze({register(e){let t=$(e,!1);return()=>t.dispose()}});Z=y({register:e=>$(e,!0)}),k.on(`session_start`,(e,t)=>{z=t;let r=++J,i=S({bus:k.events,source:`@agimon-ai/doompi-ui`,sessionId:t.sessionManager.getSessionId()});if(X=i,Q(F.flush()),B?.(),M.reset(),B=M.bind(i),V?.(),V=N.bind(i),U?.(),P.reset(),U=P.bind(i),W?.(),G?.(),W=i.provide(_,({contribution:e,generation:t},n)=>{if(n.source!==e.source)throw Error(`Leader contribution source does not match the registration envelope source.`);let r=`${n.source}:${t}:${++q}`,i={source:e.source,bindings:e.bindings.map(e=>{let[t,...n]=e.path;if(!t)throw Error(`Leader binding '${e.id}' has no path.`);return{...e,path:[t,...n]}})};return K.set(r,re.register(i)),{handleId:r}}),G=i.provide(v,({handleId:e})=>{let t=K.get(e);return t?(K.delete(e),t(),{removed:!0}):{removed:!1}}),Y=t.sessionManager.getEntries().some(e=>e.type===`message`),t.mode!==`tui`)return;for(let e of I)t.ui.notify(e,T);let l=process.env.DOOMPI_THEME||`doom-pi-dark`,d=t.ui.setTheme(l);d.success||(t.ui.notify(`Could not apply Doom Pi theme: ${d.error}`,T),A.recordWarning(u.themeApplyFailed,d.error??`Unknown theme error`,{"ui.theme":l})),H?.(),H=N.subscribe(()=>j.setModes(n(N.list()))),j.setModes(n(N.list())),t.ui.setTitle(`${E} · ${h.basename(t.cwd)||t.cwd} · pi/coding`),t.ui.setHeader((e,n)=>new s(n,t.cwd,void 0,t,()=>e.terminal.rows)),t.ui.setFooter((e,n,r)=>(R=r,new o(e,n,t,r,M,j))),t.ui.setEditorComponent((e,n,o)=>new a(e,n,o,j,e=>{if(!e.active){t.ui.setWidget(C,void 0,{placement:w});return}t.ui.setWidget(C,(n,r)=>new c(r,e,t,R,j.getModes()),{placement:w})},void 0,t.ui.theme,{registry:F,isCommandAvailable:e=>D.has(e)||k.getCommands().some(t=>t.name===e),onLeaderAction:(e,n)=>{if(z!==t||J!==r){t.ui.notify(`Leader action ${n} is unavailable.`,T);return}i.notify(g,{source:e,action:n})},onUnavailableCommand:e=>{A.recordWarning(u.leaderCommandUnavailable,`Leader command /${e} is unavailable.`,{"ui.kind":`command`}),t.ui.notify(`Leader command /${e} is unavailable.`,T)},onUnavailableAction:e=>{A.recordWarning(u.leaderActionUnavailable,`Leader action ${e} is unavailable.`,{"ui.kind":`action`}),t.ui.notify(`Leader action ${e} is unavailable.`,T)}})),A.recordEvent(u.shellInstalled,{"ui.theme":l,"ui.theme.applied":d.success,"ui.leader.group.count":F.getGroup([])?.options.length??0})}),k.on(`input`,(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||Y)return;Y=!0;let n=O(e.text,t.cwd);n&&t.ui.setTitle(n)}),k.on(`session_shutdown`,async(e,t)=>{++J,Z?.(),Z=void 0;for(let e of K.values())e();K.clear(),z=void 0,R=void 0,B?.(),B=void 0,M.reset(),V?.(),V=void 0,H?.(),H=void 0,N.reset(),U?.(),U=void 0,W?.(),W=void 0,G?.(),G=void 0,P.reset(),j.reset(),X=void 0,t.mode===`tui`&&t.ui.setWidget(C,void 0,{placement:w}),await A.shutdown()})}export{k as doomPiUiExtension};
2
2
  //# sourceMappingURL=extension.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension.mjs","names":["DoomFooterStatusRegistry","DoomConfigRegistry"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import path from 'node:path';\nimport {\n installDoomLeaderBootstrapHost,\n LeaderActionInvoked,\n type LeaderContribution,\n LeaderRegistrationProtocol,\n LeaderUnregistrationProtocol,\n} from '@agimon-ai/doompi-extension-contracts/leader';\nimport { McpStatusQueryProtocol } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport { createMinorModeCatalogClient } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createProtocolRuntime, type ProtocolRuntime } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\nimport { DoomConfigRegistry } from '../../config.ts';\nimport { DoomFooterStatusRegistry } from '../../footer.ts';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../../services/leader/leaderRegistry.ts';\nimport { DoomUiState, type LeaderSnapshot, projectMinorModeRecords } from '../../services/state/uiState.ts';\nimport { buildToolSources, type McpServerStatus } from '../../services/tools/toolInventory.ts';\nimport { openConfigOverlay } from '../../tui/configOverlay.ts';\nimport { DoomEditor } from '../../tui/doomEditor.ts';\nimport { DoomFooter } from '../../tui/doomFooter.ts';\nimport { DoomHeader } from '../../tui/doomHeader.ts';\nimport { LeaderHints } from '../../tui/leaderHints.ts';\nimport { DEFAULT_THEME_NAME } from '../../tui/theme.ts';\nimport { openToolsOverlay } from '../../tui/toolsOverlay.ts';\nimport { createUiTelemetry, UI_EVENT, type UiTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { registerBuiltinToolUi } from './toolOverrides.ts';\n\nconst LEADER_WIDGET_KEY = 'doom-pi-leader';\nconst TUI_MODE = 'tui';\nconst WIDGET_PLACEMENT = 'belowEditor';\nconst WARNING_STYLE = 'warning';\nconst THEME_ENVIRONMENT_KEY = 'DOOMPI_THEME';\nconst HOTKEYS_COMMAND = 'hotkeys';\nconst TOOLS_COMMAND = 'tools';\nconst CONFIG_COMMAND = 'config';\n/** Short: `/tools` must open promptly whether or not an MCP extension answers. */\nconst MCP_STATUS_TIMEOUT_MS = 250;\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_MESSAGE_ENTRY = 'message';\nconst INPUT_EVENT = 'input';\nconst INTERACTIVE_INPUT_SOURCE = 'interactive';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\nconst TITLE_MESSAGE_MAX_LENGTH = 64;\nconst TITLE_PREFIX = 'doom-pi';\nconst BUILTIN_LEADER_COMMANDS = new Set([HOTKEYS_COMMAND]);\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\nexport function doomPiUiExtension(pi: ExtensionAPI, telemetry: UiTelemetry = createUiTelemetry()): void {\n registerBuiltinToolUi(pi, process.cwd());\n const uiState = new DoomUiState();\n const footerStatusRegistry = new DoomFooterStatusRegistry();\n const modeCatalog = createMinorModeCatalogClient();\n const configRegistry = new DoomConfigRegistry();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n const contributionGenerations = new Map<string, symbol>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let disposeFooterStatuses: (() => void) | undefined;\n let disposeModeCatalogBinding: (() => void) | undefined;\n let disposeModeSubscription: (() => void) | undefined;\n let disposeConfigContributions: (() => void) | undefined;\n let disposeLeaderRegistration: (() => void) | undefined;\n let disposeLeaderUnregistration: (() => void) | undefined;\n const protocolContributions = new Map<string, () => void>();\n let nextProtocolHandle = 0;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let sessionProtocol: ProtocolRuntime | undefined;\n let disposeLeaderBootstrap: (() => void) | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = async (): Promise<readonly McpServerStatus[] | undefined> => {\n if (!sessionProtocol) return undefined;\n try {\n const snapshot = await sessionProtocol.request(McpStatusQueryProtocol, {}, { timeoutMs: MCP_STATUS_TIMEOUT_MS });\n return snapshot.servers;\n } catch {\n return undefined;\n }\n };\n\n pi.registerCommand(TOOLS_COMMAND, {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = await readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n });\n await openToolsOverlay(ctx, sources);\n },\n });\n\n pi.registerCommand(CONFIG_COMMAND, {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, configRegistry);\n },\n });\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) activeContext.ui.notify(message, WARNING_STYLE);\n }\n };\n\n const registerLeaderContribution = (contribution: LeaderContribution, deferred: boolean) => {\n const generation = Symbol(contribution.source);\n const register = deferred\n ? (value: LeaderContribution) => leaderRegistry.registerDeferred(value)\n : (value: LeaderContribution) => leaderRegistry.register(value);\n const result = register(contribution);\n reportDiagnostics(result.diagnostics);\n if (!result.accepted) return { update: () => undefined, dispose: () => undefined };\n contributionGenerations.set(contribution.source, generation);\n let disposed = false;\n return {\n update(bindings: LeaderContribution['bindings']) {\n if (disposed || contributionGenerations.get(contribution.source) !== generation) return;\n reportDiagnostics(register({ source: contribution.source, bindings }).diagnostics);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (contributionGenerations.get(contribution.source) !== generation) return;\n contributionGenerations.delete(contribution.source);\n register({ source: contribution.source, bindings: [] });\n },\n };\n };\n\n const leaderContext = Object.freeze({\n register(contribution: LeaderContribution) {\n const handle = registerLeaderContribution(contribution, false);\n return () => handle.dispose();\n },\n });\n // Installed during the UI factory, before the remaining Doom factories run.\n // Their registrations are validated immediately and rebuilt as one batch at\n // session_start, so the first editor always receives the complete keyspace.\n disposeLeaderBootstrap = installDoomLeaderBootstrapHost({\n register: (contribution) => registerLeaderContribution(contribution, true),\n });\n pi.on(SESSION_START_EVENT, (_event, ctx) => {\n activeContext = ctx;\n const activeGeneration = ++sessionGeneration;\n const protocol = createProtocolRuntime({\n bus: pi.events,\n source: '@agimon-ai/doompi-ui',\n sessionId: ctx.sessionManager.getSessionId(),\n });\n sessionProtocol = protocol;\n reportDiagnostics(leaderRegistry.flush());\n disposeFooterStatuses?.();\n footerStatusRegistry.reset();\n disposeFooterStatuses = footerStatusRegistry.bind(protocol);\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = modeCatalog.bind(protocol);\n // Bound above the TUI-mode guard below, like footer and mode: a headless run\n // still accepts contributions, it just never draws them.\n disposeConfigContributions?.();\n configRegistry.reset();\n disposeConfigContributions = configRegistry.bind(protocol);\n disposeLeaderRegistration?.();\n disposeLeaderUnregistration?.();\n disposeLeaderRegistration = protocol.provide(\n LeaderRegistrationProtocol,\n ({ contribution, generation }, identity) => {\n if (identity.source !== contribution.source) {\n throw new Error('Leader contribution source does not match the registration envelope source.');\n }\n const handleId = `${identity.source}:${generation}:${++nextProtocolHandle}`;\n const typedContribution: LeaderContribution = {\n source: contribution.source,\n bindings: contribution.bindings.map((binding) => {\n const [first, ...rest] = binding.path;\n if (!first) throw new Error(`Leader binding '${binding.id}' has no path.`);\n return { ...binding, path: [first, ...rest] };\n }),\n };\n protocolContributions.set(handleId, leaderContext.register(typedContribution));\n return { handleId };\n },\n );\n disposeLeaderUnregistration = protocol.provide(LeaderUnregistrationProtocol, ({ handleId }) => {\n const dispose = protocolContributions.get(handleId);\n if (!dispose) return { removed: false };\n protocolContributions.delete(handleId);\n dispose();\n return { removed: true };\n });\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) ctx.ui.notify(message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n ctx.ui.notify(`Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n // The modes go into shared state rather than a widget of their own: the\n // editor prints their names beside its badge and the leader panel prints\n // them with their detail, so there is no third surface to paint.\n disposeModeSubscription?.();\n disposeModeSubscription = modeCatalog.subscribe(() =>\n uiState.setModes(projectMinorModeRecords(modeCatalog.list())),\n );\n uiState.setModes(projectMinorModeRecords(modeCatalog.list()));\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, footerStatusRegistry, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) => new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.has(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n protocol.notify(LeaderActionInvoked, { source, action });\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n ctx.ui.notify(`Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n });\n\n pi.on(INPUT_EVENT, (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n });\n\n pi.on(SESSION_SHUTDOWN_EVENT, async (_event, ctx) => {\n ++sessionGeneration;\n disposeLeaderBootstrap?.();\n disposeLeaderBootstrap = undefined;\n for (const dispose of protocolContributions.values()) dispose();\n protocolContributions.clear();\n activeContext = undefined;\n footerData = undefined;\n disposeFooterStatuses?.();\n disposeFooterStatuses = undefined;\n footerStatusRegistry.reset();\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = undefined;\n disposeModeSubscription?.();\n disposeModeSubscription = undefined;\n modeCatalog.reset();\n disposeConfigContributions?.();\n disposeConfigContributions = undefined;\n disposeLeaderRegistration?.();\n disposeLeaderRegistration = undefined;\n disposeLeaderUnregistration?.();\n disposeLeaderUnregistration = undefined;\n configRegistry.reset();\n uiState.reset();\n sessionProtocol = undefined;\n if (ctx.mode === TUI_MODE) ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n await telemetry.shutdown();\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import path from 'node:path';\nimport { DoomConfigRegistry } from '@agimon-ai/doompi-extension-contracts/config';\nimport { DoomFooterStatusRegistry } from '@agimon-ai/doompi-extension-contracts/footer';\nimport {\n installDoomLeaderBootstrapHost,\n LeaderActionInvoked,\n type LeaderContribution,\n LeaderRegistrationProtocol,\n LeaderUnregistrationProtocol,\n} from '@agimon-ai/doompi-extension-contracts/leader';\nimport { McpStatusQueryProtocol } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport { createMinorModeCatalogClient } from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createProtocolRuntime, type ProtocolRuntime } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../../services/leader/leaderRegistry.ts';\nimport { DoomUiState, type LeaderSnapshot, projectMinorModeRecords } from '../../services/state/uiState.ts';\nimport { buildToolSources, type McpServerStatus } from '../../services/tools/toolInventory.ts';\nimport { openConfigOverlay } from '../../tui/configOverlay.ts';\nimport { DoomEditor } from '../../tui/doomEditor.ts';\nimport { DoomFooter } from '../../tui/doomFooter.ts';\nimport { DoomHeader } from '../../tui/doomHeader.ts';\nimport { LeaderHints } from '../../tui/leaderHints.ts';\nimport { DEFAULT_THEME_NAME } from '../../tui/theme.ts';\nimport { openToolsOverlay } from '../../tui/toolsOverlay.ts';\nimport { createUiTelemetry, UI_EVENT, type UiTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { extensionName, extensionToolSource } from './extensionName.ts';\nimport { registerBuiltinToolUi } from './toolOverrides.ts';\n\nconst LEADER_WIDGET_KEY = 'doom-pi-leader';\nconst TUI_MODE = 'tui';\nconst WIDGET_PLACEMENT = 'belowEditor';\nconst WARNING_STYLE = 'warning';\nconst THEME_ENVIRONMENT_KEY = 'DOOMPI_THEME';\nconst HOTKEYS_COMMAND = 'hotkeys';\nconst TOOLS_COMMAND = 'tools';\nconst CONFIG_COMMAND = 'config';\n/** Short: `/tools` must open promptly whether or not an MCP extension answers. */\nconst MCP_STATUS_TIMEOUT_MS = 250;\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_MESSAGE_ENTRY = 'message';\nconst INPUT_EVENT = 'input';\nconst INTERACTIVE_INPUT_SOURCE = 'interactive';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\nconst TITLE_MESSAGE_MAX_LENGTH = 64;\nconst TITLE_PREFIX = 'doom-pi';\nconst BUILTIN_LEADER_COMMANDS = new Set([HOTKEYS_COMMAND]);\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\nexport function doomPiUiExtension(pi: ExtensionAPI, telemetry: UiTelemetry = createUiTelemetry()): void {\n registerBuiltinToolUi(pi, process.cwd());\n const uiState = new DoomUiState();\n const footerStatusRegistry = new DoomFooterStatusRegistry();\n const modeCatalog = createMinorModeCatalogClient();\n const configRegistry = new DoomConfigRegistry();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n const contributionGenerations = new Map<string, symbol>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let disposeFooterStatuses: (() => void) | undefined;\n let disposeModeCatalogBinding: (() => void) | undefined;\n let disposeModeSubscription: (() => void) | undefined;\n let disposeConfigContributions: (() => void) | undefined;\n let disposeLeaderRegistration: (() => void) | undefined;\n let disposeLeaderUnregistration: (() => void) | undefined;\n const protocolContributions = new Map<string, () => void>();\n let nextProtocolHandle = 0;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let sessionProtocol: ProtocolRuntime | undefined;\n let disposeLeaderBootstrap: (() => void) | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = async (): Promise<readonly McpServerStatus[] | undefined> => {\n if (!sessionProtocol) return undefined;\n try {\n const snapshot = await sessionProtocol.request(McpStatusQueryProtocol, {}, { timeoutMs: MCP_STATUS_TIMEOUT_MS });\n return snapshot.servers;\n } catch {\n return undefined;\n }\n };\n\n pi.registerCommand(TOOLS_COMMAND, {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = await readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionToolSource: extensionToolSource,\n });\n await openToolsOverlay(ctx, sources);\n },\n });\n\n pi.registerCommand(CONFIG_COMMAND, {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, configRegistry);\n },\n });\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) activeContext.ui.notify(message, WARNING_STYLE);\n }\n };\n\n const registerLeaderContribution = (contribution: LeaderContribution, deferred: boolean) => {\n const generation = Symbol(contribution.source);\n const register = deferred\n ? (value: LeaderContribution) => leaderRegistry.registerDeferred(value)\n : (value: LeaderContribution) => leaderRegistry.register(value);\n const result = register(contribution);\n reportDiagnostics(result.diagnostics);\n if (!result.accepted) return { update: () => undefined, dispose: () => undefined };\n contributionGenerations.set(contribution.source, generation);\n let disposed = false;\n return {\n update(bindings: LeaderContribution['bindings']) {\n if (disposed || contributionGenerations.get(contribution.source) !== generation) return;\n reportDiagnostics(register({ source: contribution.source, bindings }).diagnostics);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (contributionGenerations.get(contribution.source) !== generation) return;\n contributionGenerations.delete(contribution.source);\n register({ source: contribution.source, bindings: [] });\n },\n };\n };\n\n const leaderContext = Object.freeze({\n register(contribution: LeaderContribution) {\n const handle = registerLeaderContribution(contribution, false);\n return () => handle.dispose();\n },\n });\n // Installed during the UI factory, before the remaining Doom factories run.\n // Their registrations are validated immediately and rebuilt as one batch at\n // session_start, so the first editor always receives the complete keyspace.\n disposeLeaderBootstrap = installDoomLeaderBootstrapHost({\n register: (contribution) => registerLeaderContribution(contribution, true),\n });\n pi.on(SESSION_START_EVENT, (_event, ctx) => {\n activeContext = ctx;\n const activeGeneration = ++sessionGeneration;\n const protocol = createProtocolRuntime({\n bus: pi.events,\n source: '@agimon-ai/doompi-ui',\n sessionId: ctx.sessionManager.getSessionId(),\n });\n sessionProtocol = protocol;\n reportDiagnostics(leaderRegistry.flush());\n disposeFooterStatuses?.();\n footerStatusRegistry.reset();\n disposeFooterStatuses = footerStatusRegistry.bind(protocol);\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = modeCatalog.bind(protocol);\n // Bound above the TUI-mode guard below, like footer and mode: a headless run\n // still accepts contributions, it just never draws them.\n disposeConfigContributions?.();\n configRegistry.reset();\n disposeConfigContributions = configRegistry.bind(protocol);\n disposeLeaderRegistration?.();\n disposeLeaderUnregistration?.();\n disposeLeaderRegistration = protocol.provide(\n LeaderRegistrationProtocol,\n ({ contribution, generation }, identity) => {\n if (identity.source !== contribution.source) {\n throw new Error('Leader contribution source does not match the registration envelope source.');\n }\n const handleId = `${identity.source}:${generation}:${++nextProtocolHandle}`;\n const typedContribution: LeaderContribution = {\n source: contribution.source,\n bindings: contribution.bindings.map((binding) => {\n const [first, ...rest] = binding.path;\n if (!first) throw new Error(`Leader binding '${binding.id}' has no path.`);\n return { ...binding, path: [first, ...rest] };\n }),\n };\n protocolContributions.set(handleId, leaderContext.register(typedContribution));\n return { handleId };\n },\n );\n disposeLeaderUnregistration = protocol.provide(LeaderUnregistrationProtocol, ({ handleId }) => {\n const dispose = protocolContributions.get(handleId);\n if (!dispose) return { removed: false };\n protocolContributions.delete(handleId);\n dispose();\n return { removed: true };\n });\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) ctx.ui.notify(message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n ctx.ui.notify(`Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n // The modes go into shared state rather than a widget of their own: the\n // editor prints their names beside its badge and the leader panel prints\n // them with their detail, so there is no third surface to paint.\n disposeModeSubscription?.();\n disposeModeSubscription = modeCatalog.subscribe(() =>\n uiState.setModes(projectMinorModeRecords(modeCatalog.list())),\n );\n uiState.setModes(projectMinorModeRecords(modeCatalog.list()));\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, footerStatusRegistry, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) => new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.has(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n protocol.notify(LeaderActionInvoked, { source, action });\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n ctx.ui.notify(`Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n ctx.ui.notify(`Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n });\n\n pi.on(INPUT_EVENT, (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n });\n\n pi.on(SESSION_SHUTDOWN_EVENT, async (_event, ctx) => {\n ++sessionGeneration;\n disposeLeaderBootstrap?.();\n disposeLeaderBootstrap = undefined;\n for (const dispose of protocolContributions.values()) dispose();\n protocolContributions.clear();\n activeContext = undefined;\n footerData = undefined;\n disposeFooterStatuses?.();\n disposeFooterStatuses = undefined;\n footerStatusRegistry.reset();\n disposeModeCatalogBinding?.();\n disposeModeCatalogBinding = undefined;\n disposeModeSubscription?.();\n disposeModeSubscription = undefined;\n modeCatalog.reset();\n disposeConfigContributions?.();\n disposeConfigContributions = undefined;\n disposeLeaderRegistration?.();\n disposeLeaderRegistration = undefined;\n disposeLeaderUnregistration?.();\n disposeLeaderUnregistration = undefined;\n configRegistry.reset();\n uiState.reset();\n sessionProtocol = undefined;\n if (ctx.mode === TUI_MODE) ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n await telemetry.shutdown();\n });\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  import { DoomEditor, DoomEditorLeaderOptions } from "../tui/doomEditor.cjs";
2
- export { DoomEditor, DoomEditorLeaderOptions };
2
+ export { DoomEditor, type DoomEditorLeaderOptions };
@@ -1,2 +1,2 @@
1
1
  import { DoomEditor, DoomEditorLeaderOptions } from "../tui/doomEditor.mjs";
2
- export { DoomEditor, DoomEditorLeaderOptions };
2
+ export { DoomEditor, type DoomEditorLeaderOptions };
@@ -1,2 +1,2 @@
1
1
  import { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, DoomOverlayChrome, DoomOverlayTui } from "../tui/doomOverlay.cjs";
2
- export { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, DoomOverlayChrome, DoomOverlayTui };
2
+ export { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, type DoomOverlayChrome, type DoomOverlayTui };
@@ -1,2 +1,2 @@
1
1
  import { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, DoomOverlayChrome, DoomOverlayTui } from "../tui/doomOverlay.mjs";
2
- export { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, DoomOverlayChrome, DoomOverlayTui };
2
+ export { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay, type DoomOverlayChrome, type DoomOverlayTui };
package/dist/config.cjs CHANGED
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs");var t=e.__exportAll({});e.__reExport(t,require("@agimon-ai/doompi-extension-contracts/config")),Object.defineProperty(exports,"config_exports",{enumerable:!0,get:function(){return t}});var n=require("@agimon-ai/doompi-extension-contracts/config");Object.keys(n).forEach(function(e){e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return n[e]}})});
2
- //# sourceMappingURL=config.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@agimon-ai/doompi-extension-contracts/config");Object.defineProperty(exports,"CONFIG_ACTION",{enumerable:!0,get:function(){return e.CONFIG_ACTION}}),Object.defineProperty(exports,"ConfigActionSchema",{enumerable:!0,get:function(){return e.ConfigActionSchema}}),Object.defineProperty(exports,"ConfigChanged",{enumerable:!0,get:function(){return e.ConfigChanged}}),Object.defineProperty(exports,"ConfigChoiceSchema",{enumerable:!0,get:function(){return e.ConfigChoiceSchema}}),Object.defineProperty(exports,"ConfigDiscovery",{enumerable:!0,get:function(){return e.ConfigDiscovery}}),Object.defineProperty(exports,"ConfigFieldKindSchema",{enumerable:!0,get:function(){return e.ConfigFieldKindSchema}}),Object.defineProperty(exports,"ConfigFieldSchema",{enumerable:!0,get:function(){return e.ConfigFieldSchema}}),Object.defineProperty(exports,"ConfigInvoked",{enumerable:!0,get:function(){return e.ConfigInvoked}}),Object.defineProperty(exports,"ConfigProgressSchema",{enumerable:!0,get:function(){return e.ConfigProgressSchema}}),Object.defineProperty(exports,"ConfigRegistration",{enumerable:!0,get:function(){return e.ConfigRegistration}}),Object.defineProperty(exports,"ConfigSectionSchema",{enumerable:!0,get:function(){return e.ConfigSectionSchema}}),Object.defineProperty(exports,"ConfigSourceSchema",{enumerable:!0,get:function(){return e.ConfigSourceSchema}}),Object.defineProperty(exports,"ConfigStatusSchema",{enumerable:!0,get:function(){return e.ConfigStatusSchema}}),Object.defineProperty(exports,"ConfigStepSchema",{enumerable:!0,get:function(){return e.ConfigStepSchema}}),Object.defineProperty(exports,"ConfigUnregistration",{enumerable:!0,get:function(){return e.ConfigUnregistration}}),Object.defineProperty(exports,"DoomConfigRegistry",{enumerable:!0,get:function(){return e.DoomConfigRegistry}}),Object.defineProperty(exports,"registerConfigProvider",{enumerable:!0,get:function(){return e.registerConfigProvider}}),Object.defineProperty(exports,"registerDoomConfigContribution",{enumerable:!0,get:function(){return e.registerDoomConfigContribution}});
package/dist/config.d.cts CHANGED
@@ -1,5 +1,2 @@
1
- export * from "@agimon-ai/doompi-extension-contracts/config";
2
- import * as import__agimon_ai_doompi_extension_contracts_config from "@agimon-ai/doompi-extension-contracts/config";
3
- //#endregion
4
- export { import__agimon_ai_doompi_extension_contracts_config as config_d_exports };
5
- //# sourceMappingURL=config.d.cts.map
1
+ import { CONFIG_ACTION, ConfigAction, ConfigActionSchema, ConfigChanged, ConfigChoice, ConfigChoiceSchema, ConfigDiscovery, ConfigField, ConfigFieldKind, ConfigFieldKindSchema, ConfigFieldSchema, ConfigInvoked, ConfigProgress, ConfigProgressSchema, ConfigProvider, ConfigProviderHandle, ConfigRegistration, ConfigSection, ConfigSectionSchema, ConfigSnapshot, ConfigSourceRef, ConfigSourceSchema, ConfigStatus, ConfigStatusSchema, ConfigStep, ConfigStepSchema, ConfigUnregistration, DoomConfigActionInput, DoomConfigContributionHandle, DoomConfigContributionOptions, DoomConfigInvocation, DoomConfigRegistry, DoomConfigSectionView, DoomExtensionContext, DoomExtensionHost, registerConfigProvider, registerDoomConfigContribution } from "@agimon-ai/doompi-extension-contracts/config";
2
+ export { CONFIG_ACTION, type ConfigAction, ConfigActionSchema, ConfigChanged, type ConfigChoice, ConfigChoiceSchema, ConfigDiscovery, type ConfigField, type ConfigFieldKind, ConfigFieldKindSchema, ConfigFieldSchema, ConfigInvoked, type ConfigProgress, ConfigProgressSchema, type ConfigProvider, type ConfigProviderHandle, ConfigRegistration, type ConfigSection, ConfigSectionSchema, type ConfigSnapshot, type ConfigSourceRef, ConfigSourceSchema, type ConfigStatus, ConfigStatusSchema, type ConfigStep, ConfigStepSchema, ConfigUnregistration, type DoomConfigActionInput, type DoomConfigContributionHandle, type DoomConfigContributionOptions, type DoomConfigInvocation, DoomConfigRegistry, type DoomConfigSectionView, type DoomExtensionContext, type DoomExtensionHost, registerConfigProvider, registerDoomConfigContribution };
package/dist/config.d.mts CHANGED
@@ -1,5 +1,2 @@
1
- export * from "@agimon-ai/doompi-extension-contracts/config";
2
- import * as import__agimon_ai_doompi_extension_contracts_config from "@agimon-ai/doompi-extension-contracts/config";
3
- //#endregion
4
- export { import__agimon_ai_doompi_extension_contracts_config as config_d_exports };
5
- //# sourceMappingURL=config.d.mts.map
1
+ import { CONFIG_ACTION, ConfigAction, ConfigActionSchema, ConfigChanged, ConfigChoice, ConfigChoiceSchema, ConfigDiscovery, ConfigField, ConfigFieldKind, ConfigFieldKindSchema, ConfigFieldSchema, ConfigInvoked, ConfigProgress, ConfigProgressSchema, ConfigProvider, ConfigProviderHandle, ConfigRegistration, ConfigSection, ConfigSectionSchema, ConfigSnapshot, ConfigSourceRef, ConfigSourceSchema, ConfigStatus, ConfigStatusSchema, ConfigStep, ConfigStepSchema, ConfigUnregistration, DoomConfigActionInput, DoomConfigContributionHandle, DoomConfigContributionOptions, DoomConfigInvocation, DoomConfigRegistry, DoomConfigSectionView, DoomExtensionContext, DoomExtensionHost, registerConfigProvider, registerDoomConfigContribution } from "@agimon-ai/doompi-extension-contracts/config";
2
+ export { CONFIG_ACTION, type ConfigAction, ConfigActionSchema, ConfigChanged, type ConfigChoice, ConfigChoiceSchema, ConfigDiscovery, type ConfigField, type ConfigFieldKind, ConfigFieldKindSchema, ConfigFieldSchema, ConfigInvoked, type ConfigProgress, ConfigProgressSchema, type ConfigProvider, type ConfigProviderHandle, ConfigRegistration, type ConfigSection, ConfigSectionSchema, type ConfigSnapshot, type ConfigSourceRef, ConfigSourceSchema, type ConfigStatus, ConfigStatusSchema, type ConfigStep, ConfigStepSchema, ConfigUnregistration, type DoomConfigActionInput, type DoomConfigContributionHandle, type DoomConfigContributionOptions, type DoomConfigInvocation, DoomConfigRegistry, type DoomConfigSectionView, type DoomExtensionContext, type DoomExtensionHost, registerConfigProvider, registerDoomConfigContribution };
package/dist/config.mjs CHANGED
@@ -1,2 +1 @@
1
- import{__exportAll as e,__reExport as t}from"./_virtual/_rolldown/runtime.mjs";export*from"@agimon-ai/doompi-extension-contracts/config";var n=e({});import*as r from"@agimon-ai/doompi-extension-contracts/config";t(n,r);export{n as config_exports};
2
- //# sourceMappingURL=config.mjs.map
1
+ import{CONFIG_ACTION as e,ConfigActionSchema as t,ConfigChanged as n,ConfigChoiceSchema as r,ConfigDiscovery as i,ConfigFieldKindSchema as a,ConfigFieldSchema as o,ConfigInvoked as s,ConfigProgressSchema as c,ConfigRegistration as l,ConfigSectionSchema as u,ConfigSourceSchema as d,ConfigStatusSchema as f,ConfigStepSchema as p,ConfigUnregistration as m,DoomConfigRegistry as h,registerConfigProvider as g,registerDoomConfigContribution as _}from"@agimon-ai/doompi-extension-contracts/config";export{e as CONFIG_ACTION,t as ConfigActionSchema,n as ConfigChanged,r as ConfigChoiceSchema,i as ConfigDiscovery,a as ConfigFieldKindSchema,o as ConfigFieldSchema,s as ConfigInvoked,c as ConfigProgressSchema,l as ConfigRegistration,u as ConfigSectionSchema,d as ConfigSourceSchema,f as ConfigStatusSchema,p as ConfigStepSchema,m as ConfigUnregistration,h as DoomConfigRegistry,g as registerConfigProvider,_ as registerDoomConfigContribution};
@@ -1 +1 @@
1
- {"version":3,"file":"pi.cjs","names":["doomPiUiExtension"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { doomPiUiExtension } from '../adapters/pi/extension.ts';\n\nexport default doomPiUiExtension;\n"],"mappings":"AAEA,IAAA,wCAAeA,CAAAA,CAAAA"}
1
+ {"version":3,"file":"pi.cjs","names":["doomPiUiExtension"],"sources":["../../src/exports/extensions/pi.ts"],"sourcesContent":["import { doomPiUiExtension } from '../../adapters/pi/extension.ts';\n\nexport default doomPiUiExtension;\n"],"mappings":"AAEA,IAAA,wCAAeA,CAAAA,CAAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { doomPiUiExtension } from '../adapters/pi/extension.ts';\n\nexport default doomPiUiExtension;\n"],"mappings":"iEAEA,IAAA,EAAe"}
1
+ {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/exports/extensions/pi.ts"],"sourcesContent":["import { doomPiUiExtension } from '../../adapters/pi/extension.ts';\n\nexport default doomPiUiExtension;\n"],"mappings":"iEAEA,IAAA,EAAe"}
package/dist/footer.cjs CHANGED
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs");var t=e.__exportAll({});e.__reExport(t,require("@agimon-ai/doompi-extension-contracts/footer")),Object.defineProperty(exports,"footer_exports",{enumerable:!0,get:function(){return t}});var n=require("@agimon-ai/doompi-extension-contracts/footer");Object.keys(n).forEach(function(e){e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return n[e]}})});
2
- //# sourceMappingURL=footer.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@agimon-ai/doompi-extension-contracts/footer");Object.defineProperty(exports,"DoomFooterStatusRegistry",{enumerable:!0,get:function(){return e.DoomFooterStatusRegistry}}),Object.defineProperty(exports,"FooterStatusChanged",{enumerable:!0,get:function(){return e.FooterStatusChanged}}),Object.defineProperty(exports,"FooterStatusDiscovery",{enumerable:!0,get:function(){return e.FooterStatusDiscovery}}),Object.defineProperty(exports,"FooterStatusItemSchema",{enumerable:!0,get:function(){return e.FooterStatusItemSchema}}),Object.defineProperty(exports,"FooterStatusPlacementSchema",{enumerable:!0,get:function(){return e.FooterStatusPlacementSchema}}),Object.defineProperty(exports,"FooterStatusRegistration",{enumerable:!0,get:function(){return e.FooterStatusRegistration}}),Object.defineProperty(exports,"FooterStatusUnregistration",{enumerable:!0,get:function(){return e.FooterStatusUnregistration}}),Object.defineProperty(exports,"FooterTextColorSchema",{enumerable:!0,get:function(){return e.FooterTextColorSchema}}),Object.defineProperty(exports,"FooterTextSegmentSchema",{enumerable:!0,get:function(){return e.FooterTextSegmentSchema}}),Object.defineProperty(exports,"registerDoomFooterContribution",{enumerable:!0,get:function(){return e.registerDoomFooterContribution}}),Object.defineProperty(exports,"registerFooterStatusProvider",{enumerable:!0,get:function(){return e.registerFooterStatusProvider}});
package/dist/footer.d.cts CHANGED
@@ -1,5 +1,2 @@
1
- export * from "@agimon-ai/doompi-extension-contracts/footer";
2
- import * as import__agimon_ai_doompi_extension_contracts_footer from "@agimon-ai/doompi-extension-contracts/footer";
3
- //#endregion
4
- export { import__agimon_ai_doompi_extension_contracts_footer as footer_d_exports };
5
- //# sourceMappingURL=footer.d.cts.map
1
+ import { DoomFooterContributionDefinition, DoomFooterContributionHandle, DoomFooterContributionValue, DoomFooterStatus, DoomFooterStatusRegistry, FooterStatusChanged, FooterStatusDiscovery, FooterStatusItem, FooterStatusItemSchema, FooterStatusPlacement, FooterStatusPlacementSchema, FooterStatusProvider, FooterStatusProviderHandle, FooterStatusRegistration, FooterStatusSnapshot, FooterStatusSource, FooterStatusUnregistration, FooterTextColor, FooterTextColorSchema, FooterTextSegment, FooterTextSegmentSchema, registerDoomFooterContribution, registerFooterStatusProvider } from "@agimon-ai/doompi-extension-contracts/footer";
2
+ export { type DoomFooterContributionDefinition, type DoomFooterContributionHandle, type DoomFooterContributionValue, type DoomFooterStatus, DoomFooterStatusRegistry, FooterStatusChanged, FooterStatusDiscovery, type FooterStatusItem, FooterStatusItemSchema, type FooterStatusPlacement, FooterStatusPlacementSchema, type FooterStatusProvider, type FooterStatusProviderHandle, FooterStatusRegistration, type FooterStatusSnapshot, type FooterStatusSource, FooterStatusUnregistration, type FooterTextColor, FooterTextColorSchema, type FooterTextSegment, FooterTextSegmentSchema, registerDoomFooterContribution, registerFooterStatusProvider };
package/dist/footer.d.mts CHANGED
@@ -1,5 +1,2 @@
1
- export * from "@agimon-ai/doompi-extension-contracts/footer";
2
- import * as import__agimon_ai_doompi_extension_contracts_footer from "@agimon-ai/doompi-extension-contracts/footer";
3
- //#endregion
4
- export { import__agimon_ai_doompi_extension_contracts_footer as footer_d_exports };
5
- //# sourceMappingURL=footer.d.mts.map
1
+ import { DoomFooterContributionDefinition, DoomFooterContributionHandle, DoomFooterContributionValue, DoomFooterStatus, DoomFooterStatusRegistry, FooterStatusChanged, FooterStatusDiscovery, FooterStatusItem, FooterStatusItemSchema, FooterStatusPlacement, FooterStatusPlacementSchema, FooterStatusProvider, FooterStatusProviderHandle, FooterStatusRegistration, FooterStatusSnapshot, FooterStatusSource, FooterStatusUnregistration, FooterTextColor, FooterTextColorSchema, FooterTextSegment, FooterTextSegmentSchema, registerDoomFooterContribution, registerFooterStatusProvider } from "@agimon-ai/doompi-extension-contracts/footer";
2
+ export { type DoomFooterContributionDefinition, type DoomFooterContributionHandle, type DoomFooterContributionValue, type DoomFooterStatus, DoomFooterStatusRegistry, FooterStatusChanged, FooterStatusDiscovery, type FooterStatusItem, FooterStatusItemSchema, type FooterStatusPlacement, FooterStatusPlacementSchema, type FooterStatusProvider, type FooterStatusProviderHandle, FooterStatusRegistration, type FooterStatusSnapshot, type FooterStatusSource, FooterStatusUnregistration, type FooterTextColor, FooterTextColorSchema, type FooterTextSegment, FooterTextSegmentSchema, registerDoomFooterContribution, registerFooterStatusProvider };
package/dist/footer.mjs CHANGED
@@ -1,2 +1 @@
1
- import{__exportAll as e,__reExport as t}from"./_virtual/_rolldown/runtime.mjs";export*from"@agimon-ai/doompi-extension-contracts/footer";var n=e({});import*as r from"@agimon-ai/doompi-extension-contracts/footer";t(n,r);export{n as footer_exports};
2
- //# sourceMappingURL=footer.mjs.map
1
+ import{DoomFooterStatusRegistry as e,FooterStatusChanged as t,FooterStatusDiscovery as n,FooterStatusItemSchema as r,FooterStatusPlacementSchema as i,FooterStatusRegistration as a,FooterStatusUnregistration as o,FooterTextColorSchema as s,FooterTextSegmentSchema as c,registerDoomFooterContribution as l,registerFooterStatusProvider as u}from"@agimon-ai/doompi-extension-contracts/footer";export{e as DoomFooterStatusRegistry,t as FooterStatusChanged,n as FooterStatusDiscovery,r as FooterStatusItemSchema,i as FooterStatusPlacementSchema,a as FooterStatusRegistration,o as FooterStatusUnregistration,s as FooterTextColorSchema,c as FooterTextSegmentSchema,l as registerDoomFooterContribution,u as registerFooterStatusProvider};
@@ -1,2 +1,2 @@
1
1
  import { DoomHarnessMetadata, readDoomHarnessMetadata } from "./types/harnessMetadata.cjs";
2
- export { DoomHarnessMetadata, readDoomHarnessMetadata };
2
+ export { type DoomHarnessMetadata, readDoomHarnessMetadata };
@@ -1,2 +1,2 @@
1
1
  import { DoomHarnessMetadata, readDoomHarnessMetadata } from "./types/harnessMetadata.mjs";
2
- export { DoomHarnessMetadata, readDoomHarnessMetadata };
2
+ export { type DoomHarnessMetadata, readDoomHarnessMetadata };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/telemetry/logSinkTelemetry.cjs");require("./config.cjs"),require("./footer.cjs"),require("./leader.cjs");const t=require("./services/state/uiState.cjs"),n=require("./types/harnessMetadata.cjs"),r=require("./tui/doomEditor.cjs"),i=require("./tui/doomFooter.cjs"),a=require("./tui/doomHeader.cjs"),o=require("./tui/doomOverlay.cjs"),s=require("./tui/leaderHints.cjs"),c=require("./tui/theme.cjs"),l=require("./tui/toolChrome.cjs");let u=require("@agimon-ai/doompi-extension-contracts/leader");exports.DEFAULT_THEME=c.DEFAULT_THEME,exports.DEFAULT_THEME_NAME=c.DEFAULT_THEME_NAME,exports.DOOM_FULLSCREEN_UI_OPTIONS=o.DOOM_FULLSCREEN_UI_OPTIONS,exports.DOOM_NAVIGATION_KEYS=o.DOOM_NAVIGATION_KEYS,exports.DoomEditor=r.DoomEditor,exports.DoomFooter=i.DoomFooter,exports.DoomHeader=a.DoomHeader,exports.DoomOverlay=o.DoomOverlay,exports.DoomToolCall=l.DoomToolCall,exports.DoomToolResult=l.DoomToolResult,exports.DoomUiState=t.DoomUiState,exports.LeaderHints=s.LeaderHints,exports.UI_EVENT=e.UI_EVENT,Object.defineProperty(exports,"createDoomLeaderContribution",{enumerable:!0,get:function(){return u.createDoomLeaderContribution}}),exports.createUiTelemetry=e.createUiTelemetry,exports.readDoomHarnessMetadata=n.readDoomHarnessMetadata,Object.defineProperty(exports,"registerDoomConfigContribution",{enumerable:!0,get:function(){return config_exports.registerDoomConfigContribution}}),Object.defineProperty(exports,"registerDoomFooterContribution",{enumerable:!0,get:function(){return footer_exports.registerDoomFooterContribution}}),Object.defineProperty(exports,"registerDoomLeaderContribution",{enumerable:!0,get:function(){return u.registerDoomLeaderContribution}}),exports.renderToolBadge=l.renderToolBadge,exports.renderToolHeading=l.renderToolHeading,exports.writeDefaultTheme=c.writeDefaultTheme;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/state/uiState.cjs"),t=require("./tui/doomOverlay.cjs"),n=require("./types/harnessMetadata.cjs"),r=require("./tui/doomEditor.cjs"),i=require("./tui/doomFooter.cjs"),a=require("./tui/doomHeader.cjs"),o=require("./tui/leaderHints.cjs"),s=require("./tui/theme.cjs"),c=require("./adapters/telemetry/logSinkTelemetry.cjs"),l=require("./tui/toolChrome.cjs");let u=require("@agimon-ai/doompi-extension-contracts/config"),d=require("@agimon-ai/doompi-extension-contracts/footer"),f=require("@agimon-ai/doompi-extension-contracts/leader");exports.DEFAULT_THEME=s.DEFAULT_THEME,exports.DEFAULT_THEME_NAME=s.DEFAULT_THEME_NAME,exports.DOOM_FULLSCREEN_UI_OPTIONS=t.DOOM_FULLSCREEN_UI_OPTIONS,exports.DOOM_NAVIGATION_KEYS=t.DOOM_NAVIGATION_KEYS,exports.DoomEditor=r.DoomEditor,exports.DoomFooter=i.DoomFooter,exports.DoomHeader=a.DoomHeader,exports.DoomOverlay=t.DoomOverlay,exports.DoomToolCall=l.DoomToolCall,exports.DoomToolResult=l.DoomToolResult,exports.DoomUiState=e.DoomUiState,exports.LeaderHints=o.LeaderHints,exports.UI_EVENT=c.UI_EVENT,Object.defineProperty(exports,"createDoomLeaderContribution",{enumerable:!0,get:function(){return f.createDoomLeaderContribution}}),exports.createUiTelemetry=c.createUiTelemetry,exports.readDoomHarnessMetadata=n.readDoomHarnessMetadata,Object.defineProperty(exports,"registerDoomConfigContribution",{enumerable:!0,get:function(){return u.registerDoomConfigContribution}}),Object.defineProperty(exports,"registerDoomFooterContribution",{enumerable:!0,get:function(){return d.registerDoomFooterContribution}}),Object.defineProperty(exports,"registerDoomLeaderContribution",{enumerable:!0,get:function(){return f.registerDoomLeaderContribution}}),exports.renderToolBadge=l.renderToolBadge,exports.renderToolHeading=l.renderToolHeading,exports.writeDefaultTheme=s.writeDefaultTheme;
package/dist/index.d.cts CHANGED
@@ -1,9 +1,6 @@
1
- import { config_d_exports } from "./config.cjs";
2
1
  import { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DoomOverlay, DoomOverlayChrome, DoomOverlayTui } from "./tui/doomOverlay.cjs";
3
- import { DoomLeaderBinding, DoomLeaderCommand, DoomLeaderContribution, DoomLeaderContributionHandle, DoomLeaderSegment, createDoomLeaderContribution, registerDoomLeaderContribution } from "./leader.cjs";
4
2
  import { DoomUiState, LeaderOption, LeaderSnapshot } from "./services/state/uiState.cjs";
5
3
  import { DoomEditor } from "./tui/doomEditor.cjs";
6
- import { footer_d_exports } from "./footer.cjs";
7
4
  import { DoomFooter } from "./tui/doomFooter.cjs";
8
5
  import { DoomHarnessMetadata, readDoomHarnessMetadata } from "./types/harnessMetadata.cjs";
9
6
  import { DoomHeader } from "./tui/doomHeader.cjs";
@@ -11,16 +8,7 @@ import { LeaderHints } from "./tui/leaderHints.cjs";
11
8
  import { UI_EVENT, UiEventAttributes, UiEventName, UiTelemetry, UiTelemetryOptions, createUiTelemetry } from "./adapters/telemetry/logSinkTelemetry.cjs";
12
9
  import { DEFAULT_THEME, DEFAULT_THEME_NAME, writeDefaultTheme } from "./tui/theme.cjs";
13
10
  import { DoomToolCall, DoomToolResult, DoomToolResultOptions, renderToolBadge, renderToolHeading } from "./tui/toolChrome.cjs";
14
- type ConfigChoice = config_d_exports.ConfigChoice;
15
- type ConfigField = config_d_exports.ConfigField;
16
- type ConfigSection = config_d_exports.ConfigSection;
17
- type ConfigStep = config_d_exports.ConfigStep;
18
- type DoomConfigActionInput = config_d_exports.DoomConfigActionInput;
19
- type DoomConfigContributionHandle = config_d_exports.DoomConfigContributionHandle;
20
- type DoomConfigContributionOptions = config_d_exports.DoomConfigContributionOptions;
21
- type DoomFooterContributionDefinition = footer_d_exports.DoomFooterContributionDefinition;
22
- type DoomFooterContributionHandle = footer_d_exports.DoomFooterContributionHandle;
23
- type DoomFooterContributionValue = footer_d_exports.DoomFooterContributionValue;
24
- type registerDoomConfigContribution = config_d_exports.registerDoomConfigContribution;
25
- type registerDoomFooterContribution = footer_d_exports.registerDoomFooterContribution;
11
+ import { ConfigChoice, ConfigField, ConfigSection, ConfigStep, DoomConfigActionInput, DoomConfigContributionHandle, DoomConfigContributionOptions, registerDoomConfigContribution } from "@agimon-ai/doompi-extension-contracts/config";
12
+ import { DoomLeaderContributionHandle, LeaderBinding as DoomLeaderBinding, LeaderCommand as DoomLeaderCommand, LeaderContribution as DoomLeaderContribution, LeaderSegment as DoomLeaderSegment, createDoomLeaderContribution, registerDoomLeaderContribution } from "@agimon-ai/doompi-extension-contracts/leader";
13
+ import { DoomFooterContributionDefinition, DoomFooterContributionHandle, DoomFooterContributionValue, registerDoomFooterContribution } from "@agimon-ai/doompi-extension-contracts/footer";
26
14
  export { type ConfigChoice, type ConfigField, type ConfigSection, type ConfigStep, DEFAULT_THEME, DEFAULT_THEME_NAME, DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, type DoomConfigActionInput, type DoomConfigContributionHandle, type DoomConfigContributionOptions, DoomEditor, DoomFooter, type DoomFooterContributionDefinition, type DoomFooterContributionHandle, type DoomFooterContributionValue, type DoomHarnessMetadata, DoomHeader, type DoomLeaderBinding, type DoomLeaderCommand, type DoomLeaderContribution, type DoomLeaderContributionHandle, type DoomLeaderSegment, DoomOverlay, type DoomOverlayChrome, type DoomOverlayTui, DoomToolCall, DoomToolResult, type DoomToolResultOptions, DoomUiState, LeaderHints, type LeaderOption, type LeaderSnapshot, UI_EVENT, type UiEventAttributes, type UiEventName, type UiTelemetry, type UiTelemetryOptions, createDoomLeaderContribution, createUiTelemetry, readDoomHarnessMetadata, registerDoomConfigContribution, registerDoomFooterContribution, registerDoomLeaderContribution, renderToolBadge, renderToolHeading, writeDefaultTheme };