@agimon-ai/doompi 0.0.1-alpha.10 → 0.0.1-alpha.11
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/dist/extensions/entries/autoStop.cjs +1 -1
- package/dist/extensions/entries/autoStop.cjs.map +1 -1
- package/dist/extensions/entries/autoStop.d.cts.map +1 -1
- package/dist/extensions/entries/autoStop.d.mts.map +1 -1
- package/dist/extensions/entries/autoStop.mjs +1 -1
- package/dist/extensions/entries/autoStop.mjs.map +1 -1
- package/dist/extensions/entries/notifications.cjs +1 -1
- package/dist/extensions/entries/notifications.cjs.map +1 -1
- package/dist/extensions/entries/notifications.mjs +1 -1
- package/dist/extensions/entries/notifications.mjs.map +1 -1
- package/dist/services/extensionAssembler.cjs +1 -1
- package/dist/services/extensionAssembler.cjs.map +1 -1
- package/dist/services/extensionAssembler.d.cts +4 -1
- package/dist/services/extensionAssembler.d.cts.map +1 -1
- package/dist/services/extensionAssembler.d.mts +4 -1
- package/dist/services/extensionAssembler.d.mts.map +1 -1
- package/dist/services/extensionAssembler.mjs +1 -1
- package/dist/services/extensionAssembler.mjs.map +1 -1
- package/package.json +18 -18
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e){let t,n=()=>{t&&=(clearTimeout(t),void 0)};e.on(`input`,()=>{n()}),e.on(`agent_start`,()=>{n()}),e.on(`session_shutdown`,()=>{n()})
|
|
1
|
+
function e(e){let t,n=()=>{t&&=(clearTimeout(t),void 0)};e.on(`input`,()=>{n()}),e.on(`agent_start`,()=>{n()}),e.on(`session_shutdown`,()=>{n()});let r=(e,n)=>{t=setTimeout(()=>{if(t=void 0,!e.hasPendingMessages()){if(e.isIdle()){e.shutdown();return}r(e,100)}},n)};e.on(`agent_settled`,(e,t)=>{n(),!t.hasPendingMessages()&&r(t,5e3)})}exports.autoStop=e;
|
|
2
2
|
//# sourceMappingURL=autoStop.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoStop.cjs","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nconst AUTO_STOP_COOLDOWN_MS = 5_000;\n\nexport function autoStop(pi: ExtensionAPI): void {\n let shutdownTimer: NodeJS.Timeout | undefined;\n\n const cancelScheduledShutdown = () => {\n if (!shutdownTimer) return;\n clearTimeout(shutdownTimer);\n shutdownTimer = undefined;\n };\n\n pi.on('input', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('agent_start', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('session_shutdown', () => {\n cancelScheduledShutdown();\n });\n\n
|
|
1
|
+
{"version":3,"file":"autoStop.cjs","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nconst AUTO_STOP_COOLDOWN_MS = 5_000;\nconst AUTO_STOP_IDLE_RETRY_MS = 100;\n\nexport function autoStop(pi: ExtensionAPI): void {\n let shutdownTimer: NodeJS.Timeout | undefined;\n\n const cancelScheduledShutdown = () => {\n if (!shutdownTimer) return;\n clearTimeout(shutdownTimer);\n shutdownTimer = undefined;\n };\n\n pi.on('input', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('agent_start', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('session_shutdown', () => {\n cancelScheduledShutdown();\n });\n\n const scheduleShutdown = (context: ExtensionContext, delayMs: number): void => {\n shutdownTimer = setTimeout(() => {\n shutdownTimer = undefined;\n if (context.hasPendingMessages()) return;\n if (context.isIdle()) {\n context.shutdown();\n return;\n }\n scheduleShutdown(context, AUTO_STOP_IDLE_RETRY_MS);\n }, delayMs);\n };\n\n pi.on('agent_settled', (_event, context) => {\n cancelScheduledShutdown();\n if (context.hasPendingMessages()) return;\n scheduleShutdown(context, AUTO_STOP_COOLDOWN_MS);\n });\n}\n"],"mappings":"AAKA,SAAgB,EAAS,EAAwB,CAC/C,IAAI,EAEE,MAAgC,CAC/B,AAEL,KADA,aAAa,EAAc,CACX,IAAA,KAGlB,EAAG,GAAG,YAAe,CACnB,GAAyB,EACzB,CAEF,EAAG,GAAG,kBAAqB,CACzB,GAAyB,EACzB,CAEF,EAAG,GAAG,uBAA0B,CAC9B,GAAyB,EACzB,CAEF,IAAM,GAAoB,EAA2B,IAA0B,CAC7E,EAAgB,eAAiB,CAC/B,KAAgB,IAAA,GACZ,GAAQ,oBAAoB,CAChC,IAAI,EAAQ,QAAQ,CAAE,CACpB,EAAQ,UAAU,CAClB,OAEF,EAAiB,EAAS,IAAwB,GACjD,EAAQ,EAGb,EAAG,GAAG,iBAAkB,EAAQ,IAAY,CAC1C,GAAyB,CACrB,GAAQ,oBAAoB,EAChC,EAAiB,EAAS,IAAsB,EAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoStop.d.cts","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"autoStop.d.cts","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"mappings":";;;iBAKgB,QAAA,CAAS,EAAA,EAAI,YAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoStop.d.mts","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"autoStop.d.mts","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"mappings":";;;iBAKgB,QAAA,CAAS,EAAA,EAAI,YAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e){let t,n=()=>{t&&=(clearTimeout(t),void 0)};e.on(`input`,()=>{n()}),e.on(`agent_start`,()=>{n()}),e.on(`session_shutdown`,()=>{n()})
|
|
1
|
+
function e(e){let t,n=()=>{t&&=(clearTimeout(t),void 0)};e.on(`input`,()=>{n()}),e.on(`agent_start`,()=>{n()}),e.on(`session_shutdown`,()=>{n()});let r=(e,n)=>{t=setTimeout(()=>{if(t=void 0,!e.hasPendingMessages()){if(e.isIdle()){e.shutdown();return}r(e,100)}},n)};e.on(`agent_settled`,(e,t)=>{n(),!t.hasPendingMessages()&&r(t,5e3)})}export{e as autoStop};
|
|
2
2
|
//# sourceMappingURL=autoStop.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoStop.mjs","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nconst AUTO_STOP_COOLDOWN_MS = 5_000;\n\nexport function autoStop(pi: ExtensionAPI): void {\n let shutdownTimer: NodeJS.Timeout | undefined;\n\n const cancelScheduledShutdown = () => {\n if (!shutdownTimer) return;\n clearTimeout(shutdownTimer);\n shutdownTimer = undefined;\n };\n\n pi.on('input', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('agent_start', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('session_shutdown', () => {\n cancelScheduledShutdown();\n });\n\n
|
|
1
|
+
{"version":3,"file":"autoStop.mjs","names":[],"sources":["../../../src/extensions/entries/autoStop.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nconst AUTO_STOP_COOLDOWN_MS = 5_000;\nconst AUTO_STOP_IDLE_RETRY_MS = 100;\n\nexport function autoStop(pi: ExtensionAPI): void {\n let shutdownTimer: NodeJS.Timeout | undefined;\n\n const cancelScheduledShutdown = () => {\n if (!shutdownTimer) return;\n clearTimeout(shutdownTimer);\n shutdownTimer = undefined;\n };\n\n pi.on('input', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('agent_start', () => {\n cancelScheduledShutdown();\n });\n\n pi.on('session_shutdown', () => {\n cancelScheduledShutdown();\n });\n\n const scheduleShutdown = (context: ExtensionContext, delayMs: number): void => {\n shutdownTimer = setTimeout(() => {\n shutdownTimer = undefined;\n if (context.hasPendingMessages()) return;\n if (context.isIdle()) {\n context.shutdown();\n return;\n }\n scheduleShutdown(context, AUTO_STOP_IDLE_RETRY_MS);\n }, delayMs);\n };\n\n pi.on('agent_settled', (_event, context) => {\n cancelScheduledShutdown();\n if (context.hasPendingMessages()) return;\n scheduleShutdown(context, AUTO_STOP_COOLDOWN_MS);\n });\n}\n"],"mappings":"AAKA,SAAgB,EAAS,EAAwB,CAC/C,IAAI,EAEE,MAAgC,CAC/B,AAEL,KADA,aAAa,EAAc,CACX,IAAA,KAGlB,EAAG,GAAG,YAAe,CACnB,GAAyB,EACzB,CAEF,EAAG,GAAG,kBAAqB,CACzB,GAAyB,EACzB,CAEF,EAAG,GAAG,uBAA0B,CAC9B,GAAyB,EACzB,CAEF,IAAM,GAAoB,EAA2B,IAA0B,CAC7E,EAAgB,eAAiB,CAC/B,KAAgB,IAAA,GACZ,GAAQ,oBAAoB,CAChC,IAAI,EAAQ,QAAQ,CAAE,CACpB,EAAQ,UAAU,CAClB,OAEF,EAAiB,EAAS,IAAwB,GACjD,EAAQ,EAGb,EAAG,GAAG,iBAAkB,EAAQ,IAAY,CAC1C,GAAyB,CACrB,GAAQ,oBAAoB,EAChC,EAAiB,EAAS,IAAsB,EAChD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`./shellTitleController.cjs`);let n=require(`node:path`);n=e.__toESM(n,1);let r=require(`@agimon-ai/doompi-extension-contracts`);function i(e){let t=e.replace(/\s+/g,` `).trim();if(t)return t.length>36?`${t.slice(0,35)}…`:t}function a(e,t,r){let i=n.default.basename(t),a=e.getSessionName()??r;return a?`π - ${a} - ${i}`:`π - ${i}`}function o(e){let t=e.replace(/\s+/g,` `).trim();return t.length>240?`${t.slice(0,239)}…`:t}async function s(e,t,n){try{return(await e.exec(t,n,{timeout:3e3})).code===0}catch{return!1}}async function c(e,t,n=process.platform){let r=o(t.body);await s(e,`cmux`,[`notify`,`--title`,t.title,`--subtitle`,t.subtitle,`--body`,r])||n!==`darwin`||await s(e,`osascript`,[`-e`,`on run argv`,`-e`,`display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)`,`-e`,`end run`,t.title,t.subtitle,r])}function l(e,t,n){let r=e.confirm.bind(e);e.confirm=(e,i,a)=>(t()&&n(`${e}: ${i}`),r(e,i,a));let i=e.select.bind(e);e.select=(e,r,a)=>(t()&&n(e),i(e,r,a));let a=e.input.bind(e);e.input=(e,r,i)=>(t()&&n(e),a(e,r,i));let o=e.editor.bind(e);e.editor=(e,r)=>(t()&&n(e),o(e,r))}function u(e,o){if(process.env.PI_SUBAGENT_CHILD)return;let s=o??t.createWorkerTitleController(),u=!1,d=!1,f,p=new WeakSet,m=e=>t=>e.ui.setTitle(t),h=t=>{t
|
|
1
|
+
const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`./shellTitleController.cjs`);let n=require(`node:path`);n=e.__toESM(n,1);let r=require(`@agimon-ai/doompi-extension-contracts`);function i(e){let t=e.replace(/\s+/g,` `).trim();if(t)return t.length>36?`${t.slice(0,35)}…`:t}function a(e,t,r){let i=n.default.basename(t),a=e.getSessionName()??r;return a?`π - ${a} - ${i}`:`π - ${i}`}function o(e){let t=e.replace(/\s+/g,` `).trim();return t.length>240?`${t.slice(0,239)}…`:t}async function s(e,t,n){try{return(await e.exec(t,n,{timeout:3e3})).code===0}catch{return!1}}async function c(e,t,n=process.platform){let r=o(t.body);await s(e,`cmux`,[`notify`,`--title`,t.title,`--subtitle`,t.subtitle,`--body`,r])||n!==`darwin`||await s(e,`osascript`,[`-e`,`on run argv`,`-e`,`display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)`,`-e`,`end run`,t.title,t.subtitle,r])}function l(e,t,n){let r=e.confirm.bind(e);e.confirm=(e,i,a)=>(t()&&n(`${e}: ${i}`),r(e,i,a));let i=e.select.bind(e);e.select=(e,r,a)=>(t()&&n(e),i(e,r,a));let a=e.input.bind(e);e.input=(e,r,i)=>(t()&&n(e),a(e,r,i));let o=e.editor.bind(e);e.editor=(e,r)=>(t()&&n(e),o(e,r))}function u(e,o){if(process.env.PI_SUBAGENT_CHILD)return;let s=o??t.createWorkerTitleController(),u=!1,d=!1,f,p=new WeakSet,m=e=>t=>e.ui.setTitle(t),h=e=>e.hasUI&&e.mode!==`rpc`,g=t=>{h(t)&&s.stop(a(e,t.cwd,f),m(t))},_=t=>{h(t)&&s.start(a(e,t.cwd,f),m(t))},v=t=>{c(e,{title:`Pi needs your input`,subtitle:`Approval or feedback required`,body:t})},y=(0,r.subscribeToAskUserEvents)(e.events,{onPrompt(e){v(e.questions[0]?.question??`The agent is waiting for your feedback.`)},onBlocked(e){d=e.active}});e.on(`input`,(t,n)=>{f||t.source===`extension`||(f=i(t.text),f&&h(n)&&s.set(a(e,n.cwd,f),m(n)))}),e.on(`session_start`,(e,t)=>{p.has(t.ui)||(p.add(t.ui),l(t.ui,()=>u&&!d,v))}),e.on(`agent_start`,(e,t)=>{u=!0,_(t)}),e.on(`agent_settled`,async(t,r)=>{u=!1,d=!1,g(r),!r.hasPendingMessages()&&await c(e,{title:`Pi finished`,subtitle:e.getSessionName()??n.default.basename(r.cwd),body:`The agent finished its work and is waiting for you.`})}),e.on(`session_shutdown`,(t,n)=>{u=!1,d=!1,y.dispose(),h(n)&&s.dispose(a(e,n.cwd,f),m(n))})}exports.notifications=u,exports.sendSystemNotification=c;
|
|
2
2
|
//# sourceMappingURL=notifications.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.cjs","names":["path","createWorkerTitleController"],"sources":["../../../src/extensions/entries/notifications.ts"],"sourcesContent":["import path from 'node:path';\nimport { subscribeToAskUserEvents } from '@agimon-ai/doompi-extension-contracts';\nimport type { ExtensionAPI, ExtensionContext, ExtensionUIContext } from '@earendil-works/pi-coding-agent';\nimport { createWorkerTitleController, type ShellTitleController } from './shellTitleController.ts';\n\ninterface Notification {\n title: string;\n subtitle: string;\n body: string;\n}\n\nconst COMMAND_TIMEOUT_MS = 3_000;\nconst EXTENSION_INPUT_SOURCE = 'extension';\nconst INPUT_EVENT = 'input';\nconst MAX_BODY_LENGTH = 240;\nconst MAX_PROMPT_TITLE_LENGTH = 36;\nconst OSASCRIPT_EXPRESSION_FLAG = '-e';\n\nfunction promptTitle(prompt: string): string | undefined {\n const normalized = prompt.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > MAX_PROMPT_TITLE_LENGTH\n ? `${normalized.slice(0, MAX_PROMPT_TITLE_LENGTH - 1)}…`\n : normalized;\n}\n\nfunction shellTabTitle(pi: ExtensionAPI, cwd: string, prompt?: string): string {\n const repository = path.basename(cwd);\n const label = pi.getSessionName() ?? prompt;\n return label ? `π - ${label} - ${repository}` : `π - ${repository}`;\n}\n\nfunction notificationBody(body: string): string {\n const normalized = body.replace(/\\s+/g, ' ').trim();\n return normalized.length > MAX_BODY_LENGTH ? `${normalized.slice(0, MAX_BODY_LENGTH - 1)}…` : normalized;\n}\n\nasync function execute(pi: ExtensionAPI, command: string, args: string[]): Promise<boolean> {\n try {\n const result = await pi.exec(command, args, { timeout: COMMAND_TIMEOUT_MS });\n return result.code === 0;\n } catch {\n return false;\n }\n}\n\nexport async function sendSystemNotification(\n pi: ExtensionAPI,\n notification: Notification,\n platform = process.platform,\n): Promise<void> {\n const body = notificationBody(notification.body);\n const sentToCmux = await execute(pi, 'cmux', [\n 'notify',\n '--title',\n notification.title,\n '--subtitle',\n notification.subtitle,\n '--body',\n body,\n ]);\n if (sentToCmux || platform !== 'darwin') return;\n\n await execute(pi, 'osascript', [\n OSASCRIPT_EXPRESSION_FLAG,\n 'on run argv',\n OSASCRIPT_EXPRESSION_FLAG,\n 'display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)',\n OSASCRIPT_EXPRESSION_FLAG,\n 'end run',\n notification.title,\n notification.subtitle,\n body,\n ]);\n}\n\nfunction wrapAttentionDialogs(\n ui: ExtensionUIContext,\n shouldNotify: () => boolean,\n notify: (title: string) => void,\n): void {\n const originalConfirm = ui.confirm.bind(ui);\n ui.confirm = (title, message, options) => {\n if (shouldNotify()) notify(`${title}: ${message}`);\n return originalConfirm(title, message, options);\n };\n\n const originalSelect = ui.select.bind(ui);\n ui.select = (title, options, dialogOptions) => {\n if (shouldNotify()) notify(title);\n return originalSelect(title, options, dialogOptions);\n };\n\n const originalInput = ui.input.bind(ui);\n ui.input = (title, placeholder, options) => {\n if (shouldNotify()) notify(title);\n return originalInput(title, placeholder, options);\n };\n\n const originalEditor = ui.editor.bind(ui);\n ui.editor = (title, prefill) => {\n if (shouldNotify()) notify(title);\n return originalEditor(title, prefill);\n };\n}\n\nexport function notifications(pi: ExtensionAPI, titleController?: ShellTitleController): void {\n if (process.env.PI_SUBAGENT_CHILD) return;\n\n const titles = titleController ?? createWorkerTitleController();\n let agentRunning = false;\n let askUserBlocked = false;\n let firstPromptTitle: string | undefined;\n const wrappedUis = new WeakSet<ExtensionUIContext>();\n const writeTitle = (context: ExtensionContext) => (title: string) => context.ui.setTitle(title);\n const stopTitleAnimation = (context: ExtensionContext) => {\n if (!context
|
|
1
|
+
{"version":3,"file":"notifications.cjs","names":["path","createWorkerTitleController"],"sources":["../../../src/extensions/entries/notifications.ts"],"sourcesContent":["import path from 'node:path';\nimport { subscribeToAskUserEvents } from '@agimon-ai/doompi-extension-contracts';\nimport type { ExtensionAPI, ExtensionContext, ExtensionUIContext } from '@earendil-works/pi-coding-agent';\nimport { createWorkerTitleController, type ShellTitleController } from './shellTitleController.ts';\n\ninterface Notification {\n title: string;\n subtitle: string;\n body: string;\n}\n\nconst COMMAND_TIMEOUT_MS = 3_000;\nconst EXTENSION_INPUT_SOURCE = 'extension';\nconst INPUT_EVENT = 'input';\nconst MAX_BODY_LENGTH = 240;\nconst MAX_PROMPT_TITLE_LENGTH = 36;\nconst OSASCRIPT_EXPRESSION_FLAG = '-e';\n\nfunction promptTitle(prompt: string): string | undefined {\n const normalized = prompt.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > MAX_PROMPT_TITLE_LENGTH\n ? `${normalized.slice(0, MAX_PROMPT_TITLE_LENGTH - 1)}…`\n : normalized;\n}\n\nfunction shellTabTitle(pi: ExtensionAPI, cwd: string, prompt?: string): string {\n const repository = path.basename(cwd);\n const label = pi.getSessionName() ?? prompt;\n return label ? `π - ${label} - ${repository}` : `π - ${repository}`;\n}\n\nfunction notificationBody(body: string): string {\n const normalized = body.replace(/\\s+/g, ' ').trim();\n return normalized.length > MAX_BODY_LENGTH ? `${normalized.slice(0, MAX_BODY_LENGTH - 1)}…` : normalized;\n}\n\nasync function execute(pi: ExtensionAPI, command: string, args: string[]): Promise<boolean> {\n try {\n const result = await pi.exec(command, args, { timeout: COMMAND_TIMEOUT_MS });\n return result.code === 0;\n } catch {\n return false;\n }\n}\n\nexport async function sendSystemNotification(\n pi: ExtensionAPI,\n notification: Notification,\n platform = process.platform,\n): Promise<void> {\n const body = notificationBody(notification.body);\n const sentToCmux = await execute(pi, 'cmux', [\n 'notify',\n '--title',\n notification.title,\n '--subtitle',\n notification.subtitle,\n '--body',\n body,\n ]);\n if (sentToCmux || platform !== 'darwin') return;\n\n await execute(pi, 'osascript', [\n OSASCRIPT_EXPRESSION_FLAG,\n 'on run argv',\n OSASCRIPT_EXPRESSION_FLAG,\n 'display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)',\n OSASCRIPT_EXPRESSION_FLAG,\n 'end run',\n notification.title,\n notification.subtitle,\n body,\n ]);\n}\n\nfunction wrapAttentionDialogs(\n ui: ExtensionUIContext,\n shouldNotify: () => boolean,\n notify: (title: string) => void,\n): void {\n const originalConfirm = ui.confirm.bind(ui);\n ui.confirm = (title, message, options) => {\n if (shouldNotify()) notify(`${title}: ${message}`);\n return originalConfirm(title, message, options);\n };\n\n const originalSelect = ui.select.bind(ui);\n ui.select = (title, options, dialogOptions) => {\n if (shouldNotify()) notify(title);\n return originalSelect(title, options, dialogOptions);\n };\n\n const originalInput = ui.input.bind(ui);\n ui.input = (title, placeholder, options) => {\n if (shouldNotify()) notify(title);\n return originalInput(title, placeholder, options);\n };\n\n const originalEditor = ui.editor.bind(ui);\n ui.editor = (title, prefill) => {\n if (shouldNotify()) notify(title);\n return originalEditor(title, prefill);\n };\n}\n\nexport function notifications(pi: ExtensionAPI, titleController?: ShellTitleController): void {\n if (process.env.PI_SUBAGENT_CHILD) return;\n\n const titles = titleController ?? createWorkerTitleController();\n let agentRunning = false;\n let askUserBlocked = false;\n let firstPromptTitle: string | undefined;\n const wrappedUis = new WeakSet<ExtensionUIContext>();\n const writeTitle = (context: ExtensionContext) => (title: string) => context.ui.setTitle(title);\n const supportsShellTitle = (context: ExtensionContext): boolean => context.hasUI && context.mode !== 'rpc';\n const stopTitleAnimation = (context: ExtensionContext) => {\n if (!supportsShellTitle(context)) return;\n titles.stop(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n };\n const startTitleAnimation = (context: ExtensionContext) => {\n if (!supportsShellTitle(context)) return;\n titles.start(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n };\n const notifyAttention = (body: string) => {\n void sendSystemNotification(pi, {\n title: 'Pi needs your input',\n subtitle: 'Approval or feedback required',\n body,\n });\n };\n\n const askUserSubscriptions = subscribeToAskUserEvents(pi.events, {\n onPrompt(prompt) {\n const firstQuestion = prompt.questions[0]?.question ?? 'The agent is waiting for your feedback.';\n notifyAttention(firstQuestion);\n },\n onBlocked(payload) {\n askUserBlocked = payload.active;\n },\n });\n\n pi.on(INPUT_EVENT, (event, context) => {\n if (firstPromptTitle || event.source === EXTENSION_INPUT_SOURCE) return;\n\n firstPromptTitle = promptTitle(event.text);\n if (firstPromptTitle && supportsShellTitle(context)) {\n titles.set(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n }\n });\n\n pi.on('session_start', (_event, context) => {\n if (wrappedUis.has(context.ui)) return;\n wrappedUis.add(context.ui);\n wrapAttentionDialogs(context.ui, () => agentRunning && !askUserBlocked, notifyAttention);\n });\n\n pi.on('agent_start', (_event, context) => {\n agentRunning = true;\n startTitleAnimation(context);\n });\n\n pi.on('agent_settled', async (_event, context) => {\n agentRunning = false;\n askUserBlocked = false;\n stopTitleAnimation(context);\n if (context.hasPendingMessages()) return;\n\n await sendSystemNotification(pi, {\n title: 'Pi finished',\n subtitle: pi.getSessionName() ?? path.basename(context.cwd),\n body: 'The agent finished its work and is waiting for you.',\n });\n });\n\n pi.on('session_shutdown', (_event, context) => {\n agentRunning = false;\n askUserBlocked = false;\n askUserSubscriptions.dispose();\n if (supportsShellTitle(context)) {\n titles.dispose(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createWorkerTitleController as e}from"./shellTitleController.mjs";import t from"node:path";import{subscribeToAskUserEvents as n}from"@agimon-ai/doompi-extension-contracts";function r(e){let t=e.replace(/\s+/g,` `).trim();if(t)return t.length>36?`${t.slice(0,35)}…`:t}function i(e,n,r){let i=t.basename(n),a=e.getSessionName()??r;return a?`π - ${a} - ${i}`:`π - ${i}`}function a(e){let t=e.replace(/\s+/g,` `).trim();return t.length>240?`${t.slice(0,239)}…`:t}async function o(e,t,n){try{return(await e.exec(t,n,{timeout:3e3})).code===0}catch{return!1}}async function s(e,t,n=process.platform){let r=a(t.body);await o(e,`cmux`,[`notify`,`--title`,t.title,`--subtitle`,t.subtitle,`--body`,r])||n!==`darwin`||await o(e,`osascript`,[`-e`,`on run argv`,`-e`,`display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)`,`-e`,`end run`,t.title,t.subtitle,r])}function c(e,t,n){let r=e.confirm.bind(e);e.confirm=(e,i,a)=>(t()&&n(`${e}: ${i}`),r(e,i,a));let i=e.select.bind(e);e.select=(e,r,a)=>(t()&&n(e),i(e,r,a));let a=e.input.bind(e);e.input=(e,r,i)=>(t()&&n(e),a(e,r,i));let o=e.editor.bind(e);e.editor=(e,r)=>(t()&&n(e),o(e,r))}function l(a,o){if(process.env.PI_SUBAGENT_CHILD)return;let l=o??e(),u=!1,d=!1,f,p=new WeakSet,m=e=>t=>e.ui.setTitle(t),h=e=>
|
|
1
|
+
import{createWorkerTitleController as e}from"./shellTitleController.mjs";import t from"node:path";import{subscribeToAskUserEvents as n}from"@agimon-ai/doompi-extension-contracts";function r(e){let t=e.replace(/\s+/g,` `).trim();if(t)return t.length>36?`${t.slice(0,35)}…`:t}function i(e,n,r){let i=t.basename(n),a=e.getSessionName()??r;return a?`π - ${a} - ${i}`:`π - ${i}`}function a(e){let t=e.replace(/\s+/g,` `).trim();return t.length>240?`${t.slice(0,239)}…`:t}async function o(e,t,n){try{return(await e.exec(t,n,{timeout:3e3})).code===0}catch{return!1}}async function s(e,t,n=process.platform){let r=a(t.body);await o(e,`cmux`,[`notify`,`--title`,t.title,`--subtitle`,t.subtitle,`--body`,r])||n!==`darwin`||await o(e,`osascript`,[`-e`,`on run argv`,`-e`,`display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)`,`-e`,`end run`,t.title,t.subtitle,r])}function c(e,t,n){let r=e.confirm.bind(e);e.confirm=(e,i,a)=>(t()&&n(`${e}: ${i}`),r(e,i,a));let i=e.select.bind(e);e.select=(e,r,a)=>(t()&&n(e),i(e,r,a));let a=e.input.bind(e);e.input=(e,r,i)=>(t()&&n(e),a(e,r,i));let o=e.editor.bind(e);e.editor=(e,r)=>(t()&&n(e),o(e,r))}function l(a,o){if(process.env.PI_SUBAGENT_CHILD)return;let l=o??e(),u=!1,d=!1,f,p=new WeakSet,m=e=>t=>e.ui.setTitle(t),h=e=>e.hasUI&&e.mode!==`rpc`,g=e=>{h(e)&&l.stop(i(a,e.cwd,f),m(e))},_=e=>{h(e)&&l.start(i(a,e.cwd,f),m(e))},v=e=>{s(a,{title:`Pi needs your input`,subtitle:`Approval or feedback required`,body:e})},y=n(a.events,{onPrompt(e){v(e.questions[0]?.question??`The agent is waiting for your feedback.`)},onBlocked(e){d=e.active}});a.on(`input`,(e,t)=>{f||e.source===`extension`||(f=r(e.text),f&&h(t)&&l.set(i(a,t.cwd,f),m(t)))}),a.on(`session_start`,(e,t)=>{p.has(t.ui)||(p.add(t.ui),c(t.ui,()=>u&&!d,v))}),a.on(`agent_start`,(e,t)=>{u=!0,_(t)}),a.on(`agent_settled`,async(e,n)=>{u=!1,d=!1,g(n),!n.hasPendingMessages()&&await s(a,{title:`Pi finished`,subtitle:a.getSessionName()??t.basename(n.cwd),body:`The agent finished its work and is waiting for you.`})}),a.on(`session_shutdown`,(e,t)=>{u=!1,d=!1,y.dispose(),h(t)&&l.dispose(i(a,t.cwd,f),m(t))})}export{l as notifications,s as sendSystemNotification};
|
|
2
2
|
//# sourceMappingURL=notifications.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.mjs","names":[],"sources":["../../../src/extensions/entries/notifications.ts"],"sourcesContent":["import path from 'node:path';\nimport { subscribeToAskUserEvents } from '@agimon-ai/doompi-extension-contracts';\nimport type { ExtensionAPI, ExtensionContext, ExtensionUIContext } from '@earendil-works/pi-coding-agent';\nimport { createWorkerTitleController, type ShellTitleController } from './shellTitleController.ts';\n\ninterface Notification {\n title: string;\n subtitle: string;\n body: string;\n}\n\nconst COMMAND_TIMEOUT_MS = 3_000;\nconst EXTENSION_INPUT_SOURCE = 'extension';\nconst INPUT_EVENT = 'input';\nconst MAX_BODY_LENGTH = 240;\nconst MAX_PROMPT_TITLE_LENGTH = 36;\nconst OSASCRIPT_EXPRESSION_FLAG = '-e';\n\nfunction promptTitle(prompt: string): string | undefined {\n const normalized = prompt.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > MAX_PROMPT_TITLE_LENGTH\n ? `${normalized.slice(0, MAX_PROMPT_TITLE_LENGTH - 1)}…`\n : normalized;\n}\n\nfunction shellTabTitle(pi: ExtensionAPI, cwd: string, prompt?: string): string {\n const repository = path.basename(cwd);\n const label = pi.getSessionName() ?? prompt;\n return label ? `π - ${label} - ${repository}` : `π - ${repository}`;\n}\n\nfunction notificationBody(body: string): string {\n const normalized = body.replace(/\\s+/g, ' ').trim();\n return normalized.length > MAX_BODY_LENGTH ? `${normalized.slice(0, MAX_BODY_LENGTH - 1)}…` : normalized;\n}\n\nasync function execute(pi: ExtensionAPI, command: string, args: string[]): Promise<boolean> {\n try {\n const result = await pi.exec(command, args, { timeout: COMMAND_TIMEOUT_MS });\n return result.code === 0;\n } catch {\n return false;\n }\n}\n\nexport async function sendSystemNotification(\n pi: ExtensionAPI,\n notification: Notification,\n platform = process.platform,\n): Promise<void> {\n const body = notificationBody(notification.body);\n const sentToCmux = await execute(pi, 'cmux', [\n 'notify',\n '--title',\n notification.title,\n '--subtitle',\n notification.subtitle,\n '--body',\n body,\n ]);\n if (sentToCmux || platform !== 'darwin') return;\n\n await execute(pi, 'osascript', [\n OSASCRIPT_EXPRESSION_FLAG,\n 'on run argv',\n OSASCRIPT_EXPRESSION_FLAG,\n 'display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)',\n OSASCRIPT_EXPRESSION_FLAG,\n 'end run',\n notification.title,\n notification.subtitle,\n body,\n ]);\n}\n\nfunction wrapAttentionDialogs(\n ui: ExtensionUIContext,\n shouldNotify: () => boolean,\n notify: (title: string) => void,\n): void {\n const originalConfirm = ui.confirm.bind(ui);\n ui.confirm = (title, message, options) => {\n if (shouldNotify()) notify(`${title}: ${message}`);\n return originalConfirm(title, message, options);\n };\n\n const originalSelect = ui.select.bind(ui);\n ui.select = (title, options, dialogOptions) => {\n if (shouldNotify()) notify(title);\n return originalSelect(title, options, dialogOptions);\n };\n\n const originalInput = ui.input.bind(ui);\n ui.input = (title, placeholder, options) => {\n if (shouldNotify()) notify(title);\n return originalInput(title, placeholder, options);\n };\n\n const originalEditor = ui.editor.bind(ui);\n ui.editor = (title, prefill) => {\n if (shouldNotify()) notify(title);\n return originalEditor(title, prefill);\n };\n}\n\nexport function notifications(pi: ExtensionAPI, titleController?: ShellTitleController): void {\n if (process.env.PI_SUBAGENT_CHILD) return;\n\n const titles = titleController ?? createWorkerTitleController();\n let agentRunning = false;\n let askUserBlocked = false;\n let firstPromptTitle: string | undefined;\n const wrappedUis = new WeakSet<ExtensionUIContext>();\n const writeTitle = (context: ExtensionContext) => (title: string) => context.ui.setTitle(title);\n const stopTitleAnimation = (context: ExtensionContext) => {\n if (!context
|
|
1
|
+
{"version":3,"file":"notifications.mjs","names":[],"sources":["../../../src/extensions/entries/notifications.ts"],"sourcesContent":["import path from 'node:path';\nimport { subscribeToAskUserEvents } from '@agimon-ai/doompi-extension-contracts';\nimport type { ExtensionAPI, ExtensionContext, ExtensionUIContext } from '@earendil-works/pi-coding-agent';\nimport { createWorkerTitleController, type ShellTitleController } from './shellTitleController.ts';\n\ninterface Notification {\n title: string;\n subtitle: string;\n body: string;\n}\n\nconst COMMAND_TIMEOUT_MS = 3_000;\nconst EXTENSION_INPUT_SOURCE = 'extension';\nconst INPUT_EVENT = 'input';\nconst MAX_BODY_LENGTH = 240;\nconst MAX_PROMPT_TITLE_LENGTH = 36;\nconst OSASCRIPT_EXPRESSION_FLAG = '-e';\n\nfunction promptTitle(prompt: string): string | undefined {\n const normalized = prompt.replace(/\\s+/g, ' ').trim();\n if (!normalized) return undefined;\n return normalized.length > MAX_PROMPT_TITLE_LENGTH\n ? `${normalized.slice(0, MAX_PROMPT_TITLE_LENGTH - 1)}…`\n : normalized;\n}\n\nfunction shellTabTitle(pi: ExtensionAPI, cwd: string, prompt?: string): string {\n const repository = path.basename(cwd);\n const label = pi.getSessionName() ?? prompt;\n return label ? `π - ${label} - ${repository}` : `π - ${repository}`;\n}\n\nfunction notificationBody(body: string): string {\n const normalized = body.replace(/\\s+/g, ' ').trim();\n return normalized.length > MAX_BODY_LENGTH ? `${normalized.slice(0, MAX_BODY_LENGTH - 1)}…` : normalized;\n}\n\nasync function execute(pi: ExtensionAPI, command: string, args: string[]): Promise<boolean> {\n try {\n const result = await pi.exec(command, args, { timeout: COMMAND_TIMEOUT_MS });\n return result.code === 0;\n } catch {\n return false;\n }\n}\n\nexport async function sendSystemNotification(\n pi: ExtensionAPI,\n notification: Notification,\n platform = process.platform,\n): Promise<void> {\n const body = notificationBody(notification.body);\n const sentToCmux = await execute(pi, 'cmux', [\n 'notify',\n '--title',\n notification.title,\n '--subtitle',\n notification.subtitle,\n '--body',\n body,\n ]);\n if (sentToCmux || platform !== 'darwin') return;\n\n await execute(pi, 'osascript', [\n OSASCRIPT_EXPRESSION_FLAG,\n 'on run argv',\n OSASCRIPT_EXPRESSION_FLAG,\n 'display notification (item 3 of argv) with title (item 1 of argv) subtitle (item 2 of argv)',\n OSASCRIPT_EXPRESSION_FLAG,\n 'end run',\n notification.title,\n notification.subtitle,\n body,\n ]);\n}\n\nfunction wrapAttentionDialogs(\n ui: ExtensionUIContext,\n shouldNotify: () => boolean,\n notify: (title: string) => void,\n): void {\n const originalConfirm = ui.confirm.bind(ui);\n ui.confirm = (title, message, options) => {\n if (shouldNotify()) notify(`${title}: ${message}`);\n return originalConfirm(title, message, options);\n };\n\n const originalSelect = ui.select.bind(ui);\n ui.select = (title, options, dialogOptions) => {\n if (shouldNotify()) notify(title);\n return originalSelect(title, options, dialogOptions);\n };\n\n const originalInput = ui.input.bind(ui);\n ui.input = (title, placeholder, options) => {\n if (shouldNotify()) notify(title);\n return originalInput(title, placeholder, options);\n };\n\n const originalEditor = ui.editor.bind(ui);\n ui.editor = (title, prefill) => {\n if (shouldNotify()) notify(title);\n return originalEditor(title, prefill);\n };\n}\n\nexport function notifications(pi: ExtensionAPI, titleController?: ShellTitleController): void {\n if (process.env.PI_SUBAGENT_CHILD) return;\n\n const titles = titleController ?? createWorkerTitleController();\n let agentRunning = false;\n let askUserBlocked = false;\n let firstPromptTitle: string | undefined;\n const wrappedUis = new WeakSet<ExtensionUIContext>();\n const writeTitle = (context: ExtensionContext) => (title: string) => context.ui.setTitle(title);\n const supportsShellTitle = (context: ExtensionContext): boolean => context.hasUI && context.mode !== 'rpc';\n const stopTitleAnimation = (context: ExtensionContext) => {\n if (!supportsShellTitle(context)) return;\n titles.stop(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n };\n const startTitleAnimation = (context: ExtensionContext) => {\n if (!supportsShellTitle(context)) return;\n titles.start(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n };\n const notifyAttention = (body: string) => {\n void sendSystemNotification(pi, {\n title: 'Pi needs your input',\n subtitle: 'Approval or feedback required',\n body,\n });\n };\n\n const askUserSubscriptions = subscribeToAskUserEvents(pi.events, {\n onPrompt(prompt) {\n const firstQuestion = prompt.questions[0]?.question ?? 'The agent is waiting for your feedback.';\n notifyAttention(firstQuestion);\n },\n onBlocked(payload) {\n askUserBlocked = payload.active;\n },\n });\n\n pi.on(INPUT_EVENT, (event, context) => {\n if (firstPromptTitle || event.source === EXTENSION_INPUT_SOURCE) return;\n\n firstPromptTitle = promptTitle(event.text);\n if (firstPromptTitle && supportsShellTitle(context)) {\n titles.set(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n }\n });\n\n pi.on('session_start', (_event, context) => {\n if (wrappedUis.has(context.ui)) return;\n wrappedUis.add(context.ui);\n wrapAttentionDialogs(context.ui, () => agentRunning && !askUserBlocked, notifyAttention);\n });\n\n pi.on('agent_start', (_event, context) => {\n agentRunning = true;\n startTitleAnimation(context);\n });\n\n pi.on('agent_settled', async (_event, context) => {\n agentRunning = false;\n askUserBlocked = false;\n stopTitleAnimation(context);\n if (context.hasPendingMessages()) return;\n\n await sendSystemNotification(pi, {\n title: 'Pi finished',\n subtitle: pi.getSessionName() ?? path.basename(context.cwd),\n body: 'The agent finished its work and is waiting for you.',\n });\n });\n\n pi.on('session_shutdown', (_event, context) => {\n agentRunning = false;\n askUserBlocked = false;\n askUserSubscriptions.dispose();\n if (supportsShellTitle(context)) {\n titles.dispose(shellTabTitle(pi, context.cwd, firstPromptTitle), writeTitle(context));\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../adapters/modules/moduleResolution.cjs`);require(`../utils/index.cjs`);let t=require(`@agimon-ai/doompi-config/majorModes`);const n={ownEntry:e.ownEntry,packageEntry:e.packageEntry,optionalPackageEntry:e.optionalPackageEntry,localEntry:e.localEntry};function
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../adapters/modules/moduleResolution.cjs`);require(`../utils/index.cjs`);let t=require(`@agimon-ai/doompi-config/majorModes`);const n=`@agimon-ai/doompi-user-feedback`;function r(e){return e===`@juicesharp/rpiv-ask-user-question`?n:e.startsWith(`@juicesharp/rpiv-ask-user-question/`)?`${n}${e.slice(34)}`:e}const i={ownEntry:e.ownEntry,packageEntry:t=>e.packageEntry(r(t)),optionalPackageEntry:t=>e.optionalPackageEntry(r(t)),localEntry:e.localEntry};function a(t){return t?{ownEntry:e.ownEntry,packageEntry:n=>{let i=r(n);return e.consumerPackageEntry(i,t)??e.packageEntry(i)},optionalPackageEntry:n=>{let i=r(n);return e.consumerPackageEntry(i,t)??e.optionalPackageEntry(i)},localEntry:e.localEntry}:i}const o=`guardrails`,s=`vibe-lint`,c=`code-intel`,l=`plan-mode`,u=`runner`,d=`ask-user`,f=`style-system`,p={autoStop:`autoStop`,domains:`domains`,effort:`effort`,majorMode:`majorMode`,notifications:`notifications`,ollamaProvider:`ollamaProvider`,profile:`profile`,skills:`skills`},m={autocompact:`@agimon-ai/doompi-autocompact/extensions/pi`,doomConfig:`@agimon-ai/doompi-config/pi`,cacheOptimizer:`pi-cache-optimizer/index.ts`,doomUi:`@agimon-ai/doompi-ui/extensions/pi`,fileEdit:`@agimon-ai/doompi-file-edit/extensions/doom`,logSinkTelemetry:`@agimon-ai/doompi-log/extensions/pi`,loop:`@agimon-ai/doompi-loop/extensions/pi`,task:`@agimon-ai/doompi-task/extensions/pi`,voice:`@agimon-ai/doompi-voice/extensions/doom`,goalDoom:`@agimon-ai/doompi-goal/extensions/doom`,goalPi:`@agimon-ai/doompi-goal/extensions/pi`},h=new Set([o,s,c]),g={mcp:`@agimon-ai/doompi-mcp/extensions/pi`,workflow:`@agimon-ai/doompi-workflow/extensions/pi`,dispatcherWorkflow:`@agimon-ai/doompi-workflow/extensions/dispatcher`};function _(e){let n=e.majorModesConfig,r=e.resolvers??i,a=e=>r.ownEntry(e),h=e=>r.packageEntry(e),g=new Set(e.layers),_=e=>g.has(e)?(0,t.layerEntries)(n,e,r):[],v=[];return e.mcpEntry&&v.push(e.mcpEntry),v.push(h(m.logSinkTelemetry)),e.personaEntry&&v.push(e.personaEntry),e.workflowExtension&&v.push(e.workflowExtension),v.push(..._(`agiflow`),..._(o),..._(s),..._(c)),e.preset===`ollama`&&v.push(a(p.ollamaProvider)),v.push(a(p.effort)),v.push(..._(l)),v.push(h(m.task)),v.push(h(m.loop)),v.push(h(m.autocompact)),v.push(h(m.fileEdit)),v.push(..._(u)),v.push(..._(d),..._(f)),v.push(h(m.voice)),v.push(a(p.domains)),v.push(a(p.skills)),v.push(a(p.majorMode)),v.push(a(p.profile)),v.push(h(m.goalDoom)),v.push(h(m.cacheOptimizer)),e.mute||v.push(a(p.notifications)),e.agents&&v.push(..._(`team`)),v.push(h(m.doomUi)),v.push(h(m.doomConfig)),e.autoStop&&v.unshift(a(p.autoStop)),v}function v(e){let n=e.resolvers??i,r=e=>n.packageEntry(e),a=new Set(e.layers),h=r=>a.has(r)?(0,t.layerEntries)(e.majorModesConfig,r,n):[],g=[];return e.mcpEntry&&g.push(e.mcpEntry),g.push(r(m.logSinkTelemetry)),e.personaEntry&&g.push(e.personaEntry),e.preset===`ollama`&&g.push(n.ownEntry(p.ollamaProvider)),g.push(...h(o),...h(s),...h(c),...h(l),...h(u),...h(d),...h(f)),g.push(r(m.goalPi)),g.push(r(m.autocompact)),g.push(r(m.doomConfig)),[...new Set(g)]}function y(e,t){return t?[...e]:e.filter(e=>!h.has(e))}exports.CONTEXT_PACKAGES=g,exports.LAYER_RESOLVERS=i,exports.LEGACY_ASK_USER_PACKAGE=`@juicesharp/rpiv-ask-user-question`,exports.OLLAMA_PRESET=`ollama`,exports.PERSONA_ENTRY=`persona`,exports.USER_FEEDBACK_PACKAGE=n,exports.assembleChildExtensions=v,exports.assembleExtensions=_,exports.canonicalPackageSpecifier=r,exports.createLayerResolvers=a,exports.filterHookDisabledLayers=y;
|
|
2
2
|
//# sourceMappingURL=extensionAssembler.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensionAssembler.cjs","names":["consumerPackageEntry","packageEntry","optionalPackageEntry"],"sources":["../../src/services/extensionAssembler.ts"],"sourcesContent":["import { type LayerResolvers, layerEntries, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { consumerPackageEntry, localEntry, optionalPackageEntry, ownEntry, packageEntry } from '../utils/index.ts';\n\nexport interface ExtensionContext {\n agents: boolean;\n autoStop: boolean;\n mute?: boolean;\n preset?: string;\n mcpEntry?: string;\n personaEntry?: string;\n workflowExtension?: string;\n /** Resolved layer names from the selected major mode. */\n layers: string[];\n majorModesConfig: MajorModesConfig;\n /**\n * How entry names become absolute paths. Defaults to resolving them here.\n *\n * The synced Pi path composes inside a Pi session, where module resolution\n * cannot be relied on, so it substitutes resolvers backed by the map\n * `doom-pi sync` recorded. Both paths therefore run this same function.\n */\n resolvers?: LayerResolvers;\n}\n\nexport const LAYER_RESOLVERS: LayerResolvers = { ownEntry, packageEntry, optionalPackageEntry, localEntry };\n\n/**\n * Resolvers that answer for the consumer repository before the meta-package.\n *\n * A repository declares its own layer packages in `.doom/modes.yaml`, and it is\n * the repository that installs them. Doom Pi owns only the Doom closure, so a\n * consumer specifier has to resolve from the consumer root and everything else\n * falls back to what ships with the installed meta-package.\n *\n * Path-style packages skip all of that: they are already anchored to the config\n * that declared them, so there is no chain to search.\n */\nexport function createLayerResolvers(consumerRoot?: string): LayerResolvers {\n if (!consumerRoot) return LAYER_RESOLVERS;\n return {\n ownEntry,\n packageEntry: (name) => consumerPackageEntry(name, consumerRoot) ?? packageEntry(name),\n optionalPackageEntry: (name) => consumerPackageEntry(name, consumerRoot) ?? optionalPackageEntry(name),\n localEntry,\n };\n}\n\nconst LAYER_AGIFLOW = 'agiflow';\nconst LAYER_GUARDRAILS = 'guardrails';\nconst LAYER_VIBE_LINT = 'vibe-lint';\nconst LAYER_CODE_INTEL = 'code-intel';\nconst LAYER_TEAM = 'team';\nconst LAYER_PLAN_MODE = 'plan-mode';\nconst LAYER_RUNNER = 'runner';\nconst LAYER_ASK_USER = 'ask-user';\nconst LAYER_STYLE_SYSTEM = 'style-system';\nexport const OLLAMA_PRESET = 'ollama';\nconst OWN_ENTRIES = {\n autoStop: 'autoStop',\n domains: 'domains',\n effort: 'effort',\n majorMode: 'majorMode',\n notifications: 'notifications',\n ollamaProvider: 'ollamaProvider',\n profile: 'profile',\n skills: 'skills',\n} as const;\nconst PACKAGE_ENTRIES = {\n autocompact: '@agimon-ai/doompi-autocompact/extensions/pi',\n doomConfig: '@agimon-ai/doompi-config/pi',\n cacheOptimizer: 'pi-cache-optimizer/index.ts',\n doomUi: '@agimon-ai/doompi-ui/extensions/pi',\n // Doom entries, not the bare Pi ones: they wrap the same extension and add the\n // leader (and, for voice, config) contributions that only exist under Doom.\n fileEdit: '@agimon-ai/doompi-file-edit/extensions/doom',\n logSinkTelemetry: '@agimon-ai/doompi-log/extensions/pi',\n loop: '@agimon-ai/doompi-loop/extensions/pi',\n task: '@agimon-ai/doompi-task/extensions/pi',\n voice: '@agimon-ai/doompi-voice/extensions/doom',\n goalDoom: '@agimon-ai/doompi-goal/extensions/doom',\n goalPi: '@agimon-ai/doompi-goal/extensions/pi',\n} as const;\nconst HOOK_DISABLED_LAYERS = new Set([LAYER_GUARDRAILS, LAYER_VIBE_LINT, LAYER_CODE_INTEL]);\n\n/**\n * Optional packages passed in as context rather than resolved from a layer.\n *\n * Named here so the launcher and the synced Pi path ask for the same three\n * specifiers; the synced path also needs them in its recorded resolution map.\n */\nexport const CONTEXT_PACKAGES = {\n mcp: '@agimon-ai/doompi-mcp/extensions/pi',\n workflow: '@agimon-ai/doompi-workflow/extensions/pi',\n dispatcherWorkflow: '@agimon-ai/doompi-workflow/extensions/dispatcher',\n} as const;\n\n/** Own entry that is always loaded so /profile can pick a persona later. */\nexport const PERSONA_ENTRY = 'persona';\n\n/**\n * Assembles the ordered Pi --extension list.\n *\n * Order is load-bearing: the workflow extension must register its launch tool\n * before the Agiflow dispatcher can steer toward it, and auto-stop must end up\n * first because Pi applies extension arguments in reverse. That is why this\n * function, not modes.yaml, owns the sequence. Layers declare WHAT they\n * contribute; each one is spliced in at its slot below. Kept pure so a snapshot\n * test can pin the result.\n */\nexport function assembleExtensions(context: ExtensionContext): string[] {\n const config = context.majorModesConfig;\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const own = (name: string): string => resolve.ownEntry(name);\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] => (selected.has(name) ? layerEntries(config, name, resolve) : []);\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n // Loaded when a profile supplies a persona, and kept available for /profile.\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.workflowExtension) extensions.push(context.workflowExtension);\n extensions.push(\n ...layer(LAYER_AGIFLOW),\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n );\n if (context.preset === OLLAMA_PRESET) extensions.push(own(OWN_ENTRIES.ollamaProvider));\n extensions.push(own(OWN_ENTRIES.effort));\n extensions.push(...layer(LAYER_PLAN_MODE));\n extensions.push(pkg(PACKAGE_ENTRIES.task));\n extensions.push(pkg(PACKAGE_ENTRIES.loop));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n extensions.push(pkg(PACKAGE_ENTRIES.fileEdit));\n // Next to task: both own long-lived work, and the runner's bash replacement\n // has to be registered before any layer that renders tool results.\n extensions.push(...layer(LAYER_RUNNER));\n extensions.push(...layer(LAYER_ASK_USER), ...layer(LAYER_STYLE_SYSTEM));\n extensions.push(pkg(PACKAGE_ENTRIES.voice));\n extensions.push(own(OWN_ENTRIES.domains));\n // Next to domains, which owns the same selection. This entry starts deferred\n // skill loading after the TUI is live and hosts the attribution registry\n // before contributors register into it (Pi applies these in reverse).\n extensions.push(own(OWN_ENTRIES.skills));\n extensions.push(own(OWN_ENTRIES.majorMode));\n extensions.push(own(OWN_ENTRIES.profile));\n // Goal is a globally available minor mode, not a configurable major-mode layer.\n extensions.push(pkg(PACKAGE_ENTRIES.goalDoom));\n extensions.push(pkg(PACKAGE_ENTRIES.cacheOptimizer));\n if (!context.mute) extensions.push(own(OWN_ENTRIES.notifications));\n if (context.agents) extensions.push(...layer(LAYER_TEAM));\n // Pi loads explicit extension arguments in reverse. Keep context providers\n // last so Doom Config registers first, followed by Leader, before consumers.\n extensions.push(pkg(PACKAGE_ENTRIES.doomUi));\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n if (context.autoStop) extensions.unshift(own(OWN_ENTRIES.autoStop));\n\n return extensions;\n}\n\n/**\n * Builds the explicit extension set inherited by detached Doom Team children.\n * UI, launch, notification, and orchestration extensions remain parent-only.\n * Domain skills and profile environment values travel through harness state.\n */\nexport function assembleChildExtensions(context: ExtensionContext): string[] {\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] =>\n selected.has(name) ? layerEntries(context.majorModesConfig, name, resolve) : [];\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.preset === OLLAMA_PRESET) extensions.push(resolve.ownEntry(OWN_ENTRIES.ollamaProvider));\n extensions.push(\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n ...layer(LAYER_PLAN_MODE),\n ...layer(LAYER_RUNNER),\n ...layer(LAYER_ASK_USER),\n ...layer(LAYER_STYLE_SYSTEM),\n );\n // Detached children receive the portable Pi entry, never Doom UI.\n extensions.push(pkg(PACKAGE_ENTRIES.goalPi));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n // Pi reverses explicit extension arguments, so the provider belongs last.\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n\n return [...new Set(extensions)];\n}\n\n/** Preserves the historical --no-hooks behavior by filtering the resolved base. */\nexport function filterHookDisabledLayers(layers: string[], hooks: boolean): string[] {\n return hooks ? [...layers] : layers.filter((name) => !HOOK_DISABLED_LAYERS.has(name));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extensionAssembler.cjs","names":["resolvePackageEntry","resolveOptionalPackageEntry","consumerPackageEntry"],"sources":["../../src/services/extensionAssembler.ts"],"sourcesContent":["import { type LayerResolvers, layerEntries, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport {\n consumerPackageEntry,\n localEntry,\n optionalPackageEntry as resolveOptionalPackageEntry,\n ownEntry,\n packageEntry as resolvePackageEntry,\n} from '../utils/index.ts';\n\nexport interface ExtensionContext {\n agents: boolean;\n autoStop: boolean;\n mute?: boolean;\n preset?: string;\n mcpEntry?: string;\n personaEntry?: string;\n workflowExtension?: string;\n /** Resolved layer names from the selected major mode. */\n layers: string[];\n majorModesConfig: MajorModesConfig;\n /**\n * How entry names become absolute paths. Defaults to resolving them here.\n *\n * The synced Pi path composes inside a Pi session, where module resolution\n * cannot be relied on, so it substitutes resolvers backed by the map\n * `doom-pi sync` recorded. Both paths therefore run this same function.\n */\n resolvers?: LayerResolvers;\n}\n\nexport const LEGACY_ASK_USER_PACKAGE = '@juicesharp/rpiv-ask-user-question';\nexport const USER_FEEDBACK_PACKAGE = '@agimon-ai/doompi-user-feedback';\n\nexport function canonicalPackageSpecifier(specifier: string): string {\n if (specifier === LEGACY_ASK_USER_PACKAGE) return USER_FEEDBACK_PACKAGE;\n if (specifier.startsWith(`${LEGACY_ASK_USER_PACKAGE}/`)) {\n return `${USER_FEEDBACK_PACKAGE}${specifier.slice(LEGACY_ASK_USER_PACKAGE.length)}`;\n }\n return specifier;\n}\n\nexport const LAYER_RESOLVERS: LayerResolvers = {\n ownEntry,\n packageEntry: (name) => resolvePackageEntry(canonicalPackageSpecifier(name)),\n optionalPackageEntry: (name) => resolveOptionalPackageEntry(canonicalPackageSpecifier(name)),\n localEntry,\n};\n\n/**\n * Resolvers that answer for the consumer repository before the meta-package.\n *\n * A repository declares its own layer packages in `.doom/modes.yaml`, and it is\n * the repository that installs them. Doom Pi owns only the Doom closure, so a\n * consumer specifier has to resolve from the consumer root and everything else\n * falls back to what ships with the installed meta-package.\n *\n * Path-style packages skip all of that: they are already anchored to the config\n * that declared them, so there is no chain to search.\n */\nexport function createLayerResolvers(consumerRoot?: string): LayerResolvers {\n if (!consumerRoot) return LAYER_RESOLVERS;\n return {\n ownEntry,\n packageEntry: (name) => {\n const target = canonicalPackageSpecifier(name);\n return consumerPackageEntry(target, consumerRoot) ?? resolvePackageEntry(target);\n },\n optionalPackageEntry: (name) => {\n const target = canonicalPackageSpecifier(name);\n return consumerPackageEntry(target, consumerRoot) ?? resolveOptionalPackageEntry(target);\n },\n localEntry,\n };\n}\n\nconst LAYER_AGIFLOW = 'agiflow';\nconst LAYER_GUARDRAILS = 'guardrails';\nconst LAYER_VIBE_LINT = 'vibe-lint';\nconst LAYER_CODE_INTEL = 'code-intel';\nconst LAYER_TEAM = 'team';\nconst LAYER_PLAN_MODE = 'plan-mode';\nconst LAYER_RUNNER = 'runner';\nconst LAYER_ASK_USER = 'ask-user';\nconst LAYER_STYLE_SYSTEM = 'style-system';\nexport const OLLAMA_PRESET = 'ollama';\nconst OWN_ENTRIES = {\n autoStop: 'autoStop',\n domains: 'domains',\n effort: 'effort',\n majorMode: 'majorMode',\n notifications: 'notifications',\n ollamaProvider: 'ollamaProvider',\n profile: 'profile',\n skills: 'skills',\n} as const;\nconst PACKAGE_ENTRIES = {\n autocompact: '@agimon-ai/doompi-autocompact/extensions/pi',\n doomConfig: '@agimon-ai/doompi-config/pi',\n cacheOptimizer: 'pi-cache-optimizer/index.ts',\n doomUi: '@agimon-ai/doompi-ui/extensions/pi',\n // Doom entries, not the bare Pi ones: they wrap the same extension and add the\n // leader (and, for voice, config) contributions that only exist under Doom.\n fileEdit: '@agimon-ai/doompi-file-edit/extensions/doom',\n logSinkTelemetry: '@agimon-ai/doompi-log/extensions/pi',\n loop: '@agimon-ai/doompi-loop/extensions/pi',\n task: '@agimon-ai/doompi-task/extensions/pi',\n voice: '@agimon-ai/doompi-voice/extensions/doom',\n goalDoom: '@agimon-ai/doompi-goal/extensions/doom',\n goalPi: '@agimon-ai/doompi-goal/extensions/pi',\n} as const;\nconst HOOK_DISABLED_LAYERS = new Set([LAYER_GUARDRAILS, LAYER_VIBE_LINT, LAYER_CODE_INTEL]);\n\n/**\n * Optional packages passed in as context rather than resolved from a layer.\n *\n * Named here so the launcher and the synced Pi path ask for the same three\n * specifiers; the synced path also needs them in its recorded resolution map.\n */\nexport const CONTEXT_PACKAGES = {\n mcp: '@agimon-ai/doompi-mcp/extensions/pi',\n workflow: '@agimon-ai/doompi-workflow/extensions/pi',\n dispatcherWorkflow: '@agimon-ai/doompi-workflow/extensions/dispatcher',\n} as const;\n\n/** Own entry that is always loaded so /profile can pick a persona later. */\nexport const PERSONA_ENTRY = 'persona';\n\n/**\n * Assembles the ordered Pi --extension list.\n *\n * Order is load-bearing: the workflow extension must register its launch tool\n * before the Agiflow dispatcher can steer toward it, and auto-stop must end up\n * first because Pi applies extension arguments in reverse. That is why this\n * function, not modes.yaml, owns the sequence. Layers declare WHAT they\n * contribute; each one is spliced in at its slot below. Kept pure so a snapshot\n * test can pin the result.\n */\nexport function assembleExtensions(context: ExtensionContext): string[] {\n const config = context.majorModesConfig;\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const own = (name: string): string => resolve.ownEntry(name);\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] => (selected.has(name) ? layerEntries(config, name, resolve) : []);\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n // Loaded when a profile supplies a persona, and kept available for /profile.\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.workflowExtension) extensions.push(context.workflowExtension);\n extensions.push(\n ...layer(LAYER_AGIFLOW),\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n );\n if (context.preset === OLLAMA_PRESET) extensions.push(own(OWN_ENTRIES.ollamaProvider));\n extensions.push(own(OWN_ENTRIES.effort));\n extensions.push(...layer(LAYER_PLAN_MODE));\n extensions.push(pkg(PACKAGE_ENTRIES.task));\n extensions.push(pkg(PACKAGE_ENTRIES.loop));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n extensions.push(pkg(PACKAGE_ENTRIES.fileEdit));\n // Next to task: both own long-lived work, and the runner's bash replacement\n // has to be registered before any layer that renders tool results.\n extensions.push(...layer(LAYER_RUNNER));\n extensions.push(...layer(LAYER_ASK_USER), ...layer(LAYER_STYLE_SYSTEM));\n extensions.push(pkg(PACKAGE_ENTRIES.voice));\n extensions.push(own(OWN_ENTRIES.domains));\n // Next to domains, which owns the same selection. This entry starts deferred\n // skill loading after the TUI is live and hosts the attribution registry\n // before contributors register into it (Pi applies these in reverse).\n extensions.push(own(OWN_ENTRIES.skills));\n extensions.push(own(OWN_ENTRIES.majorMode));\n extensions.push(own(OWN_ENTRIES.profile));\n // Goal is a globally available minor mode, not a configurable major-mode layer.\n extensions.push(pkg(PACKAGE_ENTRIES.goalDoom));\n extensions.push(pkg(PACKAGE_ENTRIES.cacheOptimizer));\n if (!context.mute) extensions.push(own(OWN_ENTRIES.notifications));\n if (context.agents) extensions.push(...layer(LAYER_TEAM));\n // Pi loads explicit extension arguments in reverse. Keep context providers\n // last so Doom Config registers first, followed by Leader, before consumers.\n extensions.push(pkg(PACKAGE_ENTRIES.doomUi));\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n if (context.autoStop) extensions.unshift(own(OWN_ENTRIES.autoStop));\n\n return extensions;\n}\n\n/**\n * Builds the explicit extension set inherited by detached Doom Team children.\n * UI, launch, notification, and orchestration extensions remain parent-only.\n * Domain skills and profile environment values travel through harness state.\n */\nexport function assembleChildExtensions(context: ExtensionContext): string[] {\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] =>\n selected.has(name) ? layerEntries(context.majorModesConfig, name, resolve) : [];\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.preset === OLLAMA_PRESET) extensions.push(resolve.ownEntry(OWN_ENTRIES.ollamaProvider));\n extensions.push(\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n ...layer(LAYER_PLAN_MODE),\n ...layer(LAYER_RUNNER),\n ...layer(LAYER_ASK_USER),\n ...layer(LAYER_STYLE_SYSTEM),\n );\n // Detached children receive the portable Pi entry, never Doom UI.\n extensions.push(pkg(PACKAGE_ENTRIES.goalPi));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n // Pi reverses explicit extension arguments, so the provider belongs last.\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n\n return [...new Set(extensions)];\n}\n\n/** Preserves the historical --no-hooks behavior by filtering the resolved base. */\nexport function filterHookDisabledLayers(layers: string[], hooks: boolean): string[] {\n return hooks ? [...layers] : layers.filter((name) => !HOOK_DISABLED_LAYERS.has(name));\n}\n"],"mappings":"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"}
|
|
@@ -21,6 +21,9 @@ interface ExtensionContext {
|
|
|
21
21
|
*/
|
|
22
22
|
resolvers?: LayerResolvers;
|
|
23
23
|
}
|
|
24
|
+
declare const LEGACY_ASK_USER_PACKAGE = "@juicesharp/rpiv-ask-user-question";
|
|
25
|
+
declare const USER_FEEDBACK_PACKAGE = "@agimon-ai/doompi-user-feedback";
|
|
26
|
+
declare function canonicalPackageSpecifier(specifier: string): string;
|
|
24
27
|
declare const LAYER_RESOLVERS: LayerResolvers;
|
|
25
28
|
/**
|
|
26
29
|
* Resolvers that answer for the consumer repository before the meta-package.
|
|
@@ -68,5 +71,5 @@ declare function assembleChildExtensions(context: ExtensionContext): string[];
|
|
|
68
71
|
/** Preserves the historical --no-hooks behavior by filtering the resolved base. */
|
|
69
72
|
declare function filterHookDisabledLayers(layers: string[], hooks: boolean): string[];
|
|
70
73
|
//#endregion
|
|
71
|
-
export { CONTEXT_PACKAGES, ExtensionContext, LAYER_RESOLVERS, OLLAMA_PRESET, PERSONA_ENTRY, assembleChildExtensions, assembleExtensions, createLayerResolvers, filterHookDisabledLayers };
|
|
74
|
+
export { CONTEXT_PACKAGES, ExtensionContext, LAYER_RESOLVERS, LEGACY_ASK_USER_PACKAGE, OLLAMA_PRESET, PERSONA_ENTRY, USER_FEEDBACK_PACKAGE, assembleChildExtensions, assembleExtensions, canonicalPackageSpecifier, createLayerResolvers, filterHookDisabledLayers };
|
|
72
75
|
//# sourceMappingURL=extensionAssembler.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensionAssembler.d.cts","names":[],"sources":["../../src/services/extensionAssembler.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"extensionAssembler.d.cts","names":[],"sources":["../../src/services/extensionAssembler.ts"],"mappings":";;;UASiB,gBAAA;EACf,MAAA;EACA,QAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,YAAA;EACA,iBAAA;EAJA;EAMA,MAAA;EACA,gBAAA,EAAkB,gBAAA;EAJlB;;;;;;;EAYA,SAAA,GAAY,cAAA;AAAA;AAAA,cAGD,uBAAA;AAAA,cACA,qBAAA;AAAA,iBAEG,yBAAA,CAA0B,SAAA;AAAA,cAQ7B,eAAA,EAAiB,cAAA;;AAV9B;;;;;AAEA;;;;;iBA0BgB,oBAAA,CAAqB,YAAA,YAAwB,cAAA;AAAA,cAyBhD,aAAA;;;;AAzBb;;;cA2Da,gBAAA;EAAA;;;;;cAOA,aAAA;AAPb;;;;;;;;;AAOA;AAPA,iBAmBgB,kBAAA,CAAmB,OAAA,EAAS,gBAAA;;;;AAA5C;;iBA0DgB,uBAAA,CAAwB,OAAA,EAAS,gBAAA;;iBA+BjC,wBAAA,CAAyB,MAAA,YAAkB,KAAA"}
|
|
@@ -21,6 +21,9 @@ interface ExtensionContext {
|
|
|
21
21
|
*/
|
|
22
22
|
resolvers?: LayerResolvers;
|
|
23
23
|
}
|
|
24
|
+
declare const LEGACY_ASK_USER_PACKAGE = "@juicesharp/rpiv-ask-user-question";
|
|
25
|
+
declare const USER_FEEDBACK_PACKAGE = "@agimon-ai/doompi-user-feedback";
|
|
26
|
+
declare function canonicalPackageSpecifier(specifier: string): string;
|
|
24
27
|
declare const LAYER_RESOLVERS: LayerResolvers;
|
|
25
28
|
/**
|
|
26
29
|
* Resolvers that answer for the consumer repository before the meta-package.
|
|
@@ -68,5 +71,5 @@ declare function assembleChildExtensions(context: ExtensionContext): string[];
|
|
|
68
71
|
/** Preserves the historical --no-hooks behavior by filtering the resolved base. */
|
|
69
72
|
declare function filterHookDisabledLayers(layers: string[], hooks: boolean): string[];
|
|
70
73
|
//#endregion
|
|
71
|
-
export { CONTEXT_PACKAGES, ExtensionContext, LAYER_RESOLVERS, OLLAMA_PRESET, PERSONA_ENTRY, assembleChildExtensions, assembleExtensions, createLayerResolvers, filterHookDisabledLayers };
|
|
74
|
+
export { CONTEXT_PACKAGES, ExtensionContext, LAYER_RESOLVERS, LEGACY_ASK_USER_PACKAGE, OLLAMA_PRESET, PERSONA_ENTRY, USER_FEEDBACK_PACKAGE, assembleChildExtensions, assembleExtensions, canonicalPackageSpecifier, createLayerResolvers, filterHookDisabledLayers };
|
|
72
75
|
//# sourceMappingURL=extensionAssembler.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensionAssembler.d.mts","names":[],"sources":["../../src/services/extensionAssembler.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"extensionAssembler.d.mts","names":[],"sources":["../../src/services/extensionAssembler.ts"],"mappings":";;;UASiB,gBAAA;EACf,MAAA;EACA,QAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,YAAA;EACA,iBAAA;EAJA;EAMA,MAAA;EACA,gBAAA,EAAkB,gBAAA;EAJlB;;;;;;;EAYA,SAAA,GAAY,cAAA;AAAA;AAAA,cAGD,uBAAA;AAAA,cACA,qBAAA;AAAA,iBAEG,yBAAA,CAA0B,SAAA;AAAA,cAQ7B,eAAA,EAAiB,cAAA;;AAV9B;;;;;AAEA;;;;;iBA0BgB,oBAAA,CAAqB,YAAA,YAAwB,cAAA;AAAA,cAyBhD,aAAA;;;;AAzBb;;;cA2Da,gBAAA;EAAA;;;;;cAOA,aAAA;AAPb;;;;;;;;;AAOA;AAPA,iBAmBgB,kBAAA,CAAmB,OAAA,EAAS,gBAAA;;;;AAA5C;;iBA0DgB,uBAAA,CAAwB,OAAA,EAAS,gBAAA;;iBA+BjC,wBAAA,CAAyB,MAAA,YAAkB,KAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{consumerPackageEntry as e,localEntry as t,optionalPackageEntry as n,ownEntry as r,packageEntry as i}from"../adapters/modules/moduleResolution.mjs";import"../utils/index.mjs";import{layerEntries as a}from"@agimon-ai/doompi-config/majorModes";const o={ownEntry:r,packageEntry:i,optionalPackageEntry:n,localEntry:t};function
|
|
1
|
+
import{consumerPackageEntry as e,localEntry as t,optionalPackageEntry as n,ownEntry as r,packageEntry as i}from"../adapters/modules/moduleResolution.mjs";import"../utils/index.mjs";import{layerEntries as a}from"@agimon-ai/doompi-config/majorModes";const o=`@juicesharp/rpiv-ask-user-question`,s=`@agimon-ai/doompi-user-feedback`;function c(e){return e===`@juicesharp/rpiv-ask-user-question`?s:e.startsWith(`@juicesharp/rpiv-ask-user-question/`)?`${s}${e.slice(34)}`:e}const l={ownEntry:r,packageEntry:e=>i(c(e)),optionalPackageEntry:e=>n(c(e)),localEntry:t};function u(a){return a?{ownEntry:r,packageEntry:t=>{let n=c(t);return e(n,a)??i(n)},optionalPackageEntry:t=>{let r=c(t);return e(r,a)??n(r)},localEntry:t}:l}const d=`guardrails`,f=`vibe-lint`,p=`code-intel`,m=`plan-mode`,h=`runner`,g=`ask-user`,_=`style-system`,v=`ollama`,y={autoStop:`autoStop`,domains:`domains`,effort:`effort`,majorMode:`majorMode`,notifications:`notifications`,ollamaProvider:`ollamaProvider`,profile:`profile`,skills:`skills`},b={autocompact:`@agimon-ai/doompi-autocompact/extensions/pi`,doomConfig:`@agimon-ai/doompi-config/pi`,cacheOptimizer:`pi-cache-optimizer/index.ts`,doomUi:`@agimon-ai/doompi-ui/extensions/pi`,fileEdit:`@agimon-ai/doompi-file-edit/extensions/doom`,logSinkTelemetry:`@agimon-ai/doompi-log/extensions/pi`,loop:`@agimon-ai/doompi-loop/extensions/pi`,task:`@agimon-ai/doompi-task/extensions/pi`,voice:`@agimon-ai/doompi-voice/extensions/doom`,goalDoom:`@agimon-ai/doompi-goal/extensions/doom`,goalPi:`@agimon-ai/doompi-goal/extensions/pi`},x=new Set([d,f,p]),S={mcp:`@agimon-ai/doompi-mcp/extensions/pi`,workflow:`@agimon-ai/doompi-workflow/extensions/pi`,dispatcherWorkflow:`@agimon-ai/doompi-workflow/extensions/dispatcher`},C=`persona`;function w(e){let t=e.majorModesConfig,n=e.resolvers??l,r=e=>n.ownEntry(e),i=e=>n.packageEntry(e),o=new Set(e.layers),s=e=>o.has(e)?a(t,e,n):[],c=[];return e.mcpEntry&&c.push(e.mcpEntry),c.push(i(b.logSinkTelemetry)),e.personaEntry&&c.push(e.personaEntry),e.workflowExtension&&c.push(e.workflowExtension),c.push(...s(`agiflow`),...s(d),...s(f),...s(p)),e.preset===`ollama`&&c.push(r(y.ollamaProvider)),c.push(r(y.effort)),c.push(...s(m)),c.push(i(b.task)),c.push(i(b.loop)),c.push(i(b.autocompact)),c.push(i(b.fileEdit)),c.push(...s(h)),c.push(...s(g),...s(_)),c.push(i(b.voice)),c.push(r(y.domains)),c.push(r(y.skills)),c.push(r(y.majorMode)),c.push(r(y.profile)),c.push(i(b.goalDoom)),c.push(i(b.cacheOptimizer)),e.mute||c.push(r(y.notifications)),e.agents&&c.push(...s(`team`)),c.push(i(b.doomUi)),c.push(i(b.doomConfig)),e.autoStop&&c.unshift(r(y.autoStop)),c}function T(e){let t=e.resolvers??l,n=e=>t.packageEntry(e),r=new Set(e.layers),i=n=>r.has(n)?a(e.majorModesConfig,n,t):[],o=[];return e.mcpEntry&&o.push(e.mcpEntry),o.push(n(b.logSinkTelemetry)),e.personaEntry&&o.push(e.personaEntry),e.preset===`ollama`&&o.push(t.ownEntry(y.ollamaProvider)),o.push(...i(d),...i(f),...i(p),...i(m),...i(h),...i(g),...i(_)),o.push(n(b.goalPi)),o.push(n(b.autocompact)),o.push(n(b.doomConfig)),[...new Set(o)]}function E(e,t){return t?[...e]:e.filter(e=>!x.has(e))}export{S as CONTEXT_PACKAGES,l as LAYER_RESOLVERS,o as LEGACY_ASK_USER_PACKAGE,v as OLLAMA_PRESET,C as PERSONA_ENTRY,s as USER_FEEDBACK_PACKAGE,T as assembleChildExtensions,w as assembleExtensions,c as canonicalPackageSpecifier,u as createLayerResolvers,E as filterHookDisabledLayers};
|
|
2
2
|
//# sourceMappingURL=extensionAssembler.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensionAssembler.mjs","names":[],"sources":["../../src/services/extensionAssembler.ts"],"sourcesContent":["import { type LayerResolvers, layerEntries, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { consumerPackageEntry, localEntry, optionalPackageEntry, ownEntry, packageEntry } from '../utils/index.ts';\n\nexport interface ExtensionContext {\n agents: boolean;\n autoStop: boolean;\n mute?: boolean;\n preset?: string;\n mcpEntry?: string;\n personaEntry?: string;\n workflowExtension?: string;\n /** Resolved layer names from the selected major mode. */\n layers: string[];\n majorModesConfig: MajorModesConfig;\n /**\n * How entry names become absolute paths. Defaults to resolving them here.\n *\n * The synced Pi path composes inside a Pi session, where module resolution\n * cannot be relied on, so it substitutes resolvers backed by the map\n * `doom-pi sync` recorded. Both paths therefore run this same function.\n */\n resolvers?: LayerResolvers;\n}\n\nexport const LAYER_RESOLVERS: LayerResolvers = { ownEntry, packageEntry, optionalPackageEntry, localEntry };\n\n/**\n * Resolvers that answer for the consumer repository before the meta-package.\n *\n * A repository declares its own layer packages in `.doom/modes.yaml`, and it is\n * the repository that installs them. Doom Pi owns only the Doom closure, so a\n * consumer specifier has to resolve from the consumer root and everything else\n * falls back to what ships with the installed meta-package.\n *\n * Path-style packages skip all of that: they are already anchored to the config\n * that declared them, so there is no chain to search.\n */\nexport function createLayerResolvers(consumerRoot?: string): LayerResolvers {\n if (!consumerRoot) return LAYER_RESOLVERS;\n return {\n ownEntry,\n packageEntry: (name) => consumerPackageEntry(name, consumerRoot) ?? packageEntry(name),\n optionalPackageEntry: (name) => consumerPackageEntry(name, consumerRoot) ?? optionalPackageEntry(name),\n localEntry,\n };\n}\n\nconst LAYER_AGIFLOW = 'agiflow';\nconst LAYER_GUARDRAILS = 'guardrails';\nconst LAYER_VIBE_LINT = 'vibe-lint';\nconst LAYER_CODE_INTEL = 'code-intel';\nconst LAYER_TEAM = 'team';\nconst LAYER_PLAN_MODE = 'plan-mode';\nconst LAYER_RUNNER = 'runner';\nconst LAYER_ASK_USER = 'ask-user';\nconst LAYER_STYLE_SYSTEM = 'style-system';\nexport const OLLAMA_PRESET = 'ollama';\nconst OWN_ENTRIES = {\n autoStop: 'autoStop',\n domains: 'domains',\n effort: 'effort',\n majorMode: 'majorMode',\n notifications: 'notifications',\n ollamaProvider: 'ollamaProvider',\n profile: 'profile',\n skills: 'skills',\n} as const;\nconst PACKAGE_ENTRIES = {\n autocompact: '@agimon-ai/doompi-autocompact/extensions/pi',\n doomConfig: '@agimon-ai/doompi-config/pi',\n cacheOptimizer: 'pi-cache-optimizer/index.ts',\n doomUi: '@agimon-ai/doompi-ui/extensions/pi',\n // Doom entries, not the bare Pi ones: they wrap the same extension and add the\n // leader (and, for voice, config) contributions that only exist under Doom.\n fileEdit: '@agimon-ai/doompi-file-edit/extensions/doom',\n logSinkTelemetry: '@agimon-ai/doompi-log/extensions/pi',\n loop: '@agimon-ai/doompi-loop/extensions/pi',\n task: '@agimon-ai/doompi-task/extensions/pi',\n voice: '@agimon-ai/doompi-voice/extensions/doom',\n goalDoom: '@agimon-ai/doompi-goal/extensions/doom',\n goalPi: '@agimon-ai/doompi-goal/extensions/pi',\n} as const;\nconst HOOK_DISABLED_LAYERS = new Set([LAYER_GUARDRAILS, LAYER_VIBE_LINT, LAYER_CODE_INTEL]);\n\n/**\n * Optional packages passed in as context rather than resolved from a layer.\n *\n * Named here so the launcher and the synced Pi path ask for the same three\n * specifiers; the synced path also needs them in its recorded resolution map.\n */\nexport const CONTEXT_PACKAGES = {\n mcp: '@agimon-ai/doompi-mcp/extensions/pi',\n workflow: '@agimon-ai/doompi-workflow/extensions/pi',\n dispatcherWorkflow: '@agimon-ai/doompi-workflow/extensions/dispatcher',\n} as const;\n\n/** Own entry that is always loaded so /profile can pick a persona later. */\nexport const PERSONA_ENTRY = 'persona';\n\n/**\n * Assembles the ordered Pi --extension list.\n *\n * Order is load-bearing: the workflow extension must register its launch tool\n * before the Agiflow dispatcher can steer toward it, and auto-stop must end up\n * first because Pi applies extension arguments in reverse. That is why this\n * function, not modes.yaml, owns the sequence. Layers declare WHAT they\n * contribute; each one is spliced in at its slot below. Kept pure so a snapshot\n * test can pin the result.\n */\nexport function assembleExtensions(context: ExtensionContext): string[] {\n const config = context.majorModesConfig;\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const own = (name: string): string => resolve.ownEntry(name);\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] => (selected.has(name) ? layerEntries(config, name, resolve) : []);\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n // Loaded when a profile supplies a persona, and kept available for /profile.\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.workflowExtension) extensions.push(context.workflowExtension);\n extensions.push(\n ...layer(LAYER_AGIFLOW),\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n );\n if (context.preset === OLLAMA_PRESET) extensions.push(own(OWN_ENTRIES.ollamaProvider));\n extensions.push(own(OWN_ENTRIES.effort));\n extensions.push(...layer(LAYER_PLAN_MODE));\n extensions.push(pkg(PACKAGE_ENTRIES.task));\n extensions.push(pkg(PACKAGE_ENTRIES.loop));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n extensions.push(pkg(PACKAGE_ENTRIES.fileEdit));\n // Next to task: both own long-lived work, and the runner's bash replacement\n // has to be registered before any layer that renders tool results.\n extensions.push(...layer(LAYER_RUNNER));\n extensions.push(...layer(LAYER_ASK_USER), ...layer(LAYER_STYLE_SYSTEM));\n extensions.push(pkg(PACKAGE_ENTRIES.voice));\n extensions.push(own(OWN_ENTRIES.domains));\n // Next to domains, which owns the same selection. This entry starts deferred\n // skill loading after the TUI is live and hosts the attribution registry\n // before contributors register into it (Pi applies these in reverse).\n extensions.push(own(OWN_ENTRIES.skills));\n extensions.push(own(OWN_ENTRIES.majorMode));\n extensions.push(own(OWN_ENTRIES.profile));\n // Goal is a globally available minor mode, not a configurable major-mode layer.\n extensions.push(pkg(PACKAGE_ENTRIES.goalDoom));\n extensions.push(pkg(PACKAGE_ENTRIES.cacheOptimizer));\n if (!context.mute) extensions.push(own(OWN_ENTRIES.notifications));\n if (context.agents) extensions.push(...layer(LAYER_TEAM));\n // Pi loads explicit extension arguments in reverse. Keep context providers\n // last so Doom Config registers first, followed by Leader, before consumers.\n extensions.push(pkg(PACKAGE_ENTRIES.doomUi));\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n if (context.autoStop) extensions.unshift(own(OWN_ENTRIES.autoStop));\n\n return extensions;\n}\n\n/**\n * Builds the explicit extension set inherited by detached Doom Team children.\n * UI, launch, notification, and orchestration extensions remain parent-only.\n * Domain skills and profile environment values travel through harness state.\n */\nexport function assembleChildExtensions(context: ExtensionContext): string[] {\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] =>\n selected.has(name) ? layerEntries(context.majorModesConfig, name, resolve) : [];\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.preset === OLLAMA_PRESET) extensions.push(resolve.ownEntry(OWN_ENTRIES.ollamaProvider));\n extensions.push(\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n ...layer(LAYER_PLAN_MODE),\n ...layer(LAYER_RUNNER),\n ...layer(LAYER_ASK_USER),\n ...layer(LAYER_STYLE_SYSTEM),\n );\n // Detached children receive the portable Pi entry, never Doom UI.\n extensions.push(pkg(PACKAGE_ENTRIES.goalPi));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n // Pi reverses explicit extension arguments, so the provider belongs last.\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n\n return [...new Set(extensions)];\n}\n\n/** Preserves the historical --no-hooks behavior by filtering the resolved base. */\nexport function filterHookDisabledLayers(layers: string[], hooks: boolean): string[] {\n return hooks ? [...layers] : layers.filter((name) => !HOOK_DISABLED_LAYERS.has(name));\n}\n"],"mappings":"wPAwBA,MAAa,EAAkC,CAAE,WAAU,eAAc,uBAAsB,aAAY,CAa3G,SAAgB,EAAqB,EAAuC,CAE1E,OADK,EACE,CACL,WACA,aAAe,GAAS,EAAqB,EAAM,EAAa,EAAI,EAAa,EAAK,CACtF,qBAAuB,GAAS,EAAqB,EAAM,EAAa,EAAI,EAAqB,EAAK,CACtG,aACD,CANyB,EAS5B,MACM,EAAmB,aACnB,EAAkB,YAClB,EAAmB,aAEnB,EAAkB,YAClB,EAAe,SACf,EAAiB,WACjB,EAAqB,eACd,EAAgB,SACvB,EAAc,CAClB,SAAU,WACV,QAAS,UACT,OAAQ,SACR,UAAW,YACX,cAAe,gBACf,eAAgB,iBAChB,QAAS,UACT,OAAQ,SACT,CACK,EAAkB,CACtB,YAAa,8CACb,WAAY,8BACZ,eAAgB,8BAChB,OAAQ,qCAGR,SAAU,8CACV,iBAAkB,sCAClB,KAAM,uCACN,KAAM,uCACN,MAAO,0CACP,SAAU,yCACV,OAAQ,uCACT,CACK,EAAuB,IAAI,IAAI,CAAC,EAAkB,EAAiB,EAAiB,CAAC,CAQ9E,EAAmB,CAC9B,IAAK,sCACL,SAAU,2CACV,mBAAoB,mDACrB,CAGY,EAAgB,UAY7B,SAAgB,EAAmB,EAAqC,CACtE,IAAM,EAAS,EAAQ,iBACjB,EAAU,EAAQ,WAAa,EAC/B,EAAO,GAAyB,EAAQ,SAAS,EAAK,CACtD,EAAO,GAAyB,EAAQ,aAAa,EAAK,CAC1D,EAAW,IAAI,IAAI,EAAQ,OAAO,CAClC,EAAS,GAA4B,EAAS,IAAI,EAAK,CAAG,EAAa,EAAQ,EAAM,EAAQ,CAAG,EAAE,CAClG,EAAuB,EAAE,CA2C/B,OAzCI,EAAQ,UAAU,EAAW,KAAK,EAAQ,SAAS,CACvD,EAAW,KAAK,EAAI,EAAgB,iBAAiB,CAAC,CAElD,EAAQ,cAAc,EAAW,KAAK,EAAQ,aAAa,CAC3D,EAAQ,mBAAmB,EAAW,KAAK,EAAQ,kBAAkB,CACzE,EAAW,KACT,GAAG,EAAM,UAAc,CACvB,GAAG,EAAM,EAAiB,CAC1B,GAAG,EAAM,EAAgB,CACzB,GAAG,EAAM,EAAiB,CAC3B,CACG,EAAQ,SAAA,UAA0B,EAAW,KAAK,EAAI,EAAY,eAAe,CAAC,CACtF,EAAW,KAAK,EAAI,EAAY,OAAO,CAAC,CACxC,EAAW,KAAK,GAAG,EAAM,EAAgB,CAAC,CAC1C,EAAW,KAAK,EAAI,EAAgB,KAAK,CAAC,CAC1C,EAAW,KAAK,EAAI,EAAgB,KAAK,CAAC,CAC1C,EAAW,KAAK,EAAI,EAAgB,YAAY,CAAC,CACjD,EAAW,KAAK,EAAI,EAAgB,SAAS,CAAC,CAG9C,EAAW,KAAK,GAAG,EAAM,EAAa,CAAC,CACvC,EAAW,KAAK,GAAG,EAAM,EAAe,CAAE,GAAG,EAAM,EAAmB,CAAC,CACvE,EAAW,KAAK,EAAI,EAAgB,MAAM,CAAC,CAC3C,EAAW,KAAK,EAAI,EAAY,QAAQ,CAAC,CAIzC,EAAW,KAAK,EAAI,EAAY,OAAO,CAAC,CACxC,EAAW,KAAK,EAAI,EAAY,UAAU,CAAC,CAC3C,EAAW,KAAK,EAAI,EAAY,QAAQ,CAAC,CAEzC,EAAW,KAAK,EAAI,EAAgB,SAAS,CAAC,CAC9C,EAAW,KAAK,EAAI,EAAgB,eAAe,CAAC,CAC/C,EAAQ,MAAM,EAAW,KAAK,EAAI,EAAY,cAAc,CAAC,CAC9D,EAAQ,QAAQ,EAAW,KAAK,GAAG,EAAM,OAAW,CAAC,CAGzD,EAAW,KAAK,EAAI,EAAgB,OAAO,CAAC,CAC5C,EAAW,KAAK,EAAI,EAAgB,WAAW,CAAC,CAC5C,EAAQ,UAAU,EAAW,QAAQ,EAAI,EAAY,SAAS,CAAC,CAE5D,EAQT,SAAgB,EAAwB,EAAqC,CAC3E,IAAM,EAAU,EAAQ,WAAa,EAC/B,EAAO,GAAyB,EAAQ,aAAa,EAAK,CAC1D,EAAW,IAAI,IAAI,EAAQ,OAAO,CAClC,EAAS,GACb,EAAS,IAAI,EAAK,CAAG,EAAa,EAAQ,iBAAkB,EAAM,EAAQ,CAAG,EAAE,CAC3E,EAAuB,EAAE,CAqB/B,OAnBI,EAAQ,UAAU,EAAW,KAAK,EAAQ,SAAS,CACvD,EAAW,KAAK,EAAI,EAAgB,iBAAiB,CAAC,CAClD,EAAQ,cAAc,EAAW,KAAK,EAAQ,aAAa,CAC3D,EAAQ,SAAA,UAA0B,EAAW,KAAK,EAAQ,SAAS,EAAY,eAAe,CAAC,CACnG,EAAW,KACT,GAAG,EAAM,EAAiB,CAC1B,GAAG,EAAM,EAAgB,CACzB,GAAG,EAAM,EAAiB,CAC1B,GAAG,EAAM,EAAgB,CACzB,GAAG,EAAM,EAAa,CACtB,GAAG,EAAM,EAAe,CACxB,GAAG,EAAM,EAAmB,CAC7B,CAED,EAAW,KAAK,EAAI,EAAgB,OAAO,CAAC,CAC5C,EAAW,KAAK,EAAI,EAAgB,YAAY,CAAC,CAEjD,EAAW,KAAK,EAAI,EAAgB,WAAW,CAAC,CAEzC,CAAC,GAAG,IAAI,IAAI,EAAW,CAAC,CAIjC,SAAgB,EAAyB,EAAkB,EAA0B,CACnF,OAAO,EAAQ,CAAC,GAAG,EAAO,CAAG,EAAO,OAAQ,GAAS,CAAC,EAAqB,IAAI,EAAK,CAAC"}
|
|
1
|
+
{"version":3,"file":"extensionAssembler.mjs","names":["resolvePackageEntry","resolveOptionalPackageEntry"],"sources":["../../src/services/extensionAssembler.ts"],"sourcesContent":["import { type LayerResolvers, layerEntries, type MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport {\n consumerPackageEntry,\n localEntry,\n optionalPackageEntry as resolveOptionalPackageEntry,\n ownEntry,\n packageEntry as resolvePackageEntry,\n} from '../utils/index.ts';\n\nexport interface ExtensionContext {\n agents: boolean;\n autoStop: boolean;\n mute?: boolean;\n preset?: string;\n mcpEntry?: string;\n personaEntry?: string;\n workflowExtension?: string;\n /** Resolved layer names from the selected major mode. */\n layers: string[];\n majorModesConfig: MajorModesConfig;\n /**\n * How entry names become absolute paths. Defaults to resolving them here.\n *\n * The synced Pi path composes inside a Pi session, where module resolution\n * cannot be relied on, so it substitutes resolvers backed by the map\n * `doom-pi sync` recorded. Both paths therefore run this same function.\n */\n resolvers?: LayerResolvers;\n}\n\nexport const LEGACY_ASK_USER_PACKAGE = '@juicesharp/rpiv-ask-user-question';\nexport const USER_FEEDBACK_PACKAGE = '@agimon-ai/doompi-user-feedback';\n\nexport function canonicalPackageSpecifier(specifier: string): string {\n if (specifier === LEGACY_ASK_USER_PACKAGE) return USER_FEEDBACK_PACKAGE;\n if (specifier.startsWith(`${LEGACY_ASK_USER_PACKAGE}/`)) {\n return `${USER_FEEDBACK_PACKAGE}${specifier.slice(LEGACY_ASK_USER_PACKAGE.length)}`;\n }\n return specifier;\n}\n\nexport const LAYER_RESOLVERS: LayerResolvers = {\n ownEntry,\n packageEntry: (name) => resolvePackageEntry(canonicalPackageSpecifier(name)),\n optionalPackageEntry: (name) => resolveOptionalPackageEntry(canonicalPackageSpecifier(name)),\n localEntry,\n};\n\n/**\n * Resolvers that answer for the consumer repository before the meta-package.\n *\n * A repository declares its own layer packages in `.doom/modes.yaml`, and it is\n * the repository that installs them. Doom Pi owns only the Doom closure, so a\n * consumer specifier has to resolve from the consumer root and everything else\n * falls back to what ships with the installed meta-package.\n *\n * Path-style packages skip all of that: they are already anchored to the config\n * that declared them, so there is no chain to search.\n */\nexport function createLayerResolvers(consumerRoot?: string): LayerResolvers {\n if (!consumerRoot) return LAYER_RESOLVERS;\n return {\n ownEntry,\n packageEntry: (name) => {\n const target = canonicalPackageSpecifier(name);\n return consumerPackageEntry(target, consumerRoot) ?? resolvePackageEntry(target);\n },\n optionalPackageEntry: (name) => {\n const target = canonicalPackageSpecifier(name);\n return consumerPackageEntry(target, consumerRoot) ?? resolveOptionalPackageEntry(target);\n },\n localEntry,\n };\n}\n\nconst LAYER_AGIFLOW = 'agiflow';\nconst LAYER_GUARDRAILS = 'guardrails';\nconst LAYER_VIBE_LINT = 'vibe-lint';\nconst LAYER_CODE_INTEL = 'code-intel';\nconst LAYER_TEAM = 'team';\nconst LAYER_PLAN_MODE = 'plan-mode';\nconst LAYER_RUNNER = 'runner';\nconst LAYER_ASK_USER = 'ask-user';\nconst LAYER_STYLE_SYSTEM = 'style-system';\nexport const OLLAMA_PRESET = 'ollama';\nconst OWN_ENTRIES = {\n autoStop: 'autoStop',\n domains: 'domains',\n effort: 'effort',\n majorMode: 'majorMode',\n notifications: 'notifications',\n ollamaProvider: 'ollamaProvider',\n profile: 'profile',\n skills: 'skills',\n} as const;\nconst PACKAGE_ENTRIES = {\n autocompact: '@agimon-ai/doompi-autocompact/extensions/pi',\n doomConfig: '@agimon-ai/doompi-config/pi',\n cacheOptimizer: 'pi-cache-optimizer/index.ts',\n doomUi: '@agimon-ai/doompi-ui/extensions/pi',\n // Doom entries, not the bare Pi ones: they wrap the same extension and add the\n // leader (and, for voice, config) contributions that only exist under Doom.\n fileEdit: '@agimon-ai/doompi-file-edit/extensions/doom',\n logSinkTelemetry: '@agimon-ai/doompi-log/extensions/pi',\n loop: '@agimon-ai/doompi-loop/extensions/pi',\n task: '@agimon-ai/doompi-task/extensions/pi',\n voice: '@agimon-ai/doompi-voice/extensions/doom',\n goalDoom: '@agimon-ai/doompi-goal/extensions/doom',\n goalPi: '@agimon-ai/doompi-goal/extensions/pi',\n} as const;\nconst HOOK_DISABLED_LAYERS = new Set([LAYER_GUARDRAILS, LAYER_VIBE_LINT, LAYER_CODE_INTEL]);\n\n/**\n * Optional packages passed in as context rather than resolved from a layer.\n *\n * Named here so the launcher and the synced Pi path ask for the same three\n * specifiers; the synced path also needs them in its recorded resolution map.\n */\nexport const CONTEXT_PACKAGES = {\n mcp: '@agimon-ai/doompi-mcp/extensions/pi',\n workflow: '@agimon-ai/doompi-workflow/extensions/pi',\n dispatcherWorkflow: '@agimon-ai/doompi-workflow/extensions/dispatcher',\n} as const;\n\n/** Own entry that is always loaded so /profile can pick a persona later. */\nexport const PERSONA_ENTRY = 'persona';\n\n/**\n * Assembles the ordered Pi --extension list.\n *\n * Order is load-bearing: the workflow extension must register its launch tool\n * before the Agiflow dispatcher can steer toward it, and auto-stop must end up\n * first because Pi applies extension arguments in reverse. That is why this\n * function, not modes.yaml, owns the sequence. Layers declare WHAT they\n * contribute; each one is spliced in at its slot below. Kept pure so a snapshot\n * test can pin the result.\n */\nexport function assembleExtensions(context: ExtensionContext): string[] {\n const config = context.majorModesConfig;\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const own = (name: string): string => resolve.ownEntry(name);\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] => (selected.has(name) ? layerEntries(config, name, resolve) : []);\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n // Loaded when a profile supplies a persona, and kept available for /profile.\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.workflowExtension) extensions.push(context.workflowExtension);\n extensions.push(\n ...layer(LAYER_AGIFLOW),\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n );\n if (context.preset === OLLAMA_PRESET) extensions.push(own(OWN_ENTRIES.ollamaProvider));\n extensions.push(own(OWN_ENTRIES.effort));\n extensions.push(...layer(LAYER_PLAN_MODE));\n extensions.push(pkg(PACKAGE_ENTRIES.task));\n extensions.push(pkg(PACKAGE_ENTRIES.loop));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n extensions.push(pkg(PACKAGE_ENTRIES.fileEdit));\n // Next to task: both own long-lived work, and the runner's bash replacement\n // has to be registered before any layer that renders tool results.\n extensions.push(...layer(LAYER_RUNNER));\n extensions.push(...layer(LAYER_ASK_USER), ...layer(LAYER_STYLE_SYSTEM));\n extensions.push(pkg(PACKAGE_ENTRIES.voice));\n extensions.push(own(OWN_ENTRIES.domains));\n // Next to domains, which owns the same selection. This entry starts deferred\n // skill loading after the TUI is live and hosts the attribution registry\n // before contributors register into it (Pi applies these in reverse).\n extensions.push(own(OWN_ENTRIES.skills));\n extensions.push(own(OWN_ENTRIES.majorMode));\n extensions.push(own(OWN_ENTRIES.profile));\n // Goal is a globally available minor mode, not a configurable major-mode layer.\n extensions.push(pkg(PACKAGE_ENTRIES.goalDoom));\n extensions.push(pkg(PACKAGE_ENTRIES.cacheOptimizer));\n if (!context.mute) extensions.push(own(OWN_ENTRIES.notifications));\n if (context.agents) extensions.push(...layer(LAYER_TEAM));\n // Pi loads explicit extension arguments in reverse. Keep context providers\n // last so Doom Config registers first, followed by Leader, before consumers.\n extensions.push(pkg(PACKAGE_ENTRIES.doomUi));\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n if (context.autoStop) extensions.unshift(own(OWN_ENTRIES.autoStop));\n\n return extensions;\n}\n\n/**\n * Builds the explicit extension set inherited by detached Doom Team children.\n * UI, launch, notification, and orchestration extensions remain parent-only.\n * Domain skills and profile environment values travel through harness state.\n */\nexport function assembleChildExtensions(context: ExtensionContext): string[] {\n const resolve = context.resolvers ?? LAYER_RESOLVERS;\n const pkg = (name: string): string => resolve.packageEntry(name);\n const selected = new Set(context.layers);\n const layer = (name: string): string[] =>\n selected.has(name) ? layerEntries(context.majorModesConfig, name, resolve) : [];\n const extensions: string[] = [];\n\n if (context.mcpEntry) extensions.push(context.mcpEntry);\n extensions.push(pkg(PACKAGE_ENTRIES.logSinkTelemetry));\n if (context.personaEntry) extensions.push(context.personaEntry);\n if (context.preset === OLLAMA_PRESET) extensions.push(resolve.ownEntry(OWN_ENTRIES.ollamaProvider));\n extensions.push(\n ...layer(LAYER_GUARDRAILS),\n ...layer(LAYER_VIBE_LINT),\n ...layer(LAYER_CODE_INTEL),\n ...layer(LAYER_PLAN_MODE),\n ...layer(LAYER_RUNNER),\n ...layer(LAYER_ASK_USER),\n ...layer(LAYER_STYLE_SYSTEM),\n );\n // Detached children receive the portable Pi entry, never Doom UI.\n extensions.push(pkg(PACKAGE_ENTRIES.goalPi));\n extensions.push(pkg(PACKAGE_ENTRIES.autocompact));\n // Pi reverses explicit extension arguments, so the provider belongs last.\n extensions.push(pkg(PACKAGE_ENTRIES.doomConfig));\n\n return [...new Set(extensions)];\n}\n\n/** Preserves the historical --no-hooks behavior by filtering the resolved base. */\nexport function filterHookDisabledLayers(layers: string[], hooks: boolean): string[] {\n return hooks ? [...layers] : layers.filter((name) => !HOOK_DISABLED_LAYERS.has(name));\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.11",
|
|
4
4
|
"description": "Pi-based agent harness for repository automations and developer workflows",
|
|
5
5
|
"homepage": "https://agimon.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -318,29 +318,29 @@
|
|
|
318
318
|
"registry": "https://registry.npmjs.org/"
|
|
319
319
|
},
|
|
320
320
|
"dependencies": {
|
|
321
|
-
"@juicesharp/rpiv-ask-user-question": "2.2.0",
|
|
322
321
|
"cross-spawn": "7.0.6",
|
|
323
322
|
"gpt-tokenizer": "3.4.0",
|
|
324
323
|
"pi-cache-optimizer": "2.6.25",
|
|
325
324
|
"protobufjs": "8.0.1",
|
|
326
325
|
"rolldown": "1.0.0-rc.17",
|
|
327
326
|
"yaml": "2.9.0",
|
|
328
|
-
"@agimon-ai/doompi-
|
|
329
|
-
"@agimon-ai/doompi-
|
|
330
|
-
"@agimon-ai/doompi-
|
|
331
|
-
"@agimon-ai/doompi-
|
|
332
|
-
"@agimon-ai/doompi-log": "0.0.1-alpha.
|
|
333
|
-
"@agimon-ai/doompi-plan": "0.0.1-alpha.
|
|
334
|
-
"@agimon-ai/doompi-
|
|
335
|
-
"@agimon-ai/doompi-
|
|
336
|
-
"@agimon-ai/doompi-
|
|
337
|
-
"@agimon-ai/doompi-
|
|
338
|
-
"@agimon-ai/doompi-
|
|
339
|
-
"@agimon-ai/doompi-
|
|
340
|
-
"@agimon-ai/doompi-
|
|
341
|
-
"@agimon-ai/doompi-
|
|
342
|
-
"@agimon-ai/doompi-
|
|
343
|
-
"@agimon-ai/doompi-
|
|
327
|
+
"@agimon-ai/doompi-autocompact": "0.0.1-alpha.11",
|
|
328
|
+
"@agimon-ai/doompi-config": "0.0.1-alpha.11",
|
|
329
|
+
"@agimon-ai/doompi-file-edit": "0.0.1-alpha.11",
|
|
330
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.11",
|
|
331
|
+
"@agimon-ai/doompi-log": "0.0.1-alpha.11",
|
|
332
|
+
"@agimon-ai/doompi-plan": "0.0.1-alpha.11",
|
|
333
|
+
"@agimon-ai/doompi-loop": "0.0.1-alpha.11",
|
|
334
|
+
"@agimon-ai/doompi-mcp": "0.0.1-alpha.11",
|
|
335
|
+
"@agimon-ai/doompi-task": "0.0.1-alpha.11",
|
|
336
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.11",
|
|
337
|
+
"@agimon-ai/doompi-runner": "0.0.1-alpha.11",
|
|
338
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.11",
|
|
339
|
+
"@agimon-ai/doompi-goal": "0.0.1-alpha.1",
|
|
340
|
+
"@agimon-ai/doompi-team": "0.0.1-alpha.11",
|
|
341
|
+
"@agimon-ai/doompi-user-feedback": "0.0.1-alpha.0",
|
|
342
|
+
"@agimon-ai/doompi-workflow": "0.0.1-alpha.11",
|
|
343
|
+
"@agimon-ai/doompi-voice": "0.0.1-alpha.11"
|
|
344
344
|
},
|
|
345
345
|
"devDependencies": {
|
|
346
346
|
"@earendil-works/pi-ai": "0.84.1",
|