@agimon-ai/doompi-major-mode 0.0.1-alpha.4 → 0.0.1-alpha.43
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.
- package/README.md +36 -14
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/adapters/pi/extension.cjs +1 -1
- package/dist/adapters/pi/extension.cjs.map +1 -1
- package/dist/adapters/pi/extension.d.cts +2 -2
- package/dist/adapters/pi/extension.d.cts.map +1 -1
- package/dist/adapters/pi/extension.d.mts +2 -2
- package/dist/adapters/pi/extension.d.mts.map +1 -1
- package/dist/adapters/pi/extension.mjs +1 -1
- package/dist/adapters/pi/extension.mjs.map +1 -1
- package/dist/adapters/pi/relaunchRequest.cjs +2 -0
- package/dist/adapters/pi/relaunchRequest.cjs.map +1 -0
- package/dist/adapters/pi/relaunchRequest.mjs +2 -0
- package/dist/adapters/pi/relaunchRequest.mjs.map +1 -0
- package/dist/adapters/pi/voiceTool.d.cts +1 -2
- package/dist/adapters/pi/voiceTool.d.cts.map +1 -1
- package/dist/adapters/pi/voiceTool.d.mts +1 -2
- package/dist/adapters/pi/voiceTool.d.mts.map +1 -1
- package/dist/adapters/telemetry/logSinkTelemetry.d.cts +2 -3
- package/dist/adapters/telemetry/logSinkTelemetry.d.cts.map +1 -1
- package/dist/adapters/telemetry/logSinkTelemetry.d.mts +2 -3
- package/dist/adapters/telemetry/logSinkTelemetry.d.mts.map +1 -1
- package/dist/commands/majorModeCommand.cjs +1 -1
- package/dist/commands/majorModeCommand.cjs.map +1 -1
- package/dist/commands/majorModeCommand.d.cts +6 -3
- package/dist/commands/majorModeCommand.d.cts.map +1 -1
- package/dist/commands/majorModeCommand.d.mts +6 -3
- package/dist/commands/majorModeCommand.d.mts.map +1 -1
- package/dist/commands/majorModeCommand.mjs +1 -1
- package/dist/commands/majorModeCommand.mjs.map +1 -1
- package/dist/schemas/majorModeVoiceTools.d.cts +5 -6
- package/dist/schemas/majorModeVoiceTools.d.cts.map +1 -1
- package/dist/schemas/majorModeVoiceTools.d.mts +5 -6
- package/dist/schemas/majorModeVoiceTools.d.mts.map +1 -1
- package/dist/services/majorModeText.cjs +4 -4
- package/dist/services/majorModeText.cjs.map +1 -1
- package/dist/services/majorModeText.d.cts +8 -9
- package/dist/services/majorModeText.d.cts.map +1 -1
- package/dist/services/majorModeText.d.mts +8 -9
- package/dist/services/majorModeText.d.mts.map +1 -1
- package/dist/services/majorModeText.mjs +4 -4
- package/dist/services/majorModeText.mjs.map +1 -1
- package/dist/services/pendingSelection.d.cts +3 -4
- package/dist/services/pendingSelection.d.cts.map +1 -1
- package/dist/services/pendingSelection.d.mts +3 -4
- package/dist/services/pendingSelection.d.mts.map +1 -1
- package/dist/services/statusLine.d.cts +3 -4
- package/dist/services/statusLine.d.cts.map +1 -1
- package/dist/services/statusLine.d.mts +3 -4
- package/dist/services/statusLine.d.mts.map +1 -1
- package/dist/types/majorMode.d.cts +3 -4
- package/dist/types/majorMode.d.cts.map +1 -1
- package/dist/types/majorMode.d.mts +3 -4
- package/dist/types/majorMode.d.mts.map +1 -1
- package/dist/types/telemetry.d.cts +6 -7
- package/dist/types/telemetry.d.cts.map +1 -1
- package/dist/types/telemetry.d.mts +6 -7
- package/dist/types/telemetry.d.mts.map +1 -1
- package/llms.txt +7 -2
- package/package.json +27 -18
- package/src/prompts/doompi-author-major-mode/SKILL.md +30 -0
- package/src/prompts/doompi-author-major-mode/references/modes-contract.md +152 -0
package/README.md
CHANGED
|
@@ -2,40 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
Named major-mode selection for [DoomPi](https://www.npmjs.com/package/@agimon-ai/doompi) sessions.
|
|
4
4
|
|
|
5
|
-
A **major mode** is one of the four axes of a DoomPi selection, alongside domains, the profile
|
|
6
|
-
the minor modes. It names an ordered list of layers, and each layer names the packages it
|
|
5
|
+
A **major mode** is one of the four axes of a DoomPi selection, alongside domains, the profile,
|
|
6
|
+
and the minor modes. It names an ordered list of layers, and each layer names the packages it
|
|
7
|
+
activates:
|
|
7
8
|
|
|
8
9
|
```yaml
|
|
9
10
|
# .doom/modes.yaml
|
|
11
|
+
layers:
|
|
12
|
+
team:
|
|
13
|
+
packages: ['@agimon-ai/doompi-team']
|
|
14
|
+
ask-user:
|
|
15
|
+
packages: ['@agimon-ai/doompi-user-feedback']
|
|
16
|
+
task:
|
|
17
|
+
packages: ['@agimon-ai/doompi-task']
|
|
18
|
+
|
|
10
19
|
majorMode:
|
|
11
20
|
minimal:
|
|
12
|
-
description: Lean
|
|
13
|
-
layers: [
|
|
21
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
22
|
+
layers: [team, task]
|
|
14
23
|
copilot:
|
|
15
|
-
description:
|
|
16
|
-
layers: [
|
|
24
|
+
description: General coding with delegation, persistent tasks, and structured user feedback.
|
|
25
|
+
layers: [team, ask-user, task]
|
|
17
26
|
```
|
|
18
27
|
|
|
19
|
-
The `layers` array is authored activation order, not a
|
|
28
|
+
Default packages load before these layers. The `layers` array is authored activation order, not a
|
|
29
|
+
set.
|
|
20
30
|
|
|
21
31
|
## What it registers
|
|
22
32
|
|
|
23
|
-
| Surface |
|
|
33
|
+
| Surface | Behavior |
|
|
24
34
|
| ----------------------- | -------------------------------------------------------------------------- |
|
|
25
35
|
| `/mode` | picks a major mode, applies it, and reloads |
|
|
26
36
|
| `major_mode` voice tool | `list` returns every mode with its purpose and layers; `switch` queues one |
|
|
27
37
|
| status line | `*profile*:[major-mode]:domains`, amber while a switch is pending |
|
|
38
|
+
| Help contribution | exposes focused `modes.yaml` guidance while DoomPi Help is active |
|
|
39
|
+
|
|
40
|
+
## Help guidance
|
|
41
|
+
|
|
42
|
+
This package registers `doompi-author-major-mode` with the session-local `doom/help` Cordis
|
|
43
|
+
service. Registration is inert until `@agimon-ai/doompi-help` is active. Once active, the Help
|
|
44
|
+
skill routes the AI through this package's validated [`llms.txt`](./llms.txt) index.
|
|
45
|
+
|
|
46
|
+
The package owns both the concise [major-mode authoring prompt](./src/prompts/doompi-author-major-mode/SKILL.md)
|
|
47
|
+
and the detailed [`modes.yaml` contract](./src/prompts/doompi-author-major-mode/references/modes-contract.md),
|
|
48
|
+
so the guidance is versioned with the parser and runtime that consume it.
|
|
28
49
|
|
|
29
50
|
## Switching, and why it is not always a reload
|
|
30
51
|
|
|
31
52
|
A major-mode change alters which extensions load, and Pi freezes the CLI `--extension` list at
|
|
32
53
|
construction. So the disposition depends on how the session started:
|
|
33
54
|
|
|
34
|
-
- **synchronized** (`dpi`)
|
|
35
|
-
layers arrive with a `pi-reload`. If the target
|
|
36
|
-
transition reports `sync-required` and asks for
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
- **synchronized** (`dpi`, or regular `pi` after `doompi sync`): the session composes its own
|
|
56
|
+
extension set on every load, so the new layers arrive with a `pi-reload`. If the target
|
|
57
|
+
composition has no synchronized bundle yet, the transition reports `sync-required` and asks for
|
|
58
|
+
`doompi sync`.
|
|
59
|
+
- **launcher**: the extension closure is fixed, so a mode whose layers differ needs a new process.
|
|
60
|
+
The switch is journaled as pending and the command prints the relaunch line rather than
|
|
39
61
|
pretending it applied.
|
|
40
62
|
|
|
41
63
|
Either way the change is planned through the session's transition coordinator first, and active
|
|
@@ -49,7 +71,7 @@ where it can be the terminal action.
|
|
|
49
71
|
## Installation
|
|
50
72
|
|
|
51
73
|
DoomPi depends on this package and activates it as fixed host core, so a DoomPi install already has
|
|
52
|
-
it. It is not selectable from `.doom/modes.yaml
|
|
74
|
+
it. It is not selectable from `.doom/modes.yaml`. It is what reads that file.
|
|
53
75
|
|
|
54
76
|
## License
|
|
55
77
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../services/statusLine.cjs"),t=require("../../types/telemetry.cjs"),n=require("../../types/majorMode.cjs"),r=require("../../commands/majorModeCommand.cjs"),i=require("../telemetry/logSinkTelemetry.cjs"),
|
|
1
|
+
const e=require("../../services/statusLine.cjs"),t=require("../../types/telemetry.cjs"),n=require("../../types/majorMode.cjs"),r=require("../../commands/majorModeCommand.cjs"),i=require("./relaunchRequest.cjs"),a=require("../telemetry/logSinkTelemetry.cjs"),o=require("./voiceTool.cjs");let s=require("@agimon-ai/doompi-config/harnessStore"),c=require("@agimon-ai/doompi-config/piContext"),l=require("@agimon-ai/doompi-extension-contracts/config"),u=require("@agimon-ai/doompi-extension-contracts/cordis-host"),d=require("@agimon-ai/doompi-extension-contracts/help"),f=require("@agimon-ai/doompi-extension-contracts/transition"),p=require("@agimon-ai/doompi-extension-contracts/voice-tools"),m=require("@agimon-ai/doompi-extension-contracts/voice-reload-handoff");function h(){let e,t,n,r;return{config:()=>e??=import(`@agimon-ai/doompi-config/majorModes`),journal:()=>t??=import(`@agimon-ai/doompi-config/piContext`),picker:()=>n??=import(`@agimon-ai/doompi-ui/components/matrixPicker`),selection:()=>r??=import(`@agimon-ai/doompi-config/selectionSwitch`)}}function g(a,{pi:u,telemetry:g}){let _=h();a.inject([d.DOOM_HELP_SERVICE],e=>{let t=(0,d.requireDoomHelpService)(e).register({source:n.MAJOR_MODE_SOURCE,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-author-major-mode`,description:`Configure DoomPi default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.pi/.doom/modes.yaml or a repository's .doom/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.`}]});return()=>t.dispose()});let v,y=a.inject([l.DOOM_CONFIG_SERVICE,f.DOOM_TRANSITION_SERVICE],e=>(v=e,()=>{v===e&&(v=void 0)})),b=()=>{if(!v)throw Error(`Doom major-mode runtime is waiting for the session config service.`);return v},x=async e=>{let t=(0,c.requireDoomConfigContext)(b()).harness,{loadMajorModesConfig:n}=await _.config();return{config:n((0,s.requireHarnessRoot)(t)),majorMode:t.majorMode,domains:t.domains,profile:t.profile}},S=(0,m.createVoiceReloadHandoffStore)({now:()=>Date.now(),createToken:()=>crypto.randomUUID()});a.inject([l.DOOM_CONFIG_SERVICE,f.DOOM_TRANSITION_SERVICE,p.DOOM_VOICE_TOOLS_SERVICE],e=>o.registerMajorModeVoiceCapability((0,p.requireDoomVoiceToolsService)(e),u,x,S,()=>e)),a.effect(function*(){r.registerMajorModeCommand(u,g,{cordisContext:b,currentView:x,reloadHandoffs:S,loadPicker:_.picker,loadSelectionSwitch:_.selection,loadConfigJournal:_.journal,resolveLayers:(e,t)=>[...e.majorMode[t]?.layers??[]],supervisedRelaunchAvailable:i.supervisedRelaunchAvailable,requestSupervisedRelaunch:i.requestSupervisedRelaunch}),u.on(`session_start`,async(n,r)=>{await y.await();try{let{majorMode:t,domains:n,profile:i}=(0,c.requireDoomConfigContext)(b()).harness;r.ui.setStatus(e.STATUS_KEY,e.colorStatus(r.ui.theme,t,n,i,!1))}catch(n){g.recordError(t.MAJOR_MODE_EVENT.majorModeUnavailable,n),r.ui.setStatus(e.STATUS_KEY,`major mode unavailable (${n instanceof Error?n.message:String(n)})`)}}),yield()=>void 0},n.MAJOR_MODE_SOURCE)}async function _(e,t=a.createMajorModeTelemetry()){let r=await(0,u.connectDoomCordisHost)(e,n.MAJOR_MODE_SOURCE),i=r.root.plugin(g,{pi:e,telemetry:t});try{await i}catch(e){try{await i.dispose()}finally{await r.dispose()}throw e}let o;e.on(`session_shutdown`,()=>o??=(async()=>{try{await i.dispose()}finally{await r.dispose()}})())}exports.default=_,exports.majorModeExtension=_;
|
|
2
2
|
//# sourceMappingURL=extension.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.cjs","names":["DOOM_CONFIG_SERVICE","DOOM_TRANSITION_SERVICE","requireDoomConfigContext","requireHarnessRoot","createVoiceReloadHandoffStore","DOOM_VOICE_TOOLS_SERVICE","registerMajorModeVoiceCapability","requireDoomVoiceToolsService","STATUS_KEY","colorStatus","MAJOR_MODE_EVENT","
|
|
1
|
+
{"version":3,"file":"extension.cjs","names":["DOOM_HELP_SERVICE","requireDoomHelpService","MAJOR_MODE_SOURCE","DOOM_CONFIG_SERVICE","DOOM_TRANSITION_SERVICE","requireDoomConfigContext","requireHarnessRoot","createVoiceReloadHandoffStore","DOOM_VOICE_TOOLS_SERVICE","registerMajorModeVoiceCapability","requireDoomVoiceToolsService","STATUS_KEY","colorStatus","MAJOR_MODE_EVENT","createMajorModeTelemetry","connectDoomCordisHost"],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { requireHarnessRoot } from '@agimon-ai/doompi-config/harnessStore';\nimport { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-extension-contracts/config';\nimport { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport { DOOM_HELP_SERVICE, requireDoomHelpService } from '@agimon-ai/doompi-extension-contracts/help';\nimport { DOOM_TRANSITION_SERVICE } from '@agimon-ai/doompi-extension-contracts/transition';\nimport {\n DOOM_VOICE_TOOLS_SERVICE,\n requireDoomVoiceToolsService,\n} from '@agimon-ai/doompi-extension-contracts/voice-tools';\nimport { createVoiceReloadHandoffStore } from '@agimon-ai/doompi-extension-contracts/voice-reload-handoff';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerMajorModeCommand } from '../../commands/majorModeCommand.ts';\nimport { requestSupervisedRelaunch, supervisedRelaunchAvailable } from './relaunchRequest.ts';\nimport { colorStatus, STATUS_KEY } from '../../services/statusLine.ts';\nimport { MAJOR_MODE_SOURCE, type MajorModeView } from '../../types/majorMode.ts';\nimport { MAJOR_MODE_EVENT, type MajorModeTelemetry } from '../../types/telemetry.ts';\nimport { createMajorModeTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { registerMajorModeVoiceCapability } from './voiceTool.ts';\n\n/**\n * Everything the axis needs beyond the session, loaded on first use.\n *\n * Every session registers /mode, but most never run it, so the picker, the\n * switch and the journal stay off the startup path.\n */\nfunction lazyModules() {\n let config: Promise<typeof import('@agimon-ai/doompi-config/majorModes')> | undefined;\n let journal: Promise<typeof import('@agimon-ai/doompi-config/piContext')> | undefined;\n let picker: Promise<typeof import('@agimon-ai/doompi-ui/components/matrixPicker')> | undefined;\n let selection: Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')> | undefined;\n return {\n config: () => (config ??= import('@agimon-ai/doompi-config/majorModes')),\n journal: () => (journal ??= import('@agimon-ai/doompi-config/piContext')),\n picker: () => (picker ??= import('@agimon-ai/doompi-ui/components/matrixPicker')),\n selection: () => (selection ??= import('@agimon-ai/doompi-config/selectionSwitch')),\n };\n}\n\ninterface MajorModePluginConfig {\n readonly pi: ExtensionAPI;\n readonly telemetry: MajorModeTelemetry;\n}\n\nfunction majorModePlugin(cordis: Context, { pi, telemetry }: MajorModePluginConfig): void {\n const load = lazyModules();\n cordis.inject([DOOM_HELP_SERVICE], (helpContext) => {\n const contribution = requireDoomHelpService(helpContext).register({\n source: MAJOR_MODE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-major-mode',\n description:\n \"Configure DoomPi default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.pi/.doom/modes.yaml or a repository's .doom/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n },\n ],\n });\n return () => contribution.dispose();\n });\n\n let activeContext: Context | undefined;\n const runtimeInjection = cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n const requireRuntimeContext = (): Context => {\n if (!activeContext) throw new Error('Doom major-mode runtime is waiting for the session config service.');\n return activeContext;\n };\n const currentView = async (_ctx: ExtensionContext): Promise<MajorModeView> => {\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const { loadMajorModesConfig } = await load.config();\n return {\n config: loadMajorModesConfig(requireHarnessRoot(state)),\n majorMode: state.majorMode,\n domains: state.domains,\n profile: state.profile,\n };\n };\n const reloadHandoffs = createVoiceReloadHandoffStore({\n now: () => Date.now(),\n createToken: () => crypto.randomUUID(),\n });\n cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE, DOOM_VOICE_TOOLS_SERVICE], (voiceContext) =>\n registerMajorModeVoiceCapability(\n requireDoomVoiceToolsService(voiceContext),\n pi,\n currentView,\n reloadHandoffs,\n () => voiceContext,\n ),\n );\n\n cordis.effect(function* () {\n registerMajorModeCommand(pi, telemetry, {\n cordisContext: requireRuntimeContext,\n currentView,\n reloadHandoffs,\n loadPicker: load.picker,\n loadSelectionSwitch: load.selection,\n loadConfigJournal: load.journal,\n resolveLayers: (config, majorMode) => [...(config.majorMode[majorMode]?.layers ?? [])],\n supervisedRelaunchAvailable,\n requestSupervisedRelaunch,\n });\n pi.on('session_start', async (_event, ctx) => {\n await runtimeInjection.await();\n try {\n const { majorMode, domains, profile } = requireDoomConfigContext(requireRuntimeContext()).harness;\n ctx.ui.setStatus(STATUS_KEY, colorStatus(ctx.ui.theme, majorMode, domains, profile, false));\n } catch (error) {\n void telemetry.recordError(MAJOR_MODE_EVENT.majorModeUnavailable, error);\n ctx.ui.setStatus(\n STATUS_KEY,\n `major mode unavailable (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n });\n yield () => undefined;\n }, MAJOR_MODE_SOURCE);\n}\n\n/** The package's single standard Pi factory. */\nexport async function majorModeExtension(\n pi: ExtensionAPI,\n telemetry: MajorModeTelemetry = createMajorModeTelemetry(),\n): Promise<void> {\n const connection = await connectDoomCordisHost(pi, MAJOR_MODE_SOURCE);\n const fiber = connection.root.plugin(majorModePlugin, { pi, telemetry });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\nexport default majorModeExtension;\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { MajorModeTelemetry } from "../../types/telemetry.cjs";
|
|
|
2
2
|
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
//#region src/adapters/pi/extension.d.ts
|
|
4
4
|
/** The package's single standard Pi factory. */
|
|
5
|
-
declare function majorModeExtension(pi: ExtensionAPI, telemetry?: MajorModeTelemetry): Promise<void>;
|
|
5
|
+
export declare function majorModeExtension(pi: ExtensionAPI, telemetry?: MajorModeTelemetry): Promise<void>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export { majorModeExtension as default
|
|
7
|
+
export { majorModeExtension as default };
|
|
8
8
|
//# sourceMappingURL=extension.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"extension.d.cts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;wBA+HsB,mBACpB,IAAI,cACJ,YAAW,qBACV"}
|
|
@@ -2,7 +2,7 @@ import { MajorModeTelemetry } from "../../types/telemetry.mjs";
|
|
|
2
2
|
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
//#region src/adapters/pi/extension.d.ts
|
|
4
4
|
/** The package's single standard Pi factory. */
|
|
5
|
-
declare function majorModeExtension(pi: ExtensionAPI, telemetry?: MajorModeTelemetry): Promise<void>;
|
|
5
|
+
export declare function majorModeExtension(pi: ExtensionAPI, telemetry?: MajorModeTelemetry): Promise<void>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export { majorModeExtension as default
|
|
7
|
+
export { majorModeExtension as default };
|
|
8
8
|
//# sourceMappingURL=extension.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"extension.d.mts","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"mappings":";;;;wBA+HsB,mBACpB,IAAI,cACJ,YAAW,qBACV"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{STATUS_KEY as e,colorStatus as t}from"../../services/statusLine.mjs";import{MAJOR_MODE_EVENT as n}from"../../types/telemetry.mjs";import{MAJOR_MODE_SOURCE as r}from"../../types/majorMode.mjs";import{registerMajorModeCommand as i}from"../../commands/majorModeCommand.mjs";import{
|
|
1
|
+
import{STATUS_KEY as e,colorStatus as t}from"../../services/statusLine.mjs";import{MAJOR_MODE_EVENT as n}from"../../types/telemetry.mjs";import{MAJOR_MODE_SOURCE as r}from"../../types/majorMode.mjs";import{registerMajorModeCommand as i}from"../../commands/majorModeCommand.mjs";import{requestSupervisedRelaunch as a,supervisedRelaunchAvailable as o}from"./relaunchRequest.mjs";import{createMajorModeTelemetry as s}from"../telemetry/logSinkTelemetry.mjs";import{registerMajorModeVoiceCapability as c}from"./voiceTool.mjs";import{requireHarnessRoot as l}from"@agimon-ai/doompi-config/harnessStore";import{requireDoomConfigContext as u}from"@agimon-ai/doompi-config/piContext";import{DOOM_CONFIG_SERVICE as d}from"@agimon-ai/doompi-extension-contracts/config";import{connectDoomCordisHost as f}from"@agimon-ai/doompi-extension-contracts/cordis-host";import{DOOM_HELP_SERVICE as p,requireDoomHelpService as m}from"@agimon-ai/doompi-extension-contracts/help";import{DOOM_TRANSITION_SERVICE as h}from"@agimon-ai/doompi-extension-contracts/transition";import{DOOM_VOICE_TOOLS_SERVICE as g,requireDoomVoiceToolsService as _}from"@agimon-ai/doompi-extension-contracts/voice-tools";import{createVoiceReloadHandoffStore as v}from"@agimon-ai/doompi-extension-contracts/voice-reload-handoff";function y(){let e,t,n,r;return{config:()=>e??=import(`@agimon-ai/doompi-config/majorModes`),journal:()=>t??=import(`@agimon-ai/doompi-config/piContext`),picker:()=>n??=import(`@agimon-ai/doompi-ui/components/matrixPicker`),selection:()=>r??=import(`@agimon-ai/doompi-config/selectionSwitch`)}}function b(s,{pi:f,telemetry:b}){let x=y();s.inject([p],e=>{let t=m(e).register({source:r,moduleUrl:import.meta.url,skills:[{name:`doompi-author-major-mode`,description:`Configure DoomPi default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.pi/.doom/modes.yaml or a repository's .doom/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.`}]});return()=>t.dispose()});let S,C=s.inject([d,h],e=>(S=e,()=>{S===e&&(S=void 0)})),w=()=>{if(!S)throw Error(`Doom major-mode runtime is waiting for the session config service.`);return S},T=async e=>{let t=u(w()).harness,{loadMajorModesConfig:n}=await x.config();return{config:n(l(t)),majorMode:t.majorMode,domains:t.domains,profile:t.profile}},E=v({now:()=>Date.now(),createToken:()=>crypto.randomUUID()});s.inject([d,h,g],e=>c(_(e),f,T,E,()=>e)),s.effect(function*(){i(f,b,{cordisContext:w,currentView:T,reloadHandoffs:E,loadPicker:x.picker,loadSelectionSwitch:x.selection,loadConfigJournal:x.journal,resolveLayers:(e,t)=>[...e.majorMode[t]?.layers??[]],supervisedRelaunchAvailable:o,requestSupervisedRelaunch:a}),f.on(`session_start`,async(r,i)=>{await C.await();try{let{majorMode:n,domains:r,profile:a}=u(w()).harness;i.ui.setStatus(e,t(i.ui.theme,n,r,a,!1))}catch(t){b.recordError(n.majorModeUnavailable,t),i.ui.setStatus(e,`major mode unavailable (${t instanceof Error?t.message:String(t)})`)}}),yield()=>void 0},r)}async function x(e,t=s()){let n=await f(e,r),i=n.root.plugin(b,{pi:e,telemetry:t});try{await i}catch(e){try{await i.dispose()}finally{await n.dispose()}throw e}let a;e.on(`session_shutdown`,()=>a??=(async()=>{try{await i.dispose()}finally{await n.dispose()}})())}export{x as default,x as majorModeExtension};
|
|
2
2
|
//# sourceMappingURL=extension.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { requireHarnessRoot } from '@agimon-ai/doompi-config/harnessStore';\nimport { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-extension-contracts/config';\nimport { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport { DOOM_TRANSITION_SERVICE } from '@agimon-ai/doompi-extension-contracts/transition';\nimport {\n DOOM_VOICE_TOOLS_SERVICE,\n requireDoomVoiceToolsService,\n} from '@agimon-ai/doompi-extension-contracts/voice-tools';\nimport { createVoiceReloadHandoffStore } from '@agimon-ai/doompi-extension-contracts/voice-reload-handoff';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerMajorModeCommand } from '../../commands/majorModeCommand.ts';\nimport { colorStatus, STATUS_KEY } from '../../services/statusLine.ts';\nimport { MAJOR_MODE_SOURCE, type MajorModeView } from '../../types/majorMode.ts';\nimport { MAJOR_MODE_EVENT, type MajorModeTelemetry } from '../../types/telemetry.ts';\nimport { createMajorModeTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { registerMajorModeVoiceCapability } from './voiceTool.ts';\n\n/**\n * Everything the axis needs beyond the session, loaded on first use.\n *\n * Every session registers /mode, but most never run it, so the picker, the\n * switch and the journal stay off the startup path.\n */\nfunction lazyModules() {\n let config: Promise<typeof import('@agimon-ai/doompi-config/majorModes')> | undefined;\n let journal: Promise<typeof import('@agimon-ai/doompi-config/piContext')> | undefined;\n let picker: Promise<typeof import('@agimon-ai/doompi-ui/components/matrixPicker')> | undefined;\n let selection: Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')> | undefined;\n return {\n config: () => (config ??= import('@agimon-ai/doompi-config/majorModes')),\n journal: () => (journal ??= import('@agimon-ai/doompi-config/piContext')),\n picker: () => (picker ??= import('@agimon-ai/doompi-ui/components/matrixPicker')),\n selection: () => (selection ??= import('@agimon-ai/doompi-config/selectionSwitch')),\n };\n}\n\ninterface MajorModePluginConfig {\n readonly pi: ExtensionAPI;\n readonly telemetry: MajorModeTelemetry;\n}\n\nfunction majorModePlugin(cordis: Context, { pi, telemetry }: MajorModePluginConfig): void {\n const load = lazyModules();\n let activeContext: Context | undefined;\n const runtimeInjection = cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n const requireRuntimeContext = (): Context => {\n if (!activeContext) throw new Error('Doom major-mode runtime is waiting for the session config service.');\n return activeContext;\n };\n const currentView = async (_ctx: ExtensionContext): Promise<MajorModeView> => {\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const { loadMajorModesConfig } = await load.config();\n return {\n config: loadMajorModesConfig(requireHarnessRoot(state)),\n majorMode: state.majorMode,\n domains: state.domains,\n profile: state.profile,\n };\n };\n const reloadHandoffs = createVoiceReloadHandoffStore({\n now: () => Date.now(),\n createToken: () => crypto.randomUUID(),\n });\n cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE, DOOM_VOICE_TOOLS_SERVICE], (voiceContext) =>\n registerMajorModeVoiceCapability(\n requireDoomVoiceToolsService(voiceContext),\n pi,\n currentView,\n reloadHandoffs,\n () => voiceContext,\n ),\n );\n\n cordis.effect(function* () {\n registerMajorModeCommand(pi, telemetry, {\n cordisContext: requireRuntimeContext,\n currentView,\n reloadHandoffs,\n loadPicker: load.picker,\n loadSelectionSwitch: load.selection,\n loadConfigJournal: load.journal,\n resolveLayers: (config, majorMode) => [...(config.majorMode[majorMode]?.layers ?? [])],\n });\n pi.on('session_start', async (_event, ctx) => {\n await runtimeInjection.await();\n try {\n const { majorMode, domains, profile } = requireDoomConfigContext(requireRuntimeContext()).harness;\n ctx.ui.setStatus(STATUS_KEY, colorStatus(ctx.ui.theme, majorMode, domains, profile, false));\n } catch (error) {\n void telemetry.recordError(MAJOR_MODE_EVENT.majorModeUnavailable, error);\n ctx.ui.setStatus(\n STATUS_KEY,\n `major mode unavailable (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n });\n yield () => undefined;\n }, MAJOR_MODE_SOURCE);\n}\n\n/** The package's single standard Pi factory. */\nexport async function majorModeExtension(\n pi: ExtensionAPI,\n telemetry: MajorModeTelemetry = createMajorModeTelemetry(),\n): Promise<void> {\n const connection = await connectDoomCordisHost(pi, MAJOR_MODE_SOURCE);\n const fiber = connection.root.plugin(majorModePlugin, { pi, telemetry });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\nexport default majorModeExtension;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"extension.mjs","names":[],"sources":["../../../src/adapters/pi/extension.ts"],"sourcesContent":["import { requireHarnessRoot } from '@agimon-ai/doompi-config/harnessStore';\nimport { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-extension-contracts/config';\nimport { connectDoomCordisHost } from '@agimon-ai/doompi-extension-contracts/cordis-host';\nimport { DOOM_HELP_SERVICE, requireDoomHelpService } from '@agimon-ai/doompi-extension-contracts/help';\nimport { DOOM_TRANSITION_SERVICE } from '@agimon-ai/doompi-extension-contracts/transition';\nimport {\n DOOM_VOICE_TOOLS_SERVICE,\n requireDoomVoiceToolsService,\n} from '@agimon-ai/doompi-extension-contracts/voice-tools';\nimport { createVoiceReloadHandoffStore } from '@agimon-ai/doompi-extension-contracts/voice-reload-handoff';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerMajorModeCommand } from '../../commands/majorModeCommand.ts';\nimport { requestSupervisedRelaunch, supervisedRelaunchAvailable } from './relaunchRequest.ts';\nimport { colorStatus, STATUS_KEY } from '../../services/statusLine.ts';\nimport { MAJOR_MODE_SOURCE, type MajorModeView } from '../../types/majorMode.ts';\nimport { MAJOR_MODE_EVENT, type MajorModeTelemetry } from '../../types/telemetry.ts';\nimport { createMajorModeTelemetry } from '../telemetry/logSinkTelemetry.ts';\nimport { registerMajorModeVoiceCapability } from './voiceTool.ts';\n\n/**\n * Everything the axis needs beyond the session, loaded on first use.\n *\n * Every session registers /mode, but most never run it, so the picker, the\n * switch and the journal stay off the startup path.\n */\nfunction lazyModules() {\n let config: Promise<typeof import('@agimon-ai/doompi-config/majorModes')> | undefined;\n let journal: Promise<typeof import('@agimon-ai/doompi-config/piContext')> | undefined;\n let picker: Promise<typeof import('@agimon-ai/doompi-ui/components/matrixPicker')> | undefined;\n let selection: Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')> | undefined;\n return {\n config: () => (config ??= import('@agimon-ai/doompi-config/majorModes')),\n journal: () => (journal ??= import('@agimon-ai/doompi-config/piContext')),\n picker: () => (picker ??= import('@agimon-ai/doompi-ui/components/matrixPicker')),\n selection: () => (selection ??= import('@agimon-ai/doompi-config/selectionSwitch')),\n };\n}\n\ninterface MajorModePluginConfig {\n readonly pi: ExtensionAPI;\n readonly telemetry: MajorModeTelemetry;\n}\n\nfunction majorModePlugin(cordis: Context, { pi, telemetry }: MajorModePluginConfig): void {\n const load = lazyModules();\n cordis.inject([DOOM_HELP_SERVICE], (helpContext) => {\n const contribution = requireDoomHelpService(helpContext).register({\n source: MAJOR_MODE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-major-mode',\n description:\n \"Configure DoomPi default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.pi/.doom/modes.yaml or a repository's .doom/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n },\n ],\n });\n return () => contribution.dispose();\n });\n\n let activeContext: Context | undefined;\n const runtimeInjection = cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n const requireRuntimeContext = (): Context => {\n if (!activeContext) throw new Error('Doom major-mode runtime is waiting for the session config service.');\n return activeContext;\n };\n const currentView = async (_ctx: ExtensionContext): Promise<MajorModeView> => {\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const { loadMajorModesConfig } = await load.config();\n return {\n config: loadMajorModesConfig(requireHarnessRoot(state)),\n majorMode: state.majorMode,\n domains: state.domains,\n profile: state.profile,\n };\n };\n const reloadHandoffs = createVoiceReloadHandoffStore({\n now: () => Date.now(),\n createToken: () => crypto.randomUUID(),\n });\n cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE, DOOM_VOICE_TOOLS_SERVICE], (voiceContext) =>\n registerMajorModeVoiceCapability(\n requireDoomVoiceToolsService(voiceContext),\n pi,\n currentView,\n reloadHandoffs,\n () => voiceContext,\n ),\n );\n\n cordis.effect(function* () {\n registerMajorModeCommand(pi, telemetry, {\n cordisContext: requireRuntimeContext,\n currentView,\n reloadHandoffs,\n loadPicker: load.picker,\n loadSelectionSwitch: load.selection,\n loadConfigJournal: load.journal,\n resolveLayers: (config, majorMode) => [...(config.majorMode[majorMode]?.layers ?? [])],\n supervisedRelaunchAvailable,\n requestSupervisedRelaunch,\n });\n pi.on('session_start', async (_event, ctx) => {\n await runtimeInjection.await();\n try {\n const { majorMode, domains, profile } = requireDoomConfigContext(requireRuntimeContext()).harness;\n ctx.ui.setStatus(STATUS_KEY, colorStatus(ctx.ui.theme, majorMode, domains, profile, false));\n } catch (error) {\n void telemetry.recordError(MAJOR_MODE_EVENT.majorModeUnavailable, error);\n ctx.ui.setStatus(\n STATUS_KEY,\n `major mode unavailable (${error instanceof Error ? error.message : String(error)})`,\n );\n }\n });\n yield () => undefined;\n }, MAJOR_MODE_SOURCE);\n}\n\n/** The package's single standard Pi factory. */\nexport async function majorModeExtension(\n pi: ExtensionAPI,\n telemetry: MajorModeTelemetry = createMajorModeTelemetry(),\n): Promise<void> {\n const connection = await connectDoomCordisHost(pi, MAJOR_MODE_SOURCE);\n const fiber = connection.root.plugin(majorModePlugin, { pi, telemetry });\n try {\n await fiber;\n } catch (error) {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n throw error;\n }\n let disposal: Promise<void> | undefined;\n pi.on(\n 'session_shutdown',\n () =>\n (disposal ??= (async () => {\n try {\n await fiber.dispose();\n } finally {\n await connection.dispose();\n }\n })()),\n );\n}\n\nexport default majorModeExtension;\n"],"mappings":"+vCA2BA,SAAS,GAAc,CACrB,IAAI,EACA,EACA,EACA,EACJ,MAAO,CACL,WAAe,IAAW,OAAO,uCACjC,YAAgB,IAAY,OAAO,sCACnC,WAAe,IAAW,OAAO,gDACjC,cAAkB,IAAc,OAAO,2CACzC,CACF,CAOA,SAAS,EAAgB,EAAiB,CAAE,KAAI,aAA0C,CACxF,IAAM,EAAO,EAAY,EACzB,EAAO,OAAO,CAAC,CAAiB,EAAI,GAAgB,CAClD,IAAM,EAAe,EAAuB,CAAW,CAAC,CAAC,SAAS,CAChE,OAAQ,EACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,2BACN,YACE,4PACJ,CACF,CACF,CAAC,EACD,UAAa,EAAa,QAAQ,CACpC,CAAC,EAED,IAAI,EACE,EAAmB,EAAO,OAAO,CAAC,EAAqB,CAAuB,EAAI,IACtF,EAAgB,MACH,CACP,IAAkB,IAAS,EAAgB,IAAA,GACjD,EACD,EACK,MAAuC,CAC3C,GAAI,CAAC,EAAe,MAAU,MAAM,oEAAoE,EACxG,OAAO,CACT,EACM,EAAc,KAAO,IAAmD,CAC5E,IAAM,EAAQ,EAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1D,CAAE,wBAAyB,MAAM,EAAK,OAAO,EACnD,MAAO,CACL,OAAQ,EAAqB,EAAmB,CAAK,CAAC,EACtD,UAAW,EAAM,UACjB,QAAS,EAAM,QACf,QAAS,EAAM,OACjB,CACF,EACM,EAAiB,EAA8B,CACnD,QAAW,KAAK,IAAI,EACpB,gBAAmB,OAAO,WAAW,CACvC,CAAC,EACD,EAAO,OAAO,CAAC,EAAqB,EAAyB,CAAwB,EAAI,GACvF,EACE,EAA6B,CAAY,EACzC,EACA,EACA,MACM,CACR,CACF,EAEA,EAAO,OAAO,WAAa,CACzB,EAAyB,EAAI,EAAW,CACtC,cAAe,EACf,cACA,iBACA,WAAY,EAAK,OACjB,oBAAqB,EAAK,UAC1B,kBAAmB,EAAK,QACxB,eAAgB,EAAQ,IAAc,CAAC,GAAI,EAAO,UAAU,EAAU,EAAE,QAAU,CAAC,CAAE,EACrF,8BACA,2BACF,CAAC,EACD,EAAG,GAAG,gBAAiB,MAAO,EAAQ,IAAQ,CAC5C,MAAM,EAAiB,MAAM,EAC7B,GAAI,CACF,GAAM,CAAE,YAAW,UAAS,WAAY,EAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1F,EAAI,GAAG,UAAU,EAAY,EAAY,EAAI,GAAG,MAAO,EAAW,EAAS,EAAS,EAAK,CAAC,CAC5F,OAAS,EAAO,CACd,EAAe,YAAY,EAAiB,qBAAsB,CAAK,EACvE,EAAI,GAAG,UACL,EACA,2BAA2B,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAE,EACpF,CACF,CACF,CAAC,EACD,SAAY,IAAA,EACd,EAAG,CAAiB,CACtB,CAGA,eAAsB,EACpB,EACA,EAAgC,EAAyB,EAC1C,CACf,IAAM,EAAa,MAAM,EAAsB,EAAI,CAAiB,EAC9D,EAAQ,EAAW,KAAK,OAAO,EAAiB,CAAE,KAAI,WAAU,CAAC,EACvE,GAAI,CACF,MAAM,CACR,OAAS,EAAO,CACd,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACA,MAAM,CACR,CACA,IAAI,EACJ,EAAG,GACD,uBAEG,KAAc,SAAY,CACzB,GAAI,CACF,MAAM,EAAM,QAAQ,CACtB,QAAU,CACR,MAAM,EAAW,QAAQ,CAC3B,CACF,EAAA,CAAG,CACP,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../../_virtual/_rolldown/runtime.cjs");let t=require("node:fs");t=e.__toESM(t,1);let n=require("@agimon-ai/doompi-extension-contracts/relaunch-handoff");function r(e=process.env){return!!e[n.DOOM_RELAUNCH_FILE_ENV]}function i(e,r,i=process.env){let a=i[n.DOOM_RELAUNCH_FILE_ENV];if(!a)return!1;try{return t.default.writeFileSync(a,(0,n.serializeRelaunchHandoff)({version:1,majorMode:e,operationId:r})),!0}catch{return!1}}exports.requestSupervisedRelaunch=i,exports.supervisedRelaunchAvailable=r;
|
|
2
|
+
//# sourceMappingURL=relaunchRequest.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relaunchRequest.cjs","names":["DOOM_RELAUNCH_FILE_ENV","serializeRelaunchHandoff"],"sources":["../../../src/adapters/pi/relaunchRequest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport {\n DOOM_RELAUNCH_FILE_ENV,\n serializeRelaunchHandoff,\n} from '@agimon-ai/doompi-extension-contracts/relaunch-handoff';\n\n/** Whether a process supervisor is listening for relaunch requests. */\nexport function supervisedRelaunchAvailable(env: NodeJS.ProcessEnv = process.env): boolean {\n return Boolean(env[DOOM_RELAUNCH_FILE_ENV]);\n}\n\n/**\n * Hands a relaunch-class major-mode switch to the process supervisor.\n *\n * A supervisor that owns this agent process (doompi-server) points\n * DOOMPI_RELAUNCH_FILE at a path it watches; writing the target selection\n * there asks it to end this agent's input for a graceful exit and respawn it\n * with the new major mode under the same session id. Write only when the\n * session is idle: the supervisor acts on the file as soon as it appears.\n * Returns false when no supervisor is listening or the write fails, in which\n * case the caller keeps the manual-relaunch message.\n */\nexport function requestSupervisedRelaunch(\n majorMode: string,\n operationId: string,\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const file = env[DOOM_RELAUNCH_FILE_ENV];\n if (!file) return false;\n try {\n fs.writeFileSync(file, serializeRelaunchHandoff({ version: 1, majorMode, operationId }));\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"0KAOA,SAAgB,EAA4B,EAAyB,QAAQ,IAAc,CACzF,MAAO,EAAQ,EAAIA,EAAAA,uBACrB,CAaA,SAAgB,EACd,EACA,EACA,EAAyB,QAAQ,IACxB,CACT,IAAM,EAAO,EAAIA,EAAAA,wBACjB,GAAI,CAAC,EAAM,MAAO,GAClB,GAAI,CAEF,OADA,EAAA,QAAG,cAAc,GAAA,EAAMC,EAAAA,yBAAAA,CAAyB,CAAE,QAAS,EAAG,YAAW,aAAY,CAAC,CAAC,EAChF,EACT,MAAQ,CACN,MAAO,EACT,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e from"node:fs";import{DOOM_RELAUNCH_FILE_ENV as t,serializeRelaunchHandoff as n}from"@agimon-ai/doompi-extension-contracts/relaunch-handoff";function r(e=process.env){return!!e[t]}function i(r,i,a=process.env){let o=a[t];if(!o)return!1;try{return e.writeFileSync(o,n({version:1,majorMode:r,operationId:i})),!0}catch{return!1}}export{i as requestSupervisedRelaunch,r as supervisedRelaunchAvailable};
|
|
2
|
+
//# sourceMappingURL=relaunchRequest.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relaunchRequest.mjs","names":[],"sources":["../../../src/adapters/pi/relaunchRequest.ts"],"sourcesContent":["import fs from 'node:fs';\nimport {\n DOOM_RELAUNCH_FILE_ENV,\n serializeRelaunchHandoff,\n} from '@agimon-ai/doompi-extension-contracts/relaunch-handoff';\n\n/** Whether a process supervisor is listening for relaunch requests. */\nexport function supervisedRelaunchAvailable(env: NodeJS.ProcessEnv = process.env): boolean {\n return Boolean(env[DOOM_RELAUNCH_FILE_ENV]);\n}\n\n/**\n * Hands a relaunch-class major-mode switch to the process supervisor.\n *\n * A supervisor that owns this agent process (doompi-server) points\n * DOOMPI_RELAUNCH_FILE at a path it watches; writing the target selection\n * there asks it to end this agent's input for a graceful exit and respawn it\n * with the new major mode under the same session id. Write only when the\n * session is idle: the supervisor acts on the file as soon as it appears.\n * Returns false when no supervisor is listening or the write fails, in which\n * case the caller keeps the manual-relaunch message.\n */\nexport function requestSupervisedRelaunch(\n majorMode: string,\n operationId: string,\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const file = env[DOOM_RELAUNCH_FILE_ENV];\n if (!file) return false;\n try {\n fs.writeFileSync(file, serializeRelaunchHandoff({ version: 1, majorMode, operationId }));\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"qJAOA,SAAgB,EAA4B,EAAyB,QAAQ,IAAc,CACzF,MAAO,EAAQ,EAAI,EACrB,CAaA,SAAgB,EACd,EACA,EACA,EAAyB,QAAQ,IACxB,CACT,IAAM,EAAO,EAAI,GACjB,GAAI,CAAC,EAAM,MAAO,GAClB,GAAI,CAEF,OADA,EAAG,cAAc,EAAM,EAAyB,CAAE,QAAS,EAAG,YAAW,aAAY,CAAC,CAAC,EAChF,EACT,MAAQ,CACN,MAAO,EACT,CACF"}
|
|
@@ -12,7 +12,6 @@ import { Context } from "@deepseek-ai/cordis";
|
|
|
12
12
|
* the reload happens inside a command handler where it can be the terminal
|
|
13
13
|
* action.
|
|
14
14
|
*/
|
|
15
|
-
declare function registerMajorModeVoiceCapability(voiceTools: DoomVoiceToolsService<ExtensionContext>, pi: ExtensionAPI, currentView: (ctx: ExtensionContext) => Promise<MajorModeView>, reloadHandoffs: VoiceReloadHandoffStore, cordisContext: () => Context): () => void;
|
|
15
|
+
export declare function registerMajorModeVoiceCapability(voiceTools: DoomVoiceToolsService<ExtensionContext>, pi: ExtensionAPI, currentView: (ctx: ExtensionContext) => Promise<MajorModeView>, reloadHandoffs: VoiceReloadHandoffStore, cordisContext: () => Context): () => void;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { registerMajorModeVoiceCapability };
|
|
18
17
|
//# sourceMappingURL=voiceTool.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceTool.d.cts","names":[],"sources":["../../../src/adapters/pi/voiceTool.ts"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"voiceTool.d.cts","names":[],"sources":["../../../src/adapters/pi/voiceTool.ts"],"mappings":";;;;;;;;;;;;;;wBA0CgB,iCACd,YAAY,sBAAsB,mBAClC,IAAI,cACJ,cAAc,KAAK,qBAAqB,QAAQ,gBAChD,gBAAgB,yBAChB,qBAAqB"}
|
|
@@ -12,7 +12,6 @@ import { Context } from "@deepseek-ai/cordis";
|
|
|
12
12
|
* the reload happens inside a command handler where it can be the terminal
|
|
13
13
|
* action.
|
|
14
14
|
*/
|
|
15
|
-
declare function registerMajorModeVoiceCapability(voiceTools: DoomVoiceToolsService<ExtensionContext>, pi: ExtensionAPI, currentView: (ctx: ExtensionContext) => Promise<MajorModeView>, reloadHandoffs: VoiceReloadHandoffStore, cordisContext: () => Context): () => void;
|
|
15
|
+
export declare function registerMajorModeVoiceCapability(voiceTools: DoomVoiceToolsService<ExtensionContext>, pi: ExtensionAPI, currentView: (ctx: ExtensionContext) => Promise<MajorModeView>, reloadHandoffs: VoiceReloadHandoffStore, cordisContext: () => Context): () => void;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { registerMajorModeVoiceCapability };
|
|
18
17
|
//# sourceMappingURL=voiceTool.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceTool.d.mts","names":[],"sources":["../../../src/adapters/pi/voiceTool.ts"],"mappings":";;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"voiceTool.d.mts","names":[],"sources":["../../../src/adapters/pi/voiceTool.ts"],"mappings":";;;;;;;;;;;;;;wBA0CgB,iCACd,YAAY,sBAAsB,mBAClC,IAAI,cACJ,cAAc,KAAK,qBAAqB,QAAQ,gBAChD,gBAAgB,yBAChB,qBAAqB"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { MajorModeTelemetry } from "../../types/telemetry.cjs";
|
|
2
2
|
import { DoomTelemetryOptions } from "@agimon-ai/doompi-telemetry";
|
|
3
3
|
//#region src/adapters/telemetry/logSinkTelemetry.d.ts
|
|
4
|
-
interface MajorModeTelemetryOptions {
|
|
4
|
+
export interface MajorModeTelemetryOptions {
|
|
5
5
|
cwd?: string;
|
|
6
6
|
workspaceRoot?: string;
|
|
7
7
|
env?: NodeJS.ProcessEnv;
|
|
8
8
|
telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;
|
|
9
9
|
warn?: (message: string) => void;
|
|
10
10
|
}
|
|
11
|
-
declare function createMajorModeTelemetry(options?: MajorModeTelemetryOptions): MajorModeTelemetry;
|
|
11
|
+
export declare function createMajorModeTelemetry(options?: MajorModeTelemetryOptions): MajorModeTelemetry;
|
|
12
12
|
//#endregion
|
|
13
|
-
export { MajorModeTelemetryOptions, createMajorModeTelemetry };
|
|
14
13
|
//# sourceMappingURL=logSinkTelemetry.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logSinkTelemetry.d.cts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logSinkTelemetry.d.cts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";;;iBAMiB;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;wBAGM,yBAAyB,UAAS,4BAAiC"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { MajorModeTelemetry } from "../../types/telemetry.mjs";
|
|
2
2
|
import { DoomTelemetryOptions } from "@agimon-ai/doompi-telemetry";
|
|
3
3
|
//#region src/adapters/telemetry/logSinkTelemetry.d.ts
|
|
4
|
-
interface MajorModeTelemetryOptions {
|
|
4
|
+
export interface MajorModeTelemetryOptions {
|
|
5
5
|
cwd?: string;
|
|
6
6
|
workspaceRoot?: string;
|
|
7
7
|
env?: NodeJS.ProcessEnv;
|
|
8
8
|
telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;
|
|
9
9
|
warn?: (message: string) => void;
|
|
10
10
|
}
|
|
11
|
-
declare function createMajorModeTelemetry(options?: MajorModeTelemetryOptions): MajorModeTelemetry;
|
|
11
|
+
export declare function createMajorModeTelemetry(options?: MajorModeTelemetryOptions): MajorModeTelemetry;
|
|
12
12
|
//#endregion
|
|
13
|
-
export { MajorModeTelemetryOptions, createMajorModeTelemetry };
|
|
14
13
|
//# sourceMappingURL=logSinkTelemetry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logSinkTelemetry.d.mts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logSinkTelemetry.d.mts","names":[],"sources":["../../../src/adapters/telemetry/logSinkTelemetry.ts"],"mappings":";;;iBAMiB;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;wBAGM,yBAAyB,UAAS,4BAAiC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../services/majorModeText.cjs"),t=require("../services/statusLine.cjs"),n=require("../types/telemetry.cjs"),r=require("../services/pendingSelection.cjs");require("../types/majorMode.cjs");let i=require("@agimon-ai/doompi-config/harnessStore"),a=require("@agimon-ai/doompi-config/piContext"),o=require("@agimon-ai/doompi-extension-contracts/transition"),s=require("@agimon-ai/doompi-extension-contracts/voice-tools"),c=require("@agimon-ai/doompi-config/majorModes"),l=require("@agimon-ai/doompi-extension-contracts/child-process");function u(e){return Error(`Major-mode transition was ${e.outcome}: ${e.diagnostics.join(`, `)}`)}function d(d,f,p){d.registerCommand(e.MAJOR_MODE_COMMAND,{description:`Pick a named major mode`,handler:async(m,h)=>{let g;try{g=e.voiceSwitchToken(m)}catch(t){h.ui.notify(e.errorMessage(t),`error`);return}if(m.trim()&&!g){h.ui.notify(`Usage: /${e.MAJOR_MODE_COMMAND}`,`warning`);return}let _=h.sessionManager.getSessionId(),v=p.cordisContext(),y,b,x,S=!1;try{let{config:m,majorMode:
|
|
1
|
+
const e=require("../services/majorModeText.cjs"),t=require("../services/statusLine.cjs"),n=require("../types/telemetry.cjs"),r=require("../services/pendingSelection.cjs");require("../types/majorMode.cjs");let i=require("@agimon-ai/doompi-config/harnessStore"),a=require("@agimon-ai/doompi-config/piContext"),o=require("@agimon-ai/doompi-extension-contracts/transition"),s=require("@agimon-ai/doompi-extension-contracts/voice-tools"),c=require("@agimon-ai/doompi-config/majorModes"),l=require("@agimon-ai/doompi-extension-contracts/child-process");function u(e){return Error(`Major-mode transition was ${e.outcome}: ${e.diagnostics.join(`, `)}`)}function d(d,f,p){d.registerCommand(e.MAJOR_MODE_COMMAND,{description:`Pick a named major mode`,handler:async(m,h)=>{let g;try{g=e.voiceSwitchToken(m)}catch(t){h.ui.notify(e.errorMessage(t),`error`);return}if(m.trim()&&!g){h.ui.notify(`Usage: /${e.MAJOR_MODE_COMMAND}`,`warning`);return}let _=h.sessionManager.getSessionId(),v=p.cordisContext(),y,b,x,S=!1,C;try{let{config:m,majorMode:w,domains:T,profile:E}=await p.currentView(h),D=Object.keys(m.majorMode),O;if(g){let e=(0,s.readDoomVoiceToolsService)(v)?.readSession(_);if(e&&(y={sessionId:_,hostGeneration:e.hostGeneration}),b=y?p.reloadHandoffs.accept(g,y):void 0,b?.kind!==`major-mode-switch`||!b.majorMode)throw Error(`The voice major-mode switch token is stale or belongs to another session.`);O=b.majorMode}else{let t=`Major mode (current: ${w})`;O=(h.mode===`tui`?await p.loadPicker().then(({MatrixPickerComponent:n})=>h.ui.custom((r,i,a,o)=>new n({title:t,items:e.majorModeItems(m,D),selected:[w],multi:!1},i,a,o))):[e.optionName(await h.ui.select(t,D.map(t=>e.majorModeOptionLabel(t,m.majorMode[t]?.layers??[],w)))??``)])?.[0]}if(!O)return;let k=(0,l.alreadyComposed)();if(O===w){g&&y&&p.reloadHandoffs.discard(g,y),r.clearPendingSelection(d,p.cordisContext()),h.ui.notify(e.majorModeSummary(O,p.resolveLayers(m,O),w,k),`info`);return}let A=(0,o.requireDoomTransitionCoordinator)(v),j=await A.execute({sessionId:h.sessionManager.getSessionId(),hostGeneration:A.hostGeneration,operationId:b?.operationId??crypto.randomUUID(),source:b?`voice`:`command`,target:{axis:`major-mode`,majorMode:O}},async(s,l)=>{let u=[...l.candidate.layers],m=l.externalRelaunchRequired,g=(0,a.requireDoomConfigContext)(v),_=g.harness;if(l.strategy===`process-relaunch`){let i={version:1,operationId:l.operationId,active:r.selectionFromSnapshot(l.previous),target:r.selectionFromSnapshot(l.candidate),strategy:l.strategy,phase:`pending`},o=(0,a.requireDoomConfigContext)(v).pendingSelection;if(o&&(0,a.supersedeDoomConfigTransition)(d,o),(0,a.appendDoomConfigTransition)(d,i),(0,a.replaceDoomConfigContext)(v,r.bindPendingSelection((0,a.requireDoomConfigContext)(v),i)),f.recordEvent(n.MAJOR_MODE_EVENT.majorModeSwitched,{"harness.major_mode.previous":_.majorMode,"harness.major_mode":O,"harness.layers":u.join(`,`),"harness.major_mode.stale":!0,"harness.transition.disposition":l.disposition,"harness.transition.operation_id":l.operationId}),h.ui.setStatus(t.STATUS_KEY,t.colorStatus(h.ui.theme,_.majorMode,_.domains,_.profile,!0)),p.supervisedRelaunchAvailable()){let e=O;C=()=>p.requestSupervisedRelaunch(e,l.operationId)}return h.ui.notify(e.applySummary(O,u,!0,k,l.strategy,C!==void 0),`info`),`queued`}let[{applyMajorMode:y},{persistHarnessSelection:b}]=await Promise.all([p.loadSelectionSwitch(),p.loadConfigJournal()]),D={version:1,operationId:l.operationId,active:r.selectionFromSnapshot(l.previous),target:r.selectionFromSnapshot(l.candidate),strategy:l.strategy??`pi-reload`,phase:`pending`},j=(0,c.loadMajorModesConfig)(_.root??h.cwd),M=(0,i.snapshotHarnessState)(),N=g.pendingSelection;x=(0,o.prepareMinorModeReloadHandoff)(v,h.sessionManager.getSessionId(),A.hostGeneration,l.operationId,l.previous.minorModes);try{N&&(0,a.supersedeDoomConfigTransition)(d,N),(0,a.appendDoomConfigTransition)(d,D),b(d,y(j,O,_,l.candidate.compositionFingerprint,l.candidate.childActivation))}catch(e){x?.discard(),x=void 0;try{(0,i.restoreHarnessStateSnapshot)(M)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Transition failed and compensation failed: ${n}`,{cause:e})}throw(0,a.appendDoomConfigTransition)(d,{...D,phase:`aborted`}),N&&(0,a.appendDoomConfigTransition)(d,N),e}return f.recordEvent(n.MAJOR_MODE_EVENT.majorModeSwitched,{"harness.major_mode.previous":w,"harness.major_mode":O,"harness.layers":u.join(`,`),"harness.major_mode.stale":m,"harness.transition.disposition":l.disposition,"harness.transition.operation_id":l.operationId}),h.ui.setStatus(t.STATUS_KEY,t.colorStatus(h.ui.theme,O,T,E,!1)),h.ui.notify(e.applySummary(O,u,!1,k,l.strategy),`info`),S=!0,`applied`});if(j.outcome===`rejected`||j.outcome===`stale`)throw u(j)}catch(t){if(S=!1,C=void 0,x?.discard(),x=void 0,!g)throw t;y&&p.reloadHandoffs.discard(g,y),h.ui.notify(e.errorMessage(t),`error`)}if(S)try{await h.waitForIdle(),await h.reload()}catch(e){throw x?.discard(),e}C&&(await h.waitForIdle(),C()&&h.shutdown())}})}exports.registerMajorModeCommand=d;
|
|
2
2
|
//# sourceMappingURL=majorModeCommand.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"majorModeCommand.cjs","names":["MAJOR_MODE_COMMAND","voiceSwitchToken","errorMessage","readDoomVoiceToolsService","majorModeItems","optionName","majorModeOptionLabel","alreadyComposed","majorModeSummary","requireDoomTransitionCoordinator","requireDoomConfigContext","selectionFromSnapshot","bindPendingSelection","MAJOR_MODE_EVENT","STATUS_KEY","colorStatus","applySummary","loadMajorModesConfig","snapshotHarnessState","prepareMinorModeReloadHandoff"],"sources":["../../src/commands/majorModeCommand.ts"],"sourcesContent":["import { restoreHarnessStateSnapshot, snapshotHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport { loadMajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport {\n appendDoomConfigTransition,\n replaceDoomConfigContext,\n requireDoomConfigContext,\n supersedeDoomConfigTransition,\n} from '@agimon-ai/doompi-config/piContext';\nimport type { DoomConfigPendingSelection } from '@agimon-ai/doompi-config/types';\nimport { alreadyComposed } from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n type DoomTransitionResult,\n type MinorModeReloadHandoffHandle,\n prepareMinorModeReloadHandoff,\n requireDoomTransitionCoordinator,\n} from '@agimon-ai/doompi-extension-contracts/transition';\nimport { readDoomVoiceToolsService } from '@agimon-ai/doompi-extension-contracts/voice-tools';\nimport type {\n VoiceReloadHandoff,\n VoiceReloadHandoffIdentity,\n VoiceReloadHandoffStore,\n} from '@agimon-ai/doompi-extension-contracts/voice-reload-handoff';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { Context } from '@deepseek-ai/cordis';\nimport {\n applySummary,\n errorMessage,\n MAJOR_MODE_COMMAND,\n majorModeItems,\n majorModeOptionLabel,\n majorModeSummary,\n optionName,\n voiceSwitchToken,\n} from '../services/majorModeText.ts';\nimport { colorStatus, STATUS_KEY } from '../services/statusLine.ts';\nimport { MAJOR_MODE_EVENT, type MajorModeTelemetry } from '../types/telemetry.ts';\nimport { bindPendingSelection, clearPendingSelection, selectionFromSnapshot } from '../services/pendingSelection.ts';\nimport { MAJOR_MODE_SWITCH_HANDOFF_KIND, type MajorModeView } from '../types/majorMode.ts';\n\nfunction transitionError(result: DoomTransitionResult): Error {\n return new Error(`Major-mode transition was ${result.outcome}: ${result.diagnostics.join(', ')}`);\n}\n\nexport interface MajorModeCommandDependencies {\n readonly cordisContext: () => Context;\n readonly currentView: (ctx: ExtensionContext) => Promise<MajorModeView>;\n readonly reloadHandoffs: VoiceReloadHandoffStore;\n readonly loadPicker: () => Promise<typeof import('@agimon-ai/doompi-ui/components/matrixPicker')>;\n readonly loadSelectionSwitch: () => Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')>;\n readonly loadConfigJournal: () => Promise<typeof import('@agimon-ai/doompi-config/piContext')>;\n readonly resolveLayers: (config: MajorModeView['config'], majorMode: string) => string[];\n}\n\nexport function registerMajorModeCommand(\n pi: ExtensionAPI,\n telemetry: MajorModeTelemetry,\n dependencies: MajorModeCommandDependencies,\n): void {\n pi.registerCommand(MAJOR_MODE_COMMAND, {\n description: 'Pick a named major mode',\n handler: async (args, ctx) => {\n let token: string | undefined;\n try {\n token = voiceSwitchToken(args);\n } catch (error) {\n ctx.ui.notify(errorMessage(error), 'error');\n return;\n }\n if (args.trim() && !token) {\n ctx.ui.notify(`Usage: /${MAJOR_MODE_COMMAND}`, 'warning');\n return;\n }\n\n const sessionId = ctx.sessionManager.getSessionId();\n const cordis = dependencies.cordisContext();\n let sessionIdentity: VoiceReloadHandoffIdentity | undefined;\n let handoff: VoiceReloadHandoff | undefined;\n let minorModeReloadHandoff: MinorModeReloadHandoffHandle | undefined;\n let reloadRequested = false;\n try {\n const { config, majorMode, domains, profile } = await dependencies.currentView(ctx);\n const names = Object.keys(config.majorMode);\n let picked: string | undefined;\n\n if (token) {\n const voiceSession = readDoomVoiceToolsService(cordis)?.readSession(sessionId);\n if (voiceSession) sessionIdentity = { sessionId, hostGeneration: voiceSession.hostGeneration };\n handoff = sessionIdentity ? dependencies.reloadHandoffs.accept(token, sessionIdentity) : undefined;\n if (handoff?.kind !== MAJOR_MODE_SWITCH_HANDOFF_KIND || !handoff.majorMode) {\n throw new Error('The voice major-mode switch token is stale or belongs to another session.');\n }\n picked = handoff.majorMode;\n } else {\n const title = `Major mode (current: ${majorMode})`;\n const chosen =\n ctx.mode === 'tui'\n ? await dependencies\n .loadPicker()\n .then(({ MatrixPickerComponent }) =>\n ctx.ui.custom<string[] | undefined>(\n (_tui, theme, keybindings, done) =>\n new MatrixPickerComponent(\n { title, items: majorModeItems(config, names), selected: [majorMode], multi: false },\n theme,\n keybindings,\n done,\n ),\n ),\n )\n : [\n optionName(\n (await ctx.ui.select(\n title,\n names.map((name) => majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], majorMode)),\n )) ?? '',\n ),\n ];\n picked = chosen?.[0];\n }\n if (!picked) return;\n\n const composed = alreadyComposed();\n if (picked === majorMode) {\n if (token && sessionIdentity) dependencies.reloadHandoffs.discard(token, sessionIdentity);\n clearPendingSelection(pi, dependencies.cordisContext());\n ctx.ui.notify(\n majorModeSummary(picked, dependencies.resolveLayers(config, picked), majorMode, composed),\n 'info',\n );\n return;\n }\n\n const coordinator = requireDoomTransitionCoordinator(cordis);\n const result = await coordinator.execute(\n {\n sessionId: ctx.sessionManager.getSessionId(),\n hostGeneration: coordinator.hostGeneration,\n operationId: handoff?.operationId ?? crypto.randomUUID(),\n source: handoff ? 'voice' : 'command',\n target: { axis: 'major-mode', majorMode: picked },\n },\n async (_request, plan) => {\n const selected = [...plan.candidate.layers];\n const stale = plan.externalRelaunchRequired;\n const currentContextAtExecution = requireDoomConfigContext(cordis);\n const harness = currentContextAtExecution.harness;\n if (plan.strategy === 'process-relaunch') {\n const pendingSelection: DoomConfigPendingSelection = {\n version: 1,\n operationId: plan.operationId,\n active: selectionFromSnapshot(plan.previous),\n target: selectionFromSnapshot(plan.candidate),\n strategy: plan.strategy,\n phase: 'pending',\n };\n const existingPending = requireDoomConfigContext(cordis).pendingSelection;\n if (existingPending) supersedeDoomConfigTransition(pi, existingPending);\n appendDoomConfigTransition(pi, pendingSelection);\n replaceDoomConfigContext(\n cordis,\n bindPendingSelection(requireDoomConfigContext(cordis), pendingSelection),\n );\n void telemetry.recordEvent(MAJOR_MODE_EVENT.majorModeSwitched, {\n 'harness.major_mode.previous': harness.majorMode,\n 'harness.major_mode': picked,\n 'harness.layers': selected.join(','),\n 'harness.major_mode.stale': true,\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n ctx.ui.setStatus(\n STATUS_KEY,\n colorStatus(ctx.ui.theme, harness.majorMode, harness.domains, harness.profile, true),\n );\n ctx.ui.notify(applySummary(picked, selected, true, composed, plan.strategy), 'info');\n return 'queued';\n }\n const [{ applyMajorMode }, { persistHarnessSelection }] = await Promise.all([\n dependencies.loadSelectionSwitch(),\n dependencies.loadConfigJournal(),\n ]);\n const transition: DoomConfigPendingSelection = {\n version: 1,\n operationId: plan.operationId,\n active: selectionFromSnapshot(plan.previous),\n target: selectionFromSnapshot(plan.candidate),\n strategy: plan.strategy ?? 'pi-reload',\n phase: 'pending',\n };\n const activeConfig = loadMajorModesConfig(harness.root ?? ctx.cwd);\n const snapshot = snapshotHarnessState();\n const existingPending = currentContextAtExecution.pendingSelection;\n minorModeReloadHandoff = prepareMinorModeReloadHandoff(\n cordis,\n ctx.sessionManager.getSessionId(),\n coordinator.hostGeneration,\n plan.operationId,\n plan.previous.minorModes,\n );\n try {\n if (existingPending) supersedeDoomConfigTransition(pi, existingPending);\n appendDoomConfigTransition(pi, transition);\n const updated = applyMajorMode(\n activeConfig,\n picked,\n harness,\n plan.candidate.compositionFingerprint,\n plan.candidate.childActivation,\n );\n persistHarnessSelection(pi, updated);\n } catch (error) {\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n try {\n restoreHarnessStateSnapshot(snapshot);\n } catch (compensationError) {\n const detail =\n compensationError instanceof Error ? compensationError.message : String(compensationError);\n throw new Error(`Transition failed and compensation failed: ${detail}`, { cause: error });\n }\n appendDoomConfigTransition(pi, { ...transition, phase: 'aborted' });\n if (existingPending) appendDoomConfigTransition(pi, existingPending);\n throw error;\n }\n\n void telemetry.recordEvent(MAJOR_MODE_EVENT.majorModeSwitched, {\n 'harness.major_mode.previous': majorMode,\n 'harness.major_mode': picked,\n 'harness.layers': selected.join(','),\n 'harness.major_mode.stale': stale,\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n ctx.ui.setStatus(STATUS_KEY, colorStatus(ctx.ui.theme, picked, domains, profile, false));\n ctx.ui.notify(applySummary(picked, selected, false, composed, plan.strategy), 'info');\n // Reload must be the command handler's terminal action. Pi invalidates\n // this command context as soon as the replacement session is active.\n reloadRequested = true;\n return 'applied';\n },\n );\n if (result.outcome === 'rejected' || result.outcome === 'stale') throw transitionError(result);\n } catch (error) {\n reloadRequested = false;\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n if (!token) throw error;\n if (sessionIdentity) dependencies.reloadHandoffs.discard(token, sessionIdentity);\n ctx.ui.notify(errorMessage(error), 'error');\n }\n\n if (reloadRequested) {\n try {\n await ctx.waitForIdle();\n // The replacement session acknowledges the pending journal after its\n // bootstrap harness is active. Do not touch ctx after this await.\n await ctx.reload();\n } catch (error) {\n minorModeReloadHandoff?.discard();\n throw error;\n }\n }\n },\n });\n}\n"],"mappings":"miBAuCA,SAAS,EAAgB,EAAqC,CAC5D,OAAW,MAAM,6BAA6B,EAAO,QAAQ,IAAI,EAAO,YAAY,KAAK,IAAI,GAAG,CAClG,CAYA,SAAgB,EACd,EACA,EACA,EACM,CACN,EAAG,gBAAgBA,EAAAA,mBAAoB,CACrC,YAAa,0BACb,QAAS,MAAO,EAAM,IAAQ,CAC5B,IAAI,EACJ,GAAI,CACF,EAAQC,EAAAA,iBAAiB,CAAI,CAC/B,OAAS,EAAO,CACd,EAAI,GAAG,OAAOC,EAAAA,aAAa,CAAK,EAAG,OAAO,EAC1C,MACF,CACA,GAAI,EAAK,KAAK,GAAK,CAAC,EAAO,CACzB,EAAI,GAAG,OAAO,WAAWF,EAAAA,qBAAsB,SAAS,EACxD,MACF,CAEA,IAAM,EAAY,EAAI,eAAe,aAAa,EAC5C,EAAS,EAAa,cAAc,EACtC,EACA,EACA,EACA,EAAkB,GACtB,GAAI,CACF,GAAM,CAAE,SAAQ,YAAW,UAAS,WAAY,MAAM,EAAa,YAAY,CAAG,EAC5E,EAAQ,OAAO,KAAK,EAAO,SAAS,EACtC,EAEJ,GAAI,EAAO,CACT,IAAM,GAAA,EAAeG,EAAAA,0BAAAA,CAA0B,CAAM,CAAC,EAAE,YAAY,CAAS,EAG7E,GAFI,IAAc,EAAkB,CAAE,YAAW,eAAgB,EAAa,cAAe,GAC7F,EAAU,EAAkB,EAAa,eAAe,OAAO,EAAO,CAAe,EAAI,IAAA,GACrF,GAAS,OAAA,qBAA2C,CAAC,EAAQ,UAC/D,MAAU,MAAM,2EAA2E,EAE7F,EAAS,EAAQ,SACnB,KAAO,CACL,IAAM,EAAQ,wBAAwB,EAAU,GAwBhD,GAtBE,EAAI,OAAS,MACT,MAAM,EACH,WAAW,CAAC,CACZ,MAAM,CAAE,2BACP,EAAI,GAAG,QACJ,EAAM,EAAO,EAAa,IACzB,IAAI,EACF,CAAE,QAAO,MAAOC,EAAAA,eAAe,EAAQ,CAAK,EAAG,SAAU,CAAC,CAAS,EAAG,MAAO,EAAM,EACnF,EACA,EACA,CACF,CACJ,CACF,EACF,CACEC,EAAAA,WACG,MAAM,EAAI,GAAG,OACZ,EACA,EAAM,IAAK,GAASC,EAAAA,qBAAqB,EAAM,EAAO,UAAU,EAAK,EAAE,QAAU,CAAC,EAAG,CAAS,CAAC,CACjG,GAAM,EACR,CACF,EAAA,GACY,EACpB,CACA,GAAI,CAAC,EAAQ,OAEb,IAAM,GAAA,EAAWC,EAAAA,gBAAAA,CAAgB,EACjC,GAAI,IAAW,EAAW,CACpB,GAAS,GAAiB,EAAa,eAAe,QAAQ,EAAO,CAAe,EACxF,EAAA,sBAAsB,EAAI,EAAa,cAAc,CAAC,EACtD,EAAI,GAAG,OACLC,EAAAA,iBAAiB,EAAQ,EAAa,cAAc,EAAQ,CAAM,EAAG,EAAW,CAAQ,EACxF,MACF,EACA,MACF,CAEA,IAAM,GAAA,EAAcC,EAAAA,iCAAAA,CAAiC,CAAM,EACrD,EAAS,MAAM,EAAY,QAC/B,CACE,UAAW,EAAI,eAAe,aAAa,EAC3C,eAAgB,EAAY,eAC5B,YAAa,GAAS,aAAe,OAAO,WAAW,EACvD,OAAQ,EAAU,QAAU,UAC5B,OAAQ,CAAE,KAAM,aAAc,UAAW,CAAO,CAClD,EACA,MAAO,EAAU,IAAS,CACxB,IAAM,EAAW,CAAC,GAAG,EAAK,UAAU,MAAM,EACpC,EAAQ,EAAK,yBACb,GAAA,EAA4BC,EAAAA,yBAAAA,CAAyB,CAAM,EAC3D,EAAU,EAA0B,QAC1C,GAAI,EAAK,WAAa,mBAAoB,CACxC,IAAM,EAA+C,CACnD,QAAS,EACT,YAAa,EAAK,YAClB,OAAQC,EAAAA,sBAAsB,EAAK,QAAQ,EAC3C,OAAQA,EAAAA,sBAAsB,EAAK,SAAS,EAC5C,SAAU,EAAK,SACf,MAAO,SACT,EACM,GAAA,EAAkBD,EAAAA,yBAAAA,CAAyB,CAAM,CAAC,CAAC,iBAoBzD,OAnBI,IAAiB,EAAA,EAAA,8BAAA,CAA8B,EAAI,CAAe,GACtE,EAAA,EAAA,2BAAA,CAA2B,EAAI,CAAgB,GAC/C,EAAA,EAAA,yBAAA,CACE,EACAE,EAAAA,sBAAAA,EAAqBF,EAAAA,yBAAAA,CAAyB,CAAM,EAAG,CAAgB,CACzE,EACA,EAAe,YAAYG,EAAAA,iBAAiB,kBAAmB,CAC7D,8BAA+B,EAAQ,UACvC,qBAAsB,EACtB,iBAAkB,EAAS,KAAK,GAAG,EACnC,2BAA4B,GAC5B,iCAAkC,EAAK,YACvC,kCAAmC,EAAK,WAC1C,CAAC,EACD,EAAI,GAAG,UACLC,EAAAA,WACAC,EAAAA,YAAY,EAAI,GAAG,MAAO,EAAQ,UAAW,EAAQ,QAAS,EAAQ,QAAS,EAAI,CACrF,EACA,EAAI,GAAG,OAAOC,EAAAA,aAAa,EAAQ,EAAU,GAAM,EAAU,EAAK,QAAQ,EAAG,MAAM,EAC5E,QACT,CACA,GAAM,CAAC,CAAE,kBAAkB,CAAE,4BAA6B,MAAM,QAAQ,IAAI,CAC1E,EAAa,oBAAoB,EACjC,EAAa,kBAAkB,CACjC,CAAC,EACK,EAAyC,CAC7C,QAAS,EACT,YAAa,EAAK,YAClB,OAAQL,EAAAA,sBAAsB,EAAK,QAAQ,EAC3C,OAAQA,EAAAA,sBAAsB,EAAK,SAAS,EAC5C,SAAU,EAAK,UAAY,YAC3B,MAAO,SACT,EACM,GAAA,EAAeM,EAAAA,qBAAAA,CAAqB,EAAQ,MAAQ,EAAI,GAAG,EAC3D,GAAA,EAAWC,EAAAA,qBAAAA,CAAqB,EAChC,EAAkB,EAA0B,iBAClD,GAAA,EAAyBC,EAAAA,8BAAAA,CACvB,EACA,EAAI,eAAe,aAAa,EAChC,EAAY,eACZ,EAAK,YACL,EAAK,SAAS,UAChB,EACA,GAAI,CACE,IAAiB,EAAA,EAAA,8BAAA,CAA8B,EAAI,CAAe,GACtE,EAAA,EAAA,2BAAA,CAA2B,EAAI,CAAU,EAQzC,EAAwB,EAPR,EACd,EACA,EACA,EACA,EAAK,UAAU,uBACf,EAAK,UAAU,eAEiB,CAAC,CACrC,OAAS,EAAO,CACd,GAAwB,QAAQ,EAChC,EAAyB,IAAA,GACzB,GAAI,EACF,EAAA,EAAA,4BAAA,CAA4B,CAAQ,CACtC,OAAS,EAAmB,CAC1B,IAAM,EACJ,aAA6B,MAAQ,EAAkB,QAAU,OAAO,CAAiB,EAC3F,MAAU,MAAM,8CAA8C,IAAU,CAAE,MAAO,CAAM,CAAC,CAC1F,CAGA,MAFA,EAAA,EAAA,2BAAA,CAA2B,EAAI,CAAE,GAAG,EAAY,MAAO,SAAU,CAAC,EAC9D,IAAiB,EAAA,EAAA,2BAAA,CAA2B,EAAI,CAAe,EAC7D,CACR,CAeA,OAbA,EAAe,YAAYN,EAAAA,iBAAiB,kBAAmB,CAC7D,8BAA+B,EAC/B,qBAAsB,EACtB,iBAAkB,EAAS,KAAK,GAAG,EACnC,2BAA4B,EAC5B,iCAAkC,EAAK,YACvC,kCAAmC,EAAK,WAC1C,CAAC,EACD,EAAI,GAAG,UAAUC,EAAAA,WAAYC,EAAAA,YAAY,EAAI,GAAG,MAAO,EAAQ,EAAS,EAAS,EAAK,CAAC,EACvF,EAAI,GAAG,OAAOC,EAAAA,aAAa,EAAQ,EAAU,GAAO,EAAU,EAAK,QAAQ,EAAG,MAAM,EAGpF,EAAkB,GACX,SACT,CACF,EACA,GAAI,EAAO,UAAY,YAAc,EAAO,UAAY,QAAS,MAAM,EAAgB,CAAM,CAC/F,OAAS,EAAO,CAId,GAHA,EAAkB,GAClB,GAAwB,QAAQ,EAChC,EAAyB,IAAA,GACrB,CAAC,EAAO,MAAM,EACd,GAAiB,EAAa,eAAe,QAAQ,EAAO,CAAe,EAC/E,EAAI,GAAG,OAAOd,EAAAA,aAAa,CAAK,EAAG,OAAO,CAC5C,CAEA,GAAI,EACF,GAAI,CACF,MAAM,EAAI,YAAY,EAGtB,MAAM,EAAI,OAAO,CACnB,OAAS,EAAO,CAEd,MADA,GAAwB,QAAQ,EAC1B,CACR,CAEJ,CACF,CAAC,CACH"}
|
|
1
|
+
{"version":3,"file":"majorModeCommand.cjs","names":["MAJOR_MODE_COMMAND","voiceSwitchToken","errorMessage","readDoomVoiceToolsService","majorModeItems","optionName","majorModeOptionLabel","alreadyComposed","majorModeSummary","requireDoomTransitionCoordinator","requireDoomConfigContext","selectionFromSnapshot","bindPendingSelection","MAJOR_MODE_EVENT","STATUS_KEY","colorStatus","applySummary","loadMajorModesConfig","snapshotHarnessState","prepareMinorModeReloadHandoff"],"sources":["../../src/commands/majorModeCommand.ts"],"sourcesContent":["import { restoreHarnessStateSnapshot, snapshotHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport { loadMajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport {\n appendDoomConfigTransition,\n replaceDoomConfigContext,\n requireDoomConfigContext,\n supersedeDoomConfigTransition,\n} from '@agimon-ai/doompi-config/piContext';\nimport type { DoomConfigPendingSelection } from '@agimon-ai/doompi-config/types';\nimport { alreadyComposed } from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n type DoomTransitionResult,\n type MinorModeReloadHandoffHandle,\n prepareMinorModeReloadHandoff,\n requireDoomTransitionCoordinator,\n} from '@agimon-ai/doompi-extension-contracts/transition';\nimport { readDoomVoiceToolsService } from '@agimon-ai/doompi-extension-contracts/voice-tools';\nimport type {\n VoiceReloadHandoff,\n VoiceReloadHandoffIdentity,\n VoiceReloadHandoffStore,\n} from '@agimon-ai/doompi-extension-contracts/voice-reload-handoff';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { Context } from '@deepseek-ai/cordis';\nimport {\n applySummary,\n errorMessage,\n MAJOR_MODE_COMMAND,\n majorModeItems,\n majorModeOptionLabel,\n majorModeSummary,\n optionName,\n voiceSwitchToken,\n} from '../services/majorModeText.ts';\nimport { colorStatus, STATUS_KEY } from '../services/statusLine.ts';\nimport { MAJOR_MODE_EVENT, type MajorModeTelemetry } from '../types/telemetry.ts';\nimport { bindPendingSelection, clearPendingSelection, selectionFromSnapshot } from '../services/pendingSelection.ts';\nimport { MAJOR_MODE_SWITCH_HANDOFF_KIND, type MajorModeView } from '../types/majorMode.ts';\n\nfunction transitionError(result: DoomTransitionResult): Error {\n return new Error(`Major-mode transition was ${result.outcome}: ${result.diagnostics.join(', ')}`);\n}\n\nexport interface MajorModeCommandDependencies {\n readonly cordisContext: () => Context;\n readonly currentView: (ctx: ExtensionContext) => Promise<MajorModeView>;\n readonly reloadHandoffs: VoiceReloadHandoffStore;\n readonly loadPicker: () => Promise<typeof import('@agimon-ai/doompi-ui/components/matrixPicker')>;\n readonly loadSelectionSwitch: () => Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')>;\n readonly loadConfigJournal: () => Promise<typeof import('@agimon-ai/doompi-config/piContext')>;\n readonly resolveLayers: (config: MajorModeView['config'], majorMode: string) => string[];\n /** Whether an owning process supervisor listens for relaunch requests. */\n readonly supervisedRelaunchAvailable: () => boolean;\n /** Asks the supervisor to relaunch with the picked mode; call only at idle. */\n readonly requestSupervisedRelaunch: (majorMode: string, operationId: string) => boolean;\n}\n\nexport function registerMajorModeCommand(\n pi: ExtensionAPI,\n telemetry: MajorModeTelemetry,\n dependencies: MajorModeCommandDependencies,\n): void {\n pi.registerCommand(MAJOR_MODE_COMMAND, {\n description: 'Pick a named major mode',\n handler: async (args, ctx) => {\n let token: string | undefined;\n try {\n token = voiceSwitchToken(args);\n } catch (error) {\n ctx.ui.notify(errorMessage(error), 'error');\n return;\n }\n if (args.trim() && !token) {\n ctx.ui.notify(`Usage: /${MAJOR_MODE_COMMAND}`, 'warning');\n return;\n }\n\n const sessionId = ctx.sessionManager.getSessionId();\n const cordis = dependencies.cordisContext();\n let sessionIdentity: VoiceReloadHandoffIdentity | undefined;\n let handoff: VoiceReloadHandoff | undefined;\n let minorModeReloadHandoff: MinorModeReloadHandoffHandle | undefined;\n let reloadRequested = false;\n let performRelaunch: (() => boolean) | undefined;\n try {\n const { config, majorMode, domains, profile } = await dependencies.currentView(ctx);\n const names = Object.keys(config.majorMode);\n let picked: string | undefined;\n\n if (token) {\n const voiceSession = readDoomVoiceToolsService(cordis)?.readSession(sessionId);\n if (voiceSession) sessionIdentity = { sessionId, hostGeneration: voiceSession.hostGeneration };\n handoff = sessionIdentity ? dependencies.reloadHandoffs.accept(token, sessionIdentity) : undefined;\n if (handoff?.kind !== MAJOR_MODE_SWITCH_HANDOFF_KIND || !handoff.majorMode) {\n throw new Error('The voice major-mode switch token is stale or belongs to another session.');\n }\n picked = handoff.majorMode;\n } else {\n const title = `Major mode (current: ${majorMode})`;\n const chosen =\n ctx.mode === 'tui'\n ? await dependencies\n .loadPicker()\n .then(({ MatrixPickerComponent }) =>\n ctx.ui.custom<string[] | undefined>(\n (_tui, theme, keybindings, done) =>\n new MatrixPickerComponent(\n { title, items: majorModeItems(config, names), selected: [majorMode], multi: false },\n theme,\n keybindings,\n done,\n ),\n ),\n )\n : [\n optionName(\n (await ctx.ui.select(\n title,\n names.map((name) => majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], majorMode)),\n )) ?? '',\n ),\n ];\n picked = chosen?.[0];\n }\n if (!picked) return;\n\n const composed = alreadyComposed();\n if (picked === majorMode) {\n if (token && sessionIdentity) dependencies.reloadHandoffs.discard(token, sessionIdentity);\n clearPendingSelection(pi, dependencies.cordisContext());\n ctx.ui.notify(\n majorModeSummary(picked, dependencies.resolveLayers(config, picked), majorMode, composed),\n 'info',\n );\n return;\n }\n\n const coordinator = requireDoomTransitionCoordinator(cordis);\n const result = await coordinator.execute(\n {\n sessionId: ctx.sessionManager.getSessionId(),\n hostGeneration: coordinator.hostGeneration,\n operationId: handoff?.operationId ?? crypto.randomUUID(),\n source: handoff ? 'voice' : 'command',\n target: { axis: 'major-mode', majorMode: picked },\n },\n async (_request, plan) => {\n const selected = [...plan.candidate.layers];\n const stale = plan.externalRelaunchRequired;\n const currentContextAtExecution = requireDoomConfigContext(cordis);\n const harness = currentContextAtExecution.harness;\n if (plan.strategy === 'process-relaunch') {\n const pendingSelection: DoomConfigPendingSelection = {\n version: 1,\n operationId: plan.operationId,\n active: selectionFromSnapshot(plan.previous),\n target: selectionFromSnapshot(plan.candidate),\n strategy: plan.strategy,\n phase: 'pending',\n };\n const existingPending = requireDoomConfigContext(cordis).pendingSelection;\n if (existingPending) supersedeDoomConfigTransition(pi, existingPending);\n appendDoomConfigTransition(pi, pendingSelection);\n replaceDoomConfigContext(\n cordis,\n bindPendingSelection(requireDoomConfigContext(cordis), pendingSelection),\n );\n void telemetry.recordEvent(MAJOR_MODE_EVENT.majorModeSwitched, {\n 'harness.major_mode.previous': harness.majorMode,\n 'harness.major_mode': picked,\n 'harness.layers': selected.join(','),\n 'harness.major_mode.stale': true,\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n ctx.ui.setStatus(\n STATUS_KEY,\n colorStatus(ctx.ui.theme, harness.majorMode, harness.domains, harness.profile, true),\n );\n if (dependencies.supervisedRelaunchAvailable()) {\n const target = picked;\n performRelaunch = () => dependencies.requestSupervisedRelaunch(target, plan.operationId);\n }\n ctx.ui.notify(\n applySummary(picked, selected, true, composed, plan.strategy, performRelaunch !== undefined),\n 'info',\n );\n return 'queued';\n }\n const [{ applyMajorMode }, { persistHarnessSelection }] = await Promise.all([\n dependencies.loadSelectionSwitch(),\n dependencies.loadConfigJournal(),\n ]);\n const transition: DoomConfigPendingSelection = {\n version: 1,\n operationId: plan.operationId,\n active: selectionFromSnapshot(plan.previous),\n target: selectionFromSnapshot(plan.candidate),\n strategy: plan.strategy ?? 'pi-reload',\n phase: 'pending',\n };\n const activeConfig = loadMajorModesConfig(harness.root ?? ctx.cwd);\n const snapshot = snapshotHarnessState();\n const existingPending = currentContextAtExecution.pendingSelection;\n minorModeReloadHandoff = prepareMinorModeReloadHandoff(\n cordis,\n ctx.sessionManager.getSessionId(),\n coordinator.hostGeneration,\n plan.operationId,\n plan.previous.minorModes,\n );\n try {\n if (existingPending) supersedeDoomConfigTransition(pi, existingPending);\n appendDoomConfigTransition(pi, transition);\n const updated = applyMajorMode(\n activeConfig,\n picked,\n harness,\n plan.candidate.compositionFingerprint,\n plan.candidate.childActivation,\n );\n persistHarnessSelection(pi, updated);\n } catch (error) {\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n try {\n restoreHarnessStateSnapshot(snapshot);\n } catch (compensationError) {\n const detail =\n compensationError instanceof Error ? compensationError.message : String(compensationError);\n throw new Error(`Transition failed and compensation failed: ${detail}`, { cause: error });\n }\n appendDoomConfigTransition(pi, { ...transition, phase: 'aborted' });\n if (existingPending) appendDoomConfigTransition(pi, existingPending);\n throw error;\n }\n\n void telemetry.recordEvent(MAJOR_MODE_EVENT.majorModeSwitched, {\n 'harness.major_mode.previous': majorMode,\n 'harness.major_mode': picked,\n 'harness.layers': selected.join(','),\n 'harness.major_mode.stale': stale,\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n ctx.ui.setStatus(STATUS_KEY, colorStatus(ctx.ui.theme, picked, domains, profile, false));\n ctx.ui.notify(applySummary(picked, selected, false, composed, plan.strategy), 'info');\n // Reload must be the command handler's terminal action. Pi invalidates\n // this command context as soon as the replacement session is active.\n reloadRequested = true;\n return 'applied';\n },\n );\n if (result.outcome === 'rejected' || result.outcome === 'stale') throw transitionError(result);\n } catch (error) {\n reloadRequested = false;\n performRelaunch = undefined;\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n if (!token) throw error;\n if (sessionIdentity) dependencies.reloadHandoffs.discard(token, sessionIdentity);\n ctx.ui.notify(errorMessage(error), 'error');\n }\n\n if (reloadRequested) {\n try {\n await ctx.waitForIdle();\n // The replacement session acknowledges the pending journal after its\n // bootstrap harness is active. Do not touch ctx after this await.\n await ctx.reload();\n } catch (error) {\n minorModeReloadHandoff?.discard();\n throw error;\n }\n }\n if (performRelaunch) {\n // Written only at idle: the supervisor ends this agent's input for a\n // graceful exit the moment the file appears, then respawns it with the\n // pending major mode; the replacement resumes the session and\n // acknowledges the journal.\n await ctx.waitForIdle();\n if (performRelaunch()) ctx.shutdown();\n }\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent"
|
|
|
4
4
|
import { VoiceReloadHandoffStore } from "@agimon-ai/doompi-extension-contracts/voice-reload-handoff";
|
|
5
5
|
import { Context } from "@deepseek-ai/cordis";
|
|
6
6
|
//#region src/commands/majorModeCommand.d.ts
|
|
7
|
-
interface MajorModeCommandDependencies {
|
|
7
|
+
export interface MajorModeCommandDependencies {
|
|
8
8
|
readonly cordisContext: () => Context;
|
|
9
9
|
readonly currentView: (ctx: ExtensionContext) => Promise<MajorModeView>;
|
|
10
10
|
readonly reloadHandoffs: VoiceReloadHandoffStore;
|
|
@@ -12,8 +12,11 @@ interface MajorModeCommandDependencies {
|
|
|
12
12
|
readonly loadSelectionSwitch: () => Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')>;
|
|
13
13
|
readonly loadConfigJournal: () => Promise<typeof import('@agimon-ai/doompi-config/piContext')>;
|
|
14
14
|
readonly resolveLayers: (config: MajorModeView['config'], majorMode: string) => string[];
|
|
15
|
+
/** Whether an owning process supervisor listens for relaunch requests. */
|
|
16
|
+
readonly supervisedRelaunchAvailable: () => boolean;
|
|
17
|
+
/** Asks the supervisor to relaunch with the picked mode; call only at idle. */
|
|
18
|
+
readonly requestSupervisedRelaunch: (majorMode: string, operationId: string) => boolean;
|
|
15
19
|
}
|
|
16
|
-
declare function registerMajorModeCommand(pi: ExtensionAPI, telemetry: MajorModeTelemetry, dependencies: MajorModeCommandDependencies): void;
|
|
20
|
+
export declare function registerMajorModeCommand(pi: ExtensionAPI, telemetry: MajorModeTelemetry, dependencies: MajorModeCommandDependencies): void;
|
|
17
21
|
//#endregion
|
|
18
|
-
export { MajorModeCommandDependencies, registerMajorModeCommand };
|
|
19
22
|
//# sourceMappingURL=majorModeCommand.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"majorModeCommand.d.cts","names":[],"sources":["../../src/commands/majorModeCommand.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"majorModeCommand.d.cts","names":[],"sources":["../../src/commands/majorModeCommand.ts"],"mappings":";;;;;;iBA2CiB;WACN,qBAAqB;WACrB,cAAc,KAAK,qBAAqB,QAAQ;WAChD,gBAAgB;WAChB,kBAAkB;WAClB,2BAA2B;WAC3B,yBAAyB;WACzB,gBAAgB,QAAQ,yBAAyB;;WAEjD;;WAEA,4BAA4B,mBAAmB;;wBAG1C,yBACd,IAAI,cACJ,WAAW,oBACX,cAAc"}
|
|
@@ -4,7 +4,7 @@ import { VoiceReloadHandoffStore } from "@agimon-ai/doompi-extension-contracts/v
|
|
|
4
4
|
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
import { Context } from "@deepseek-ai/cordis";
|
|
6
6
|
//#region src/commands/majorModeCommand.d.ts
|
|
7
|
-
interface MajorModeCommandDependencies {
|
|
7
|
+
export interface MajorModeCommandDependencies {
|
|
8
8
|
readonly cordisContext: () => Context;
|
|
9
9
|
readonly currentView: (ctx: ExtensionContext) => Promise<MajorModeView>;
|
|
10
10
|
readonly reloadHandoffs: VoiceReloadHandoffStore;
|
|
@@ -12,8 +12,11 @@ interface MajorModeCommandDependencies {
|
|
|
12
12
|
readonly loadSelectionSwitch: () => Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')>;
|
|
13
13
|
readonly loadConfigJournal: () => Promise<typeof import('@agimon-ai/doompi-config/piContext')>;
|
|
14
14
|
readonly resolveLayers: (config: MajorModeView['config'], majorMode: string) => string[];
|
|
15
|
+
/** Whether an owning process supervisor listens for relaunch requests. */
|
|
16
|
+
readonly supervisedRelaunchAvailable: () => boolean;
|
|
17
|
+
/** Asks the supervisor to relaunch with the picked mode; call only at idle. */
|
|
18
|
+
readonly requestSupervisedRelaunch: (majorMode: string, operationId: string) => boolean;
|
|
15
19
|
}
|
|
16
|
-
declare function registerMajorModeCommand(pi: ExtensionAPI, telemetry: MajorModeTelemetry, dependencies: MajorModeCommandDependencies): void;
|
|
20
|
+
export declare function registerMajorModeCommand(pi: ExtensionAPI, telemetry: MajorModeTelemetry, dependencies: MajorModeCommandDependencies): void;
|
|
17
21
|
//#endregion
|
|
18
|
-
export { MajorModeCommandDependencies, registerMajorModeCommand };
|
|
19
22
|
//# sourceMappingURL=majorModeCommand.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"majorModeCommand.d.mts","names":[],"sources":["../../src/commands/majorModeCommand.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"majorModeCommand.d.mts","names":[],"sources":["../../src/commands/majorModeCommand.ts"],"mappings":";;;;;;iBA2CiB;WACN,qBAAqB;WACrB,cAAc,KAAK,qBAAqB,QAAQ;WAChD,gBAAgB;WAChB,kBAAkB;WAClB,2BAA2B;WAC3B,yBAAyB;WACzB,gBAAgB,QAAQ,yBAAyB;;WAEjD;;WAEA,4BAA4B,mBAAmB;;wBAG1C,yBACd,IAAI,cACJ,WAAW,oBACX,cAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{MAJOR_MODE_COMMAND as e,applySummary as t,errorMessage as n,majorModeItems as r,majorModeOptionLabel as i,majorModeSummary as a,optionName as o,voiceSwitchToken as s}from"../services/majorModeText.mjs";import{STATUS_KEY as c,colorStatus as l}from"../services/statusLine.mjs";import{MAJOR_MODE_EVENT as u}from"../types/telemetry.mjs";import{bindPendingSelection as d,clearPendingSelection as f,selectionFromSnapshot as p}from"../services/pendingSelection.mjs";import"../types/majorMode.mjs";import{restoreHarnessStateSnapshot as m,snapshotHarnessState as h}from"@agimon-ai/doompi-config/harnessStore";import{appendDoomConfigTransition as g,replaceDoomConfigContext as _,requireDoomConfigContext as v,supersedeDoomConfigTransition as y}from"@agimon-ai/doompi-config/piContext";import{prepareMinorModeReloadHandoff as b,requireDoomTransitionCoordinator as x}from"@agimon-ai/doompi-extension-contracts/transition";import{readDoomVoiceToolsService as S}from"@agimon-ai/doompi-extension-contracts/voice-tools";import{loadMajorModesConfig as C}from"@agimon-ai/doompi-config/majorModes";import{alreadyComposed as w}from"@agimon-ai/doompi-extension-contracts/child-process";function T(e){return Error(`Major-mode transition was ${e.outcome}: ${e.diagnostics.join(`, `)}`)}function E(E,D,O){E.registerCommand(e,{description:`Pick a named major mode`,handler:async(k,A)=>{let j;try{j=s(k)}catch(e){A.ui.notify(n(e),`error`);return}if(k.trim()&&!j){A.ui.notify(`Usage: /${e}`,`warning`);return}let M=A.sessionManager.getSessionId(),N=O.cordisContext(),P,F,I,L=!1;try{let{config:e,majorMode:n,domains:s,profile:k}=await O.currentView(A),
|
|
1
|
+
import{MAJOR_MODE_COMMAND as e,applySummary as t,errorMessage as n,majorModeItems as r,majorModeOptionLabel as i,majorModeSummary as a,optionName as o,voiceSwitchToken as s}from"../services/majorModeText.mjs";import{STATUS_KEY as c,colorStatus as l}from"../services/statusLine.mjs";import{MAJOR_MODE_EVENT as u}from"../types/telemetry.mjs";import{bindPendingSelection as d,clearPendingSelection as f,selectionFromSnapshot as p}from"../services/pendingSelection.mjs";import"../types/majorMode.mjs";import{restoreHarnessStateSnapshot as m,snapshotHarnessState as h}from"@agimon-ai/doompi-config/harnessStore";import{appendDoomConfigTransition as g,replaceDoomConfigContext as _,requireDoomConfigContext as v,supersedeDoomConfigTransition as y}from"@agimon-ai/doompi-config/piContext";import{prepareMinorModeReloadHandoff as b,requireDoomTransitionCoordinator as x}from"@agimon-ai/doompi-extension-contracts/transition";import{readDoomVoiceToolsService as S}from"@agimon-ai/doompi-extension-contracts/voice-tools";import{loadMajorModesConfig as C}from"@agimon-ai/doompi-config/majorModes";import{alreadyComposed as w}from"@agimon-ai/doompi-extension-contracts/child-process";function T(e){return Error(`Major-mode transition was ${e.outcome}: ${e.diagnostics.join(`, `)}`)}function E(E,D,O){E.registerCommand(e,{description:`Pick a named major mode`,handler:async(k,A)=>{let j;try{j=s(k)}catch(e){A.ui.notify(n(e),`error`);return}if(k.trim()&&!j){A.ui.notify(`Usage: /${e}`,`warning`);return}let M=A.sessionManager.getSessionId(),N=O.cordisContext(),P,F,I,L=!1,R;try{let{config:e,majorMode:n,domains:s,profile:k}=await O.currentView(A),z=Object.keys(e.majorMode),B;if(j){let e=S(N)?.readSession(M);if(e&&(P={sessionId:M,hostGeneration:e.hostGeneration}),F=P?O.reloadHandoffs.accept(j,P):void 0,F?.kind!==`major-mode-switch`||!F.majorMode)throw Error(`The voice major-mode switch token is stale or belongs to another session.`);B=F.majorMode}else{let t=`Major mode (current: ${n})`;B=(A.mode===`tui`?await O.loadPicker().then(({MatrixPickerComponent:i})=>A.ui.custom((a,o,s,c)=>new i({title:t,items:r(e,z),selected:[n],multi:!1},o,s,c))):[o(await A.ui.select(t,z.map(t=>i(t,e.majorMode[t]?.layers??[],n)))??``)])?.[0]}if(!B)return;let V=w();if(B===n){j&&P&&O.reloadHandoffs.discard(j,P),f(E,O.cordisContext()),A.ui.notify(a(B,O.resolveLayers(e,B),n,V),`info`);return}let H=x(N),U=await H.execute({sessionId:A.sessionManager.getSessionId(),hostGeneration:H.hostGeneration,operationId:F?.operationId??crypto.randomUUID(),source:F?`voice`:`command`,target:{axis:`major-mode`,majorMode:B}},async(e,r)=>{let i=[...r.candidate.layers],a=r.externalRelaunchRequired,o=v(N),f=o.harness;if(r.strategy===`process-relaunch`){let e={version:1,operationId:r.operationId,active:p(r.previous),target:p(r.candidate),strategy:r.strategy,phase:`pending`},n=v(N).pendingSelection;if(n&&y(E,n),g(E,e),_(N,d(v(N),e)),D.recordEvent(u.majorModeSwitched,{"harness.major_mode.previous":f.majorMode,"harness.major_mode":B,"harness.layers":i.join(`,`),"harness.major_mode.stale":!0,"harness.transition.disposition":r.disposition,"harness.transition.operation_id":r.operationId}),A.ui.setStatus(c,l(A.ui.theme,f.majorMode,f.domains,f.profile,!0)),O.supervisedRelaunchAvailable()){let e=B;R=()=>O.requestSupervisedRelaunch(e,r.operationId)}return A.ui.notify(t(B,i,!0,V,r.strategy,R!==void 0),`info`),`queued`}let[{applyMajorMode:x},{persistHarnessSelection:S}]=await Promise.all([O.loadSelectionSwitch(),O.loadConfigJournal()]),w={version:1,operationId:r.operationId,active:p(r.previous),target:p(r.candidate),strategy:r.strategy??`pi-reload`,phase:`pending`},T=C(f.root??A.cwd),j=h(),M=o.pendingSelection;I=b(N,A.sessionManager.getSessionId(),H.hostGeneration,r.operationId,r.previous.minorModes);try{M&&y(E,M),g(E,w),S(E,x(T,B,f,r.candidate.compositionFingerprint,r.candidate.childActivation))}catch(e){I?.discard(),I=void 0;try{m(j)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`Transition failed and compensation failed: ${n}`,{cause:e})}throw g(E,{...w,phase:`aborted`}),M&&g(E,M),e}return D.recordEvent(u.majorModeSwitched,{"harness.major_mode.previous":n,"harness.major_mode":B,"harness.layers":i.join(`,`),"harness.major_mode.stale":a,"harness.transition.disposition":r.disposition,"harness.transition.operation_id":r.operationId}),A.ui.setStatus(c,l(A.ui.theme,B,s,k,!1)),A.ui.notify(t(B,i,!1,V,r.strategy),`info`),L=!0,`applied`});if(U.outcome===`rejected`||U.outcome===`stale`)throw T(U)}catch(e){if(L=!1,R=void 0,I?.discard(),I=void 0,!j)throw e;P&&O.reloadHandoffs.discard(j,P),A.ui.notify(n(e),`error`)}if(L)try{await A.waitForIdle(),await A.reload()}catch(e){throw I?.discard(),e}R&&(await A.waitForIdle(),R()&&A.shutdown())}})}export{E as registerMajorModeCommand};
|
|
2
2
|
//# sourceMappingURL=majorModeCommand.mjs.map
|