@agimon-ai/doompi-web-contracts 0.0.1-alpha.3 → 0.0.1-alpha.6

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 (33) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.d.cts +4 -3
  3. package/dist/index.d.mts +4 -3
  4. package/dist/index.mjs +1 -1
  5. package/dist/services/globalStore.cjs +2 -0
  6. package/dist/services/globalStore.cjs.map +1 -0
  7. package/dist/services/globalStore.d.cts +7 -0
  8. package/dist/services/globalStore.d.cts.map +1 -0
  9. package/dist/services/globalStore.d.mts +7 -0
  10. package/dist/services/globalStore.d.mts.map +1 -0
  11. package/dist/services/globalStore.mjs +2 -0
  12. package/dist/services/globalStore.mjs.map +1 -0
  13. package/dist/services/testing/channels.cjs +1 -1
  14. package/dist/services/testing/channels.cjs.map +1 -1
  15. package/dist/services/testing/channels.mjs +1 -1
  16. package/dist/services/testing/channels.mjs.map +1 -1
  17. package/dist/services/testing/slotProps.cjs +1 -1
  18. package/dist/services/testing/slotProps.cjs.map +1 -1
  19. package/dist/services/testing/slotProps.d.cts +4 -2
  20. package/dist/services/testing/slotProps.d.cts.map +1 -1
  21. package/dist/services/testing/slotProps.d.mts +4 -2
  22. package/dist/services/testing/slotProps.d.mts.map +1 -1
  23. package/dist/services/testing/slotProps.mjs +1 -1
  24. package/dist/services/testing/slotProps.mjs.map +1 -1
  25. package/dist/types/webHub.d.cts +22 -1
  26. package/dist/types/webHub.d.cts.map +1 -1
  27. package/dist/types/webHub.d.mts +22 -1
  28. package/dist/types/webHub.d.mts.map +1 -1
  29. package/dist/types/webPlugin.d.cts +71 -11
  30. package/dist/types/webPlugin.d.cts.map +1 -1
  31. package/dist/types/webPlugin.d.mts +71 -11
  32. package/dist/types/webPlugin.d.mts.map +1 -1
  33. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/define.cjs"),t=require("./services/sessionStore.cjs"),n=require("./services/toolResult.cjs");exports.defineSessionChannel=e.defineSessionChannel,exports.defineSessionStore=t.defineSessionStore,exports.defineSlot=e.defineSlot,exports.defineWebPlugin=e.defineWebPlugin,exports.toolResultText=n.toolResultText,exports.toolResultTextLines=n.toolResultTextLines;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/define.cjs"),t=require("./services/globalStore.cjs"),n=require("./services/sessionStore.cjs"),r=require("./services/toolResult.cjs");exports.defineGlobalStore=t.defineGlobalStore,exports.defineSessionChannel=e.defineSessionChannel,exports.defineSessionStore=n.defineSessionStore,exports.defineSlot=e.defineSlot,exports.defineWebPlugin=e.defineWebPlugin,exports.toolResultText=r.toolResultText,exports.toolResultTextLines=r.toolResultTextLines;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,7 @@
1
- import { ActivityGroupContribution, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps } from "./types/webPlugin.cjs";
1
+ import { ActivityGroupContribution, GlobalStore, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, RepositorySettingsPanelContribution, RepositorySettingsPanelProps, RepositorySettingsRepository, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps } from "./types/webPlugin.cjs";
2
2
  import { defineSessionChannel, defineSlot, defineWebPlugin } from "./services/define.cjs";
3
+ import { defineGlobalStore } from "./services/globalStore.cjs";
3
4
  import { defineSessionStore } from "./services/sessionStore.cjs";
4
5
  import { toolResultText, toolResultTextLines } from "./services/toolResult.cjs";
5
- import { ChannelFrame, HubChannelHost, HubChannelSource, HubSessionScope, WebHubChannel } from "./types/webHub.cjs";
6
- export { type ActivityGroupContribution, type ChannelFrame, type HubChannelHost, type HubChannelSource, type HubSessionScope, type LeaderBindingContribution, type LeaderKeyContribution, type MinorModeContribution, type PaletteCommandContext, type PaletteCommandContribution, type SelectionAxisContribution, type SessionChannelContribution, type SessionFrameSender, type SessionRecords, type SessionStore, type SessionStoreChannel, type SettingsFieldContribution, type SettingsFieldOption, type SettingsSectionContribution, type SlotDataFill, type SlotDeclaration, type SlotFillContribution, type SurfaceContribution, type TabContribution, type ToolMessageRenderProps, type ToolPromptContribution, type ToolPromptDialog, type ToolPromptRenderProps, type ToolRendererContribution, type ToolResultView, type TransientTab, type WebHubChannel, type WebPluginDefinition, type WebPluginRuntime, type WebPluginSlotProps, defineSessionChannel, defineSessionStore, defineSlot, defineWebPlugin, toolResultText, toolResultTextLines };
6
+ import { ChannelFrame, HubChannelConnection, HubChannelHost, HubChannelSource, HubSessionApiRequest, HubSessionScope, WebHubChannel } from "./types/webHub.cjs";
7
+ export { type ActivityGroupContribution, type ChannelFrame, type GlobalStore, type HubChannelConnection, type HubChannelHost, type HubChannelSource, type HubSessionApiRequest, type HubSessionScope, type LeaderBindingContribution, type LeaderKeyContribution, type MinorModeContribution, type PaletteCommandContext, type PaletteCommandContribution, type RepositorySettingsPanelContribution, type RepositorySettingsPanelProps, type RepositorySettingsRepository, type SelectionAxisContribution, type SessionChannelContribution, type SessionFrameSender, type SessionRecords, type SessionStore, type SessionStoreChannel, type SettingsFieldContribution, type SettingsFieldOption, type SettingsSectionContribution, type SlotDataFill, type SlotDeclaration, type SlotFillContribution, type SurfaceContribution, type TabContribution, type ToolMessageRenderProps, type ToolPromptContribution, type ToolPromptDialog, type ToolPromptRenderProps, type ToolRendererContribution, type ToolResultView, type TransientTab, type WebHubChannel, type WebPluginDefinition, type WebPluginRuntime, type WebPluginSlotProps, defineGlobalStore, defineSessionChannel, defineSessionStore, defineSlot, defineWebPlugin, toolResultText, toolResultTextLines };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
- import { ActivityGroupContribution, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps } from "./types/webPlugin.mjs";
1
+ import { ActivityGroupContribution, GlobalStore, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, RepositorySettingsPanelContribution, RepositorySettingsPanelProps, RepositorySettingsRepository, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps } from "./types/webPlugin.mjs";
2
2
  import { defineSessionChannel, defineSlot, defineWebPlugin } from "./services/define.mjs";
3
+ import { defineGlobalStore } from "./services/globalStore.mjs";
3
4
  import { defineSessionStore } from "./services/sessionStore.mjs";
4
5
  import { toolResultText, toolResultTextLines } from "./services/toolResult.mjs";
5
- import { ChannelFrame, HubChannelHost, HubChannelSource, HubSessionScope, WebHubChannel } from "./types/webHub.mjs";
6
- export { type ActivityGroupContribution, type ChannelFrame, type HubChannelHost, type HubChannelSource, type HubSessionScope, type LeaderBindingContribution, type LeaderKeyContribution, type MinorModeContribution, type PaletteCommandContext, type PaletteCommandContribution, type SelectionAxisContribution, type SessionChannelContribution, type SessionFrameSender, type SessionRecords, type SessionStore, type SessionStoreChannel, type SettingsFieldContribution, type SettingsFieldOption, type SettingsSectionContribution, type SlotDataFill, type SlotDeclaration, type SlotFillContribution, type SurfaceContribution, type TabContribution, type ToolMessageRenderProps, type ToolPromptContribution, type ToolPromptDialog, type ToolPromptRenderProps, type ToolRendererContribution, type ToolResultView, type TransientTab, type WebHubChannel, type WebPluginDefinition, type WebPluginRuntime, type WebPluginSlotProps, defineSessionChannel, defineSessionStore, defineSlot, defineWebPlugin, toolResultText, toolResultTextLines };
6
+ import { ChannelFrame, HubChannelConnection, HubChannelHost, HubChannelSource, HubSessionApiRequest, HubSessionScope, WebHubChannel } from "./types/webHub.mjs";
7
+ export { type ActivityGroupContribution, type ChannelFrame, type GlobalStore, type HubChannelConnection, type HubChannelHost, type HubChannelSource, type HubSessionApiRequest, type HubSessionScope, type LeaderBindingContribution, type LeaderKeyContribution, type MinorModeContribution, type PaletteCommandContext, type PaletteCommandContribution, type RepositorySettingsPanelContribution, type RepositorySettingsPanelProps, type RepositorySettingsRepository, type SelectionAxisContribution, type SessionChannelContribution, type SessionFrameSender, type SessionRecords, type SessionStore, type SessionStoreChannel, type SettingsFieldContribution, type SettingsFieldOption, type SettingsSectionContribution, type SlotDataFill, type SlotDeclaration, type SlotFillContribution, type SurfaceContribution, type TabContribution, type ToolMessageRenderProps, type ToolPromptContribution, type ToolPromptDialog, type ToolPromptRenderProps, type ToolRendererContribution, type ToolResultView, type TransientTab, type WebHubChannel, type WebPluginDefinition, type WebPluginRuntime, type WebPluginSlotProps, defineGlobalStore, defineSessionChannel, defineSessionStore, defineSlot, defineWebPlugin, toolResultText, toolResultTextLines };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{defineSessionChannel as e,defineSlot as t,defineWebPlugin as n}from"./services/define.mjs";import{defineSessionStore as r}from"./services/sessionStore.mjs";import{toolResultText as i,toolResultTextLines as a}from"./services/toolResult.mjs";export{e as defineSessionChannel,r as defineSessionStore,t as defineSlot,n as defineWebPlugin,i as toolResultText,a as toolResultTextLines};
1
+ import{defineSessionChannel as e,defineSlot as t,defineWebPlugin as n}from"./services/define.mjs";import{defineGlobalStore as r}from"./services/globalStore.mjs";import{defineSessionStore as i}from"./services/sessionStore.mjs";import{toolResultText as a,toolResultTextLines as o}from"./services/toolResult.mjs";export{r as defineGlobalStore,e as defineSessionChannel,i as defineSessionStore,t as defineSlot,n as defineWebPlugin,a as toolResultText,o as toolResultTextLines};
@@ -0,0 +1,2 @@
1
+ let e=require("@tanstack/store");function t(t){let n=new e.Store(t);return{store:n,update:e=>{let t=n.state,r=e(t);r!==t&&n.setState(()=>r)},reset:()=>{n.setState(e=>e===t?e:t)}}}exports.defineGlobalStore=t;
2
+ //# sourceMappingURL=globalStore.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalStore.cjs","names":["Store"],"sources":["../../src/services/globalStore.ts"],"sourcesContent":["import { Store } from '@tanstack/store';\nimport type { GlobalStore } from '../types/webPlugin.ts';\n\n/** Page-wide plugin state shared by every contribution from the plugin. */\nexport function defineGlobalStore<T>(initial: T): GlobalStore<T> {\n const store = new Store<T>(initial);\n\n const update = (updater: (current: T) => T): void => {\n const current = store.state;\n const next = updater(current);\n if (next !== current) store.setState(() => next);\n };\n\n const reset = (): void => {\n store.setState((current) => (current === initial ? current : initial));\n };\n\n return { store, update, reset };\n}\n"],"mappings":"iCAIA,SAAgB,EAAqB,EAA4B,CAC/D,IAAM,EAAQ,IAAIA,EAAAA,MAAS,CAAO,EAYlC,MAAO,CAAE,QAAO,OAVA,GAAqC,CACnD,IAAM,EAAU,EAAM,MAChB,EAAO,EAAQ,CAAO,EACxB,IAAS,GAAS,EAAM,aAAe,CAAI,CACjD,EAMwB,UAJE,CACxB,EAAM,SAAU,GAAa,IAAY,EAAU,EAAU,CAAQ,CACvE,CAE8B,CAChC"}
@@ -0,0 +1,7 @@
1
+ import { GlobalStore } from "../types/webPlugin.cjs";
2
+ //#region src/services/globalStore.d.ts
3
+ /** Page-wide plugin state shared by every contribution from the plugin. */
4
+ declare function defineGlobalStore<T>(initial: T): GlobalStore<T>;
5
+ //#endregion
6
+ export { defineGlobalStore };
7
+ //# sourceMappingURL=globalStore.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalStore.d.cts","names":[],"sources":["../../src/services/globalStore.ts"],"mappings":";;;iBAIgB,kBAAkB,GAAG,SAAS,IAAI,YAAY"}
@@ -0,0 +1,7 @@
1
+ import { GlobalStore } from "../types/webPlugin.mjs";
2
+ //#region src/services/globalStore.d.ts
3
+ /** Page-wide plugin state shared by every contribution from the plugin. */
4
+ declare function defineGlobalStore<T>(initial: T): GlobalStore<T>;
5
+ //#endregion
6
+ export { defineGlobalStore };
7
+ //# sourceMappingURL=globalStore.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalStore.d.mts","names":[],"sources":["../../src/services/globalStore.ts"],"mappings":";;;iBAIgB,kBAAkB,GAAG,SAAS,IAAI,YAAY"}
@@ -0,0 +1,2 @@
1
+ import{Store as e}from"@tanstack/store";function t(t){let n=new e(t);return{store:n,update:e=>{let t=n.state,r=e(t);r!==t&&n.setState(()=>r)},reset:()=>{n.setState(e=>e===t?e:t)}}}export{t as defineGlobalStore};
2
+ //# sourceMappingURL=globalStore.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalStore.mjs","names":[],"sources":["../../src/services/globalStore.ts"],"sourcesContent":["import { Store } from '@tanstack/store';\nimport type { GlobalStore } from '../types/webPlugin.ts';\n\n/** Page-wide plugin state shared by every contribution from the plugin. */\nexport function defineGlobalStore<T>(initial: T): GlobalStore<T> {\n const store = new Store<T>(initial);\n\n const update = (updater: (current: T) => T): void => {\n const current = store.state;\n const next = updater(current);\n if (next !== current) store.setState(() => next);\n };\n\n const reset = (): void => {\n store.setState((current) => (current === initial ? current : initial));\n };\n\n return { store, update, reset };\n}\n"],"mappings":"wCAIA,SAAgB,EAAqB,EAA4B,CAC/D,IAAM,EAAQ,IAAI,EAAS,CAAO,EAYlC,MAAO,CAAE,QAAO,OAVA,GAAqC,CACnD,IAAM,EAAU,EAAM,MAChB,EAAO,EAAQ,CAAO,EACxB,IAAS,GAAS,EAAM,aAAe,CAAI,CACjD,EAMwB,UAJE,CACxB,EAAM,SAAU,GAAa,IAAY,EAAU,EAAU,CAAQ,CACvE,CAE8B,CAChC"}
@@ -1,2 +1,2 @@
1
- function e(e,t,n){let r=e.parse(n);return r===null?{accepted:!1}:(e.apply(t,r),{accepted:!0})}const t={sessionId:`s1`,cwd:`/repo`};function n(e,n={}){let r=[...n.sessions??[t]],i=[],a=[],o=e.start({sessions:()=>r,publish:(t,n)=>{i.push({type:e.frameType,sessionId:t,payload:n})},onNotice:e=>a.push(e)});return{source:o,published:i,notices:a,snapshot(e){let n=r.find(t=>t.sessionId===e)??r[0]??t;return o.payloadFor(n)},addSession(e){r.push(e),o.sessionAdded?.(e)},removeSession(e){let t=r.findIndex(t=>t.sessionId===e);t>=0&&r.splice(t,1),o.sessionRemoved?.(e)},close:()=>o.close()}}exports.driveChannel=e,exports.hubChannelHarness=n;
1
+ function e(e,t,n){let r=e.parse(n);return r===null?{accepted:!1}:(e.apply(t,r),{accepted:!0})}const t={sessionId:`s1`,cwd:`/repo`};function n(e,n={}){let r=[...n.sessions??[t]],i=[],a=[],o=e.start({sessions:()=>r,publish:(t,n)=>{i.push({type:e.frameType,sessionId:t,payload:n})},requestSessionApi:()=>Promise.resolve(Response.json({error:`No session API in the channel harness.`},{status:501})),onNotice:e=>a.push(e)});return{source:o,published:i,notices:a,snapshot(e){let n=r.find(t=>t.sessionId===e)??r[0]??t;return o.payloadFor(n)},addSession(e){r.push(e),o.sessionAdded?.(e)},removeSession(e){let t=r.findIndex(t=>t.sessionId===e);t>=0&&r.splice(t,1),o.sessionRemoved?.(e)},close:()=>o.close()}}exports.driveChannel=e,exports.hubChannelHarness=n;
2
2
  //# sourceMappingURL=channels.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.cjs","names":[],"sources":["../../../src/services/testing/channels.ts"],"sourcesContent":["import type {\n ChannelFrame,\n HubChannelHost,\n HubChannelSource,\n HubSessionScope,\n WebHubChannel,\n} from '../../types/webHub.ts';\nimport type { SessionChannelContribution } from '../../types/webPlugin.ts';\n\n/**\n * The two halves of a plugin's data channel, driven the way the hub drives them.\n *\n * A channel is the one place a plugin parses input it did not produce, so its\n * parse gate is the boundary that matters, and a test that calls `apply`\n * directly steps straight over it. `driveChannel` sends a wire payload the way\n * the page does: through `parse` first, and nothing applied when it is\n * rejected.\n */\n\nexport interface ChannelDelivery {\n /** Whether the parse gate accepted the payload. */\n accepted: boolean;\n}\n\n/**\n * Sends one wire payload to a session channel.\n *\n * Returns whether the gate accepted it, so a test can assert a rejection\n * without knowing what the plugin's parsed shape looks like.\n */\nexport function driveChannel(\n channel: SessionChannelContribution,\n sessionId: string,\n payload: unknown,\n): ChannelDelivery {\n const parsed: unknown = channel.parse(payload);\n if (parsed === null) return { accepted: false };\n channel.apply(sessionId, parsed);\n return { accepted: true };\n}\n\nexport interface HubChannelHarness {\n /** The running source, as the hub holds it. */\n source: HubChannelSource;\n /** Everything the source pushed, in order. */\n readonly published: readonly ChannelFrame[];\n /** What the source told the hub. */\n readonly notices: readonly string[];\n /** The subscribe-time snapshot one session would receive; undefined means no frame. */\n snapshot(sessionId?: string): unknown;\n /** Registers a session with the source, as the hub does when one appears. */\n addSession(scope: HubSessionScope): void;\n removeSession(sessionId: string): void;\n close(): void;\n}\n\nexport interface HubChannelHarnessOptions {\n /** Sessions the hub already manages when the channel starts. */\n sessions?: readonly HubSessionScope[];\n}\n\nconst DEFAULT_SESSION: HubSessionScope = { sessionId: 's1', cwd: '/repo' };\n\n/**\n * A plugin's hub channel, started against a real host.\n *\n * The hub calls `payloadFor` once per subscriber and pushes through `publish`\n * afterwards, and a channel that only answers one of those looks correct in a\n * test that exercises the other.\n */\nexport function hubChannelHarness(channel: WebHubChannel, options: HubChannelHarnessOptions = {}): HubChannelHarness {\n const sessions = [...(options.sessions ?? [DEFAULT_SESSION])];\n const published: ChannelFrame[] = [];\n const notices: string[] = [];\n const host: HubChannelHost = {\n sessions: () => sessions,\n publish: (sessionId, payload) => {\n published.push({ type: channel.frameType, sessionId, payload });\n },\n onNotice: (message) => notices.push(message),\n };\n const source = channel.start(host);\n\n return {\n source,\n published,\n notices,\n snapshot(sessionId) {\n const scope = sessions.find((candidate) => candidate.sessionId === sessionId) ?? sessions[0] ?? DEFAULT_SESSION;\n return source.payloadFor(scope);\n },\n addSession(scope) {\n sessions.push(scope);\n source.sessionAdded?.(scope);\n },\n removeSession(sessionId) {\n const index = sessions.findIndex((candidate) => candidate.sessionId === sessionId);\n if (index >= 0) sessions.splice(index, 1);\n source.sessionRemoved?.(sessionId);\n },\n close: () => source.close(),\n };\n}\n"],"mappings":"AA8BA,SAAgB,EACd,EACA,EACA,EACiB,CACjB,IAAM,EAAkB,EAAQ,MAAM,CAAO,EAG7C,OAFI,IAAW,KAAa,CAAE,SAAU,EAAM,GAC9C,EAAQ,MAAM,EAAW,CAAM,EACxB,CAAE,SAAU,EAAK,EAC1B,CAsBA,MAAM,EAAmC,CAAE,UAAW,KAAM,IAAK,OAAQ,EASzE,SAAgB,EAAkB,EAAwB,EAAoC,CAAC,EAAsB,CACnH,IAAM,EAAW,CAAC,GAAI,EAAQ,UAAY,CAAC,CAAe,CAAE,EACtD,EAA4B,CAAC,EAC7B,EAAoB,CAAC,EAQrB,EAAS,EAAQ,MAAM,CAN3B,aAAgB,EAChB,SAAU,EAAW,IAAY,CAC/B,EAAU,KAAK,CAAE,KAAM,EAAQ,UAAW,YAAW,SAAQ,CAAC,CAChE,EACA,SAAW,GAAY,EAAQ,KAAK,CAAO,CAEb,CAAC,EAEjC,MAAO,CACL,SACA,YACA,UACA,SAAS,EAAW,CAClB,IAAM,EAAQ,EAAS,KAAM,GAAc,EAAU,YAAc,CAAS,GAAK,EAAS,IAAM,EAChG,OAAO,EAAO,WAAW,CAAK,CAChC,EACA,WAAW,EAAO,CAChB,EAAS,KAAK,CAAK,EACnB,EAAO,eAAe,CAAK,CAC7B,EACA,cAAc,EAAW,CACvB,IAAM,EAAQ,EAAS,UAAW,GAAc,EAAU,YAAc,CAAS,EAC7E,GAAS,GAAG,EAAS,OAAO,EAAO,CAAC,EACxC,EAAO,iBAAiB,CAAS,CACnC,EACA,UAAa,EAAO,MAAM,CAC5B,CACF"}
1
+ {"version":3,"file":"channels.cjs","names":[],"sources":["../../../src/services/testing/channels.ts"],"sourcesContent":["import type {\n ChannelFrame,\n HubChannelHost,\n HubChannelSource,\n HubSessionScope,\n WebHubChannel,\n} from '../../types/webHub.ts';\nimport type { SessionChannelContribution } from '../../types/webPlugin.ts';\n\n/**\n * The two halves of a plugin's data channel, driven the way the hub drives them.\n *\n * A channel is the one place a plugin parses input it did not produce, so its\n * parse gate is the boundary that matters, and a test that calls `apply`\n * directly steps straight over it. `driveChannel` sends a wire payload the way\n * the page does: through `parse` first, and nothing applied when it is\n * rejected.\n */\n\nexport interface ChannelDelivery {\n /** Whether the parse gate accepted the payload. */\n accepted: boolean;\n}\n\n/**\n * Sends one wire payload to a session channel.\n *\n * Returns whether the gate accepted it, so a test can assert a rejection\n * without knowing what the plugin's parsed shape looks like.\n */\nexport function driveChannel(\n channel: SessionChannelContribution,\n sessionId: string,\n payload: unknown,\n): ChannelDelivery {\n const parsed: unknown = channel.parse(payload);\n if (parsed === null) return { accepted: false };\n channel.apply(sessionId, parsed);\n return { accepted: true };\n}\n\nexport interface HubChannelHarness {\n /** The running source, as the hub holds it. */\n source: HubChannelSource;\n /** Everything the source pushed, in order. */\n readonly published: readonly ChannelFrame[];\n /** What the source told the hub. */\n readonly notices: readonly string[];\n /** The subscribe-time snapshot one session would receive; undefined means no frame. */\n snapshot(sessionId?: string): unknown;\n /** Registers a session with the source, as the hub does when one appears. */\n addSession(scope: HubSessionScope): void;\n removeSession(sessionId: string): void;\n close(): void;\n}\n\nexport interface HubChannelHarnessOptions {\n /** Sessions the hub already manages when the channel starts. */\n sessions?: readonly HubSessionScope[];\n}\n\nconst DEFAULT_SESSION: HubSessionScope = { sessionId: 's1', cwd: '/repo' };\n\n/**\n * A plugin's hub channel, started against a real host.\n *\n * The hub calls `payloadFor` once per subscriber and pushes through `publish`\n * afterwards, and a channel that only answers one of those looks correct in a\n * test that exercises the other.\n */\nexport function hubChannelHarness(channel: WebHubChannel, options: HubChannelHarnessOptions = {}): HubChannelHarness {\n const sessions = [...(options.sessions ?? [DEFAULT_SESSION])];\n const published: ChannelFrame[] = [];\n const notices: string[] = [];\n const host: HubChannelHost = {\n sessions: () => sessions,\n publish: (sessionId, payload) => {\n published.push({ type: channel.frameType, sessionId, payload });\n },\n requestSessionApi: () =>\n Promise.resolve(Response.json({ error: 'No session API in the channel harness.' }, { status: 501 })),\n onNotice: (message) => notices.push(message),\n };\n const source = channel.start(host);\n\n return {\n source,\n published,\n notices,\n snapshot(sessionId) {\n const scope = sessions.find((candidate) => candidate.sessionId === sessionId) ?? sessions[0] ?? DEFAULT_SESSION;\n return source.payloadFor(scope);\n },\n addSession(scope) {\n sessions.push(scope);\n source.sessionAdded?.(scope);\n },\n removeSession(sessionId) {\n const index = sessions.findIndex((candidate) => candidate.sessionId === sessionId);\n if (index >= 0) sessions.splice(index, 1);\n source.sessionRemoved?.(sessionId);\n },\n close: () => source.close(),\n };\n}\n"],"mappings":"AA8BA,SAAgB,EACd,EACA,EACA,EACiB,CACjB,IAAM,EAAkB,EAAQ,MAAM,CAAO,EAG7C,OAFI,IAAW,KAAa,CAAE,SAAU,EAAM,GAC9C,EAAQ,MAAM,EAAW,CAAM,EACxB,CAAE,SAAU,EAAK,EAC1B,CAsBA,MAAM,EAAmC,CAAE,UAAW,KAAM,IAAK,OAAQ,EASzE,SAAgB,EAAkB,EAAwB,EAAoC,CAAC,EAAsB,CACnH,IAAM,EAAW,CAAC,GAAI,EAAQ,UAAY,CAAC,CAAe,CAAE,EACtD,EAA4B,CAAC,EAC7B,EAAoB,CAAC,EAUrB,EAAS,EAAQ,MAAM,CAR3B,aAAgB,EAChB,SAAU,EAAW,IAAY,CAC/B,EAAU,KAAK,CAAE,KAAM,EAAQ,UAAW,YAAW,SAAQ,CAAC,CAChE,EACA,sBACE,QAAQ,QAAQ,SAAS,KAAK,CAAE,MAAO,wCAAyC,EAAG,CAAE,OAAQ,GAAI,CAAC,CAAC,EACrG,SAAW,GAAY,EAAQ,KAAK,CAAO,CAEb,CAAC,EAEjC,MAAO,CACL,SACA,YACA,UACA,SAAS,EAAW,CAClB,IAAM,EAAQ,EAAS,KAAM,GAAc,EAAU,YAAc,CAAS,GAAK,EAAS,IAAM,EAChG,OAAO,EAAO,WAAW,CAAK,CAChC,EACA,WAAW,EAAO,CAChB,EAAS,KAAK,CAAK,EACnB,EAAO,eAAe,CAAK,CAC7B,EACA,cAAc,EAAW,CACvB,IAAM,EAAQ,EAAS,UAAW,GAAc,EAAU,YAAc,CAAS,EAC7E,GAAS,GAAG,EAAS,OAAO,EAAO,CAAC,EACxC,EAAO,iBAAiB,CAAS,CACnC,EACA,UAAa,EAAO,MAAM,CAC5B,CACF"}
@@ -1,2 +1,2 @@
1
- function e(e,t,n){let r=e.parse(n);return r===null?{accepted:!1}:(e.apply(t,r),{accepted:!0})}const t={sessionId:`s1`,cwd:`/repo`};function n(e,n={}){let r=[...n.sessions??[t]],i=[],a=[],o=e.start({sessions:()=>r,publish:(t,n)=>{i.push({type:e.frameType,sessionId:t,payload:n})},onNotice:e=>a.push(e)});return{source:o,published:i,notices:a,snapshot(e){let n=r.find(t=>t.sessionId===e)??r[0]??t;return o.payloadFor(n)},addSession(e){r.push(e),o.sessionAdded?.(e)},removeSession(e){let t=r.findIndex(t=>t.sessionId===e);t>=0&&r.splice(t,1),o.sessionRemoved?.(e)},close:()=>o.close()}}export{e as driveChannel,n as hubChannelHarness};
1
+ function e(e,t,n){let r=e.parse(n);return r===null?{accepted:!1}:(e.apply(t,r),{accepted:!0})}const t={sessionId:`s1`,cwd:`/repo`};function n(e,n={}){let r=[...n.sessions??[t]],i=[],a=[],o=e.start({sessions:()=>r,publish:(t,n)=>{i.push({type:e.frameType,sessionId:t,payload:n})},requestSessionApi:()=>Promise.resolve(Response.json({error:`No session API in the channel harness.`},{status:501})),onNotice:e=>a.push(e)});return{source:o,published:i,notices:a,snapshot(e){let n=r.find(t=>t.sessionId===e)??r[0]??t;return o.payloadFor(n)},addSession(e){r.push(e),o.sessionAdded?.(e)},removeSession(e){let t=r.findIndex(t=>t.sessionId===e);t>=0&&r.splice(t,1),o.sessionRemoved?.(e)},close:()=>o.close()}}export{e as driveChannel,n as hubChannelHarness};
2
2
  //# sourceMappingURL=channels.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.mjs","names":[],"sources":["../../../src/services/testing/channels.ts"],"sourcesContent":["import type {\n ChannelFrame,\n HubChannelHost,\n HubChannelSource,\n HubSessionScope,\n WebHubChannel,\n} from '../../types/webHub.ts';\nimport type { SessionChannelContribution } from '../../types/webPlugin.ts';\n\n/**\n * The two halves of a plugin's data channel, driven the way the hub drives them.\n *\n * A channel is the one place a plugin parses input it did not produce, so its\n * parse gate is the boundary that matters, and a test that calls `apply`\n * directly steps straight over it. `driveChannel` sends a wire payload the way\n * the page does: through `parse` first, and nothing applied when it is\n * rejected.\n */\n\nexport interface ChannelDelivery {\n /** Whether the parse gate accepted the payload. */\n accepted: boolean;\n}\n\n/**\n * Sends one wire payload to a session channel.\n *\n * Returns whether the gate accepted it, so a test can assert a rejection\n * without knowing what the plugin's parsed shape looks like.\n */\nexport function driveChannel(\n channel: SessionChannelContribution,\n sessionId: string,\n payload: unknown,\n): ChannelDelivery {\n const parsed: unknown = channel.parse(payload);\n if (parsed === null) return { accepted: false };\n channel.apply(sessionId, parsed);\n return { accepted: true };\n}\n\nexport interface HubChannelHarness {\n /** The running source, as the hub holds it. */\n source: HubChannelSource;\n /** Everything the source pushed, in order. */\n readonly published: readonly ChannelFrame[];\n /** What the source told the hub. */\n readonly notices: readonly string[];\n /** The subscribe-time snapshot one session would receive; undefined means no frame. */\n snapshot(sessionId?: string): unknown;\n /** Registers a session with the source, as the hub does when one appears. */\n addSession(scope: HubSessionScope): void;\n removeSession(sessionId: string): void;\n close(): void;\n}\n\nexport interface HubChannelHarnessOptions {\n /** Sessions the hub already manages when the channel starts. */\n sessions?: readonly HubSessionScope[];\n}\n\nconst DEFAULT_SESSION: HubSessionScope = { sessionId: 's1', cwd: '/repo' };\n\n/**\n * A plugin's hub channel, started against a real host.\n *\n * The hub calls `payloadFor` once per subscriber and pushes through `publish`\n * afterwards, and a channel that only answers one of those looks correct in a\n * test that exercises the other.\n */\nexport function hubChannelHarness(channel: WebHubChannel, options: HubChannelHarnessOptions = {}): HubChannelHarness {\n const sessions = [...(options.sessions ?? [DEFAULT_SESSION])];\n const published: ChannelFrame[] = [];\n const notices: string[] = [];\n const host: HubChannelHost = {\n sessions: () => sessions,\n publish: (sessionId, payload) => {\n published.push({ type: channel.frameType, sessionId, payload });\n },\n onNotice: (message) => notices.push(message),\n };\n const source = channel.start(host);\n\n return {\n source,\n published,\n notices,\n snapshot(sessionId) {\n const scope = sessions.find((candidate) => candidate.sessionId === sessionId) ?? sessions[0] ?? DEFAULT_SESSION;\n return source.payloadFor(scope);\n },\n addSession(scope) {\n sessions.push(scope);\n source.sessionAdded?.(scope);\n },\n removeSession(sessionId) {\n const index = sessions.findIndex((candidate) => candidate.sessionId === sessionId);\n if (index >= 0) sessions.splice(index, 1);\n source.sessionRemoved?.(sessionId);\n },\n close: () => source.close(),\n };\n}\n"],"mappings":"AA8BA,SAAgB,EACd,EACA,EACA,EACiB,CACjB,IAAM,EAAkB,EAAQ,MAAM,CAAO,EAG7C,OAFI,IAAW,KAAa,CAAE,SAAU,EAAM,GAC9C,EAAQ,MAAM,EAAW,CAAM,EACxB,CAAE,SAAU,EAAK,EAC1B,CAsBA,MAAM,EAAmC,CAAE,UAAW,KAAM,IAAK,OAAQ,EASzE,SAAgB,EAAkB,EAAwB,EAAoC,CAAC,EAAsB,CACnH,IAAM,EAAW,CAAC,GAAI,EAAQ,UAAY,CAAC,CAAe,CAAE,EACtD,EAA4B,CAAC,EAC7B,EAAoB,CAAC,EAQrB,EAAS,EAAQ,MAAM,CAN3B,aAAgB,EAChB,SAAU,EAAW,IAAY,CAC/B,EAAU,KAAK,CAAE,KAAM,EAAQ,UAAW,YAAW,SAAQ,CAAC,CAChE,EACA,SAAW,GAAY,EAAQ,KAAK,CAAO,CAEb,CAAC,EAEjC,MAAO,CACL,SACA,YACA,UACA,SAAS,EAAW,CAClB,IAAM,EAAQ,EAAS,KAAM,GAAc,EAAU,YAAc,CAAS,GAAK,EAAS,IAAM,EAChG,OAAO,EAAO,WAAW,CAAK,CAChC,EACA,WAAW,EAAO,CAChB,EAAS,KAAK,CAAK,EACnB,EAAO,eAAe,CAAK,CAC7B,EACA,cAAc,EAAW,CACvB,IAAM,EAAQ,EAAS,UAAW,GAAc,EAAU,YAAc,CAAS,EAC7E,GAAS,GAAG,EAAS,OAAO,EAAO,CAAC,EACxC,EAAO,iBAAiB,CAAS,CACnC,EACA,UAAa,EAAO,MAAM,CAC5B,CACF"}
1
+ {"version":3,"file":"channels.mjs","names":[],"sources":["../../../src/services/testing/channels.ts"],"sourcesContent":["import type {\n ChannelFrame,\n HubChannelHost,\n HubChannelSource,\n HubSessionScope,\n WebHubChannel,\n} from '../../types/webHub.ts';\nimport type { SessionChannelContribution } from '../../types/webPlugin.ts';\n\n/**\n * The two halves of a plugin's data channel, driven the way the hub drives them.\n *\n * A channel is the one place a plugin parses input it did not produce, so its\n * parse gate is the boundary that matters, and a test that calls `apply`\n * directly steps straight over it. `driveChannel` sends a wire payload the way\n * the page does: through `parse` first, and nothing applied when it is\n * rejected.\n */\n\nexport interface ChannelDelivery {\n /** Whether the parse gate accepted the payload. */\n accepted: boolean;\n}\n\n/**\n * Sends one wire payload to a session channel.\n *\n * Returns whether the gate accepted it, so a test can assert a rejection\n * without knowing what the plugin's parsed shape looks like.\n */\nexport function driveChannel(\n channel: SessionChannelContribution,\n sessionId: string,\n payload: unknown,\n): ChannelDelivery {\n const parsed: unknown = channel.parse(payload);\n if (parsed === null) return { accepted: false };\n channel.apply(sessionId, parsed);\n return { accepted: true };\n}\n\nexport interface HubChannelHarness {\n /** The running source, as the hub holds it. */\n source: HubChannelSource;\n /** Everything the source pushed, in order. */\n readonly published: readonly ChannelFrame[];\n /** What the source told the hub. */\n readonly notices: readonly string[];\n /** The subscribe-time snapshot one session would receive; undefined means no frame. */\n snapshot(sessionId?: string): unknown;\n /** Registers a session with the source, as the hub does when one appears. */\n addSession(scope: HubSessionScope): void;\n removeSession(sessionId: string): void;\n close(): void;\n}\n\nexport interface HubChannelHarnessOptions {\n /** Sessions the hub already manages when the channel starts. */\n sessions?: readonly HubSessionScope[];\n}\n\nconst DEFAULT_SESSION: HubSessionScope = { sessionId: 's1', cwd: '/repo' };\n\n/**\n * A plugin's hub channel, started against a real host.\n *\n * The hub calls `payloadFor` once per subscriber and pushes through `publish`\n * afterwards, and a channel that only answers one of those looks correct in a\n * test that exercises the other.\n */\nexport function hubChannelHarness(channel: WebHubChannel, options: HubChannelHarnessOptions = {}): HubChannelHarness {\n const sessions = [...(options.sessions ?? [DEFAULT_SESSION])];\n const published: ChannelFrame[] = [];\n const notices: string[] = [];\n const host: HubChannelHost = {\n sessions: () => sessions,\n publish: (sessionId, payload) => {\n published.push({ type: channel.frameType, sessionId, payload });\n },\n requestSessionApi: () =>\n Promise.resolve(Response.json({ error: 'No session API in the channel harness.' }, { status: 501 })),\n onNotice: (message) => notices.push(message),\n };\n const source = channel.start(host);\n\n return {\n source,\n published,\n notices,\n snapshot(sessionId) {\n const scope = sessions.find((candidate) => candidate.sessionId === sessionId) ?? sessions[0] ?? DEFAULT_SESSION;\n return source.payloadFor(scope);\n },\n addSession(scope) {\n sessions.push(scope);\n source.sessionAdded?.(scope);\n },\n removeSession(sessionId) {\n const index = sessions.findIndex((candidate) => candidate.sessionId === sessionId);\n if (index >= 0) sessions.splice(index, 1);\n source.sessionRemoved?.(sessionId);\n },\n close: () => source.close(),\n };\n}\n"],"mappings":"AA8BA,SAAgB,EACd,EACA,EACA,EACiB,CACjB,IAAM,EAAkB,EAAQ,MAAM,CAAO,EAG7C,OAFI,IAAW,KAAa,CAAE,SAAU,EAAM,GAC9C,EAAQ,MAAM,EAAW,CAAM,EACxB,CAAE,SAAU,EAAK,EAC1B,CAsBA,MAAM,EAAmC,CAAE,UAAW,KAAM,IAAK,OAAQ,EASzE,SAAgB,EAAkB,EAAwB,EAAoC,CAAC,EAAsB,CACnH,IAAM,EAAW,CAAC,GAAI,EAAQ,UAAY,CAAC,CAAe,CAAE,EACtD,EAA4B,CAAC,EAC7B,EAAoB,CAAC,EAUrB,EAAS,EAAQ,MAAM,CAR3B,aAAgB,EAChB,SAAU,EAAW,IAAY,CAC/B,EAAU,KAAK,CAAE,KAAM,EAAQ,UAAW,YAAW,SAAQ,CAAC,CAChE,EACA,sBACE,QAAQ,QAAQ,SAAS,KAAK,CAAE,MAAO,wCAAyC,EAAG,CAAE,OAAQ,GAAI,CAAC,CAAC,EACrG,SAAW,GAAY,EAAQ,KAAK,CAAO,CAEb,CAAC,EAEjC,MAAO,CACL,SACA,YACA,UACA,SAAS,EAAW,CAClB,IAAM,EAAQ,EAAS,KAAM,GAAc,EAAU,YAAc,CAAS,GAAK,EAAS,IAAM,EAChG,OAAO,EAAO,WAAW,CAAK,CAChC,EACA,WAAW,EAAO,CAChB,EAAS,KAAK,CAAK,EACnB,EAAO,eAAe,CAAK,CAC7B,EACA,cAAc,EAAW,CACvB,IAAM,EAAQ,EAAS,UAAW,GAAc,EAAU,YAAc,CAAS,EAC7E,GAAS,GAAG,EAAS,OAAO,EAAO,CAAC,EACxC,EAAO,iBAAiB,CAAS,CACnC,EACA,UAAa,EAAO,MAAM,CAC5B,CACF"}
@@ -1,2 +1,2 @@
1
- function e(e={}){let t=[];return{props:{sessionId:e.sessionId===void 0?`s1`:e.sessionId,statuses:e.statuses??{},openTab:e=>{t.push({action:`openTab`,target:e})},openTransientTab:e=>{t.push({action:`openTransientTab`,target:e.id})},closeTransientTab:e=>{t.push({action:`closeTransientTab`,target:e})},sendSessionFrame:(e,n)=>{t.push({action:`sendSessionFrame`,target:e,frame:n})},renderThread:t=>e.thread?.(t)??null,renderSlot:t=>e.slotContent?.[t]??null,slotData:t=>e.slotData?.[t.slot]??[]},actions:t,frames:()=>t.flatMap(e=>e.frame?[e.frame]:[])}}function t(t){let n=e(t),r=t.result===void 0?null:t.result;return{...n,props:{...n.props,toolCallId:t.toolCallId??`call-1`,toolName:t.toolName,args:t.args??{},result:r,output:t.output??``,running:t.running??!1,isError:t.isError??!1}}}exports.slotPropsFixture=e,exports.toolMessagePropsFixture=t;
1
+ function e(e={}){let t=[],n={sessionId:e.sessionId===void 0?`s1`:e.sessionId,statuses:e.statuses??{},openTab:e=>{t.push({action:`openTab`,target:e})},openTransientTab:e=>{t.push({action:`openTransientTab`,target:e.id})},closeTransientTab:e=>{t.push({action:`closeTransientTab`,target:e})},appendComposerDraft:e=>{t.push({action:`appendComposerDraft`,target:n.sessionId,text:e})},sendSessionFrame:(e,n)=>{t.push({action:`sendSessionFrame`,target:e,frame:n})},renderThread:t=>e.thread?.(t)??null,renderSlot:t=>e.slotContent?.[t]??null,slotData:t=>e.slotData?.[t.slot]??[]};return{props:n,actions:t,frames:()=>t.flatMap(e=>e.frame?[e.frame]:[])}}function t(t){let n=e(t),r=t.result===void 0?null:t.result;return{...n,props:{...n.props,toolCallId:t.toolCallId??`call-1`,toolName:t.toolName,args:t.args??{},result:r,output:t.output??``,running:t.running??!1,isError:t.isError??!1}}}exports.slotPropsFixture=e,exports.toolMessagePropsFixture=t;
2
2
  //# sourceMappingURL=slotProps.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"slotProps.cjs","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n SlotDataFill,\n SlotDeclaration,\n ToolMessageRenderProps,\n ToolResultView,\n TransientTab,\n WebPluginSlotProps,\n} from '../../types/webPlugin.ts';\n\n/**\n * The props the cockpit hands a plugin's components, built for a test.\n *\n * A plugin component takes fifteen props and reads three of them. Written out\n * by hand in each test, the other twelve are noise that goes stale the moment\n * the contract grows a member; written as a cast, the component compiles\n * against props the host never sends. This builds all of them, records what the\n * component did with the actions, and lets a test override the two or three it\n * cares about.\n */\n\nexport interface RecordedSlotAction {\n action: 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';\n /** The tab id, the transient tab's id, or the target session of a frame. */\n target: string | null;\n /** The frame a component sent, for `sendSessionFrame`. */\n frame?: Record<string, unknown>;\n}\n\nexport interface SlotPropsFixture {\n props: WebPluginSlotProps;\n /** Everything the component did through its props, in order. */\n readonly actions: readonly RecordedSlotAction[];\n /** Frames the component sent, which is what most assertions want. */\n frames(): readonly Record<string, unknown>[];\n}\n\nexport interface SlotPropsOptions {\n sessionId?: string | null;\n statuses?: Readonly<Record<string, string>>;\n /** Component fills this slot owner should see; keyed by slot name. */\n slotContent?: Readonly<Record<string, ReactNode>>;\n /** Data fills this slot owner should read back, keyed by slot name. */\n slotData?: Readonly<Record<string, readonly SlotDataFill[]>>;\n /** What `renderThread` returns for a plugin that renders one. */\n thread?: (threadId: string) => ReactNode;\n}\n\nconst DEFAULT_SESSION_ID = 's1';\n\nexport function slotPropsFixture(options: SlotPropsOptions = {}): SlotPropsFixture {\n const actions: RecordedSlotAction[] = [];\n const props: WebPluginSlotProps = {\n sessionId: options.sessionId === undefined ? DEFAULT_SESSION_ID : options.sessionId,\n statuses: options.statuses ?? {},\n openTab: (tabId) => {\n actions.push({ action: 'openTab', target: tabId });\n },\n openTransientTab: (tab: TransientTab) => {\n actions.push({ action: 'openTransientTab', target: tab.id });\n },\n closeTransientTab: (tabId: string) => {\n actions.push({ action: 'closeTransientTab', target: tabId });\n },\n sendSessionFrame: (sessionId, frame) => {\n actions.push({ action: 'sendSessionFrame', target: sessionId, frame });\n },\n renderThread: (threadId) => options.thread?.(threadId) ?? null,\n renderSlot: (slot) => options.slotContent?.[slot] ?? null,\n // The host resolves fills by slot name and hands the owner its own typed\n // view, so a test declares them by name too.\n slotData: <Data>(slot: SlotDeclaration<Data>) =>\n (options.slotData?.[slot.slot] ?? []) as readonly SlotDataFill<Data>[],\n };\n\n return {\n props,\n actions,\n frames: () => actions.flatMap((entry) => (entry.frame ? [entry.frame] : [])),\n };\n}\n\nexport interface ToolMessagePropsOptions extends SlotPropsOptions {\n toolCallId?: string;\n toolName: string;\n args?: Record<string, unknown>;\n /** The newest result; null is what the host sends before any output. */\n result?: ToolResultView | null;\n /** The result's text blocks joined, as the host's own fallback item shows them. */\n output?: string;\n running?: boolean;\n isError?: boolean;\n}\n\nexport interface ToolMessagePropsFixture extends Omit<SlotPropsFixture, 'props'> {\n props: ToolMessageRenderProps;\n}\n\nconst DEFAULT_TOOL_CALL_ID = 'call-1';\n\n/** The props a tool's timeline item receives, in any of its four states. */\nexport function toolMessagePropsFixture(options: ToolMessagePropsOptions): ToolMessagePropsFixture {\n const base = slotPropsFixture(options);\n const result = options.result === undefined ? null : options.result;\n return {\n ...base,\n props: {\n ...base.props,\n toolCallId: options.toolCallId ?? DEFAULT_TOOL_CALL_ID,\n toolName: options.toolName,\n args: options.args ?? {},\n result,\n output: options.output ?? '',\n running: options.running ?? false,\n isError: options.isError ?? false,\n },\n };\n}\n"],"mappings":"AAkDA,SAAgB,EAAiB,EAA4B,CAAC,EAAqB,CACjF,IAAM,EAAgC,CAAC,EAwBvC,MAAO,CACL,MAAA,CAvBA,UAAW,EAAQ,YAAc,IAAA,GAAY,KAAqB,EAAQ,UAC1E,SAAU,EAAQ,UAAY,CAAC,EAC/B,QAAU,GAAU,CAClB,EAAQ,KAAK,CAAE,OAAQ,UAAW,OAAQ,CAAM,CAAC,CACnD,EACA,iBAAmB,GAAsB,CACvC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAI,EAAG,CAAC,CAC7D,EACA,kBAAoB,GAAkB,CACpC,EAAQ,KAAK,CAAE,OAAQ,oBAAqB,OAAQ,CAAM,CAAC,CAC7D,EACA,kBAAmB,EAAW,IAAU,CACtC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAW,OAAM,CAAC,CACvE,EACA,aAAe,GAAa,EAAQ,SAAS,CAAQ,GAAK,KAC1D,WAAa,GAAS,EAAQ,cAAc,IAAS,KAGrD,SAAiB,GACd,EAAQ,WAAW,EAAK,OAAS,CAAC,CAIjC,EACJ,UACA,WAAc,EAAQ,QAAS,GAAW,EAAM,MAAQ,CAAC,EAAM,KAAK,EAAI,CAAC,CAAE,CAC7E,CACF,CAqBA,SAAgB,EAAwB,EAA2D,CACjG,IAAM,EAAO,EAAiB,CAAO,EAC/B,EAAS,EAAQ,SAAW,IAAA,GAAY,KAAO,EAAQ,OAC7D,MAAO,CACL,GAAG,EACH,MAAO,CACL,GAAG,EAAK,MACR,WAAY,EAAQ,YAAc,SAClC,SAAU,EAAQ,SAClB,KAAM,EAAQ,MAAQ,CAAC,EACvB,SACA,OAAQ,EAAQ,QAAU,GAC1B,QAAS,EAAQ,SAAW,GAC5B,QAAS,EAAQ,SAAW,EAC9B,CACF,CACF"}
1
+ {"version":3,"file":"slotProps.cjs","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n SlotDataFill,\n SlotDeclaration,\n ToolMessageRenderProps,\n ToolResultView,\n TransientTab,\n WebPluginSlotProps,\n} from '../../types/webPlugin.ts';\n\n/**\n * The props the cockpit hands a plugin's components, built for a test.\n *\n * A plugin component takes fifteen props and reads three of them. Written out\n * by hand in each test, the other twelve are noise that goes stale the moment\n * the contract grows a member; written as a cast, the component compiles\n * against props the host never sends. This builds all of them, records what the\n * component did with the actions, and lets a test override the two or three it\n * cares about.\n */\n\nexport interface RecordedSlotAction {\n action: 'appendComposerDraft' | 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';\n /** The tab id, the transient tab's id, or the target session of a frame or composer append. */\n target: string | null;\n /** The text passed to `appendComposerDraft`. */\n text?: string;\n /** The frame a component sent, for `sendSessionFrame`. */\n frame?: Record<string, unknown>;\n}\n\nexport interface SlotPropsFixture {\n props: WebPluginSlotProps;\n /** Everything the component did through its props, in order. */\n readonly actions: readonly RecordedSlotAction[];\n /** Frames the component sent, which is what most assertions want. */\n frames(): readonly Record<string, unknown>[];\n}\n\nexport interface SlotPropsOptions {\n sessionId?: string | null;\n statuses?: Readonly<Record<string, string>>;\n /** Component fills this slot owner should see; keyed by slot name. */\n slotContent?: Readonly<Record<string, ReactNode>>;\n /** Data fills this slot owner should read back, keyed by slot name. */\n slotData?: Readonly<Record<string, readonly SlotDataFill[]>>;\n /** What `renderThread` returns for a plugin that renders one. */\n thread?: (threadId: string) => ReactNode;\n}\n\nconst DEFAULT_SESSION_ID = 's1';\n\nexport function slotPropsFixture(options: SlotPropsOptions = {}): SlotPropsFixture {\n const actions: RecordedSlotAction[] = [];\n const props: WebPluginSlotProps = {\n sessionId: options.sessionId === undefined ? DEFAULT_SESSION_ID : options.sessionId,\n statuses: options.statuses ?? {},\n openTab: (tabId) => {\n actions.push({ action: 'openTab', target: tabId });\n },\n openTransientTab: (tab: TransientTab) => {\n actions.push({ action: 'openTransientTab', target: tab.id });\n },\n closeTransientTab: (tabId: string) => {\n actions.push({ action: 'closeTransientTab', target: tabId });\n },\n appendComposerDraft: (text) => {\n actions.push({ action: 'appendComposerDraft', target: props.sessionId, text });\n },\n sendSessionFrame: (sessionId, frame) => {\n actions.push({ action: 'sendSessionFrame', target: sessionId, frame });\n },\n renderThread: (threadId) => options.thread?.(threadId) ?? null,\n renderSlot: (slot) => options.slotContent?.[slot] ?? null,\n // The host resolves fills by slot name and hands the owner its own typed\n // view, so a test declares them by name too.\n slotData: <Data>(slot: SlotDeclaration<Data>) =>\n (options.slotData?.[slot.slot] ?? []) as readonly SlotDataFill<Data>[],\n };\n\n return {\n props,\n actions,\n frames: () => actions.flatMap((entry) => (entry.frame ? [entry.frame] : [])),\n };\n}\n\nexport interface ToolMessagePropsOptions extends SlotPropsOptions {\n toolCallId?: string;\n toolName: string;\n args?: Record<string, unknown>;\n /** The newest result; null is what the host sends before any output. */\n result?: ToolResultView | null;\n /** The result's text blocks joined, as the host's own fallback item shows them. */\n output?: string;\n running?: boolean;\n isError?: boolean;\n}\n\nexport interface ToolMessagePropsFixture extends Omit<SlotPropsFixture, 'props'> {\n props: ToolMessageRenderProps;\n}\n\nconst DEFAULT_TOOL_CALL_ID = 'call-1';\n\n/** The props a tool's timeline item receives, in any of its four states. */\nexport function toolMessagePropsFixture(options: ToolMessagePropsOptions): ToolMessagePropsFixture {\n const base = slotPropsFixture(options);\n const result = options.result === undefined ? null : options.result;\n return {\n ...base,\n props: {\n ...base.props,\n toolCallId: options.toolCallId ?? DEFAULT_TOOL_CALL_ID,\n toolName: options.toolName,\n args: options.args ?? {},\n result,\n output: options.output ?? '',\n running: options.running ?? false,\n isError: options.isError ?? false,\n },\n };\n}\n"],"mappings":"AAoDA,SAAgB,EAAiB,EAA4B,CAAC,EAAqB,CACjF,IAAM,EAAgC,CAAC,EACjC,EAA4B,CAChC,UAAW,EAAQ,YAAc,IAAA,GAAY,KAAqB,EAAQ,UAC1E,SAAU,EAAQ,UAAY,CAAC,EAC/B,QAAU,GAAU,CAClB,EAAQ,KAAK,CAAE,OAAQ,UAAW,OAAQ,CAAM,CAAC,CACnD,EACA,iBAAmB,GAAsB,CACvC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAI,EAAG,CAAC,CAC7D,EACA,kBAAoB,GAAkB,CACpC,EAAQ,KAAK,CAAE,OAAQ,oBAAqB,OAAQ,CAAM,CAAC,CAC7D,EACA,oBAAsB,GAAS,CAC7B,EAAQ,KAAK,CAAE,OAAQ,sBAAuB,OAAQ,EAAM,UAAW,MAAK,CAAC,CAC/E,EACA,kBAAmB,EAAW,IAAU,CACtC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAW,OAAM,CAAC,CACvE,EACA,aAAe,GAAa,EAAQ,SAAS,CAAQ,GAAK,KAC1D,WAAa,GAAS,EAAQ,cAAc,IAAS,KAGrD,SAAiB,GACd,EAAQ,WAAW,EAAK,OAAS,CAAC,CACvC,EAEA,MAAO,CACL,QACA,UACA,WAAc,EAAQ,QAAS,GAAW,EAAM,MAAQ,CAAC,EAAM,KAAK,EAAI,CAAC,CAAE,CAC7E,CACF,CAqBA,SAAgB,EAAwB,EAA2D,CACjG,IAAM,EAAO,EAAiB,CAAO,EAC/B,EAAS,EAAQ,SAAW,IAAA,GAAY,KAAO,EAAQ,OAC7D,MAAO,CACL,GAAG,EACH,MAAO,CACL,GAAG,EAAK,MACR,WAAY,EAAQ,YAAc,SAClC,SAAU,EAAQ,SAClB,KAAM,EAAQ,MAAQ,CAAC,EACvB,SACA,OAAQ,EAAQ,QAAU,GAC1B,QAAS,EAAQ,SAAW,GAC5B,QAAS,EAAQ,SAAW,EAC9B,CACF,CACF"}
@@ -12,9 +12,11 @@ import { ReactNode } from "react";
12
12
  * cares about.
13
13
  */
14
14
  interface RecordedSlotAction {
15
- action: 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';
16
- /** The tab id, the transient tab's id, or the target session of a frame. */
15
+ action: 'appendComposerDraft' | 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';
16
+ /** The tab id, the transient tab's id, or the target session of a frame or composer append. */
17
17
  target: string | null;
18
+ /** The text passed to `appendComposerDraft`. */
19
+ text?: string;
18
20
  /** The frame a component sent, for `sendSessionFrame`. */
19
21
  frame?: Record<string, unknown>;
20
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slotProps.d.cts","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"mappings":";;;;;;;;;;;;;UAqBiB;EACf;;EAEA;;EAEA,QAAQ;;UAGO;EACf,OAAO;;WAEE,kBAAkB;;EAE3B,mBAAmB;;UAGJ;EACf;EACA,WAAW,SAAS;;EAEpB,cAAc,SAAS,eAAe;;EAEtC,WAAW,SAAS,wBAAwB;;EAE5C,UAAU,qBAAqB;;iBAKjB,iBAAiB,UAAS,mBAAwB;UAgCjD,gCAAgC;EAC/C;EACA;EACA,OAAO;;EAEP,SAAS;;EAET;EACA;EACA;;UAGe,gCAAgC,KAAK;EACpD,OAAO;;;iBAMO,wBAAwB,SAAS,0BAA0B"}
1
+ {"version":3,"file":"slotProps.d.cts","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"mappings":";;;;;;;;;;;;;UAqBiB;EACf;;EAEA;;EAEA;;EAEA,QAAQ;;UAGO;EACf,OAAO;;WAEE,kBAAkB;;EAE3B,mBAAmB;;UAGJ;EACf;EACA,WAAW,SAAS;;EAEpB,cAAc,SAAS,eAAe;;EAEtC,WAAW,SAAS,wBAAwB;;EAE5C,UAAU,qBAAqB;;iBAKjB,iBAAiB,UAAS,mBAAwB;UAmCjD,gCAAgC;EAC/C;EACA;EACA,OAAO;;EAEP,SAAS;;EAET;EACA;EACA;;UAGe,gCAAgC,KAAK;EACpD,OAAO;;;iBAMO,wBAAwB,SAAS,0BAA0B"}
@@ -12,9 +12,11 @@ import { ReactNode } from "react";
12
12
  * cares about.
13
13
  */
14
14
  interface RecordedSlotAction {
15
- action: 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';
16
- /** The tab id, the transient tab's id, or the target session of a frame. */
15
+ action: 'appendComposerDraft' | 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';
16
+ /** The tab id, the transient tab's id, or the target session of a frame or composer append. */
17
17
  target: string | null;
18
+ /** The text passed to `appendComposerDraft`. */
19
+ text?: string;
18
20
  /** The frame a component sent, for `sendSessionFrame`. */
19
21
  frame?: Record<string, unknown>;
20
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slotProps.d.mts","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"mappings":";;;;;;;;;;;;;UAqBiB;EACf;;EAEA;;EAEA,QAAQ;;UAGO;EACf,OAAO;;WAEE,kBAAkB;;EAE3B,mBAAmB;;UAGJ;EACf;EACA,WAAW,SAAS;;EAEpB,cAAc,SAAS,eAAe;;EAEtC,WAAW,SAAS,wBAAwB;;EAE5C,UAAU,qBAAqB;;iBAKjB,iBAAiB,UAAS,mBAAwB;UAgCjD,gCAAgC;EAC/C;EACA;EACA,OAAO;;EAEP,SAAS;;EAET;EACA;EACA;;UAGe,gCAAgC,KAAK;EACpD,OAAO;;;iBAMO,wBAAwB,SAAS,0BAA0B"}
1
+ {"version":3,"file":"slotProps.d.mts","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"mappings":";;;;;;;;;;;;;UAqBiB;EACf;;EAEA;;EAEA;;EAEA,QAAQ;;UAGO;EACf,OAAO;;WAEE,kBAAkB;;EAE3B,mBAAmB;;UAGJ;EACf;EACA,WAAW,SAAS;;EAEpB,cAAc,SAAS,eAAe;;EAEtC,WAAW,SAAS,wBAAwB;;EAE5C,UAAU,qBAAqB;;iBAKjB,iBAAiB,UAAS,mBAAwB;UAmCjD,gCAAgC;EAC/C;EACA;EACA,OAAO;;EAEP,SAAS;;EAET;EACA;EACA;;UAGe,gCAAgC,KAAK;EACpD,OAAO;;;iBAMO,wBAAwB,SAAS,0BAA0B"}
@@ -1,2 +1,2 @@
1
- function e(e={}){let t=[];return{props:{sessionId:e.sessionId===void 0?`s1`:e.sessionId,statuses:e.statuses??{},openTab:e=>{t.push({action:`openTab`,target:e})},openTransientTab:e=>{t.push({action:`openTransientTab`,target:e.id})},closeTransientTab:e=>{t.push({action:`closeTransientTab`,target:e})},sendSessionFrame:(e,n)=>{t.push({action:`sendSessionFrame`,target:e,frame:n})},renderThread:t=>e.thread?.(t)??null,renderSlot:t=>e.slotContent?.[t]??null,slotData:t=>e.slotData?.[t.slot]??[]},actions:t,frames:()=>t.flatMap(e=>e.frame?[e.frame]:[])}}function t(t){let n=e(t),r=t.result===void 0?null:t.result;return{...n,props:{...n.props,toolCallId:t.toolCallId??`call-1`,toolName:t.toolName,args:t.args??{},result:r,output:t.output??``,running:t.running??!1,isError:t.isError??!1}}}export{e as slotPropsFixture,t as toolMessagePropsFixture};
1
+ function e(e={}){let t=[],n={sessionId:e.sessionId===void 0?`s1`:e.sessionId,statuses:e.statuses??{},openTab:e=>{t.push({action:`openTab`,target:e})},openTransientTab:e=>{t.push({action:`openTransientTab`,target:e.id})},closeTransientTab:e=>{t.push({action:`closeTransientTab`,target:e})},appendComposerDraft:e=>{t.push({action:`appendComposerDraft`,target:n.sessionId,text:e})},sendSessionFrame:(e,n)=>{t.push({action:`sendSessionFrame`,target:e,frame:n})},renderThread:t=>e.thread?.(t)??null,renderSlot:t=>e.slotContent?.[t]??null,slotData:t=>e.slotData?.[t.slot]??[]};return{props:n,actions:t,frames:()=>t.flatMap(e=>e.frame?[e.frame]:[])}}function t(t){let n=e(t),r=t.result===void 0?null:t.result;return{...n,props:{...n.props,toolCallId:t.toolCallId??`call-1`,toolName:t.toolName,args:t.args??{},result:r,output:t.output??``,running:t.running??!1,isError:t.isError??!1}}}export{e as slotPropsFixture,t as toolMessagePropsFixture};
2
2
  //# sourceMappingURL=slotProps.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"slotProps.mjs","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n SlotDataFill,\n SlotDeclaration,\n ToolMessageRenderProps,\n ToolResultView,\n TransientTab,\n WebPluginSlotProps,\n} from '../../types/webPlugin.ts';\n\n/**\n * The props the cockpit hands a plugin's components, built for a test.\n *\n * A plugin component takes fifteen props and reads three of them. Written out\n * by hand in each test, the other twelve are noise that goes stale the moment\n * the contract grows a member; written as a cast, the component compiles\n * against props the host never sends. This builds all of them, records what the\n * component did with the actions, and lets a test override the two or three it\n * cares about.\n */\n\nexport interface RecordedSlotAction {\n action: 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';\n /** The tab id, the transient tab's id, or the target session of a frame. */\n target: string | null;\n /** The frame a component sent, for `sendSessionFrame`. */\n frame?: Record<string, unknown>;\n}\n\nexport interface SlotPropsFixture {\n props: WebPluginSlotProps;\n /** Everything the component did through its props, in order. */\n readonly actions: readonly RecordedSlotAction[];\n /** Frames the component sent, which is what most assertions want. */\n frames(): readonly Record<string, unknown>[];\n}\n\nexport interface SlotPropsOptions {\n sessionId?: string | null;\n statuses?: Readonly<Record<string, string>>;\n /** Component fills this slot owner should see; keyed by slot name. */\n slotContent?: Readonly<Record<string, ReactNode>>;\n /** Data fills this slot owner should read back, keyed by slot name. */\n slotData?: Readonly<Record<string, readonly SlotDataFill[]>>;\n /** What `renderThread` returns for a plugin that renders one. */\n thread?: (threadId: string) => ReactNode;\n}\n\nconst DEFAULT_SESSION_ID = 's1';\n\nexport function slotPropsFixture(options: SlotPropsOptions = {}): SlotPropsFixture {\n const actions: RecordedSlotAction[] = [];\n const props: WebPluginSlotProps = {\n sessionId: options.sessionId === undefined ? DEFAULT_SESSION_ID : options.sessionId,\n statuses: options.statuses ?? {},\n openTab: (tabId) => {\n actions.push({ action: 'openTab', target: tabId });\n },\n openTransientTab: (tab: TransientTab) => {\n actions.push({ action: 'openTransientTab', target: tab.id });\n },\n closeTransientTab: (tabId: string) => {\n actions.push({ action: 'closeTransientTab', target: tabId });\n },\n sendSessionFrame: (sessionId, frame) => {\n actions.push({ action: 'sendSessionFrame', target: sessionId, frame });\n },\n renderThread: (threadId) => options.thread?.(threadId) ?? null,\n renderSlot: (slot) => options.slotContent?.[slot] ?? null,\n // The host resolves fills by slot name and hands the owner its own typed\n // view, so a test declares them by name too.\n slotData: <Data>(slot: SlotDeclaration<Data>) =>\n (options.slotData?.[slot.slot] ?? []) as readonly SlotDataFill<Data>[],\n };\n\n return {\n props,\n actions,\n frames: () => actions.flatMap((entry) => (entry.frame ? [entry.frame] : [])),\n };\n}\n\nexport interface ToolMessagePropsOptions extends SlotPropsOptions {\n toolCallId?: string;\n toolName: string;\n args?: Record<string, unknown>;\n /** The newest result; null is what the host sends before any output. */\n result?: ToolResultView | null;\n /** The result's text blocks joined, as the host's own fallback item shows them. */\n output?: string;\n running?: boolean;\n isError?: boolean;\n}\n\nexport interface ToolMessagePropsFixture extends Omit<SlotPropsFixture, 'props'> {\n props: ToolMessageRenderProps;\n}\n\nconst DEFAULT_TOOL_CALL_ID = 'call-1';\n\n/** The props a tool's timeline item receives, in any of its four states. */\nexport function toolMessagePropsFixture(options: ToolMessagePropsOptions): ToolMessagePropsFixture {\n const base = slotPropsFixture(options);\n const result = options.result === undefined ? null : options.result;\n return {\n ...base,\n props: {\n ...base.props,\n toolCallId: options.toolCallId ?? DEFAULT_TOOL_CALL_ID,\n toolName: options.toolName,\n args: options.args ?? {},\n result,\n output: options.output ?? '',\n running: options.running ?? false,\n isError: options.isError ?? false,\n },\n };\n}\n"],"mappings":"AAkDA,SAAgB,EAAiB,EAA4B,CAAC,EAAqB,CACjF,IAAM,EAAgC,CAAC,EAwBvC,MAAO,CACL,MAAA,CAvBA,UAAW,EAAQ,YAAc,IAAA,GAAY,KAAqB,EAAQ,UAC1E,SAAU,EAAQ,UAAY,CAAC,EAC/B,QAAU,GAAU,CAClB,EAAQ,KAAK,CAAE,OAAQ,UAAW,OAAQ,CAAM,CAAC,CACnD,EACA,iBAAmB,GAAsB,CACvC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAI,EAAG,CAAC,CAC7D,EACA,kBAAoB,GAAkB,CACpC,EAAQ,KAAK,CAAE,OAAQ,oBAAqB,OAAQ,CAAM,CAAC,CAC7D,EACA,kBAAmB,EAAW,IAAU,CACtC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAW,OAAM,CAAC,CACvE,EACA,aAAe,GAAa,EAAQ,SAAS,CAAQ,GAAK,KAC1D,WAAa,GAAS,EAAQ,cAAc,IAAS,KAGrD,SAAiB,GACd,EAAQ,WAAW,EAAK,OAAS,CAAC,CAIjC,EACJ,UACA,WAAc,EAAQ,QAAS,GAAW,EAAM,MAAQ,CAAC,EAAM,KAAK,EAAI,CAAC,CAAE,CAC7E,CACF,CAqBA,SAAgB,EAAwB,EAA2D,CACjG,IAAM,EAAO,EAAiB,CAAO,EAC/B,EAAS,EAAQ,SAAW,IAAA,GAAY,KAAO,EAAQ,OAC7D,MAAO,CACL,GAAG,EACH,MAAO,CACL,GAAG,EAAK,MACR,WAAY,EAAQ,YAAc,SAClC,SAAU,EAAQ,SAClB,KAAM,EAAQ,MAAQ,CAAC,EACvB,SACA,OAAQ,EAAQ,QAAU,GAC1B,QAAS,EAAQ,SAAW,GAC5B,QAAS,EAAQ,SAAW,EAC9B,CACF,CACF"}
1
+ {"version":3,"file":"slotProps.mjs","names":[],"sources":["../../../src/services/testing/slotProps.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n SlotDataFill,\n SlotDeclaration,\n ToolMessageRenderProps,\n ToolResultView,\n TransientTab,\n WebPluginSlotProps,\n} from '../../types/webPlugin.ts';\n\n/**\n * The props the cockpit hands a plugin's components, built for a test.\n *\n * A plugin component takes fifteen props and reads three of them. Written out\n * by hand in each test, the other twelve are noise that goes stale the moment\n * the contract grows a member; written as a cast, the component compiles\n * against props the host never sends. This builds all of them, records what the\n * component did with the actions, and lets a test override the two or three it\n * cares about.\n */\n\nexport interface RecordedSlotAction {\n action: 'appendComposerDraft' | 'openTab' | 'openTransientTab' | 'closeTransientTab' | 'sendSessionFrame';\n /** The tab id, the transient tab's id, or the target session of a frame or composer append. */\n target: string | null;\n /** The text passed to `appendComposerDraft`. */\n text?: string;\n /** The frame a component sent, for `sendSessionFrame`. */\n frame?: Record<string, unknown>;\n}\n\nexport interface SlotPropsFixture {\n props: WebPluginSlotProps;\n /** Everything the component did through its props, in order. */\n readonly actions: readonly RecordedSlotAction[];\n /** Frames the component sent, which is what most assertions want. */\n frames(): readonly Record<string, unknown>[];\n}\n\nexport interface SlotPropsOptions {\n sessionId?: string | null;\n statuses?: Readonly<Record<string, string>>;\n /** Component fills this slot owner should see; keyed by slot name. */\n slotContent?: Readonly<Record<string, ReactNode>>;\n /** Data fills this slot owner should read back, keyed by slot name. */\n slotData?: Readonly<Record<string, readonly SlotDataFill[]>>;\n /** What `renderThread` returns for a plugin that renders one. */\n thread?: (threadId: string) => ReactNode;\n}\n\nconst DEFAULT_SESSION_ID = 's1';\n\nexport function slotPropsFixture(options: SlotPropsOptions = {}): SlotPropsFixture {\n const actions: RecordedSlotAction[] = [];\n const props: WebPluginSlotProps = {\n sessionId: options.sessionId === undefined ? DEFAULT_SESSION_ID : options.sessionId,\n statuses: options.statuses ?? {},\n openTab: (tabId) => {\n actions.push({ action: 'openTab', target: tabId });\n },\n openTransientTab: (tab: TransientTab) => {\n actions.push({ action: 'openTransientTab', target: tab.id });\n },\n closeTransientTab: (tabId: string) => {\n actions.push({ action: 'closeTransientTab', target: tabId });\n },\n appendComposerDraft: (text) => {\n actions.push({ action: 'appendComposerDraft', target: props.sessionId, text });\n },\n sendSessionFrame: (sessionId, frame) => {\n actions.push({ action: 'sendSessionFrame', target: sessionId, frame });\n },\n renderThread: (threadId) => options.thread?.(threadId) ?? null,\n renderSlot: (slot) => options.slotContent?.[slot] ?? null,\n // The host resolves fills by slot name and hands the owner its own typed\n // view, so a test declares them by name too.\n slotData: <Data>(slot: SlotDeclaration<Data>) =>\n (options.slotData?.[slot.slot] ?? []) as readonly SlotDataFill<Data>[],\n };\n\n return {\n props,\n actions,\n frames: () => actions.flatMap((entry) => (entry.frame ? [entry.frame] : [])),\n };\n}\n\nexport interface ToolMessagePropsOptions extends SlotPropsOptions {\n toolCallId?: string;\n toolName: string;\n args?: Record<string, unknown>;\n /** The newest result; null is what the host sends before any output. */\n result?: ToolResultView | null;\n /** The result's text blocks joined, as the host's own fallback item shows them. */\n output?: string;\n running?: boolean;\n isError?: boolean;\n}\n\nexport interface ToolMessagePropsFixture extends Omit<SlotPropsFixture, 'props'> {\n props: ToolMessageRenderProps;\n}\n\nconst DEFAULT_TOOL_CALL_ID = 'call-1';\n\n/** The props a tool's timeline item receives, in any of its four states. */\nexport function toolMessagePropsFixture(options: ToolMessagePropsOptions): ToolMessagePropsFixture {\n const base = slotPropsFixture(options);\n const result = options.result === undefined ? null : options.result;\n return {\n ...base,\n props: {\n ...base.props,\n toolCallId: options.toolCallId ?? DEFAULT_TOOL_CALL_ID,\n toolName: options.toolName,\n args: options.args ?? {},\n result,\n output: options.output ?? '',\n running: options.running ?? false,\n isError: options.isError ?? false,\n },\n };\n}\n"],"mappings":"AAoDA,SAAgB,EAAiB,EAA4B,CAAC,EAAqB,CACjF,IAAM,EAAgC,CAAC,EACjC,EAA4B,CAChC,UAAW,EAAQ,YAAc,IAAA,GAAY,KAAqB,EAAQ,UAC1E,SAAU,EAAQ,UAAY,CAAC,EAC/B,QAAU,GAAU,CAClB,EAAQ,KAAK,CAAE,OAAQ,UAAW,OAAQ,CAAM,CAAC,CACnD,EACA,iBAAmB,GAAsB,CACvC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAI,EAAG,CAAC,CAC7D,EACA,kBAAoB,GAAkB,CACpC,EAAQ,KAAK,CAAE,OAAQ,oBAAqB,OAAQ,CAAM,CAAC,CAC7D,EACA,oBAAsB,GAAS,CAC7B,EAAQ,KAAK,CAAE,OAAQ,sBAAuB,OAAQ,EAAM,UAAW,MAAK,CAAC,CAC/E,EACA,kBAAmB,EAAW,IAAU,CACtC,EAAQ,KAAK,CAAE,OAAQ,mBAAoB,OAAQ,EAAW,OAAM,CAAC,CACvE,EACA,aAAe,GAAa,EAAQ,SAAS,CAAQ,GAAK,KAC1D,WAAa,GAAS,EAAQ,cAAc,IAAS,KAGrD,SAAiB,GACd,EAAQ,WAAW,EAAK,OAAS,CAAC,CACvC,EAEA,MAAO,CACL,QACA,UACA,WAAc,EAAQ,QAAS,GAAW,EAAM,MAAQ,CAAC,EAAM,KAAK,EAAI,CAAC,CAAE,CAC7E,CACF,CAqBA,SAAgB,EAAwB,EAA2D,CACjG,IAAM,EAAO,EAAiB,CAAO,EAC/B,EAAS,EAAQ,SAAW,IAAA,GAAY,KAAO,EAAQ,OAC7D,MAAO,CACL,GAAG,EACH,MAAO,CACL,GAAG,EAAK,MACR,WAAY,EAAQ,YAAc,SAClC,SAAU,EAAQ,SAClB,KAAM,EAAQ,MAAQ,CAAC,EACvB,SACA,OAAQ,EAAQ,QAAU,GAC1B,QAAS,EAAQ,SAAW,GAC5B,QAAS,EAAQ,SAAW,EAC9B,CACF,CACF"}
@@ -20,12 +20,27 @@ interface HubSessionScope {
20
20
  /** The session's working directory, for repo-scoped data sources. */
21
21
  cwd: string;
22
22
  }
23
+ interface HubSessionApiRequest {
24
+ basePath: string;
25
+ path: string;
26
+ method: string;
27
+ body?: string | Uint8Array<ArrayBuffer> | null;
28
+ signal?: AbortSignal;
29
+ }
30
+ interface HubChannelConnection {
31
+ /** Opaque for one page socket lifetime. */
32
+ connectionId: string;
33
+ }
23
34
  /** What the hub hands a channel when it starts. */
24
35
  interface HubChannelHost {
25
36
  /** Every session the hub currently manages. */
26
37
  sessions(): readonly HubSessionScope[];
27
38
  /** Live fan-out to the session's page subscribers. */
28
39
  publish(sessionId: string, payload: unknown): void;
40
+ /** Delivers only to the authenticated page socket named by connectionId. */
41
+ publishToConnection?(connectionId: string, sessionId: string, payload: unknown): boolean;
42
+ /** Authenticated machine-local transport to a session package API. */
43
+ requestSessionApi(scope: HubSessionScope, request: HubSessionApiRequest): Promise<Response>;
29
44
  onNotice(message: string): void;
30
45
  }
31
46
  /**
@@ -50,7 +65,13 @@ interface WebHubChannel {
50
65
  /** Wire frame type; globally unique across every loaded plugin. */
51
66
  frameType: string;
52
67
  start(host: HubChannelHost): HubChannelSource;
68
+ /** Allows an authenticated connection to acknowledge targeted frames after its session subscription changes. */
69
+ receiveWithoutSubscription?: boolean;
70
+ /** Receives only frames matching frameType and a live session scope. */
71
+ receive?(scope: HubSessionScope, payload: unknown, connection: HubChannelConnection): void;
72
+ /** The authenticated page socket has closed. */
73
+ disconnected?(connection: HubChannelConnection): void;
53
74
  }
54
75
  //#endregion
55
- export { ChannelFrame, HubChannelHost, HubChannelSource, HubSessionScope, WebHubChannel };
76
+ export { ChannelFrame, HubChannelConnection, HubChannelHost, HubChannelSource, HubSessionApiRequest, HubSessionScope, WebHubChannel };
56
77
  //# sourceMappingURL=webHub.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webHub.d.cts","names":[],"sources":["../../src/types/webHub.ts"],"mappings":";;;;;;;;;;;;UAYiB;EACf;EACA;EACA;;UAGe;EACf;;EAEA;;;UAIe;;EAEf,qBAAqB;;EAErB,QAAQ,mBAAmB;EAC3B,SAAS;;;;;;;UAQM;;EAEf,WAAW,OAAO;EAClB,cAAc,OAAO;EACrB,gBAAgB;;;;;;EAMhB,eAAe,OAAO,iBAAiB;EACvC;;UAGe;;EAEf;EACA,MAAM,MAAM,iBAAiB"}
1
+ {"version":3,"file":"webHub.d.cts","names":[],"sources":["../../src/types/webHub.ts"],"mappings":";;;;;;;;;;;;UAYiB;EACf;EACA;EACA;;UAGe;EACf;;EAEA;;UAGe;EACf;EACA;EACA;EACA,gBAAgB,WAAW;EAC3B,SAAS;;UAGM;;EAEf;;;UAIe;;EAEf,qBAAqB;;EAErB,QAAQ,mBAAmB;;EAE3B,qBAAqB,sBAAsB,mBAAmB;;EAE9D,kBAAkB,OAAO,iBAAiB,SAAS,uBAAuB,QAAQ;EAClF,SAAS;;;;;;;UAQM;;EAEf,WAAW,OAAO;EAClB,cAAc,OAAO;EACrB,gBAAgB;;;;;;EAMhB,eAAe,OAAO,iBAAiB;EACvC;;UAGe;;EAEf;EACA,MAAM,MAAM,iBAAiB;;EAE7B;;EAEA,SAAS,OAAO,iBAAiB,kBAAkB,YAAY;;EAE/D,cAAc,YAAY"}
@@ -20,12 +20,27 @@ interface HubSessionScope {
20
20
  /** The session's working directory, for repo-scoped data sources. */
21
21
  cwd: string;
22
22
  }
23
+ interface HubSessionApiRequest {
24
+ basePath: string;
25
+ path: string;
26
+ method: string;
27
+ body?: string | Uint8Array<ArrayBuffer> | null;
28
+ signal?: AbortSignal;
29
+ }
30
+ interface HubChannelConnection {
31
+ /** Opaque for one page socket lifetime. */
32
+ connectionId: string;
33
+ }
23
34
  /** What the hub hands a channel when it starts. */
24
35
  interface HubChannelHost {
25
36
  /** Every session the hub currently manages. */
26
37
  sessions(): readonly HubSessionScope[];
27
38
  /** Live fan-out to the session's page subscribers. */
28
39
  publish(sessionId: string, payload: unknown): void;
40
+ /** Delivers only to the authenticated page socket named by connectionId. */
41
+ publishToConnection?(connectionId: string, sessionId: string, payload: unknown): boolean;
42
+ /** Authenticated machine-local transport to a session package API. */
43
+ requestSessionApi(scope: HubSessionScope, request: HubSessionApiRequest): Promise<Response>;
29
44
  onNotice(message: string): void;
30
45
  }
31
46
  /**
@@ -50,7 +65,13 @@ interface WebHubChannel {
50
65
  /** Wire frame type; globally unique across every loaded plugin. */
51
66
  frameType: string;
52
67
  start(host: HubChannelHost): HubChannelSource;
68
+ /** Allows an authenticated connection to acknowledge targeted frames after its session subscription changes. */
69
+ receiveWithoutSubscription?: boolean;
70
+ /** Receives only frames matching frameType and a live session scope. */
71
+ receive?(scope: HubSessionScope, payload: unknown, connection: HubChannelConnection): void;
72
+ /** The authenticated page socket has closed. */
73
+ disconnected?(connection: HubChannelConnection): void;
53
74
  }
54
75
  //#endregion
55
- export { ChannelFrame, HubChannelHost, HubChannelSource, HubSessionScope, WebHubChannel };
76
+ export { ChannelFrame, HubChannelConnection, HubChannelHost, HubChannelSource, HubSessionApiRequest, HubSessionScope, WebHubChannel };
56
77
  //# sourceMappingURL=webHub.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webHub.d.mts","names":[],"sources":["../../src/types/webHub.ts"],"mappings":";;;;;;;;;;;;UAYiB;EACf;EACA;EACA;;UAGe;EACf;;EAEA;;;UAIe;;EAEf,qBAAqB;;EAErB,QAAQ,mBAAmB;EAC3B,SAAS;;;;;;;UAQM;;EAEf,WAAW,OAAO;EAClB,cAAc,OAAO;EACrB,gBAAgB;;;;;;EAMhB,eAAe,OAAO,iBAAiB;EACvC;;UAGe;;EAEf;EACA,MAAM,MAAM,iBAAiB"}
1
+ {"version":3,"file":"webHub.d.mts","names":[],"sources":["../../src/types/webHub.ts"],"mappings":";;;;;;;;;;;;UAYiB;EACf;EACA;EACA;;UAGe;EACf;;EAEA;;UAGe;EACf;EACA;EACA;EACA,gBAAgB,WAAW;EAC3B,SAAS;;UAGM;;EAEf;;;UAIe;;EAEf,qBAAqB;;EAErB,QAAQ,mBAAmB;;EAE3B,qBAAqB,sBAAsB,mBAAmB;;EAE9D,kBAAkB,OAAO,iBAAiB,SAAS,uBAAuB,QAAQ;EAClF,SAAS;;;;;;;UAQM;;EAEf,WAAW,OAAO;EAClB,cAAc,OAAO;EACrB,gBAAgB;;;;;;EAMhB,eAAe,OAAO,iBAAiB;EACvC;;UAGe;;EAEf;EACA,MAAM,MAAM,iBAAiB;;EAE7B;;EAEA,SAAS,OAAO,iBAAiB,kBAAkB,YAAY;;EAE/D,cAAc,YAAY"}
@@ -10,9 +10,11 @@ import { ComponentType, ReactNode } from "react";
10
10
  * @tanstack/store, @tanstack/react-store, this contract,
11
11
  * @agimon-ai/doompi-web-components, and the package's own web/ and src/types
12
12
  * modules; never another plugin, a node builtin, or a server framework, which
13
- * the host bundle would swallow. Per-session state takes the shape
14
- * defineSessionStore gives it. Tailwind utility classes must appear as
15
- * complete literal strings so the host's class scanner can see them.
13
+ * modules; never another plugin, a node builtin, or a server framework, which
14
+ * the host bundle would swallow. Page-wide state takes the shape
15
+ * defineGlobalStore gives it; per-session state takes the shape defineSessionStore
16
+ * gives it. Tailwind utility classes must appear as complete literal strings so
17
+ * the host's class scanner can see them.
16
18
  *
17
19
  * Plugins are independent: none depends on another, any of them may be added
18
20
  * or removed at the next sync, and every relation between two plugins (a fill
@@ -70,6 +72,8 @@ interface WebPluginSlotProps {
70
72
  * plugin's hub source names the thread's journal (HubChannelSource.threadJournal).
71
73
  */
72
74
  renderThread: (threadId: string) => ReactNode;
75
+ /** Appends text to the focused session's current composer draft. Bound, so a component may destructure it. */
76
+ appendComposerDraft: (text: string) => void;
73
77
  /** The same sender palette commands and `start` receive; components act through it. */
74
78
  sendSessionFrame: SessionFrameSender;
75
79
  /** The component fills of one slot, in slot order; the host resolves them, so this contract holds no state. */
@@ -140,6 +144,33 @@ interface SettingsFieldOption {
140
144
  /** Groups entries under a heading, as providers group their models. */
141
145
  group?: string;
142
146
  }
147
+ /** One repository the host has admitted into repository-scoped settings. */
148
+ interface RepositorySettingsRepository {
149
+ /** Opaque hub-issued identity. Package APIs resolve this through DoomApiContext. */
150
+ id: string;
151
+ /** Last path segment, for compact pickers and headings. */
152
+ name: string;
153
+ /** Display-only absolute path. APIs must use id rather than trusting this value. */
154
+ path: string;
155
+ /** True while at least one session is open inside this repository. */
156
+ active: boolean;
157
+ }
158
+ /** Props for a package panel placed inside the host's repository control plane. */
159
+ interface RepositorySettingsPanelProps {
160
+ repository: RepositorySettingsRepository | null;
161
+ /** Same-origin request routed through the host's sealed transport when remote. */
162
+ request: (input: string, init?: RequestInit) => Promise<Response>;
163
+ /** The same transport, retrying once after the host's fresh passkey gesture. */
164
+ requestWithStepUp: (input: string, init?: RequestInit) => Promise<Response>;
165
+ }
166
+ /** One package-owned panel below the host's repository selection controls. */
167
+ interface RepositorySettingsPanelContribution {
168
+ label: string;
169
+ detail: string;
170
+ /** Sort position below the host controls; lower first, then plugin id. */
171
+ order?: number;
172
+ component: ComponentType<RepositorySettingsPanelProps>;
173
+ }
143
174
  /**
144
175
  * A page in cockpit settings, contributed by the package that owns the
145
176
  * settings on it. The id is the URL segment (/settings/:id), so it is unique
@@ -244,13 +275,17 @@ interface SelectionAxisContribution {
244
275
  /** Sort position in the bar; lower first, name breaks ties. */
245
276
  order?: number;
246
277
  }
278
+ /** Reactive session activity owned by a plugin's session-scoped store. */
279
+ interface ActivityGroupActiveSource {
280
+ subscribe(listener: () => void): () => void;
281
+ isActive(sessionId: string | null): boolean;
282
+ }
247
283
  /**
248
- * An activity-dock group, declared as data: the host renders the group's
249
- * frame when the session publishes its signal (the footer status key, or any
250
- * of the widget keys). The body is the status content as a one-line summary
251
- * unless some plugin fills the group's slot, `activity.<name>`, with an
252
- * activity section of the same name, in which case those sections render the
253
- * body themselves.
284
+ * An activity-dock group, declared as data. The host renders its frame when the
285
+ * session publishes a footer or widget signal, or whenever the contribution
286
+ * owns an active source. The latter keeps an idle group's launcher available.
287
+ * The body is the status content as a one-line summary unless some plugin fills
288
+ * the group's slot, `activity.<name>`, with a section of the same name.
254
289
  */
255
290
  interface ActivityGroupContribution {
256
291
  name: string;
@@ -260,6 +295,16 @@ interface ActivityGroupContribution {
260
295
  statusKey?: string;
261
296
  /** Widget keys any of which shows the group without a summary. */
262
297
  widgetKeys?: string[];
298
+ /**
299
+ * Widget keys that mean this session has active background work.
300
+ *
301
+ * Defaults to every widget key. Ignored when activeSource is present.
302
+ */
303
+ activeWidgetKeys?: string[];
304
+ /** Session-scoped activity state. Its presence also keeps the group visible while idle. */
305
+ activeSource?: ActivityGroupActiveSource;
306
+ /** Whether a non-empty signal represents background work. Defaults to true. */
307
+ marksBackgroundWork?: boolean;
263
308
  /** The plugin tab the group's key chip opens; without one the chip is a plain label. */
264
309
  tab?: string;
265
310
  /**
@@ -275,9 +320,18 @@ interface ActivityGroupContribution {
275
320
  * leaves this off: its frame is worth keeping when it is idle.
276
321
  */
277
322
  hideWhenEmpty?: boolean;
323
+ /** Keeps the group visible below the dock's scrolling ordinary groups. */
324
+ placement?: 'bottom';
278
325
  /** Sort position in the dock; lower first, name breaks ties. */
279
326
  order?: number;
280
327
  }
328
+ /** Page-wide plugin state shared by its runtime, channels, and every rendered contribution. */
329
+ interface GlobalStore<T> {
330
+ readonly store: Store<T>;
331
+ /** Replaces the value; an updater returning the current value publishes nothing. */
332
+ update(updater: (current: T) => T): void;
333
+ reset(): void;
334
+ }
281
335
  /**
282
336
  * One session-scoped data channel: the hub pushes ChannelFrame payloads whose
283
337
  * frame type equals `channel`; parse is the validation gate at the boundary
@@ -415,10 +469,11 @@ interface ToolRendererContribution {
415
469
  /** Stands in for the composer input while this tool runs and holds a request. */
416
470
  prompt?: ToolPromptContribution;
417
471
  }
418
- /** What a plugin's optional runtime may do; both send on the page's hub socket. */
472
+ /** What a plugin's optional runtime may do through the page's hub socket. */
419
473
  interface WebPluginRuntime {
420
474
  sendSessionFrame: SessionFrameSender;
421
475
  sendHubFrame(frame: Record<string, unknown>): void;
476
+ onHubConnected(listener: () => void): () => void;
422
477
  }
423
478
  interface WebPluginDefinition {
424
479
  id: string;
@@ -446,6 +501,11 @@ interface WebPluginDefinition {
446
501
  * owns the scope switch, the repository picker, and every write.
447
502
  */
448
503
  settingsSections?: SettingsSectionContribution[];
504
+ /**
505
+ * A package-owned management panel inside the host's repository page. The
506
+ * host owns repository identity and passes only repositories it admitted.
507
+ */
508
+ repositorySettingsPanel?: RepositorySettingsPanelContribution;
449
509
  /** The slots this plugin opens for others, each named '<this plugin id>.<name>'. */
450
510
  slots?: SlotDeclaration[];
451
511
  /** This plugin's contributions into slots other plugins (or the host) declare. */
@@ -454,5 +514,5 @@ interface WebPluginDefinition {
454
514
  start?(runtime: WebPluginRuntime): (() => void) | void;
455
515
  }
456
516
  //#endregion
457
- export { ActivityGroupContribution, LeaderBindingBase, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps };
517
+ export { ActivityGroupActiveSource, ActivityGroupContribution, GlobalStore, LeaderBindingBase, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, RepositorySettingsPanelContribution, RepositorySettingsPanelProps, RepositorySettingsRepository, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps };
458
518
  //# sourceMappingURL=webPlugin.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webPlugin.d.cts","names":[],"sources":["../../src/types/webPlugin.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAwBY,sBAAsB,mBAAmB,OAAO;;;;;;;;;;UAU3C,gBAAgB;EAC/B;;EAEA,OAAO,iBAAiB;;;UAGT,aAAa;EAC5B;EACA;EACA;EACA,MAAM;;;;;;;;UAQS;;EAEf;EACA;EACA,OAAO,cAAc;;;UAGN;EACf;;EAEA,UAAU;;EAEV,mBAAmB,KAAK;EACxB,oBAAoB;;;;;;EAMpB,eAAe,qBAAqB;;EAEpC,kBAAkB;;EAElB,aAAa,iBAAiB;;EAE9B,WAAW,MAAM,MAAM,gBAAgB,mBAAmB,aAAa;;;;;;;EAOvE,UAAU,SAAS;;;;;;;UAOJ;EACf;EACA;;EAEA;EACA;EACA,YAAY,cAAc;;UAEX;;EAEf;EACA;EACA,OAAO,cAAc;;EAErB,YAAY;;;;;;;;;;;UAWG;;EAEf;EACA;EACA;;EAEA;;EAEA;;EAEA;;EAEA,mBAAmB;;;;;;EAMnB;;UAEe;EACf;EACA;;EAEA;;;;;;;UAOe;EACf;EACA;EACA;;EAEA;EACA,iBAAiB;;UAEF;EACf;EACA,WAAW,cAAc;;UAEV;EACf;;EAEA,QAAQ;EACR,kBAAkB;;UAEH;EACf;EACA;EACA;EACA,IAAI,SAAS;;;;;;;UAOE;EACf;EACA;EACA;;UAEe;EACf;;EAEA,MAAM;;;;;;;;;;;;;KAaI,6BACP;EACC;MAED;EACC,IAAI,SAAS;;;;;;;;UAQF;EACf;;;;;;;EAOA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;UAQe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;UAUe;EACf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;EAaA;;EAEA;;;;;;;UAOe,2BAA2B;EAC1C;EACA,MAAM,iBAAiB;EACvB,MAAM,mBAAmB,SAAS;EAClC,KAAK;;;KAGK,eAAe,KAAK,QAAQ,eAAe;;UAEtC,oBAAoB,GAAG;EACtC;EACA,MAAM,iBAAiB;;EAEvB,OAAO,SAAS,GAAG,SAAS,UAAU;;;;;;;UAOvB,aAAa;WACnB,OAAO,MAAM,eAAe;;;;;;EAMrC,OAAO,OAAO,eAAe,IAAI,2BAA2B;;EAE5D,OAAO,mBAAmB,UAAU,SAAS,MAAM;EACnD,KAAK;EACL;;EAEA,QAAQ,SAAS,SAAS,oBAAoB,GAAG,WAAW;;;;;;;UAO7C;EACf;EACA;;;;;;;;;;UAUe,+BAA+B;EAC9C;;EAEA;EACA,MAAM;;EAEN,UAAU,SAAS;;EAEnB,QAAQ;;EAER;;EAEA;EACA;;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;UAWe,8BAA8B;EAC7C,QAAQ;;EAER,SAAS;;EAET;;;;;;;;;;;UAWe;;;;;;;EAOf,QAAQ,QAAQ,kBAAkB,MAAM;EACxC,WAAW,cAAc;;;;;;;;UAQV;;EAEf;;;;;;;EAOA,SAAS,kBAAkB,UAAU,SAAS;EAC9C,SAAS,cAAc;;EAEvB,SAAS;;;UAGM;EACf,kBAAkB;EAClB,aAAa,OAAO;;UAEL;EACf;EACA,OAAO;EACP,WAAW;EACX,gBAAgB;EAChB,aAAa;EACb,iBAAiB;EACjB,WAAW;EACX,kBAAkB;EAClB,iBAAiB;EACjB,eAAe;EACf,oBAAoB;;EAEpB,kBAAkB;EAClB,gBAAgB;;;;;;EAMhB,mBAAmB;;;;;EAKnB,mBAAmB;;EAEnB,QAAQ;;EAER,QAAQ;;EAER,OAAO,SAAS"}
1
+ {"version":3,"file":"webPlugin.d.cts","names":[],"sources":["../../src/types/webPlugin.ts"],"mappings":"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"}
@@ -10,9 +10,11 @@ import { ComponentType, ReactNode } from "react";
10
10
  * @tanstack/store, @tanstack/react-store, this contract,
11
11
  * @agimon-ai/doompi-web-components, and the package's own web/ and src/types
12
12
  * modules; never another plugin, a node builtin, or a server framework, which
13
- * the host bundle would swallow. Per-session state takes the shape
14
- * defineSessionStore gives it. Tailwind utility classes must appear as
15
- * complete literal strings so the host's class scanner can see them.
13
+ * modules; never another plugin, a node builtin, or a server framework, which
14
+ * the host bundle would swallow. Page-wide state takes the shape
15
+ * defineGlobalStore gives it; per-session state takes the shape defineSessionStore
16
+ * gives it. Tailwind utility classes must appear as complete literal strings so
17
+ * the host's class scanner can see them.
16
18
  *
17
19
  * Plugins are independent: none depends on another, any of them may be added
18
20
  * or removed at the next sync, and every relation between two plugins (a fill
@@ -70,6 +72,8 @@ interface WebPluginSlotProps {
70
72
  * plugin's hub source names the thread's journal (HubChannelSource.threadJournal).
71
73
  */
72
74
  renderThread: (threadId: string) => ReactNode;
75
+ /** Appends text to the focused session's current composer draft. Bound, so a component may destructure it. */
76
+ appendComposerDraft: (text: string) => void;
73
77
  /** The same sender palette commands and `start` receive; components act through it. */
74
78
  sendSessionFrame: SessionFrameSender;
75
79
  /** The component fills of one slot, in slot order; the host resolves them, so this contract holds no state. */
@@ -140,6 +144,33 @@ interface SettingsFieldOption {
140
144
  /** Groups entries under a heading, as providers group their models. */
141
145
  group?: string;
142
146
  }
147
+ /** One repository the host has admitted into repository-scoped settings. */
148
+ interface RepositorySettingsRepository {
149
+ /** Opaque hub-issued identity. Package APIs resolve this through DoomApiContext. */
150
+ id: string;
151
+ /** Last path segment, for compact pickers and headings. */
152
+ name: string;
153
+ /** Display-only absolute path. APIs must use id rather than trusting this value. */
154
+ path: string;
155
+ /** True while at least one session is open inside this repository. */
156
+ active: boolean;
157
+ }
158
+ /** Props for a package panel placed inside the host's repository control plane. */
159
+ interface RepositorySettingsPanelProps {
160
+ repository: RepositorySettingsRepository | null;
161
+ /** Same-origin request routed through the host's sealed transport when remote. */
162
+ request: (input: string, init?: RequestInit) => Promise<Response>;
163
+ /** The same transport, retrying once after the host's fresh passkey gesture. */
164
+ requestWithStepUp: (input: string, init?: RequestInit) => Promise<Response>;
165
+ }
166
+ /** One package-owned panel below the host's repository selection controls. */
167
+ interface RepositorySettingsPanelContribution {
168
+ label: string;
169
+ detail: string;
170
+ /** Sort position below the host controls; lower first, then plugin id. */
171
+ order?: number;
172
+ component: ComponentType<RepositorySettingsPanelProps>;
173
+ }
143
174
  /**
144
175
  * A page in cockpit settings, contributed by the package that owns the
145
176
  * settings on it. The id is the URL segment (/settings/:id), so it is unique
@@ -244,13 +275,17 @@ interface SelectionAxisContribution {
244
275
  /** Sort position in the bar; lower first, name breaks ties. */
245
276
  order?: number;
246
277
  }
278
+ /** Reactive session activity owned by a plugin's session-scoped store. */
279
+ interface ActivityGroupActiveSource {
280
+ subscribe(listener: () => void): () => void;
281
+ isActive(sessionId: string | null): boolean;
282
+ }
247
283
  /**
248
- * An activity-dock group, declared as data: the host renders the group's
249
- * frame when the session publishes its signal (the footer status key, or any
250
- * of the widget keys). The body is the status content as a one-line summary
251
- * unless some plugin fills the group's slot, `activity.<name>`, with an
252
- * activity section of the same name, in which case those sections render the
253
- * body themselves.
284
+ * An activity-dock group, declared as data. The host renders its frame when the
285
+ * session publishes a footer or widget signal, or whenever the contribution
286
+ * owns an active source. The latter keeps an idle group's launcher available.
287
+ * The body is the status content as a one-line summary unless some plugin fills
288
+ * the group's slot, `activity.<name>`, with a section of the same name.
254
289
  */
255
290
  interface ActivityGroupContribution {
256
291
  name: string;
@@ -260,6 +295,16 @@ interface ActivityGroupContribution {
260
295
  statusKey?: string;
261
296
  /** Widget keys any of which shows the group without a summary. */
262
297
  widgetKeys?: string[];
298
+ /**
299
+ * Widget keys that mean this session has active background work.
300
+ *
301
+ * Defaults to every widget key. Ignored when activeSource is present.
302
+ */
303
+ activeWidgetKeys?: string[];
304
+ /** Session-scoped activity state. Its presence also keeps the group visible while idle. */
305
+ activeSource?: ActivityGroupActiveSource;
306
+ /** Whether a non-empty signal represents background work. Defaults to true. */
307
+ marksBackgroundWork?: boolean;
263
308
  /** The plugin tab the group's key chip opens; without one the chip is a plain label. */
264
309
  tab?: string;
265
310
  /**
@@ -275,9 +320,18 @@ interface ActivityGroupContribution {
275
320
  * leaves this off: its frame is worth keeping when it is idle.
276
321
  */
277
322
  hideWhenEmpty?: boolean;
323
+ /** Keeps the group visible below the dock's scrolling ordinary groups. */
324
+ placement?: 'bottom';
278
325
  /** Sort position in the dock; lower first, name breaks ties. */
279
326
  order?: number;
280
327
  }
328
+ /** Page-wide plugin state shared by its runtime, channels, and every rendered contribution. */
329
+ interface GlobalStore<T> {
330
+ readonly store: Store<T>;
331
+ /** Replaces the value; an updater returning the current value publishes nothing. */
332
+ update(updater: (current: T) => T): void;
333
+ reset(): void;
334
+ }
281
335
  /**
282
336
  * One session-scoped data channel: the hub pushes ChannelFrame payloads whose
283
337
  * frame type equals `channel`; parse is the validation gate at the boundary
@@ -415,10 +469,11 @@ interface ToolRendererContribution {
415
469
  /** Stands in for the composer input while this tool runs and holds a request. */
416
470
  prompt?: ToolPromptContribution;
417
471
  }
418
- /** What a plugin's optional runtime may do; both send on the page's hub socket. */
472
+ /** What a plugin's optional runtime may do through the page's hub socket. */
419
473
  interface WebPluginRuntime {
420
474
  sendSessionFrame: SessionFrameSender;
421
475
  sendHubFrame(frame: Record<string, unknown>): void;
476
+ onHubConnected(listener: () => void): () => void;
422
477
  }
423
478
  interface WebPluginDefinition {
424
479
  id: string;
@@ -446,6 +501,11 @@ interface WebPluginDefinition {
446
501
  * owns the scope switch, the repository picker, and every write.
447
502
  */
448
503
  settingsSections?: SettingsSectionContribution[];
504
+ /**
505
+ * A package-owned management panel inside the host's repository page. The
506
+ * host owns repository identity and passes only repositories it admitted.
507
+ */
508
+ repositorySettingsPanel?: RepositorySettingsPanelContribution;
449
509
  /** The slots this plugin opens for others, each named '<this plugin id>.<name>'. */
450
510
  slots?: SlotDeclaration[];
451
511
  /** This plugin's contributions into slots other plugins (or the host) declare. */
@@ -454,5 +514,5 @@ interface WebPluginDefinition {
454
514
  start?(runtime: WebPluginRuntime): (() => void) | void;
455
515
  }
456
516
  //#endregion
457
- export { ActivityGroupContribution, LeaderBindingBase, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps };
517
+ export { ActivityGroupActiveSource, ActivityGroupContribution, GlobalStore, LeaderBindingBase, LeaderBindingContribution, LeaderKeyContribution, MinorModeContribution, PaletteCommandContext, PaletteCommandContribution, RepositorySettingsPanelContribution, RepositorySettingsPanelProps, RepositorySettingsRepository, SelectionAxisContribution, SessionChannelContribution, SessionFrameSender, SessionRecords, SessionStore, SessionStoreChannel, SettingsFieldContribution, SettingsFieldOption, SettingsSectionContribution, SlotDataFill, SlotDeclaration, SlotFillContribution, SurfaceContribution, TabContribution, ToolMessageRenderProps, ToolPromptContribution, ToolPromptDialog, ToolPromptRenderProps, ToolRendererContribution, ToolResultView, TransientTab, WebPluginDefinition, WebPluginRuntime, WebPluginSlotProps };
458
518
  //# sourceMappingURL=webPlugin.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webPlugin.d.mts","names":[],"sources":["../../src/types/webPlugin.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAwBY,sBAAsB,mBAAmB,OAAO;;;;;;;;;;UAU3C,gBAAgB;EAC/B;;EAEA,OAAO,iBAAiB;;;UAGT,aAAa;EAC5B;EACA;EACA;EACA,MAAM;;;;;;;;UAQS;;EAEf;EACA;EACA,OAAO,cAAc;;;UAGN;EACf;;EAEA,UAAU;;EAEV,mBAAmB,KAAK;EACxB,oBAAoB;;;;;;EAMpB,eAAe,qBAAqB;;EAEpC,kBAAkB;;EAElB,aAAa,iBAAiB;;EAE9B,WAAW,MAAM,MAAM,gBAAgB,mBAAmB,aAAa;;;;;;;EAOvE,UAAU,SAAS;;;;;;;UAOJ;EACf;EACA;;EAEA;EACA;EACA,YAAY,cAAc;;UAEX;;EAEf;EACA;EACA,OAAO,cAAc;;EAErB,YAAY;;;;;;;;;;;UAWG;;EAEf;EACA;EACA;;EAEA;;EAEA;;EAEA;;EAEA,mBAAmB;;;;;;EAMnB;;UAEe;EACf;EACA;;EAEA;;;;;;;UAOe;EACf;EACA;EACA;;EAEA;EACA,iBAAiB;;UAEF;EACf;EACA,WAAW,cAAc;;UAEV;EACf;;EAEA,QAAQ;EACR,kBAAkB;;UAEH;EACf;EACA;EACA;EACA,IAAI,SAAS;;;;;;;UAOE;EACf;EACA;EACA;;UAEe;EACf;;EAEA,MAAM;;;;;;;;;;;;;KAaI,6BACP;EACC;MAED;EACC,IAAI,SAAS;;;;;;;;UAQF;EACf;;;;;;;EAOA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;UAQe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;UAUe;EACf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;EAaA;;EAEA;;;;;;;UAOe,2BAA2B;EAC1C;EACA,MAAM,iBAAiB;EACvB,MAAM,mBAAmB,SAAS;EAClC,KAAK;;;KAGK,eAAe,KAAK,QAAQ,eAAe;;UAEtC,oBAAoB,GAAG;EACtC;EACA,MAAM,iBAAiB;;EAEvB,OAAO,SAAS,GAAG,SAAS,UAAU;;;;;;;UAOvB,aAAa;WACnB,OAAO,MAAM,eAAe;;;;;;EAMrC,OAAO,OAAO,eAAe,IAAI,2BAA2B;;EAE5D,OAAO,mBAAmB,UAAU,SAAS,MAAM;EACnD,KAAK;EACL;;EAEA,QAAQ,SAAS,SAAS,oBAAoB,GAAG,WAAW;;;;;;;UAO7C;EACf;EACA;;;;;;;;;;UAUe,+BAA+B;EAC9C;;EAEA;EACA,MAAM;;EAEN,UAAU,SAAS;;EAEnB,QAAQ;;EAER;;EAEA;EACA;;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;UAWe,8BAA8B;EAC7C,QAAQ;;EAER,SAAS;;EAET;;;;;;;;;;;UAWe;;;;;;;EAOf,QAAQ,QAAQ,kBAAkB,MAAM;EACxC,WAAW,cAAc;;;;;;;;UAQV;;EAEf;;;;;;;EAOA,SAAS,kBAAkB,UAAU,SAAS;EAC9C,SAAS,cAAc;;EAEvB,SAAS;;;UAGM;EACf,kBAAkB;EAClB,aAAa,OAAO;;UAEL;EACf;EACA,OAAO;EACP,WAAW;EACX,gBAAgB;EAChB,aAAa;EACb,iBAAiB;EACjB,WAAW;EACX,kBAAkB;EAClB,iBAAiB;EACjB,eAAe;EACf,oBAAoB;;EAEpB,kBAAkB;EAClB,gBAAgB;;;;;;EAMhB,mBAAmB;;;;;EAKnB,mBAAmB;;EAEnB,QAAQ;;EAER,QAAQ;;EAER,OAAO,SAAS"}
1
+ {"version":3,"file":"webPlugin.d.mts","names":[],"sources":["../../src/types/webPlugin.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-web-contracts",
3
- "version": "0.0.1-alpha.3",
3
+ "version": "0.0.1-alpha.6",
4
4
  "description": "Web cockpit plugin contracts for DoomPi: plugin definitions, slot contributions, session data channels, and hub channel sources.",
5
5
  "keywords": [
6
6
  "ai",