@agimon-ai/doompi-profile 0.0.1-alpha.46 → 0.0.1-alpha.48
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 +2 -0
- package/dist/api-contracts.cjs +1 -0
- package/dist/api-contracts.d.cts +2 -0
- package/dist/api-contracts.d.mts +2 -0
- package/dist/api-contracts.mjs +1 -0
- package/dist/controllers/identityEntry.cjs +2 -0
- package/dist/controllers/identityEntry.cjs.map +1 -0
- package/dist/controllers/identityEntry.mjs +2 -0
- package/dist/controllers/identityEntry.mjs.map +1 -0
- package/dist/controllers/personaRuntime.cjs +2 -0
- package/dist/controllers/personaRuntime.cjs.map +1 -0
- package/dist/controllers/personaRuntime.mjs +2 -0
- package/dist/controllers/personaRuntime.mjs.map +1 -0
- package/dist/controllers/profileCommand.cjs +2 -0
- package/dist/controllers/profileCommand.cjs.map +1 -0
- package/dist/controllers/profileCommand.mjs +2 -0
- package/dist/controllers/profileCommand.mjs.map +1 -0
- package/dist/controllers/profileRuntime.cjs +2 -0
- package/dist/controllers/profileRuntime.cjs.map +1 -0
- package/dist/controllers/profileRuntime.mjs +2 -0
- package/dist/controllers/profileRuntime.mjs.map +1 -0
- package/dist/controllers/profileServer.cjs +2 -0
- package/dist/controllers/profileServer.cjs.map +1 -0
- package/dist/controllers/profileServer.mjs +2 -0
- package/dist/controllers/profileServer.mjs.map +1 -0
- package/dist/controllers/voiceTool.cjs +2 -0
- package/dist/controllers/voiceTool.cjs.map +1 -0
- package/dist/controllers/voiceTool.mjs +2 -0
- package/dist/controllers/voiceTool.mjs.map +1 -0
- package/dist/extensions/persona.cjs +2 -1
- package/dist/extensions/persona.cjs.map +1 -0
- package/dist/extensions/persona.d.cts +6 -2
- package/dist/extensions/persona.d.cts.map +1 -0
- package/dist/extensions/persona.d.mts +6 -2
- package/dist/extensions/persona.d.mts.map +1 -0
- package/dist/extensions/persona.mjs +2 -1
- package/dist/extensions/persona.mjs.map +1 -0
- package/dist/extensions/pi.cjs +2 -1
- package/dist/extensions/pi.cjs.map +1 -0
- package/dist/extensions/pi.d.cts +6 -2
- package/dist/extensions/pi.d.cts.map +1 -0
- package/dist/extensions/pi.d.mts +6 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +2 -1
- package/dist/extensions/pi.mjs.map +1 -0
- package/dist/extensions/server.cjs +2 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.cts +5 -0
- package/dist/extensions/server.d.cts.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +2 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -5
- package/dist/index.d.mts +3 -5
- package/dist/index.mjs +1 -1
- package/dist/schemas/apiContracts.cjs +2 -0
- package/dist/schemas/apiContracts.cjs.map +1 -0
- package/dist/schemas/apiContracts.d.cts +53 -0
- package/dist/schemas/apiContracts.d.cts.map +1 -0
- package/dist/schemas/apiContracts.d.mts +53 -0
- package/dist/schemas/apiContracts.d.mts.map +1 -0
- package/dist/schemas/apiContracts.mjs +2 -0
- package/dist/schemas/apiContracts.mjs.map +1 -0
- package/dist/schemas/profileVoiceTools.cjs +1 -1
- package/dist/schemas/profileVoiceTools.cjs.map +1 -1
- package/dist/schemas/profileVoiceTools.mjs +1 -1
- package/dist/schemas/profileVoiceTools.mjs.map +1 -1
- package/dist/{adapters/telemetry/logSinkTelemetry.cjs → services/logSinkTelemetry/index.cjs} +1 -1
- package/dist/services/logSinkTelemetry/index.cjs.map +1 -0
- package/dist/{adapters/telemetry/logSinkTelemetry.d.cts → services/logSinkTelemetry/index.d.cts} +2 -2
- package/dist/services/logSinkTelemetry/index.d.cts.map +1 -0
- package/dist/{adapters/telemetry/logSinkTelemetry.d.mts → services/logSinkTelemetry/index.d.mts} +2 -2
- package/dist/services/logSinkTelemetry/index.d.mts.map +1 -0
- package/dist/{adapters/telemetry/logSinkTelemetry.mjs → services/logSinkTelemetry/index.mjs} +1 -1
- package/dist/services/logSinkTelemetry/index.mjs.map +1 -0
- package/dist/services/packageResources/index.cjs +2 -0
- package/dist/services/packageResources/index.cjs.map +1 -0
- package/dist/services/packageResources/index.mjs +2 -0
- package/dist/services/packageResources/index.mjs.map +1 -0
- package/dist/services/{profileText.cjs → profileText/index.cjs} +1 -1
- package/dist/services/profileText/index.cjs.map +1 -0
- package/dist/services/{profileText.d.cts → profileText/index.d.cts} +2 -2
- package/dist/services/profileText/index.d.cts.map +1 -0
- package/dist/services/{profileText.d.mts → profileText/index.d.mts} +2 -2
- package/dist/services/profileText/index.d.mts.map +1 -0
- package/dist/services/{profileText.mjs → profileText/index.mjs} +1 -1
- package/dist/services/profileText/index.mjs.map +1 -0
- package/package.json +36 -11
- package/src/{web/index.ts → extensions/web.ts} +6 -4
- package/src/web/tsconfig.json +1 -1
- package/dist/adapters/pi/extension.cjs +0 -2
- package/dist/adapters/pi/extension.cjs.map +0 -1
- package/dist/adapters/pi/extension.d.cts +0 -10
- package/dist/adapters/pi/extension.d.cts.map +0 -1
- package/dist/adapters/pi/extension.d.mts +0 -10
- package/dist/adapters/pi/extension.d.mts.map +0 -1
- package/dist/adapters/pi/extension.mjs +0 -2
- package/dist/adapters/pi/extension.mjs.map +0 -1
- package/dist/adapters/pi/identityEntry.cjs +0 -2
- package/dist/adapters/pi/identityEntry.cjs.map +0 -1
- package/dist/adapters/pi/identityEntry.mjs +0 -2
- package/dist/adapters/pi/identityEntry.mjs.map +0 -1
- package/dist/adapters/pi/persona.cjs +0 -2
- package/dist/adapters/pi/persona.cjs.map +0 -1
- package/dist/adapters/pi/persona.d.cts +0 -8
- package/dist/adapters/pi/persona.d.cts.map +0 -1
- package/dist/adapters/pi/persona.d.mts +0 -8
- package/dist/adapters/pi/persona.d.mts.map +0 -1
- package/dist/adapters/pi/persona.mjs +0 -2
- package/dist/adapters/pi/persona.mjs.map +0 -1
- package/dist/adapters/pi/voiceTool.cjs +0 -2
- package/dist/adapters/pi/voiceTool.cjs.map +0 -1
- package/dist/adapters/pi/voiceTool.mjs +0 -2
- package/dist/adapters/pi/voiceTool.mjs.map +0 -1
- package/dist/adapters/telemetry/logSinkTelemetry.cjs.map +0 -1
- package/dist/adapters/telemetry/logSinkTelemetry.d.cts.map +0 -1
- package/dist/adapters/telemetry/logSinkTelemetry.d.mts.map +0 -1
- package/dist/adapters/telemetry/logSinkTelemetry.mjs.map +0 -1
- package/dist/commands/profileCommand.cjs +0 -2
- package/dist/commands/profileCommand.cjs.map +0 -1
- package/dist/commands/profileCommand.mjs +0 -2
- package/dist/commands/profileCommand.mjs.map +0 -1
- package/dist/services/profileText.cjs.map +0 -1
- package/dist/services/profileText.d.cts.map +0 -1
- package/dist/services/profileText.d.mts.map +0 -1
- package/dist/services/profileText.mjs.map +0 -1
- package/src/exports/webClient.ts +0 -1
package/README.md
CHANGED
|
@@ -98,3 +98,5 @@ it. It is not selectable from `.doom/modes.yaml`.
|
|
|
98
98
|
## License
|
|
99
99
|
|
|
100
100
|
MIT
|
|
101
|
+
|
|
102
|
+
Plugin entries live in `src/extensions`. Controllers connect host events and commands to services, while `src/exports` contains public helpers and types. Pi service bindings are owned by `definePiExtension`; startup mounts services before publishing commands and events, and disposal releases those bindings. The separate persona entry supports child sessions without a transition coordinator.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./schemas/apiContracts.cjs");exports.apiContracts=e.apiContracts,exports.default=e.apiContracts;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{apiContracts as e}from"./schemas/apiContracts.mjs";export{e as apiContracts,e as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require("@agimon-ai/doompi-core/profile-identity");function t(t,n,r,i){if(!n)return i;let a={profile:n,...r?.name===void 0?{}:{name:r.name},...r?.icon===void 0?{}:{icon:r.icon}},o=JSON.stringify(a);return o===i?i:(t.appendEntry(e.DOOM_PROFILE_IDENTITY_ENTRY_TYPE,a),o)}exports.publishProfileIdentity=t;
|
|
2
|
+
//# sourceMappingURL=identityEntry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identityEntry.cjs","names":["DOOM_PROFILE_IDENTITY_ENTRY_TYPE"],"sources":["../../src/controllers/identityEntry.ts"],"sourcesContent":["import type { PersonaIdentity } from '@agimon-ai/doompi-config/profiles';\nimport {\n DOOM_PROFILE_IDENTITY_ENTRY_TYPE,\n type ProfileIdentityProjection,\n} from '@agimon-ai/doompi-core/profile-identity';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\n/**\n * Journals the persona the session is speaking as.\n *\n * A profile switch reloads the session, so each activation publishes once on\n * session start and the entries accumulate in journal order. That order is the\n * whole mechanism: a cockpit folding the journal forward attributes every\n * assistant message to the identity most recently published before it, which is\n * how a message keeps the persona it was written under after a switch.\n *\n * For that to hold, the entry must not be treated as a projection. A projection\n * keeps only the latest record and replays that one, which would repaint the\n * entire transcript as the current persona.\n */\nexport function publishProfileIdentity(\n pi: Pick<ExtensionAPI, 'appendEntry'>,\n profile: string | undefined,\n identity: PersonaIdentity | undefined,\n published: string | undefined,\n): string | undefined {\n if (!profile) return published;\n\n const projection: ProfileIdentityProjection = {\n profile,\n ...(identity?.name === undefined ? {} : { name: identity.name }),\n ...(identity?.icon === undefined ? {} : { icon: identity.icon }),\n };\n const serialized = JSON.stringify(projection);\n // Reload republishes on every session start. Re-announcing an identity the\n // transcript already carries would add a seam where nothing changed.\n if (serialized === published) return published;\n pi.appendEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, projection);\n return serialized;\n}\n"],"mappings":"yDAoBA,SAAgB,EACd,EACA,EACA,EACA,EACoB,CACpB,GAAI,CAAC,EAAS,OAAO,EAErB,IAAM,EAAwC,CAC5C,UACA,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,EAC9D,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,CAChE,EACM,EAAa,KAAK,UAAU,CAAU,EAK5C,OAFI,IAAe,EAAkB,GACrC,EAAG,YAAYA,EAAAA,iCAAkC,CAAU,EACpD,EACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{DOOM_PROFILE_IDENTITY_ENTRY_TYPE as e}from"@agimon-ai/doompi-core/profile-identity";function t(t,n,r,i){if(!n)return i;let a={profile:n,...r?.name===void 0?{}:{name:r.name},...r?.icon===void 0?{}:{icon:r.icon}},o=JSON.stringify(a);return o===i?i:(t.appendEntry(e,a),o)}export{t as publishProfileIdentity};
|
|
2
|
+
//# sourceMappingURL=identityEntry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identityEntry.mjs","names":[],"sources":["../../src/controllers/identityEntry.ts"],"sourcesContent":["import type { PersonaIdentity } from '@agimon-ai/doompi-config/profiles';\nimport {\n DOOM_PROFILE_IDENTITY_ENTRY_TYPE,\n type ProfileIdentityProjection,\n} from '@agimon-ai/doompi-core/profile-identity';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\n/**\n * Journals the persona the session is speaking as.\n *\n * A profile switch reloads the session, so each activation publishes once on\n * session start and the entries accumulate in journal order. That order is the\n * whole mechanism: a cockpit folding the journal forward attributes every\n * assistant message to the identity most recently published before it, which is\n * how a message keeps the persona it was written under after a switch.\n *\n * For that to hold, the entry must not be treated as a projection. A projection\n * keeps only the latest record and replays that one, which would repaint the\n * entire transcript as the current persona.\n */\nexport function publishProfileIdentity(\n pi: Pick<ExtensionAPI, 'appendEntry'>,\n profile: string | undefined,\n identity: PersonaIdentity | undefined,\n published: string | undefined,\n): string | undefined {\n if (!profile) return published;\n\n const projection: ProfileIdentityProjection = {\n profile,\n ...(identity?.name === undefined ? {} : { name: identity.name }),\n ...(identity?.icon === undefined ? {} : { icon: identity.icon }),\n };\n const serialized = JSON.stringify(projection);\n // Reload republishes on every session start. Re-announcing an identity the\n // transcript already carries would add a seam where nothing changed.\n if (serialized === published) return published;\n pi.appendEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, projection);\n return serialized;\n}\n"],"mappings":"2FAoBA,SAAgB,EACd,EACA,EACA,EACA,EACoB,CACpB,GAAI,CAAC,EAAS,OAAO,EAErB,IAAM,EAAwC,CAC5C,UACA,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,EAC9D,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,CAChE,EACM,EAAa,KAAK,UAAU,CAAU,EAK5C,OAFI,IAAe,EAAkB,GACrC,EAAG,YAAY,EAAkC,CAAU,EACpD,EACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../types/telemetry.cjs");let n=require("@agimon-ai/doompi-core/config"),r=require("node:fs");r=e.__toESM(r,1);let i=require("@agimon-ai/doompi-config");function a(e,n){return{before_agent_start:async(a,o)=>{let{personaFile:s}=(0,i.requireDoomConfigContext)(n()).harness;if(s)try{let e=(await r.default.promises.readFile(s,`utf8`)).trim();return e?{systemPrompt:`${a.systemPrompt}\n\n${e}`}:void 0}catch(n){let r=n instanceof Error?n.message:String(n);e.recordError(t.PROFILE_EVENT.personaReadFailed,n),process.stderr.write(`[pi-persona] could not read ${s}: ${r}\n`);return}}}}function o(e){let t;return{services:[e=>{e.inject([n.DOOM_CONFIG_SERVICE],e=>(t=e,()=>{t===e&&(t=void 0)}))}],events:a(e,()=>{if(!t)throw Error(`Doom persona runtime is waiting for the session config service.`);return t})}}exports.createPersonaEvents=a,exports.createPersonaRuntime=o;
|
|
2
|
+
//# sourceMappingURL=personaRuntime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personaRuntime.cjs","names":["requireDoomConfigContext","fs","PROFILE_EVENT","DOOM_CONFIG_SERVICE"],"sources":["../../src/controllers/personaRuntime.ts"],"sourcesContent":["import fs from 'node:fs';\n\nimport { requireDoomConfigContext } from '@agimon-ai/doompi-config';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-core/config';\nimport { type PiEventHandlers, type PiPluginContributions } from '@agimon-ai/doompi-core/pi-extension';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\n\n/**\n * Appends the selected profile's persona to the system prompt.\n *\n * The harness writes the assembled persona to a file in the run directory and\n * records the path in the harness state, so agents/ stays the single source of\n * persona material and is never copied into config.\n *\n * This is a separate Pi entry from the /profile command because detached\n * children need the persona without the command: they have no transition\n * coordinator to run a switch through.\n */\n\nexport function createPersonaEvents(telemetry: ProfileTelemetry, cordisContext: () => Context): PiEventHandlers {\n return {\n before_agent_start: async (event, _ctx) => {\n const { personaFile } = requireDoomConfigContext(cordisContext()).harness;\n if (!personaFile) return undefined;\n\n try {\n const content = (await fs.promises.readFile(personaFile, 'utf8')).trim();\n return content ? { systemPrompt: `${event.systemPrompt}\\n\\n${content}` } : undefined;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n void telemetry.recordError(PROFILE_EVENT.personaReadFailed, error);\n process.stderr.write(`[pi-persona] could not read ${personaFile}: ${reason}\\n`);\n return undefined;\n }\n },\n };\n}\n\nexport function createPersonaRuntime(telemetry: ProfileTelemetry): PiPluginContributions<ProfileTelemetry> {\n let activeContext: Context | undefined;\n return {\n services: [\n (cordis: Context) => {\n cordis.inject([DOOM_CONFIG_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n },\n ],\n events: createPersonaEvents(telemetry, () => {\n if (!activeContext) throw new Error('Doom persona runtime is waiting for the session config service.');\n return activeContext;\n }),\n };\n}\n"],"mappings":"wNAqBA,SAAgB,EAAoB,EAA6B,EAA+C,CAC9G,MAAO,CACL,mBAAoB,MAAO,EAAO,IAAS,CACzC,GAAM,CAAE,gBAAA,EAAgBA,EAAAA,yBAAAA,CAAyB,EAAc,CAAC,CAAC,CAAC,QAC7D,KAEL,GAAI,CACF,IAAM,GAAW,MAAMC,EAAAA,QAAG,SAAS,SAAS,EAAa,MAAM,EAAA,CAAG,KAAK,EACvE,OAAO,EAAU,CAAE,aAAc,GAAG,EAAM,aAAa,MAAM,GAAU,EAAI,IAAA,EAC7E,OAAS,EAAO,CACd,IAAM,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACpE,EAAe,YAAYC,EAAAA,cAAc,kBAAmB,CAAK,EACjE,QAAQ,OAAO,MAAM,+BAA+B,EAAY,IAAI,EAAO,GAAG,EAC9E,MACF,CACF,CACF,CACF,CAEA,SAAgB,EAAqB,EAAsE,CACzG,IAAI,EACJ,MAAO,CACL,SAAU,CACP,GAAoB,CACnB,EAAO,OAAO,CAACC,EAAAA,mBAAmB,EAAI,IACpC,EAAgB,MACH,CACP,IAAkB,IAAS,EAAgB,IAAA,GACjD,EACD,CACH,CACF,EACA,OAAQ,EAAoB,MAAiB,CAC3C,GAAI,CAAC,EAAe,MAAU,MAAM,iEAAiE,EACrG,OAAO,CACT,CAAC,CACH,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{PROFILE_EVENT as e}from"../types/telemetry.mjs";import{DOOM_CONFIG_SERVICE as t}from"@agimon-ai/doompi-core/config";import n from"node:fs";import{requireDoomConfigContext as r}from"@agimon-ai/doompi-config";function i(t,i){return{before_agent_start:async(a,o)=>{let{personaFile:s}=r(i()).harness;if(s)try{let e=(await n.promises.readFile(s,`utf8`)).trim();return e?{systemPrompt:`${a.systemPrompt}\n\n${e}`}:void 0}catch(n){let r=n instanceof Error?n.message:String(n);t.recordError(e.personaReadFailed,n),process.stderr.write(`[pi-persona] could not read ${s}: ${r}\n`);return}}}}function a(e){let n;return{services:[e=>{e.inject([t],e=>(n=e,()=>{n===e&&(n=void 0)}))}],events:i(e,()=>{if(!n)throw Error(`Doom persona runtime is waiting for the session config service.`);return n})}}export{i as createPersonaEvents,a as createPersonaRuntime};
|
|
2
|
+
//# sourceMappingURL=personaRuntime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personaRuntime.mjs","names":[],"sources":["../../src/controllers/personaRuntime.ts"],"sourcesContent":["import fs from 'node:fs';\n\nimport { requireDoomConfigContext } from '@agimon-ai/doompi-config';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-core/config';\nimport { type PiEventHandlers, type PiPluginContributions } from '@agimon-ai/doompi-core/pi-extension';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\n\n/**\n * Appends the selected profile's persona to the system prompt.\n *\n * The harness writes the assembled persona to a file in the run directory and\n * records the path in the harness state, so agents/ stays the single source of\n * persona material and is never copied into config.\n *\n * This is a separate Pi entry from the /profile command because detached\n * children need the persona without the command: they have no transition\n * coordinator to run a switch through.\n */\n\nexport function createPersonaEvents(telemetry: ProfileTelemetry, cordisContext: () => Context): PiEventHandlers {\n return {\n before_agent_start: async (event, _ctx) => {\n const { personaFile } = requireDoomConfigContext(cordisContext()).harness;\n if (!personaFile) return undefined;\n\n try {\n const content = (await fs.promises.readFile(personaFile, 'utf8')).trim();\n return content ? { systemPrompt: `${event.systemPrompt}\\n\\n${content}` } : undefined;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n void telemetry.recordError(PROFILE_EVENT.personaReadFailed, error);\n process.stderr.write(`[pi-persona] could not read ${personaFile}: ${reason}\\n`);\n return undefined;\n }\n },\n };\n}\n\nexport function createPersonaRuntime(telemetry: ProfileTelemetry): PiPluginContributions<ProfileTelemetry> {\n let activeContext: Context | undefined;\n return {\n services: [\n (cordis: Context) => {\n cordis.inject([DOOM_CONFIG_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n },\n ],\n events: createPersonaEvents(telemetry, () => {\n if (!activeContext) throw new Error('Doom persona runtime is waiting for the session config service.');\n return activeContext;\n }),\n };\n}\n"],"mappings":"sNAqBA,SAAgB,EAAoB,EAA6B,EAA+C,CAC9G,MAAO,CACL,mBAAoB,MAAO,EAAO,IAAS,CACzC,GAAM,CAAE,eAAgB,EAAyB,EAAc,CAAC,CAAC,CAAC,QAC7D,KAEL,GAAI,CACF,IAAM,GAAW,MAAM,EAAG,SAAS,SAAS,EAAa,MAAM,EAAA,CAAG,KAAK,EACvE,OAAO,EAAU,CAAE,aAAc,GAAG,EAAM,aAAa,MAAM,GAAU,EAAI,IAAA,EAC7E,OAAS,EAAO,CACd,IAAM,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACpE,EAAe,YAAY,EAAc,kBAAmB,CAAK,EACjE,QAAQ,OAAO,MAAM,+BAA+B,EAAY,IAAI,EAAO,GAAG,EAC9E,MACF,CACF,CACF,CACF,CAEA,SAAgB,EAAqB,EAAsE,CACzG,IAAI,EACJ,MAAO,CACL,SAAU,CACP,GAAoB,CACnB,EAAO,OAAO,CAAC,CAAmB,EAAI,IACpC,EAAgB,MACH,CACP,IAAkB,IAAS,EAAgB,IAAA,GACjD,EACD,CACH,CACF,EACA,OAAQ,EAAoB,MAAiB,CAC3C,GAAI,CAAC,EAAe,MAAU,MAAM,iEAAiE,EACrG,OAAO,CACT,CAAC,CACH,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/profileText/index.cjs"),t=require("../types/telemetry.cjs");let n=require("@agimon-ai/doompi-config/piContext"),r=require("@agimon-ai/doompi-core/transition"),i=require("@agimon-ai/doompi-core/voice-tools"),a=require("@agimon-ai/doompi-minor-mode"),o=require("@agimon-ai/doompi-minor-mode/reload-handoff");const s=`warning`,c=`info`,l=`.doom/profiles.yaml`;function u(){let e,t,n,r,i;return{harnessStore:()=>e??=import(`@agimon-ai/doompi-config/harnessStore`),journal:()=>t??=import(`@agimon-ai/doompi-config/piContext`),picker:()=>n??=import(`@agimon-ai/doompi-ui/matrix-picker`),profiles:()=>r??=import(`@agimon-ai/doompi-config/profiles`),selection:()=>i??=import(`@agimon-ai/doompi-config/selectionSwitch`)}}async function d(t,n,r,i){let a=e.profileTitle(r);if(t.mode!==`tui`)return t.ui.select(a,n.map(e=>e.name));let{MatrixPickerComponent:o}=await i();return(await t.ui.custom((t,i,s,c)=>new o({title:a,items:e.profileItems(n),selected:r?[r]:[],multi:!1},i,s,c)))?.[0]}function f(f,p,m,h){let g=u();return[`profile`,{description:`Show profiles and load a different persona and environment`,handler:async(u,_)=>{let v=m(),y=(0,n.requireDoomConfigContext)(v).harness,[{requireHarnessRoot:b},{loadProfiles:x}]=await Promise.all([g.harnessStore(),g.profiles()]),S=b(y),C=y.profile,w=_.sessionManager.getSessionId(),T=h?e.voiceSwitchToken(u):void 0,E,D;try{D=x(S)}catch(e){let n=e instanceof Error?e.message:String(e);p.recordError(t.PROFILE_EVENT.profileLoadFailed,e),_.ui.notify(`Could not load ${l}: ${n}`,s);return}if(D.length===0){_.ui.notify(`No profiles found in ${l}.`,s);return}let O;if(T&&h){let e=(0,i.readDoomVoiceToolsService)(v)?.readSession(w);if(E=e?h.accept(T,{sessionId:w,hostGeneration:e.hostGeneration}):void 0,E?.kind!==`profile-switch`||!E.profile)throw Error(`The voice profile switch token is stale or belongs to another session.`);O=E.profile}else O=await d(_,D,C,g.picker);let k=D.find(e=>e.name===O);if(!k)return;if(k.name===C){_.ui.notify(e.profileSummary(k),c);return}let A=(0,r.requireDoomTransitionCoordinator)(v),j,M=await A.execute({sessionId:_.sessionManager.getSessionId(),hostGeneration:A.hostGeneration,operationId:crypto.randomUUID(),source:_.mode===`tui`?`ui`:`command`,target:{axis:`profile`,profile:k.name}},async(e,n)=>{j=(0,o.prepareMinorModeReloadHandoff)(v,_.sessionManager.getSessionId(),A.hostGeneration,n.operationId,(0,a.readMinorModeCatalog)(v)?.getSnapshot());try{let{applyProfile:e}=await g.selection();_.ui.notify(await e(k,y),c);let{persistHarnessSelection:r}=await g.journal();return r(f,{...y,profile:k.name}),p.recordEvent(t.PROFILE_EVENT.profileApplied,{"harness.profile":k.name,...C?{"harness.profile.previous":C}:{},"harness.transition.disposition":n.disposition,"harness.transition.operation_id":n.operationId}),`applied`}catch(e){throw j?.discard(),j=void 0,e}});if(M.outcome===`rejected`||M.outcome===`stale`){j?.discard(),_.ui.notify(`Profile transition was ${M.outcome}: ${M.diagnostics.join(`, `)}`,s);return}if(M.outcome!==`applied`){j?.discard();return}try{await _.waitForIdle(),await _.reload()}catch(e){throw j?.discard(),e}}}]}exports.createProfileCommand=f;
|
|
2
|
+
//# sourceMappingURL=profileCommand.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileCommand.cjs","names":["profileTitle","profileItems","requireDoomConfigContext","voiceSwitchToken","PROFILE_EVENT","readDoomVoiceToolsService","profileSummary","requireDoomTransitionCoordinator","prepareMinorModeReloadHandoff","readMinorModeCatalog"],"sources":["../../src/controllers/profileCommand.ts"],"sourcesContent":["import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { AgentProfile } from '@agimon-ai/doompi-config/profiles';\nimport { requireDoomTransitionCoordinator } from '@agimon-ai/doompi-core/transition';\nimport type { VoiceReloadHandoff, VoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport { readDoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport {\n type MinorModeReloadHandoffHandle,\n prepareMinorModeReloadHandoff,\n} from '@agimon-ai/doompi-minor-mode/reload-handoff';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n PROFILE_SWITCH_HANDOFF_KIND,\n profileItems,\n profileSummary,\n profileTitle,\n voiceSwitchToken,\n} from '../services/profileText';\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\n\nconst WARNING = 'warning';\nconst INFO = 'info';\nconst PROFILE_CONFIG_PATH = '.doom/profiles.yaml';\n\n/**\n * The picker and everything behind it load on first use.\n *\n * Every session registers this command, but almost none of them run it, so the\n * profile catalogue, the TUI component and the switch stay off the startup path.\n */\nfunction lazyModules() {\n let harnessStore: Promise<typeof import('@agimon-ai/doompi-config/harnessStore')> | undefined;\n let journal: Promise<typeof import('@agimon-ai/doompi-config/piContext')> | undefined;\n let picker: Promise<typeof import('@agimon-ai/doompi-ui/matrix-picker')> | undefined;\n let profiles: Promise<typeof import('@agimon-ai/doompi-config/profiles')> | undefined;\n let selection: Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')> | undefined;\n return {\n harnessStore: () => (harnessStore ??= import('@agimon-ai/doompi-config/harnessStore')),\n journal: () => (journal ??= import('@agimon-ai/doompi-config/piContext')),\n picker: () => (picker ??= import('@agimon-ai/doompi-ui/matrix-picker')),\n profiles: () => (profiles ??= import('@agimon-ai/doompi-config/profiles')),\n selection: () => (selection ??= import('@agimon-ai/doompi-config/selectionSwitch')),\n };\n}\n\nasync function pickProfile(\n ctx: ExtensionContext,\n profiles: AgentProfile[],\n current: string | undefined,\n loadPicker: () => Promise<typeof import('@agimon-ai/doompi-ui/matrix-picker')>,\n): Promise<string | undefined> {\n const title = profileTitle(current);\n if (ctx.mode !== 'tui') {\n return ctx.ui.select(\n title,\n profiles.map((profile) => profile.name),\n );\n }\n const { MatrixPickerComponent } = await loadPicker();\n const chosen = await ctx.ui.custom<string[] | undefined>(\n (_tui, theme, keybindings, done) =>\n new MatrixPickerComponent(\n { title, items: profileItems(profiles), selected: current ? [current] : [], multi: false },\n theme,\n keybindings,\n done,\n ),\n );\n return chosen?.[0];\n}\n\nexport function createProfileCommand(\n pi: ExtensionAPI,\n telemetry: ProfileTelemetry,\n cordisContext: () => Context,\n reloadHandoffs?: VoiceReloadHandoffStore,\n): Parameters<ExtensionAPI['registerCommand']> {\n const load = lazyModules();\n\n return [\n 'profile',\n {\n description: 'Show profiles and load a different persona and environment',\n handler: async (args, ctx) => {\n const cordis = cordisContext();\n const state = requireDoomConfigContext(cordis).harness;\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([load.harnessStore(), load.profiles()]);\n const root = requireHarnessRoot(state);\n const current = state.profile;\n const sessionId = ctx.sessionManager.getSessionId();\n // A voice switch arrives as a bare token: the name never rides the text.\n const token = reloadHandoffs ? voiceSwitchToken(args) : undefined;\n let voiceHandoff: VoiceReloadHandoff | undefined;\n let profiles: AgentProfile[];\n try {\n profiles = loadProfiles(root);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n void telemetry.recordError(PROFILE_EVENT.profileLoadFailed, error);\n ctx.ui.notify(`Could not load ${PROFILE_CONFIG_PATH}: ${reason}`, WARNING);\n return;\n }\n\n if (profiles.length === 0) {\n ctx.ui.notify(`No profiles found in ${PROFILE_CONFIG_PATH}.`, WARNING);\n return;\n }\n\n let picked: string | undefined;\n if (token && reloadHandoffs) {\n const voiceSession = readDoomVoiceToolsService(cordis)?.readSession(sessionId);\n voiceHandoff = voiceSession\n ? reloadHandoffs.accept(token, { sessionId, hostGeneration: voiceSession.hostGeneration })\n : undefined;\n if (voiceHandoff?.kind !== PROFILE_SWITCH_HANDOFF_KIND || !voiceHandoff.profile) {\n throw new Error('The voice profile switch token is stale or belongs to another session.');\n }\n picked = voiceHandoff.profile;\n } else {\n picked = await pickProfile(ctx, profiles, current, load.picker);\n }\n const profile = profiles.find((candidate) => candidate.name === picked);\n if (!profile) return;\n if (profile.name === current) {\n ctx.ui.notify(profileSummary(profile), INFO);\n return;\n }\n\n const coordinator = requireDoomTransitionCoordinator(cordis);\n let minorModeReloadHandoff: MinorModeReloadHandoffHandle | undefined;\n const result = await coordinator.execute(\n {\n sessionId: ctx.sessionManager.getSessionId(),\n hostGeneration: coordinator.hostGeneration,\n operationId: crypto.randomUUID(),\n source: ctx.mode === 'tui' ? 'ui' : 'command',\n target: { axis: 'profile', profile: profile.name },\n },\n async (_request, plan) => {\n minorModeReloadHandoff = prepareMinorModeReloadHandoff(\n cordis,\n ctx.sessionManager.getSessionId(),\n coordinator.hostGeneration,\n plan.operationId,\n readMinorModeCatalog(cordis)?.getSnapshot(),\n );\n try {\n const { applyProfile } = await load.selection();\n ctx.ui.notify(await applyProfile(profile, state), INFO);\n const { persistHarnessSelection } = await load.journal();\n persistHarnessSelection(pi, { ...state, profile: profile.name });\n void telemetry.recordEvent(PROFILE_EVENT.profileApplied, {\n 'harness.profile': profile.name,\n ...(current ? { 'harness.profile.previous': current } : {}),\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n return 'applied';\n } catch (error) {\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n throw error;\n }\n },\n );\n if (result.outcome === 'rejected' || result.outcome === 'stale') {\n minorModeReloadHandoff?.discard();\n ctx.ui.notify(`Profile transition was ${result.outcome}: ${result.diagnostics.join(', ')}`, WARNING);\n return;\n }\n if (result.outcome !== 'applied') {\n minorModeReloadHandoff?.discard();\n return;\n }\n\n try {\n await ctx.waitForIdle();\n // Reload replaces the session and invalidates this command context.\n // Keep it as the handler's final action.\n await ctx.reload();\n } catch (error) {\n minorModeReloadHandoff?.discard();\n throw error;\n }\n },\n },\n ];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{profileItems as e,profileSummary as t,profileTitle as n,voiceSwitchToken as r}from"../services/profileText/index.mjs";import{PROFILE_EVENT as i}from"../types/telemetry.mjs";import{requireDoomConfigContext as a}from"@agimon-ai/doompi-config/piContext";import{requireDoomTransitionCoordinator as o}from"@agimon-ai/doompi-core/transition";import{readDoomVoiceToolsService as s}from"@agimon-ai/doompi-core/voice-tools";import{readMinorModeCatalog as c}from"@agimon-ai/doompi-minor-mode";import{prepareMinorModeReloadHandoff as l}from"@agimon-ai/doompi-minor-mode/reload-handoff";const u=`warning`,d=`info`,f=`.doom/profiles.yaml`;function p(){let e,t,n,r,i;return{harnessStore:()=>e??=import(`@agimon-ai/doompi-config/harnessStore`),journal:()=>t??=import(`@agimon-ai/doompi-config/piContext`),picker:()=>n??=import(`@agimon-ai/doompi-ui/matrix-picker`),profiles:()=>r??=import(`@agimon-ai/doompi-config/profiles`),selection:()=>i??=import(`@agimon-ai/doompi-config/selectionSwitch`)}}async function m(t,r,i,a){let o=n(i);if(t.mode!==`tui`)return t.ui.select(o,r.map(e=>e.name));let{MatrixPickerComponent:s}=await a();return(await t.ui.custom((t,n,a,c)=>new s({title:o,items:e(r),selected:i?[i]:[],multi:!1},n,a,c)))?.[0]}function h(e,n,h,g){let _=p();return[`profile`,{description:`Show profiles and load a different persona and environment`,handler:async(p,v)=>{let y=h(),b=a(y).harness,[{requireHarnessRoot:x},{loadProfiles:S}]=await Promise.all([_.harnessStore(),_.profiles()]),C=x(b),w=b.profile,T=v.sessionManager.getSessionId(),E=g?r(p):void 0,D,O;try{O=S(C)}catch(e){let t=e instanceof Error?e.message:String(e);n.recordError(i.profileLoadFailed,e),v.ui.notify(`Could not load ${f}: ${t}`,u);return}if(O.length===0){v.ui.notify(`No profiles found in ${f}.`,u);return}let k;if(E&&g){let e=s(y)?.readSession(T);if(D=e?g.accept(E,{sessionId:T,hostGeneration:e.hostGeneration}):void 0,D?.kind!==`profile-switch`||!D.profile)throw Error(`The voice profile switch token is stale or belongs to another session.`);k=D.profile}else k=await m(v,O,w,_.picker);let A=O.find(e=>e.name===k);if(!A)return;if(A.name===w){v.ui.notify(t(A),d);return}let j=o(y),M,N=await j.execute({sessionId:v.sessionManager.getSessionId(),hostGeneration:j.hostGeneration,operationId:crypto.randomUUID(),source:v.mode===`tui`?`ui`:`command`,target:{axis:`profile`,profile:A.name}},async(t,r)=>{M=l(y,v.sessionManager.getSessionId(),j.hostGeneration,r.operationId,c(y)?.getSnapshot());try{let{applyProfile:t}=await _.selection();v.ui.notify(await t(A,b),d);let{persistHarnessSelection:a}=await _.journal();return a(e,{...b,profile:A.name}),n.recordEvent(i.profileApplied,{"harness.profile":A.name,...w?{"harness.profile.previous":w}:{},"harness.transition.disposition":r.disposition,"harness.transition.operation_id":r.operationId}),`applied`}catch(e){throw M?.discard(),M=void 0,e}});if(N.outcome===`rejected`||N.outcome===`stale`){M?.discard(),v.ui.notify(`Profile transition was ${N.outcome}: ${N.diagnostics.join(`, `)}`,u);return}if(N.outcome!==`applied`){M?.discard();return}try{await v.waitForIdle(),await v.reload()}catch(e){throw M?.discard(),e}}}]}export{h as createProfileCommand};
|
|
2
|
+
//# sourceMappingURL=profileCommand.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileCommand.mjs","names":[],"sources":["../../src/controllers/profileCommand.ts"],"sourcesContent":["import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { AgentProfile } from '@agimon-ai/doompi-config/profiles';\nimport { requireDoomTransitionCoordinator } from '@agimon-ai/doompi-core/transition';\nimport type { VoiceReloadHandoff, VoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport { readDoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport {\n type MinorModeReloadHandoffHandle,\n prepareMinorModeReloadHandoff,\n} from '@agimon-ai/doompi-minor-mode/reload-handoff';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n PROFILE_SWITCH_HANDOFF_KIND,\n profileItems,\n profileSummary,\n profileTitle,\n voiceSwitchToken,\n} from '../services/profileText';\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\n\nconst WARNING = 'warning';\nconst INFO = 'info';\nconst PROFILE_CONFIG_PATH = '.doom/profiles.yaml';\n\n/**\n * The picker and everything behind it load on first use.\n *\n * Every session registers this command, but almost none of them run it, so the\n * profile catalogue, the TUI component and the switch stay off the startup path.\n */\nfunction lazyModules() {\n let harnessStore: Promise<typeof import('@agimon-ai/doompi-config/harnessStore')> | undefined;\n let journal: Promise<typeof import('@agimon-ai/doompi-config/piContext')> | undefined;\n let picker: Promise<typeof import('@agimon-ai/doompi-ui/matrix-picker')> | undefined;\n let profiles: Promise<typeof import('@agimon-ai/doompi-config/profiles')> | undefined;\n let selection: Promise<typeof import('@agimon-ai/doompi-config/selectionSwitch')> | undefined;\n return {\n harnessStore: () => (harnessStore ??= import('@agimon-ai/doompi-config/harnessStore')),\n journal: () => (journal ??= import('@agimon-ai/doompi-config/piContext')),\n picker: () => (picker ??= import('@agimon-ai/doompi-ui/matrix-picker')),\n profiles: () => (profiles ??= import('@agimon-ai/doompi-config/profiles')),\n selection: () => (selection ??= import('@agimon-ai/doompi-config/selectionSwitch')),\n };\n}\n\nasync function pickProfile(\n ctx: ExtensionContext,\n profiles: AgentProfile[],\n current: string | undefined,\n loadPicker: () => Promise<typeof import('@agimon-ai/doompi-ui/matrix-picker')>,\n): Promise<string | undefined> {\n const title = profileTitle(current);\n if (ctx.mode !== 'tui') {\n return ctx.ui.select(\n title,\n profiles.map((profile) => profile.name),\n );\n }\n const { MatrixPickerComponent } = await loadPicker();\n const chosen = await ctx.ui.custom<string[] | undefined>(\n (_tui, theme, keybindings, done) =>\n new MatrixPickerComponent(\n { title, items: profileItems(profiles), selected: current ? [current] : [], multi: false },\n theme,\n keybindings,\n done,\n ),\n );\n return chosen?.[0];\n}\n\nexport function createProfileCommand(\n pi: ExtensionAPI,\n telemetry: ProfileTelemetry,\n cordisContext: () => Context,\n reloadHandoffs?: VoiceReloadHandoffStore,\n): Parameters<ExtensionAPI['registerCommand']> {\n const load = lazyModules();\n\n return [\n 'profile',\n {\n description: 'Show profiles and load a different persona and environment',\n handler: async (args, ctx) => {\n const cordis = cordisContext();\n const state = requireDoomConfigContext(cordis).harness;\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([load.harnessStore(), load.profiles()]);\n const root = requireHarnessRoot(state);\n const current = state.profile;\n const sessionId = ctx.sessionManager.getSessionId();\n // A voice switch arrives as a bare token: the name never rides the text.\n const token = reloadHandoffs ? voiceSwitchToken(args) : undefined;\n let voiceHandoff: VoiceReloadHandoff | undefined;\n let profiles: AgentProfile[];\n try {\n profiles = loadProfiles(root);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n void telemetry.recordError(PROFILE_EVENT.profileLoadFailed, error);\n ctx.ui.notify(`Could not load ${PROFILE_CONFIG_PATH}: ${reason}`, WARNING);\n return;\n }\n\n if (profiles.length === 0) {\n ctx.ui.notify(`No profiles found in ${PROFILE_CONFIG_PATH}.`, WARNING);\n return;\n }\n\n let picked: string | undefined;\n if (token && reloadHandoffs) {\n const voiceSession = readDoomVoiceToolsService(cordis)?.readSession(sessionId);\n voiceHandoff = voiceSession\n ? reloadHandoffs.accept(token, { sessionId, hostGeneration: voiceSession.hostGeneration })\n : undefined;\n if (voiceHandoff?.kind !== PROFILE_SWITCH_HANDOFF_KIND || !voiceHandoff.profile) {\n throw new Error('The voice profile switch token is stale or belongs to another session.');\n }\n picked = voiceHandoff.profile;\n } else {\n picked = await pickProfile(ctx, profiles, current, load.picker);\n }\n const profile = profiles.find((candidate) => candidate.name === picked);\n if (!profile) return;\n if (profile.name === current) {\n ctx.ui.notify(profileSummary(profile), INFO);\n return;\n }\n\n const coordinator = requireDoomTransitionCoordinator(cordis);\n let minorModeReloadHandoff: MinorModeReloadHandoffHandle | undefined;\n const result = await coordinator.execute(\n {\n sessionId: ctx.sessionManager.getSessionId(),\n hostGeneration: coordinator.hostGeneration,\n operationId: crypto.randomUUID(),\n source: ctx.mode === 'tui' ? 'ui' : 'command',\n target: { axis: 'profile', profile: profile.name },\n },\n async (_request, plan) => {\n minorModeReloadHandoff = prepareMinorModeReloadHandoff(\n cordis,\n ctx.sessionManager.getSessionId(),\n coordinator.hostGeneration,\n plan.operationId,\n readMinorModeCatalog(cordis)?.getSnapshot(),\n );\n try {\n const { applyProfile } = await load.selection();\n ctx.ui.notify(await applyProfile(profile, state), INFO);\n const { persistHarnessSelection } = await load.journal();\n persistHarnessSelection(pi, { ...state, profile: profile.name });\n void telemetry.recordEvent(PROFILE_EVENT.profileApplied, {\n 'harness.profile': profile.name,\n ...(current ? { 'harness.profile.previous': current } : {}),\n 'harness.transition.disposition': plan.disposition,\n 'harness.transition.operation_id': plan.operationId,\n });\n return 'applied';\n } catch (error) {\n minorModeReloadHandoff?.discard();\n minorModeReloadHandoff = undefined;\n throw error;\n }\n },\n );\n if (result.outcome === 'rejected' || result.outcome === 'stale') {\n minorModeReloadHandoff?.discard();\n ctx.ui.notify(`Profile transition was ${result.outcome}: ${result.diagnostics.join(', ')}`, WARNING);\n return;\n }\n if (result.outcome !== 'applied') {\n minorModeReloadHandoff?.discard();\n return;\n }\n\n try {\n await ctx.waitForIdle();\n // Reload replaces the session and invalidates this command context.\n // Keep it as the handler's final action.\n await ctx.reload();\n } catch (error) {\n minorModeReloadHandoff?.discard();\n throw error;\n }\n },\n },\n ];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/profileText/index.cjs"),t=require("../types/telemetry.cjs"),n=require("./identityEntry.cjs"),r=require("./profileCommand.cjs"),i=require("./voiceTool.cjs");let a=require("@agimon-ai/doompi-config/piContext"),o=require("@agimon-ai/doompi-core/config"),s=require("@agimon-ai/doompi-core/transition"),c=require("@agimon-ai/doompi-core/voice-reload-handoff"),l=require("@agimon-ai/doompi-core/voice-tools");async function u(e,n){try{let[{requireHarnessRoot:t},{loadProfiles:n}]=await Promise.all([import(`@agimon-ai/doompi-config/harnessStore`),import(`@agimon-ai/doompi-config/profiles`)]);return n(t(e)).length>0}catch(e){return n.recordError(t.PROFILE_EVENT.profileLoadFailed,e),!0}}function d(t){let d,f,p=e=>{f=e.inject([o.DOOM_CONFIG_SERVICE,s.DOOM_TRANSITION_SERVICE],e=>(d=e,()=>{d===e&&(d=void 0)}))},m=()=>{if(!d)throw Error(`Doom profile runtime is waiting for the session config service.`);return d},h=(0,c.createVoiceReloadHandoffStore)({now:()=>Date.now(),createToken:()=>crypto.randomUUID()}),g=async()=>{let e=(0,a.requireDoomConfigContext)(m()).harness,[{requireHarnessRoot:t},{loadProfiles:n}]=await Promise.all([import(`@agimon-ai/doompi-config/harnessStore`),import(`@agimon-ai/doompi-config/profiles`)]);return{...e.profile===void 0?{}:{current:e.profile},profiles:n(t(e))}},_=e=>{e.inject([o.DOOM_CONFIG_SERVICE,s.DOOM_TRANSITION_SERVICE,l.DOOM_VOICE_TOOLS_SERVICE],e=>i.registerProfileVoiceCapability((0,l.requireDoomVoiceToolsService)(e),t.pi,g,h,()=>e))},v;return{services:[p,_],commands:[r.createProfileCommand(t.pi,t.telemetry,m,h)],events:{session_start:async(r,i)=>{await f?.await();let o=(0,a.requireDoomConfigContext)(m()).harness,s=e.profileStatus(o.profile,await u(o,t.telemetry));s!==void 0&&i.ui.setStatus(e.PROFILE_STATUS_KEY,s),v=n.publishProfileIdentity(t.pi,o.profile,o.profileIdentity,v)}}}}exports.createProfileRuntime=d;
|
|
2
|
+
//# sourceMappingURL=profileRuntime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileRuntime.cjs","names":["PROFILE_EVENT","DOOM_CONFIG_SERVICE","DOOM_TRANSITION_SERVICE","createVoiceReloadHandoffStore","requireDoomConfigContext","DOOM_VOICE_TOOLS_SERVICE","registerProfileVoiceCapability","requireDoomVoiceToolsService","createProfileCommand","profileStatus","PROFILE_STATUS_KEY","publishProfileIdentity"],"sources":["../../src/controllers/profileRuntime.ts"],"sourcesContent":["import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { HarnessState } from '@agimon-ai/doompi-config/types';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-core/config';\nimport { type PiPluginContributions } from '@agimon-ai/doompi-core/pi-extension';\nimport { DOOM_TRANSITION_SERVICE } from '@agimon-ai/doompi-core/transition';\nimport { createVoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport { DOOM_VOICE_TOOLS_SERVICE, requireDoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { PROFILE_STATUS_KEY, profileStatus } from '../services/profileText';\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\nimport { publishProfileIdentity } from './identityEntry';\nimport { createProfileCommand } from './profileCommand';\nimport { registerProfileVoiceCapability, type ProfileVoiceView } from './voiceTool';\n\n/**\n * Whether the session has any profiles to offer. Reading the catalogue is\n * the one startup cost the axis needs; a broken catalogue reports true so\n * the axis stays on the bar and /profile can explain the failure.\n */\nasync function profileCatalogueExists(\n state: Pick<HarnessState, 'root'>,\n telemetry: ProfileTelemetry,\n): Promise<boolean> {\n try {\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([\n import('@agimon-ai/doompi-config/harnessStore'),\n import('@agimon-ai/doompi-config/profiles'),\n ]);\n return loadProfiles(requireHarnessRoot(state)).length > 0;\n } catch (error) {\n void telemetry.recordError(PROFILE_EVENT.profileLoadFailed, error);\n return true;\n }\n}\n\ninterface ProfilePluginConfig {\n readonly pi: ExtensionAPI;\n readonly telemetry: ProfileTelemetry;\n}\n\nexport function createProfileRuntime(config: ProfilePluginConfig): PiPluginContributions<ProfileTelemetry> {\n let activeContext: Context | undefined;\n let runtimeInjection: ReturnType<Context['inject']> | undefined;\n const bindRuntime = (cordis: Context) => {\n runtimeInjection = cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n };\n const requireRuntimeContext = (): Context => {\n if (!activeContext) throw new Error('Doom profile runtime is waiting for the session config service.');\n return activeContext;\n };\n\n // The store standing between the voice capability and the command handler:\n // the tool cannot reload the session itself, so it parks the chosen profile\n // here and hands the command an opaque token.\n const reloadHandoffs = createVoiceReloadHandoffStore({\n now: () => Date.now(),\n createToken: () => crypto.randomUUID(),\n });\n\n const currentView = async (): Promise<ProfileVoiceView> => {\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([\n import('@agimon-ai/doompi-config/harnessStore'),\n import('@agimon-ai/doompi-config/profiles'),\n ]);\n return {\n ...(state.profile === undefined ? {} : { current: state.profile }),\n profiles: loadProfiles(requireHarnessRoot(state)),\n };\n };\n\n // A separate injection, so the command keeps working in a session that has no\n // autonomous voice and the two-service inject above stays exactly as it was.\n const bindVoice = (cordis: Context) => {\n cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE, DOOM_VOICE_TOOLS_SERVICE], (voiceContext) =>\n registerProfileVoiceCapability(\n requireDoomVoiceToolsService(voiceContext),\n config.pi,\n currentView,\n reloadHandoffs,\n () => voiceContext,\n ),\n );\n };\n let publishedIdentity: string | undefined;\n return {\n services: [bindRuntime, bindVoice],\n commands: [createProfileCommand(config.pi, config.telemetry, requireRuntimeContext, reloadHandoffs)],\n events: {\n session_start: async (_event, ctx) => {\n await runtimeInjection?.await();\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const status = profileStatus(state.profile, await profileCatalogueExists(state, config.telemetry));\n if (status !== undefined) ctx.ui.setStatus(PROFILE_STATUS_KEY, status);\n publishedIdentity = publishProfileIdentity(config.pi, state.profile, state.profileIdentity, publishedIdentity);\n },\n },\n };\n}\n"],"mappings":"gbAqBA,eAAe,EACb,EACA,EACkB,CAClB,GAAI,CACF,GAAM,CAAC,CAAE,sBAAsB,CAAE,iBAAkB,MAAM,QAAQ,IAAI,CACnE,OAAO,yCACP,OAAO,oCACT,CAAC,EACD,OAAO,EAAa,EAAmB,CAAK,CAAC,CAAC,CAAC,OAAS,CAC1D,OAAS,EAAO,CAEd,OADA,EAAe,YAAYA,EAAAA,cAAc,kBAAmB,CAAK,EAC1D,EACT,CACF,CAOA,SAAgB,EAAqB,EAAsE,CACzG,IAAI,EACA,EACE,EAAe,GAAoB,CACvC,EAAmB,EAAO,OAAO,CAACC,EAAAA,oBAAqBC,EAAAA,uBAAuB,EAAI,IAChF,EAAgB,MACH,CACP,IAAkB,IAAS,EAAgB,IAAA,GACjD,EACD,CACH,EACM,MAAuC,CAC3C,GAAI,CAAC,EAAe,MAAU,MAAM,iEAAiE,EACrG,OAAO,CACT,EAKM,GAAA,EAAiBC,EAAAA,8BAAAA,CAA8B,CACnD,QAAW,KAAK,IAAI,EACpB,gBAAmB,OAAO,WAAW,CACvC,CAAC,EAEK,EAAc,SAAuC,CACzD,IAAM,GAAA,EAAQC,EAAAA,yBAAAA,CAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1D,CAAC,CAAE,sBAAsB,CAAE,iBAAkB,MAAM,QAAQ,IAAI,CACnE,OAAO,yCACP,OAAO,oCACT,CAAC,EACD,MAAO,CACL,GAAI,EAAM,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAM,OAAQ,EAChE,SAAU,EAAa,EAAmB,CAAK,CAAC,CAClD,CACF,EAIM,EAAa,GAAoB,CACrC,EAAO,OAAO,CAACH,EAAAA,oBAAqBC,EAAAA,wBAAyBG,EAAAA,wBAAwB,EAAI,GACvFC,EAAAA,gCAAAA,EACEC,EAAAA,6BAAAA,CAA6B,CAAY,EACzC,EAAO,GACP,EACA,MACM,CACR,CACF,CACF,EACI,EACJ,MAAO,CACL,SAAU,CAAC,EAAa,CAAS,EACjC,SAAU,CAACC,EAAAA,qBAAqB,EAAO,GAAI,EAAO,UAAW,EAAuB,CAAc,CAAC,EACnG,OAAQ,CACN,cAAe,MAAO,EAAQ,IAAQ,CACpC,MAAM,GAAkB,MAAM,EAC9B,IAAM,GAAA,EAAQJ,EAAAA,yBAAAA,CAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1D,EAASK,EAAAA,cAAc,EAAM,QAAS,MAAM,EAAuB,EAAO,EAAO,SAAS,CAAC,EAC7F,IAAW,IAAA,IAAW,EAAI,GAAG,UAAUC,EAAAA,mBAAoB,CAAM,EACrE,EAAoBC,EAAAA,uBAAuB,EAAO,GAAI,EAAM,QAAS,EAAM,gBAAiB,CAAiB,CAC/G,CACF,CACF,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{PROFILE_STATUS_KEY as e,profileStatus as t}from"../services/profileText/index.mjs";import{PROFILE_EVENT as n}from"../types/telemetry.mjs";import{publishProfileIdentity as r}from"./identityEntry.mjs";import{createProfileCommand as i}from"./profileCommand.mjs";import{registerProfileVoiceCapability as a}from"./voiceTool.mjs";import{requireDoomConfigContext as o}from"@agimon-ai/doompi-config/piContext";import{DOOM_CONFIG_SERVICE as s}from"@agimon-ai/doompi-core/config";import{DOOM_TRANSITION_SERVICE as c}from"@agimon-ai/doompi-core/transition";import{createVoiceReloadHandoffStore as l}from"@agimon-ai/doompi-core/voice-reload-handoff";import{DOOM_VOICE_TOOLS_SERVICE as u,requireDoomVoiceToolsService as d}from"@agimon-ai/doompi-core/voice-tools";async function f(e,t){try{let[{requireHarnessRoot:t},{loadProfiles:n}]=await Promise.all([import(`@agimon-ai/doompi-config/harnessStore`),import(`@agimon-ai/doompi-config/profiles`)]);return n(t(e)).length>0}catch(e){return t.recordError(n.profileLoadFailed,e),!0}}function p(n){let p,m,h=e=>{m=e.inject([s,c],e=>(p=e,()=>{p===e&&(p=void 0)}))},g=()=>{if(!p)throw Error(`Doom profile runtime is waiting for the session config service.`);return p},_=l({now:()=>Date.now(),createToken:()=>crypto.randomUUID()}),v=async()=>{let e=o(g()).harness,[{requireHarnessRoot:t},{loadProfiles:n}]=await Promise.all([import(`@agimon-ai/doompi-config/harnessStore`),import(`@agimon-ai/doompi-config/profiles`)]);return{...e.profile===void 0?{}:{current:e.profile},profiles:n(t(e))}},y=e=>{e.inject([s,c,u],e=>a(d(e),n.pi,v,_,()=>e))},b;return{services:[h,y],commands:[i(n.pi,n.telemetry,g,_)],events:{session_start:async(i,a)=>{await m?.await();let s=o(g()).harness,c=t(s.profile,await f(s,n.telemetry));c!==void 0&&a.ui.setStatus(e,c),b=r(n.pi,s.profile,s.profileIdentity,b)}}}}export{p as createProfileRuntime};
|
|
2
|
+
//# sourceMappingURL=profileRuntime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileRuntime.mjs","names":[],"sources":["../../src/controllers/profileRuntime.ts"],"sourcesContent":["import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { HarnessState } from '@agimon-ai/doompi-config/types';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-core/config';\nimport { type PiPluginContributions } from '@agimon-ai/doompi-core/pi-extension';\nimport { DOOM_TRANSITION_SERVICE } from '@agimon-ai/doompi-core/transition';\nimport { createVoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport { DOOM_VOICE_TOOLS_SERVICE, requireDoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { PROFILE_STATUS_KEY, profileStatus } from '../services/profileText';\nimport { PROFILE_EVENT, type ProfileTelemetry } from '../types/telemetry';\nimport { publishProfileIdentity } from './identityEntry';\nimport { createProfileCommand } from './profileCommand';\nimport { registerProfileVoiceCapability, type ProfileVoiceView } from './voiceTool';\n\n/**\n * Whether the session has any profiles to offer. Reading the catalogue is\n * the one startup cost the axis needs; a broken catalogue reports true so\n * the axis stays on the bar and /profile can explain the failure.\n */\nasync function profileCatalogueExists(\n state: Pick<HarnessState, 'root'>,\n telemetry: ProfileTelemetry,\n): Promise<boolean> {\n try {\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([\n import('@agimon-ai/doompi-config/harnessStore'),\n import('@agimon-ai/doompi-config/profiles'),\n ]);\n return loadProfiles(requireHarnessRoot(state)).length > 0;\n } catch (error) {\n void telemetry.recordError(PROFILE_EVENT.profileLoadFailed, error);\n return true;\n }\n}\n\ninterface ProfilePluginConfig {\n readonly pi: ExtensionAPI;\n readonly telemetry: ProfileTelemetry;\n}\n\nexport function createProfileRuntime(config: ProfilePluginConfig): PiPluginContributions<ProfileTelemetry> {\n let activeContext: Context | undefined;\n let runtimeInjection: ReturnType<Context['inject']> | undefined;\n const bindRuntime = (cordis: Context) => {\n runtimeInjection = cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE], (context) => {\n activeContext = context;\n return () => {\n if (activeContext === context) activeContext = undefined;\n };\n });\n };\n const requireRuntimeContext = (): Context => {\n if (!activeContext) throw new Error('Doom profile runtime is waiting for the session config service.');\n return activeContext;\n };\n\n // The store standing between the voice capability and the command handler:\n // the tool cannot reload the session itself, so it parks the chosen profile\n // here and hands the command an opaque token.\n const reloadHandoffs = createVoiceReloadHandoffStore({\n now: () => Date.now(),\n createToken: () => crypto.randomUUID(),\n });\n\n const currentView = async (): Promise<ProfileVoiceView> => {\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const [{ requireHarnessRoot }, { loadProfiles }] = await Promise.all([\n import('@agimon-ai/doompi-config/harnessStore'),\n import('@agimon-ai/doompi-config/profiles'),\n ]);\n return {\n ...(state.profile === undefined ? {} : { current: state.profile }),\n profiles: loadProfiles(requireHarnessRoot(state)),\n };\n };\n\n // A separate injection, so the command keeps working in a session that has no\n // autonomous voice and the two-service inject above stays exactly as it was.\n const bindVoice = (cordis: Context) => {\n cordis.inject([DOOM_CONFIG_SERVICE, DOOM_TRANSITION_SERVICE, DOOM_VOICE_TOOLS_SERVICE], (voiceContext) =>\n registerProfileVoiceCapability(\n requireDoomVoiceToolsService(voiceContext),\n config.pi,\n currentView,\n reloadHandoffs,\n () => voiceContext,\n ),\n );\n };\n let publishedIdentity: string | undefined;\n return {\n services: [bindRuntime, bindVoice],\n commands: [createProfileCommand(config.pi, config.telemetry, requireRuntimeContext, reloadHandoffs)],\n events: {\n session_start: async (_event, ctx) => {\n await runtimeInjection?.await();\n const state = requireDoomConfigContext(requireRuntimeContext()).harness;\n const status = profileStatus(state.profile, await profileCatalogueExists(state, config.telemetry));\n if (status !== undefined) ctx.ui.setStatus(PROFILE_STATUS_KEY, status);\n publishedIdentity = publishProfileIdentity(config.pi, state.profile, state.profileIdentity, publishedIdentity);\n },\n },\n };\n}\n"],"mappings":"qvBAqBA,eAAe,EACb,EACA,EACkB,CAClB,GAAI,CACF,GAAM,CAAC,CAAE,sBAAsB,CAAE,iBAAkB,MAAM,QAAQ,IAAI,CACnE,OAAO,yCACP,OAAO,oCACT,CAAC,EACD,OAAO,EAAa,EAAmB,CAAK,CAAC,CAAC,CAAC,OAAS,CAC1D,OAAS,EAAO,CAEd,OADA,EAAe,YAAY,EAAc,kBAAmB,CAAK,EAC1D,EACT,CACF,CAOA,SAAgB,EAAqB,EAAsE,CACzG,IAAI,EACA,EACE,EAAe,GAAoB,CACvC,EAAmB,EAAO,OAAO,CAAC,EAAqB,CAAuB,EAAI,IAChF,EAAgB,MACH,CACP,IAAkB,IAAS,EAAgB,IAAA,GACjD,EACD,CACH,EACM,MAAuC,CAC3C,GAAI,CAAC,EAAe,MAAU,MAAM,iEAAiE,EACrG,OAAO,CACT,EAKM,EAAiB,EAA8B,CACnD,QAAW,KAAK,IAAI,EACpB,gBAAmB,OAAO,WAAW,CACvC,CAAC,EAEK,EAAc,SAAuC,CACzD,IAAM,EAAQ,EAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1D,CAAC,CAAE,sBAAsB,CAAE,iBAAkB,MAAM,QAAQ,IAAI,CACnE,OAAO,yCACP,OAAO,oCACT,CAAC,EACD,MAAO,CACL,GAAI,EAAM,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAM,OAAQ,EAChE,SAAU,EAAa,EAAmB,CAAK,CAAC,CAClD,CACF,EAIM,EAAa,GAAoB,CACrC,EAAO,OAAO,CAAC,EAAqB,EAAyB,CAAwB,EAAI,GACvF,EACE,EAA6B,CAAY,EACzC,EAAO,GACP,EACA,MACM,CACR,CACF,CACF,EACI,EACJ,MAAO,CACL,SAAU,CAAC,EAAa,CAAS,EACjC,SAAU,CAAC,EAAqB,EAAO,GAAI,EAAO,UAAW,EAAuB,CAAc,CAAC,EACnG,OAAQ,CACN,cAAe,MAAO,EAAQ,IAAQ,CACpC,MAAM,GAAkB,MAAM,EAC9B,IAAM,EAAQ,EAAyB,EAAsB,CAAC,CAAC,CAAC,QAC1D,EAAS,EAAc,EAAM,QAAS,MAAM,EAAuB,EAAO,EAAO,SAAS,CAAC,EAC7F,IAAW,IAAA,IAAW,EAAI,GAAG,UAAU,EAAoB,CAAM,EACrE,EAAoB,EAAuB,EAAO,GAAI,EAAM,QAAS,EAAM,gBAAiB,CAAiB,CAC/G,CACF,CACF,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/profileText/index.cjs");let t=require("@agimon-ai/doompi-core/profile-identity"),n=require("@agimon-ai/doompi-config/profiles");async function r(e){let t=e.selection.profile;if(!t)return`(no active profile)`;let r=(0,n.resolveProfile)(e.repoRoot,t),i=(0,n.buildPersonaPrompt)(r.personaRoot,r.persona);if(!i)throw Error(`Profile "${t}" has no readable persona text`);return i}async function i(e,r){let i=(0,n.resolveProfile)(e.repoRoot,r).identity;await e.session.appendCustomEntry(t.DOOM_PROFILE_IDENTITY_ENTRY_TYPE,{profile:r,...i?.name===void 0?{}:{name:i.name},...i?.icon===void 0?{}:{icon:i.icon}})}function a(t){return{name:e.PROFILE_COMMAND,description:`Show or change the active DoomPi profile.`,async execute(r,a){let o=(0,n.loadProfiles)(a.repoRoot),s=r.trim();if(!s){let t=await a.client.request({kind:`select`,title:e.profileTitle(a.selection.profile),options:e.profileItems(o)});if(typeof t!=`string`||!t)return;s=t}if(!o.some(({name:e})=>e===s))throw Error(`Unknown profile: ${s}`);s!==a.selection.profile&&(await t.changeSelection({axis:`profile`,profile:s}),await i(a,s))}}}const o={event:`session_start`,async handle(e,t){let n=t.selection.profile;n!==void 0&&await i(t,n)}};exports.createProfileServerCommand=a,exports.profileIdentityHook=o,exports.readSelectedPersona=r;
|
|
2
|
+
//# sourceMappingURL=profileServer.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileServer.cjs","names":["resolveProfile","buildPersonaPrompt","DOOM_PROFILE_IDENTITY_ENTRY_TYPE","PROFILE_COMMAND","loadProfiles","profileTitle","profileItems"],"sources":["../../src/controllers/profileServer.ts"],"sourcesContent":["import { buildPersonaPrompt, loadProfiles, resolveProfile } from '@agimon-ai/doompi-config/profiles';\nimport {\n type DoomHeadlessCommand,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHostService,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport { DOOM_PROFILE_IDENTITY_ENTRY_TYPE } from '@agimon-ai/doompi-core/profile-identity';\n\nimport { PROFILE_COMMAND, profileItems, profileTitle } from '../services/profileText';\n\nexport async function readSelectedPersona(execution: {\n readonly repoRoot: string;\n readonly selection: { readonly profile?: string };\n}): Promise<string> {\n const name = execution.selection.profile;\n if (!name) return '(no active profile)';\n const profile = resolveProfile(execution.repoRoot, name);\n const prompt = buildPersonaPrompt(profile.personaRoot, profile.persona);\n if (!prompt) throw new Error(`Profile \"${name}\" has no readable persona text`);\n return prompt;\n}\n\nasync function publishSelectedIdentity(execution: DoomHeadlessExecutionContext, profile: string): Promise<void> {\n const identity = resolveProfile(execution.repoRoot, profile).identity;\n await execution.session.appendCustomEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, {\n profile,\n ...(identity?.name === undefined ? {} : { name: identity.name }),\n ...(identity?.icon === undefined ? {} : { icon: identity.icon }),\n });\n}\n\nexport function createProfileServerCommand(host: DoomHeadlessHostService): DoomHeadlessCommand {\n return {\n name: PROFILE_COMMAND,\n description: 'Show or change the active DoomPi profile.',\n async execute(args, execution) {\n const profiles = loadProfiles(execution.repoRoot);\n let requested = args.trim();\n if (!requested) {\n const selected = await execution.client.request({\n kind: 'select',\n title: profileTitle(execution.selection.profile),\n options: profileItems(profiles),\n });\n if (typeof selected !== 'string' || !selected) return;\n requested = selected;\n }\n if (!profiles.some(({ name }) => name === requested)) throw new Error(`Unknown profile: ${requested}`);\n if (requested === execution.selection.profile) return;\n await host.changeSelection({ axis: 'profile', profile: requested });\n await publishSelectedIdentity(execution, requested);\n },\n };\n}\nexport const profileIdentityHook: DoomHeadlessHook = {\n event: 'session_start',\n async handle(_event, execution) {\n const profile = execution.selection.profile;\n if (profile !== undefined) await publishSelectedIdentity(execution, profile);\n },\n};\n"],"mappings":"6JAWA,eAAsB,EAAoB,EAGtB,CAClB,IAAM,EAAO,EAAU,UAAU,QACjC,GAAI,CAAC,EAAM,MAAO,sBAClB,IAAM,GAAA,EAAUA,EAAAA,eAAAA,CAAe,EAAU,SAAU,CAAI,EACjD,GAAA,EAASC,EAAAA,mBAAAA,CAAmB,EAAQ,YAAa,EAAQ,OAAO,EACtE,GAAI,CAAC,EAAQ,MAAU,MAAM,YAAY,EAAK,+BAA+B,EAC7E,OAAO,CACT,CAEA,eAAe,EAAwB,EAAyC,EAAgC,CAC9G,IAAM,GAAA,EAAWD,EAAAA,eAAAA,CAAe,EAAU,SAAU,CAAO,CAAC,CAAC,SAC7D,MAAM,EAAU,QAAQ,kBAAkBE,EAAAA,iCAAkC,CAC1E,UACA,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,EAC9D,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,CAChE,CAAC,CACH,CAEA,SAAgB,EAA2B,EAAoD,CAC7F,MAAO,CACL,KAAMC,EAAAA,gBACN,YAAa,4CACb,MAAM,QAAQ,EAAM,EAAW,CAC7B,IAAM,GAAA,EAAWC,EAAAA,aAAAA,CAAa,EAAU,QAAQ,EAC5C,EAAY,EAAK,KAAK,EAC1B,GAAI,CAAC,EAAW,CACd,IAAM,EAAW,MAAM,EAAU,OAAO,QAAQ,CAC9C,KAAM,SACN,MAAOC,EAAAA,aAAa,EAAU,UAAU,OAAO,EAC/C,QAASC,EAAAA,aAAa,CAAQ,CAChC,CAAC,EACD,GAAI,OAAO,GAAa,UAAY,CAAC,EAAU,OAC/C,EAAY,CACd,CACA,GAAI,CAAC,EAAS,MAAM,CAAE,UAAW,IAAS,CAAS,EAAG,MAAU,MAAM,oBAAoB,GAAW,EACjG,IAAc,EAAU,UAAU,UACtC,MAAM,EAAK,gBAAgB,CAAE,KAAM,UAAW,QAAS,CAAU,CAAC,EAClE,MAAM,EAAwB,EAAW,CAAS,EACpD,CACF,CACF,CACA,MAAa,EAAwC,CACnD,MAAO,gBACP,MAAM,OAAO,EAAQ,EAAW,CAC9B,IAAM,EAAU,EAAU,UAAU,QAChC,IAAY,IAAA,IAAW,MAAM,EAAwB,EAAW,CAAO,CAC7E,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{PROFILE_COMMAND as e,profileItems as t,profileTitle as n}from"../services/profileText/index.mjs";import{DOOM_PROFILE_IDENTITY_ENTRY_TYPE as r}from"@agimon-ai/doompi-core/profile-identity";import{buildPersonaPrompt as i,loadProfiles as a,resolveProfile as o}from"@agimon-ai/doompi-config/profiles";async function s(e){let t=e.selection.profile;if(!t)return`(no active profile)`;let n=o(e.repoRoot,t),r=i(n.personaRoot,n.persona);if(!r)throw Error(`Profile "${t}" has no readable persona text`);return r}async function c(e,t){let n=o(e.repoRoot,t).identity;await e.session.appendCustomEntry(r,{profile:t,...n?.name===void 0?{}:{name:n.name},...n?.icon===void 0?{}:{icon:n.icon}})}function l(r){return{name:e,description:`Show or change the active DoomPi profile.`,async execute(e,i){let o=a(i.repoRoot),s=e.trim();if(!s){let e=await i.client.request({kind:`select`,title:n(i.selection.profile),options:t(o)});if(typeof e!=`string`||!e)return;s=e}if(!o.some(({name:e})=>e===s))throw Error(`Unknown profile: ${s}`);s!==i.selection.profile&&(await r.changeSelection({axis:`profile`,profile:s}),await c(i,s))}}}const u={event:`session_start`,async handle(e,t){let n=t.selection.profile;n!==void 0&&await c(t,n)}};export{l as createProfileServerCommand,u as profileIdentityHook,s as readSelectedPersona};
|
|
2
|
+
//# sourceMappingURL=profileServer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileServer.mjs","names":[],"sources":["../../src/controllers/profileServer.ts"],"sourcesContent":["import { buildPersonaPrompt, loadProfiles, resolveProfile } from '@agimon-ai/doompi-config/profiles';\nimport {\n type DoomHeadlessCommand,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHostService,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport { DOOM_PROFILE_IDENTITY_ENTRY_TYPE } from '@agimon-ai/doompi-core/profile-identity';\n\nimport { PROFILE_COMMAND, profileItems, profileTitle } from '../services/profileText';\n\nexport async function readSelectedPersona(execution: {\n readonly repoRoot: string;\n readonly selection: { readonly profile?: string };\n}): Promise<string> {\n const name = execution.selection.profile;\n if (!name) return '(no active profile)';\n const profile = resolveProfile(execution.repoRoot, name);\n const prompt = buildPersonaPrompt(profile.personaRoot, profile.persona);\n if (!prompt) throw new Error(`Profile \"${name}\" has no readable persona text`);\n return prompt;\n}\n\nasync function publishSelectedIdentity(execution: DoomHeadlessExecutionContext, profile: string): Promise<void> {\n const identity = resolveProfile(execution.repoRoot, profile).identity;\n await execution.session.appendCustomEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, {\n profile,\n ...(identity?.name === undefined ? {} : { name: identity.name }),\n ...(identity?.icon === undefined ? {} : { icon: identity.icon }),\n });\n}\n\nexport function createProfileServerCommand(host: DoomHeadlessHostService): DoomHeadlessCommand {\n return {\n name: PROFILE_COMMAND,\n description: 'Show or change the active DoomPi profile.',\n async execute(args, execution) {\n const profiles = loadProfiles(execution.repoRoot);\n let requested = args.trim();\n if (!requested) {\n const selected = await execution.client.request({\n kind: 'select',\n title: profileTitle(execution.selection.profile),\n options: profileItems(profiles),\n });\n if (typeof selected !== 'string' || !selected) return;\n requested = selected;\n }\n if (!profiles.some(({ name }) => name === requested)) throw new Error(`Unknown profile: ${requested}`);\n if (requested === execution.selection.profile) return;\n await host.changeSelection({ axis: 'profile', profile: requested });\n await publishSelectedIdentity(execution, requested);\n },\n };\n}\nexport const profileIdentityHook: DoomHeadlessHook = {\n event: 'session_start',\n async handle(_event, execution) {\n const profile = execution.selection.profile;\n if (profile !== undefined) await publishSelectedIdentity(execution, profile);\n },\n};\n"],"mappings":"gTAWA,eAAsB,EAAoB,EAGtB,CAClB,IAAM,EAAO,EAAU,UAAU,QACjC,GAAI,CAAC,EAAM,MAAO,sBAClB,IAAM,EAAU,EAAe,EAAU,SAAU,CAAI,EACjD,EAAS,EAAmB,EAAQ,YAAa,EAAQ,OAAO,EACtE,GAAI,CAAC,EAAQ,MAAU,MAAM,YAAY,EAAK,+BAA+B,EAC7E,OAAO,CACT,CAEA,eAAe,EAAwB,EAAyC,EAAgC,CAC9G,IAAM,EAAW,EAAe,EAAU,SAAU,CAAO,CAAC,CAAC,SAC7D,MAAM,EAAU,QAAQ,kBAAkB,EAAkC,CAC1E,UACA,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,EAC9D,GAAI,GAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,KAAM,EAAS,IAAK,CAChE,CAAC,CACH,CAEA,SAAgB,EAA2B,EAAoD,CAC7F,MAAO,CACL,KAAM,EACN,YAAa,4CACb,MAAM,QAAQ,EAAM,EAAW,CAC7B,IAAM,EAAW,EAAa,EAAU,QAAQ,EAC5C,EAAY,EAAK,KAAK,EAC1B,GAAI,CAAC,EAAW,CACd,IAAM,EAAW,MAAM,EAAU,OAAO,QAAQ,CAC9C,KAAM,SACN,MAAO,EAAa,EAAU,UAAU,OAAO,EAC/C,QAAS,EAAa,CAAQ,CAChC,CAAC,EACD,GAAI,OAAO,GAAa,UAAY,CAAC,EAAU,OAC/C,EAAY,CACd,CACA,GAAI,CAAC,EAAS,MAAM,CAAE,UAAW,IAAS,CAAS,EAAG,MAAU,MAAM,oBAAoB,GAAW,EACjG,IAAc,EAAU,UAAU,UACtC,MAAM,EAAK,gBAAgB,CAAE,KAAM,UAAW,QAAS,CAAU,CAAC,EAClE,MAAM,EAAwB,EAAW,CAAS,EACpD,CACF,CACF,CACA,MAAa,EAAwC,CACnD,MAAO,gBACP,MAAM,OAAO,EAAQ,EAAW,CAC9B,IAAM,EAAU,EAAU,UAAU,QAChC,IAAY,IAAA,IAAW,MAAM,EAAwB,EAAW,CAAO,CAC7E,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/profileText/index.cjs"),t=require("../schemas/profileVoiceTools.cjs");let n=require("@agimon-ai/doompi-core/transition");function r(t){return{status:`listed`,...t.current===void 0?{}:{current:t.current},profiles:t.profiles.map(t=>({name:t.name,description:e.profileDescription(t),...t.identity?.name===void 0?{}:{displayName:t.identity.name}}))}}function i(i,a,o,s,c){let l=i.register({descriptor:{source:e.PROFILE_SOURCE,id:t.PROFILE_VOICE_TOOL_NAME,name:t.PROFILE_VOICE_TOOL_NAME,label:`Profile`,description:`List the personas configured for this session with their display names, or queue a switch to one of them.`,order:20,inputSchema:t.PROFILE_VOICE_INPUT_SCHEMA,resultSchema:t.PROFILE_VOICE_RESULT_SCHEMA},async execute(t,i){let l=t,u=await o(i.context);if(l.action===`list`)return r(u);let d=u.profiles.find(e=>e.name===l.profile);if(!d)throw Error(`Unknown profile: ${l.profile}`);if(d.name===u.current)return{status:`unchanged`,profile:d.name};let f=(0,n.requireDoomTransitionCoordinator)(c());f.plan({sessionId:i.sessionId,hostGeneration:f.hostGeneration,operationId:i.operationId,source:`voice`,target:{axis:`profile`,profile:d.name},signal:i.signal});let p=s.prepare({active:!i.signal.aborted,sessionId:i.sessionId,hostGeneration:i.hostGeneration},{operationId:i.operationId,kind:e.PROFILE_SWITCH_HANDOFF_KIND,profile:d.name});try{a.sendUserMessage.bind(a)(`/${e.PROFILE_COMMAND} ${e.VOICE_SWITCH_TOKEN_PREFIX}${p.token}`,{deliverAs:`followUp`,expandPromptTemplates:!0})}catch(e){throw p.discard(),e}return{status:`queued`,profile:d.name,stopBatch:`session-reload`}}});return()=>l.dispose()}exports.registerProfileVoiceCapability=i;
|
|
2
|
+
//# sourceMappingURL=voiceTool.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voiceTool.cjs","names":["profileDescription","PROFILE_SOURCE","PROFILE_VOICE_TOOL_NAME","PROFILE_VOICE_INPUT_SCHEMA","PROFILE_VOICE_RESULT_SCHEMA","requireDoomTransitionCoordinator","PROFILE_SWITCH_HANDOFF_KIND","PROFILE_COMMAND","VOICE_SWITCH_TOKEN_PREFIX"],"sources":["../../src/controllers/voiceTool.ts"],"sourcesContent":["import type { AgentProfile } from '@agimon-ai/doompi-config/profiles';\nimport { requireDoomTransitionCoordinator } from '@agimon-ai/doompi-core/transition';\nimport type { VoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport type { DoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n PROFILE_VOICE_INPUT_SCHEMA,\n PROFILE_VOICE_RESULT_SCHEMA,\n PROFILE_VOICE_TOOL_NAME,\n type ProfileVoiceInput,\n type ProfileVoiceResult,\n} from '../schemas/profileVoiceTools';\nimport {\n PROFILE_COMMAND,\n PROFILE_SOURCE,\n PROFILE_SWITCH_HANDOFF_KIND,\n profileDescription,\n VOICE_SWITCH_TOKEN_PREFIX,\n} from '../services/profileText';\n\ntype VoiceMessageSender = (\n content: string,\n options: { readonly deliverAs: 'followUp'; readonly expandPromptTemplates: true },\n) => void;\n\n/** What the capability needs from the session, kept narrow so tests need no harness. */\nexport interface ProfileVoiceView {\n readonly current?: string;\n readonly profiles: readonly AgentProfile[];\n}\n\nfunction profileListing(view: ProfileVoiceView): ProfileVoiceResult {\n return {\n status: 'listed',\n ...(view.current === undefined ? {} : { current: view.current }),\n profiles: view.profiles.map((profile) => ({\n name: profile.name,\n description: profileDescription(profile),\n ...(profile.identity?.name === undefined ? {} : { displayName: profile.identity.name }),\n })),\n };\n}\n\n/**\n * The model-facing half of the axis.\n *\n * A switch is never applied here. It plans the transition, mints an opaque\n * handoff token and sends `/profile --voice-switch-token=…` back as a follow-up,\n * so the reload happens inside a command handler where it can be the terminal\n * action. The profile name stays out of the message text on purpose: an edited\n * transcript must not be able to redirect the switch.\n */\nexport function registerProfileVoiceCapability(\n voiceTools: DoomVoiceToolsService<ExtensionContext>,\n pi: ExtensionAPI,\n currentView: (ctx: ExtensionContext) => Promise<ProfileVoiceView>,\n reloadHandoffs: VoiceReloadHandoffStore,\n cordisContext: () => Context,\n): () => void {\n const registration = voiceTools.register({\n descriptor: {\n source: PROFILE_SOURCE,\n id: PROFILE_VOICE_TOOL_NAME,\n name: PROFILE_VOICE_TOOL_NAME,\n label: 'Profile',\n description:\n 'List the personas configured for this session with their display names, or queue a switch to one of them.',\n order: 20,\n inputSchema: PROFILE_VOICE_INPUT_SCHEMA,\n resultSchema: PROFILE_VOICE_RESULT_SCHEMA,\n },\n async execute(input, execution) {\n const params = input as ProfileVoiceInput;\n const view = await currentView(execution.context);\n if (params.action === 'list') return profileListing(view);\n\n const profile = view.profiles.find((candidate) => candidate.name === params.profile);\n if (!profile) {\n throw new Error(`Unknown profile: ${params.profile}`);\n }\n if (profile.name === view.current) return { status: 'unchanged', profile: profile.name };\n\n const coordinator = requireDoomTransitionCoordinator(cordisContext());\n coordinator.plan({\n sessionId: execution.sessionId,\n hostGeneration: coordinator.hostGeneration,\n operationId: execution.operationId,\n source: 'voice',\n target: { axis: 'profile', profile: profile.name },\n signal: execution.signal,\n });\n\n const reloadHandoff = reloadHandoffs.prepare(\n {\n active: !execution.signal.aborted,\n sessionId: execution.sessionId,\n hostGeneration: execution.hostGeneration,\n },\n {\n operationId: execution.operationId,\n kind: PROFILE_SWITCH_HANDOFF_KIND,\n profile: profile.name,\n },\n );\n try {\n const sendUserMessage = pi.sendUserMessage.bind(pi) as unknown as VoiceMessageSender;\n sendUserMessage(`/${PROFILE_COMMAND} ${VOICE_SWITCH_TOKEN_PREFIX}${reloadHandoff.token}`, {\n deliverAs: 'followUp',\n expandPromptTemplates: true,\n });\n } catch (error) {\n reloadHandoff.discard();\n throw error;\n }\n return { status: 'queued', profile: profile.name, stopBatch: 'session-reload' };\n },\n });\n return () => registration.dispose();\n}\n"],"mappings":"sJAiCA,SAAS,EAAe,EAA4C,CAClE,MAAO,CACL,OAAQ,SACR,GAAI,EAAK,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAK,OAAQ,EAC9D,SAAU,EAAK,SAAS,IAAK,IAAa,CACxC,KAAM,EAAQ,KACd,YAAaA,EAAAA,mBAAmB,CAAO,EACvC,GAAI,EAAQ,UAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAQ,SAAS,IAAK,CACvF,EAAE,CACJ,CACF,CAWA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAe,EAAW,SAAS,CACvC,WAAY,CACV,OAAQC,EAAAA,eACR,GAAIC,EAAAA,wBACJ,KAAMA,EAAAA,wBACN,MAAO,UACP,YACE,4GACF,MAAO,GACP,YAAaC,EAAAA,2BACb,aAAcC,EAAAA,2BAChB,EACA,MAAM,QAAQ,EAAO,EAAW,CAC9B,IAAM,EAAS,EACT,EAAO,MAAM,EAAY,EAAU,OAAO,EAChD,GAAI,EAAO,SAAW,OAAQ,OAAO,EAAe,CAAI,EAExD,IAAM,EAAU,EAAK,SAAS,KAAM,GAAc,EAAU,OAAS,EAAO,OAAO,EACnF,GAAI,CAAC,EACH,MAAU,MAAM,oBAAoB,EAAO,SAAS,EAEtD,GAAI,EAAQ,OAAS,EAAK,QAAS,MAAO,CAAE,OAAQ,YAAa,QAAS,EAAQ,IAAK,EAEvF,IAAM,GAAA,EAAcC,EAAAA,iCAAAA,CAAiC,EAAc,CAAC,EACpE,EAAY,KAAK,CACf,UAAW,EAAU,UACrB,eAAgB,EAAY,eAC5B,YAAa,EAAU,YACvB,OAAQ,QACR,OAAQ,CAAE,KAAM,UAAW,QAAS,EAAQ,IAAK,EACjD,OAAQ,EAAU,MACpB,CAAC,EAED,IAAM,EAAgB,EAAe,QACnC,CACE,OAAQ,CAAC,EAAU,OAAO,QAC1B,UAAW,EAAU,UACrB,eAAgB,EAAU,cAC5B,EACA,CACE,YAAa,EAAU,YACvB,KAAMC,EAAAA,4BACN,QAAS,EAAQ,IACnB,CACF,EACA,GAAI,CAEF,EAD2B,gBAAgB,KAAK,CAClC,CAAC,CAAC,IAAIC,EAAAA,gBAAgB,GAAGC,EAAAA,4BAA4B,EAAc,QAAS,CACxF,UAAW,WACX,sBAAuB,EACzB,CAAC,CACH,OAAS,EAAO,CAEd,MADA,EAAc,QAAQ,EAChB,CACR,CACA,MAAO,CAAE,OAAQ,SAAU,QAAS,EAAQ,KAAM,UAAW,gBAAiB,CAChF,CACF,CAAC,EACD,UAAa,EAAa,QAAQ,CACpC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{PROFILE_COMMAND as e,PROFILE_SOURCE as t,PROFILE_SWITCH_HANDOFF_KIND as n,VOICE_SWITCH_TOKEN_PREFIX as r,profileDescription as i}from"../services/profileText/index.mjs";import{PROFILE_VOICE_INPUT_SCHEMA as a,PROFILE_VOICE_RESULT_SCHEMA as o,PROFILE_VOICE_TOOL_NAME as s}from"../schemas/profileVoiceTools.mjs";import{requireDoomTransitionCoordinator as c}from"@agimon-ai/doompi-core/transition";function l(e){return{status:`listed`,...e.current===void 0?{}:{current:e.current},profiles:e.profiles.map(e=>({name:e.name,description:i(e),...e.identity?.name===void 0?{}:{displayName:e.identity.name}}))}}function u(i,u,d,f,p){let m=i.register({descriptor:{source:t,id:s,name:s,label:`Profile`,description:`List the personas configured for this session with their display names, or queue a switch to one of them.`,order:20,inputSchema:a,resultSchema:o},async execute(t,i){let a=t,o=await d(i.context);if(a.action===`list`)return l(o);let s=o.profiles.find(e=>e.name===a.profile);if(!s)throw Error(`Unknown profile: ${a.profile}`);if(s.name===o.current)return{status:`unchanged`,profile:s.name};let m=c(p());m.plan({sessionId:i.sessionId,hostGeneration:m.hostGeneration,operationId:i.operationId,source:`voice`,target:{axis:`profile`,profile:s.name},signal:i.signal});let h=f.prepare({active:!i.signal.aborted,sessionId:i.sessionId,hostGeneration:i.hostGeneration},{operationId:i.operationId,kind:n,profile:s.name});try{u.sendUserMessage.bind(u)(`/${e} ${r}${h.token}`,{deliverAs:`followUp`,expandPromptTemplates:!0})}catch(e){throw h.discard(),e}return{status:`queued`,profile:s.name,stopBatch:`session-reload`}}});return()=>m.dispose()}export{u as registerProfileVoiceCapability};
|
|
2
|
+
//# sourceMappingURL=voiceTool.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voiceTool.mjs","names":[],"sources":["../../src/controllers/voiceTool.ts"],"sourcesContent":["import type { AgentProfile } from '@agimon-ai/doompi-config/profiles';\nimport { requireDoomTransitionCoordinator } from '@agimon-ai/doompi-core/transition';\nimport type { VoiceReloadHandoffStore } from '@agimon-ai/doompi-core/voice-reload-handoff';\nimport type { DoomVoiceToolsService } from '@agimon-ai/doompi-core/voice-tools';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n PROFILE_VOICE_INPUT_SCHEMA,\n PROFILE_VOICE_RESULT_SCHEMA,\n PROFILE_VOICE_TOOL_NAME,\n type ProfileVoiceInput,\n type ProfileVoiceResult,\n} from '../schemas/profileVoiceTools';\nimport {\n PROFILE_COMMAND,\n PROFILE_SOURCE,\n PROFILE_SWITCH_HANDOFF_KIND,\n profileDescription,\n VOICE_SWITCH_TOKEN_PREFIX,\n} from '../services/profileText';\n\ntype VoiceMessageSender = (\n content: string,\n options: { readonly deliverAs: 'followUp'; readonly expandPromptTemplates: true },\n) => void;\n\n/** What the capability needs from the session, kept narrow so tests need no harness. */\nexport interface ProfileVoiceView {\n readonly current?: string;\n readonly profiles: readonly AgentProfile[];\n}\n\nfunction profileListing(view: ProfileVoiceView): ProfileVoiceResult {\n return {\n status: 'listed',\n ...(view.current === undefined ? {} : { current: view.current }),\n profiles: view.profiles.map((profile) => ({\n name: profile.name,\n description: profileDescription(profile),\n ...(profile.identity?.name === undefined ? {} : { displayName: profile.identity.name }),\n })),\n };\n}\n\n/**\n * The model-facing half of the axis.\n *\n * A switch is never applied here. It plans the transition, mints an opaque\n * handoff token and sends `/profile --voice-switch-token=…` back as a follow-up,\n * so the reload happens inside a command handler where it can be the terminal\n * action. The profile name stays out of the message text on purpose: an edited\n * transcript must not be able to redirect the switch.\n */\nexport function registerProfileVoiceCapability(\n voiceTools: DoomVoiceToolsService<ExtensionContext>,\n pi: ExtensionAPI,\n currentView: (ctx: ExtensionContext) => Promise<ProfileVoiceView>,\n reloadHandoffs: VoiceReloadHandoffStore,\n cordisContext: () => Context,\n): () => void {\n const registration = voiceTools.register({\n descriptor: {\n source: PROFILE_SOURCE,\n id: PROFILE_VOICE_TOOL_NAME,\n name: PROFILE_VOICE_TOOL_NAME,\n label: 'Profile',\n description:\n 'List the personas configured for this session with their display names, or queue a switch to one of them.',\n order: 20,\n inputSchema: PROFILE_VOICE_INPUT_SCHEMA,\n resultSchema: PROFILE_VOICE_RESULT_SCHEMA,\n },\n async execute(input, execution) {\n const params = input as ProfileVoiceInput;\n const view = await currentView(execution.context);\n if (params.action === 'list') return profileListing(view);\n\n const profile = view.profiles.find((candidate) => candidate.name === params.profile);\n if (!profile) {\n throw new Error(`Unknown profile: ${params.profile}`);\n }\n if (profile.name === view.current) return { status: 'unchanged', profile: profile.name };\n\n const coordinator = requireDoomTransitionCoordinator(cordisContext());\n coordinator.plan({\n sessionId: execution.sessionId,\n hostGeneration: coordinator.hostGeneration,\n operationId: execution.operationId,\n source: 'voice',\n target: { axis: 'profile', profile: profile.name },\n signal: execution.signal,\n });\n\n const reloadHandoff = reloadHandoffs.prepare(\n {\n active: !execution.signal.aborted,\n sessionId: execution.sessionId,\n hostGeneration: execution.hostGeneration,\n },\n {\n operationId: execution.operationId,\n kind: PROFILE_SWITCH_HANDOFF_KIND,\n profile: profile.name,\n },\n );\n try {\n const sendUserMessage = pi.sendUserMessage.bind(pi) as unknown as VoiceMessageSender;\n sendUserMessage(`/${PROFILE_COMMAND} ${VOICE_SWITCH_TOKEN_PREFIX}${reloadHandoff.token}`, {\n deliverAs: 'followUp',\n expandPromptTemplates: true,\n });\n } catch (error) {\n reloadHandoff.discard();\n throw error;\n }\n return { status: 'queued', profile: profile.name, stopBatch: 'session-reload' };\n },\n });\n return () => registration.dispose();\n}\n"],"mappings":"iZAiCA,SAAS,EAAe,EAA4C,CAClE,MAAO,CACL,OAAQ,SACR,GAAI,EAAK,UAAY,IAAA,GAAY,CAAC,EAAI,CAAE,QAAS,EAAK,OAAQ,EAC9D,SAAU,EAAK,SAAS,IAAK,IAAa,CACxC,KAAM,EAAQ,KACd,YAAa,EAAmB,CAAO,EACvC,GAAI,EAAQ,UAAU,OAAS,IAAA,GAAY,CAAC,EAAI,CAAE,YAAa,EAAQ,SAAS,IAAK,CACvF,EAAE,CACJ,CACF,CAWA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAe,EAAW,SAAS,CACvC,WAAY,CACV,OAAQ,EACR,GAAI,EACJ,KAAM,EACN,MAAO,UACP,YACE,4GACF,MAAO,GACP,YAAa,EACb,aAAc,CAChB,EACA,MAAM,QAAQ,EAAO,EAAW,CAC9B,IAAM,EAAS,EACT,EAAO,MAAM,EAAY,EAAU,OAAO,EAChD,GAAI,EAAO,SAAW,OAAQ,OAAO,EAAe,CAAI,EAExD,IAAM,EAAU,EAAK,SAAS,KAAM,GAAc,EAAU,OAAS,EAAO,OAAO,EACnF,GAAI,CAAC,EACH,MAAU,MAAM,oBAAoB,EAAO,SAAS,EAEtD,GAAI,EAAQ,OAAS,EAAK,QAAS,MAAO,CAAE,OAAQ,YAAa,QAAS,EAAQ,IAAK,EAEvF,IAAM,EAAc,EAAiC,EAAc,CAAC,EACpE,EAAY,KAAK,CACf,UAAW,EAAU,UACrB,eAAgB,EAAY,eAC5B,YAAa,EAAU,YACvB,OAAQ,QACR,OAAQ,CAAE,KAAM,UAAW,QAAS,EAAQ,IAAK,EACjD,OAAQ,EAAU,MACpB,CAAC,EAED,IAAM,EAAgB,EAAe,QACnC,CACE,OAAQ,CAAC,EAAU,OAAO,QAC1B,UAAW,EAAU,UACrB,eAAgB,EAAU,cAC5B,EACA,CACE,YAAa,EAAU,YACvB,KAAM,EACN,QAAS,EAAQ,IACnB,CACF,EACA,GAAI,CAEF,EAD2B,gBAAgB,KAAK,CAClC,CAAC,CAAC,IAAI,EAAgB,GAAG,IAA4B,EAAc,QAAS,CACxF,UAAW,WACX,sBAAuB,EACzB,CAAC,CACH,OAAS,EAAO,CAEd,MADA,EAAc,QAAQ,EAChB,CACR,CACA,MAAO,CAAE,OAAQ,SAAU,QAAS,EAAQ,KAAM,UAAW,gBAAiB,CAChF,CACF,CAAC,EACD,UAAa,EAAa,QAAQ,CACpC"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../services/logSinkTelemetry/index.cjs"),t=require("../controllers/personaRuntime.cjs"),n=(0,require("@agimon-ai/doompi-core/pi-extension").definePiExtension)(`@agimon-ai/doompi-profile/persona`,({options:n})=>t.createPersonaRuntime(n??e.createProfileTelemetry()));exports.default=n,exports.personaExtension=n;
|
|
2
|
+
//# sourceMappingURL=persona.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.cjs","names":["definePiExtension","createPersonaRuntime","createProfileTelemetry"],"sources":["../../src/extensions/persona.ts"],"sourcesContent":["import { definePiExtension } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { createPersonaRuntime } from '../controllers/personaRuntime';\nimport { createProfileTelemetry } from '../services/logSinkTelemetry';\nimport type { ProfileTelemetry } from '../types/telemetry';\nexport const personaExtension = definePiExtension<ProfileTelemetry>(\n '@agimon-ai/doompi-profile/persona',\n ({ options }) => createPersonaRuntime(options ?? createProfileTelemetry()),\n);\nexport default personaExtension;\n"],"mappings":"wMAKa,GAAA,+CAAmBA,CAAAA,CAAAA,kBAAAA,CAC9B,qCACC,CAAE,aAAcC,EAAAA,qBAAqB,GAAWC,EAAAA,uBAAuB,CAAC,CAC3E"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { ProfileTelemetry } from "../types/telemetry.cjs";
|
|
2
|
+
//#region src/extensions/persona.d.ts
|
|
3
|
+
export declare const personaExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<ProfileTelemetry>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { personaExtension as default };
|
|
6
|
+
//# sourceMappingURL=persona.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.d.cts","names":[],"sources":["../../src/extensions/persona.ts"],"mappings":";;qBAKa,wEAAgB,mBAAA"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { ProfileTelemetry } from "../types/telemetry.mjs";
|
|
2
|
+
//#region src/extensions/persona.d.ts
|
|
3
|
+
export declare const personaExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<ProfileTelemetry>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { personaExtension as default };
|
|
6
|
+
//# sourceMappingURL=persona.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.d.mts","names":[],"sources":["../../src/extensions/persona.ts"],"mappings":";;qBAKa,wEAAgB,mBAAA"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{createProfileTelemetry as e}from"../services/logSinkTelemetry/index.mjs";import{createPersonaRuntime as t}from"../controllers/personaRuntime.mjs";import{definePiExtension as n}from"@agimon-ai/doompi-core/pi-extension";const r=n(`@agimon-ai/doompi-profile/persona`,({options:n})=>t(n??e()));export{r as default,r as personaExtension};
|
|
2
|
+
//# sourceMappingURL=persona.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona.mjs","names":[],"sources":["../../src/extensions/persona.ts"],"sourcesContent":["import { definePiExtension } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { createPersonaRuntime } from '../controllers/personaRuntime';\nimport { createProfileTelemetry } from '../services/logSinkTelemetry';\nimport type { ProfileTelemetry } from '../types/telemetry';\nexport const personaExtension = definePiExtension<ProfileTelemetry>(\n '@agimon-ai/doompi-profile/persona',\n ({ options }) => createPersonaRuntime(options ?? createProfileTelemetry()),\n);\nexport default personaExtension;\n"],"mappings":"iOAKA,MAAa,EAAmB,EAC9B,qCACC,CAAE,aAAc,EAAqB,GAAW,EAAuB,CAAC,CAC3E"}
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../services/logSinkTelemetry/index.cjs"),t=require("../controllers/profileRuntime.cjs");let n=require("@agimon-ai/doompi-core/pi-extension");const r=`@agimon-ai/doompi-profile`,i=(0,n.definePiExtension)(r,({pi:n,options:i})=>({...t.createProfileRuntime({pi:n,telemetry:i??e.createProfileTelemetry()}),resources:[{source:r,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-author-profile`,description:`Configure DoomPi profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.`}]}]}));exports.default=i,exports.profileExtension=i;
|
|
2
|
+
//# sourceMappingURL=pi.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.cjs","names":["definePiExtension","createProfileRuntime","createProfileTelemetry"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { createProfileRuntime } from '../controllers/profileRuntime';\nimport { createProfileTelemetry } from '../services/logSinkTelemetry';\nimport type { ProfileTelemetry } from '../types/telemetry';\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-profile';\nexport const profileExtension = definePiExtension<ProfileTelemetry>(PACKAGE_SOURCE, ({ pi, options }) => ({\n ...createProfileRuntime({ pi, telemetry: options ?? createProfileTelemetry() }),\n resources: [\n {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-profile',\n description:\n 'Configure DoomPi profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.',\n },\n ],\n },\n ],\n}));\nexport default profileExtension;\n"],"mappings":"6PAKA,MAAM,EAAiB,4BACV,GAAA,EAAmBA,EAAAA,kBAAAA,CAAoC,GAAiB,CAAE,KAAI,cAAe,CACxG,GAAGC,EAAAA,qBAAqB,CAAE,KAAI,UAAW,GAAWC,EAAAA,uBAAuB,CAAE,CAAC,EAC9E,UAAW,CACT,CACE,OAAQ,EACR,UAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,KACA,OAAQ,CACN,CACE,KAAM,wBACN,YACE,+OACJ,CACF,CACF,CACF,CACF,EAAE"}
|
package/dist/extensions/pi.d.cts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { ProfileTelemetry } from "../types/telemetry.cjs";
|
|
2
|
+
//#region src/extensions/pi.d.ts
|
|
3
|
+
export declare const profileExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<ProfileTelemetry>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { profileExtension as default };
|
|
6
|
+
//# sourceMappingURL=pi.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;qBAMa,wEAAgB,mBAAA"}
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { ProfileTelemetry } from "../types/telemetry.mjs";
|
|
2
|
+
//#region src/extensions/pi.d.ts
|
|
3
|
+
export declare const profileExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<ProfileTelemetry>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { profileExtension as default };
|
|
6
|
+
//# sourceMappingURL=pi.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;qBAMa,wEAAgB,mBAAA"}
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import e
|
|
1
|
+
import{createProfileTelemetry as e}from"../services/logSinkTelemetry/index.mjs";import{createProfileRuntime as t}from"../controllers/profileRuntime.mjs";import{definePiExtension as n}from"@agimon-ai/doompi-core/pi-extension";const r=`@agimon-ai/doompi-profile`,i=n(r,({pi:n,options:i})=>({...t({pi:n,telemetry:i??e()}),resources:[{source:r,moduleUrl:import.meta.url,skills:[{name:`doompi-author-profile`,description:`Configure DoomPi profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.`}]}]}));export{i as default,i as profileExtension};
|
|
2
|
+
//# sourceMappingURL=pi.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension } from '@agimon-ai/doompi-core/pi-extension';\n\nimport { createProfileRuntime } from '../controllers/profileRuntime';\nimport { createProfileTelemetry } from '../services/logSinkTelemetry';\nimport type { ProfileTelemetry } from '../types/telemetry';\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-profile';\nexport const profileExtension = definePiExtension<ProfileTelemetry>(PACKAGE_SOURCE, ({ pi, options }) => ({\n ...createProfileRuntime({ pi, telemetry: options ?? createProfileTelemetry() }),\n resources: [\n {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-profile',\n description:\n 'Configure DoomPi profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.',\n },\n ],\n },\n ],\n}));\nexport default profileExtension;\n"],"mappings":"iOAKA,MAAM,EAAiB,4BACV,EAAmB,EAAoC,GAAiB,CAAE,KAAI,cAAe,CACxG,GAAG,EAAqB,CAAE,KAAI,UAAW,GAAW,EAAuB,CAAE,CAAC,EAC9E,UAAW,CACT,CACE,OAAQ,EACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,wBACN,YACE,+OACJ,CACF,CACF,CACF,CACF,EAAE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../controllers/profileServer.cjs"),t=require("../services/packageResources/index.cjs"),n=(0,require("@agimon-ai/doompi-core/server-facet").defineServerPlugin)({name:`@agimon-ai/doompi-profile`,session:({agent:n})=>({commands:n?[e.createProfileServerCommand(n)]:[],resources:[{name:`doompi/profile-config`,kind:`context`,read:e.readSelectedPersona},{name:`doompi-author-profile`,kind:`skill`,read:()=>t.readPackageResource(`src/prompts/doompi-author-profile/SKILL.md`)}],hooks:[e.profileIdentityHook]})});exports.default=n,exports.profileServerFacet=n;
|
|
2
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["defineServerPlugin","createProfileServerCommand","readSelectedPersona","readPackageResource","profileIdentityHook"],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { createProfileServerCommand, profileIdentityHook, readSelectedPersona } from '../controllers/profileServer';\nimport { readPackageResource } from '../services/packageResources';\nexport const profileServerFacet = defineServerPlugin({\n name: '@agimon-ai/doompi-profile',\n session: ({ agent }) => ({\n commands: agent ? [createProfileServerCommand(agent)] : [],\n resources: [\n { name: 'doompi/profile-config', kind: 'context', read: readSelectedPersona },\n {\n name: 'doompi-author-profile',\n kind: 'skill',\n read: () => readPackageResource('src/prompts/doompi-author-profile/SKILL.md'),\n },\n ],\n hooks: [profileIdentityHook],\n }),\n});\n\nexport default profileServerFacet;\n"],"mappings":"uMAIa,GAAA,+CAAqBA,CAAAA,CAAAA,mBAAAA,CAAmB,CACnD,KAAM,4BACN,SAAU,CAAE,YAAa,CACvB,SAAU,EAAQ,CAACC,EAAAA,2BAA2B,CAAK,CAAC,EAAI,CAAC,EACzD,UAAW,CACT,CAAE,KAAM,wBAAyB,KAAM,UAAW,KAAMC,EAAAA,mBAAoB,EAC5E,CACE,KAAM,wBACN,KAAM,QACN,SAAYC,EAAAA,oBAAoB,4CAA4C,CAC9E,CACF,EACA,MAAO,CAACC,EAAAA,mBAAmB,CAC7B,EACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.cts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAIa,kEAAkB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAIa,kEAAkB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createProfileServerCommand as e,profileIdentityHook as t,readSelectedPersona as n}from"../controllers/profileServer.mjs";import{readPackageResource as r}from"../services/packageResources/index.mjs";import{defineServerPlugin as i}from"@agimon-ai/doompi-core/server-facet";const a=i({name:`@agimon-ai/doompi-profile`,session:({agent:i})=>({commands:i?[e(i)]:[],resources:[{name:`doompi/profile-config`,kind:`context`,read:n},{name:`doompi-author-profile`,kind:`skill`,read:()=>r(`src/prompts/doompi-author-profile/SKILL.md`)}],hooks:[t]})});export{a as default,a as profileServerFacet};
|
|
2
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { createProfileServerCommand, profileIdentityHook, readSelectedPersona } from '../controllers/profileServer';\nimport { readPackageResource } from '../services/packageResources';\nexport const profileServerFacet = defineServerPlugin({\n name: '@agimon-ai/doompi-profile',\n session: ({ agent }) => ({\n commands: agent ? [createProfileServerCommand(agent)] : [],\n resources: [\n { name: 'doompi/profile-config', kind: 'context', read: readSelectedPersona },\n {\n name: 'doompi-author-profile',\n kind: 'skill',\n read: () => readPackageResource('src/prompts/doompi-author-profile/SKILL.md'),\n },\n ],\n hooks: [profileIdentityHook],\n }),\n});\n\nexport default profileServerFacet;\n"],"mappings":"sRAIA,MAAa,EAAqB,EAAmB,CACnD,KAAM,4BACN,SAAU,CAAE,YAAa,CACvB,SAAU,EAAQ,CAAC,EAA2B,CAAK,CAAC,EAAI,CAAC,EACzD,UAAW,CACT,CAAE,KAAM,wBAAyB,KAAM,UAAW,KAAM,CAAoB,EAC5E,CACE,KAAM,wBACN,KAAM,QACN,SAAY,EAAoB,4CAA4C,CAC9E,CACF,EACA,MAAO,CAAC,CAAmB,CAC7B,EACF,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./services/logSinkTelemetry/index.cjs"),t=require("./services/profileText/index.cjs"),n=require("./types/telemetry.cjs");exports.PROFILE_EVENT=n.PROFILE_EVENT,exports.PROFILE_STATUS_KEY=t.PROFILE_STATUS_KEY,exports.createProfileTelemetry=e.createProfileTelemetry,exports.profileDescription=t.profileDescription,exports.profileItems=t.profileItems,exports.profileStatus=t.profileStatus,exports.profileSummary=t.profileSummary,exports.profileTitle=t.profileTitle;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { PROFILE_EVENT, ProfileEventAttributes, ProfileEventName, ProfileTelemetry } from "./types/telemetry.cjs";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import { PROFILE_STATUS_KEY, profileDescription, profileItems, profileStatus, profileSummary, profileTitle } from "./services/profileText.cjs";
|
|
6
|
-
export { PROFILE_EVENT, PROFILE_STATUS_KEY, type ProfileEventAttributes, type ProfileEventName, type ProfileTelemetry, type ProfileTelemetryOptions, createProfileTelemetry, personaExtension, profileDescription, profileExtension, profileItems, profileStatus, profileSummary, profileTitle };
|
|
2
|
+
import { ProfileTelemetryOptions, createProfileTelemetry } from "./services/logSinkTelemetry/index.cjs";
|
|
3
|
+
import { PROFILE_STATUS_KEY, profileDescription, profileItems, profileStatus, profileSummary, profileTitle } from "./services/profileText/index.cjs";
|
|
4
|
+
export { PROFILE_EVENT, PROFILE_STATUS_KEY, type ProfileEventAttributes, type ProfileEventName, type ProfileTelemetry, type ProfileTelemetryOptions, createProfileTelemetry, profileDescription, profileItems, profileStatus, profileSummary, profileTitle };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { PROFILE_EVENT, ProfileEventAttributes, ProfileEventName, ProfileTelemetry } from "./types/telemetry.mjs";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import { PROFILE_STATUS_KEY, profileDescription, profileItems, profileStatus, profileSummary, profileTitle } from "./services/profileText.mjs";
|
|
6
|
-
export { PROFILE_EVENT, PROFILE_STATUS_KEY, type ProfileEventAttributes, type ProfileEventName, type ProfileTelemetry, type ProfileTelemetryOptions, createProfileTelemetry, personaExtension, profileDescription, profileExtension, profileItems, profileStatus, profileSummary, profileTitle };
|
|
2
|
+
import { ProfileTelemetryOptions, createProfileTelemetry } from "./services/logSinkTelemetry/index.mjs";
|
|
3
|
+
import { PROFILE_STATUS_KEY, profileDescription, profileItems, profileStatus, profileSummary, profileTitle } from "./services/profileText/index.mjs";
|
|
4
|
+
export { PROFILE_EVENT, PROFILE_STATUS_KEY, type ProfileEventAttributes, type ProfileEventName, type ProfileTelemetry, type ProfileTelemetryOptions, createProfileTelemetry, profileDescription, profileItems, profileStatus, profileSummary, profileTitle };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createProfileTelemetry as e}from"./
|
|
1
|
+
import{createProfileTelemetry as e}from"./services/logSinkTelemetry/index.mjs";import{PROFILE_STATUS_KEY as t,profileDescription as n,profileItems as r,profileStatus as i,profileSummary as a,profileTitle as o}from"./services/profileText/index.mjs";import{PROFILE_EVENT as s}from"./types/telemetry.mjs";export{s as PROFILE_EVENT,t as PROFILE_STATUS_KEY,e as createProfileTelemetry,n as profileDescription,r as profileItems,i as profileStatus,a as profileSummary,o as profileTitle};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/api-contracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":"AAGA,MAAa,GAAA,gDAAeA,CAAAA,CAAAA,kBAAAA,CAAkB,CAAE,QAAS,EAAG,KAAM,CAAC,EAAG,QAAS,CAAC,EAAG,QAAS,CAAC,CAAE,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/schemas/apiContracts.d.ts
|
|
2
|
+
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
+
export declare const apiContracts: {
|
|
4
|
+
version: 1;
|
|
5
|
+
protocols?: Record<string, string> | undefined;
|
|
6
|
+
schemas?: Record<string, boolean | object> | undefined;
|
|
7
|
+
http: {
|
|
8
|
+
id: string;
|
|
9
|
+
scope: "global" | "session" | "workspace";
|
|
10
|
+
basePath?: string | undefined;
|
|
11
|
+
path: string;
|
|
12
|
+
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
13
|
+
description: string;
|
|
14
|
+
availability?: string | undefined;
|
|
15
|
+
authentication: "device" | "none" | "owner";
|
|
16
|
+
parameters?: {
|
|
17
|
+
name: string;
|
|
18
|
+
in: "header" | "path" | "query";
|
|
19
|
+
required: boolean;
|
|
20
|
+
schema: boolean | object;
|
|
21
|
+
}[] | undefined;
|
|
22
|
+
body?: {
|
|
23
|
+
contentType: string;
|
|
24
|
+
contentTypes?: string[] | undefined;
|
|
25
|
+
required: boolean;
|
|
26
|
+
schema: boolean | object;
|
|
27
|
+
} | undefined;
|
|
28
|
+
responses: Record<string, {
|
|
29
|
+
description: string;
|
|
30
|
+
contentType?: string | undefined;
|
|
31
|
+
schema?: boolean | object | undefined;
|
|
32
|
+
events?: Record<string, boolean | object> | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
}[];
|
|
35
|
+
sockets: {
|
|
36
|
+
id: string;
|
|
37
|
+
scope: "global" | "session" | "workspace";
|
|
38
|
+
description: string;
|
|
39
|
+
availability?: string | undefined;
|
|
40
|
+
service: string;
|
|
41
|
+
member: string;
|
|
42
|
+
direction: "client-to-server" | "server-to-client";
|
|
43
|
+
kind: "channel" | "method" | "state";
|
|
44
|
+
input: boolean | object;
|
|
45
|
+
output?: boolean | object | undefined;
|
|
46
|
+
errors?: boolean | object | undefined;
|
|
47
|
+
}[];
|
|
48
|
+
dynamic: string[];
|
|
49
|
+
gaps?: string[] | undefined;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { apiContracts as default };
|
|
53
|
+
//# sourceMappingURL=apiContracts.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.d.cts","names":[],"sources":["../../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|