@agimon-ai/doompi-ui 0.0.1-alpha.71 → 0.0.1-alpha.72
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/services/eventLoopLag/index.cjs +2 -0
- package/dist/services/eventLoopLag/index.cjs.map +1 -0
- package/dist/services/eventLoopLag/index.mjs +2 -0
- package/dist/services/eventLoopLag/index.mjs.map +1 -0
- package/dist/services/telemetry/index.cjs +1 -1
- package/dist/services/telemetry/index.cjs.map +1 -1
- package/dist/services/telemetry/index.d.cts +1 -0
- package/dist/services/telemetry/index.d.cts.map +1 -1
- package/dist/services/telemetry/index.d.mts +1 -0
- package/dist/services/telemetry/index.d.mts.map +1 -1
- package/dist/services/telemetry/index.mjs +1 -1
- package/dist/services/telemetry/index.mjs.map +1 -1
- package/dist/tui/uiRuntime.cjs +1 -1
- package/dist/tui/uiRuntime.cjs.map +1 -1
- package/dist/tui/uiRuntime.mjs +1 -1
- package/dist/tui/uiRuntime.mjs.map +1 -1
- package/package.json +16 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/services/eventLoopLag/index.ts"],"sourcesContent":["/** How often the sampler asks to be woken. Short enough to catch a stall inside a single tool call. */\nconst SAMPLE_INTERVAL_MS = 250;\n/**\n * Below this, a late timer is ordinary scheduling jitter rather than something a\n * user would feel. Reporting every sample would cost more than it measures.\n */\nconst REPORT_THRESHOLD_MS = 250;\n\nexport interface EventLoopLagSampler {\n stop(): void;\n}\n\n/**\n * Reports how far behind schedule the event loop is running.\n *\n * A timer that wakes late is the only signal from inside the process that\n * something synchronous, garbage collection included, held the loop. Nothing in\n * a session transcript records it, so a stall here is otherwise invisible and\n * reads as a slow model or a slow tool.\n */\nexport function startEventLoopLagSampler(report: (lagMs: number) => void): EventLoopLagSampler {\n let expected = Date.now() + SAMPLE_INTERVAL_MS;\n const timer = setInterval(() => {\n const now = Date.now();\n const lagMs = now - expected;\n // Rebased on the wake that just happened rather than advanced by a fixed\n // step, so one long stall does not report itself again on every later tick.\n expected = now + SAMPLE_INTERVAL_MS;\n if (lagMs >= REPORT_THRESHOLD_MS) report(lagMs);\n }, SAMPLE_INTERVAL_MS);\n // A diagnostic must never be the reason a process refuses to exit.\n timer.unref();\n return {\n stop: () => {\n clearInterval(timer);\n },\n };\n}\n"],"mappings":"AAoBA,SAAgB,EAAyB,EAAsD,CAC7F,IAAI,EAAW,KAAK,IAAI,EAAI,IACtB,EAAQ,gBAAkB,CAC9B,IAAM,EAAM,KAAK,IAAI,EACf,EAAQ,EAAM,EAGpB,EAAW,EAAM,IACb,GAAS,KAAqB,EAAO,CAAK,CAChD,EAAG,GAAkB,EAGrB,OADA,EAAM,MAAM,EACL,CACL,SAAY,CACV,cAAc,CAAK,CACrB,CACF,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/eventLoopLag/index.ts"],"sourcesContent":["/** How often the sampler asks to be woken. Short enough to catch a stall inside a single tool call. */\nconst SAMPLE_INTERVAL_MS = 250;\n/**\n * Below this, a late timer is ordinary scheduling jitter rather than something a\n * user would feel. Reporting every sample would cost more than it measures.\n */\nconst REPORT_THRESHOLD_MS = 250;\n\nexport interface EventLoopLagSampler {\n stop(): void;\n}\n\n/**\n * Reports how far behind schedule the event loop is running.\n *\n * A timer that wakes late is the only signal from inside the process that\n * something synchronous, garbage collection included, held the loop. Nothing in\n * a session transcript records it, so a stall here is otherwise invisible and\n * reads as a slow model or a slow tool.\n */\nexport function startEventLoopLagSampler(report: (lagMs: number) => void): EventLoopLagSampler {\n let expected = Date.now() + SAMPLE_INTERVAL_MS;\n const timer = setInterval(() => {\n const now = Date.now();\n const lagMs = now - expected;\n // Rebased on the wake that just happened rather than advanced by a fixed\n // step, so one long stall does not report itself again on every later tick.\n expected = now + SAMPLE_INTERVAL_MS;\n if (lagMs >= REPORT_THRESHOLD_MS) report(lagMs);\n }, SAMPLE_INTERVAL_MS);\n // A diagnostic must never be the reason a process refuses to exit.\n timer.unref();\n return {\n stop: () => {\n clearInterval(timer);\n },\n };\n}\n"],"mappings":"AAoBA,SAAgB,EAAyB,EAAsD,CAC7F,IAAI,EAAW,KAAK,IAAI,EAAI,IACtB,EAAQ,gBAAkB,CAC9B,IAAM,EAAM,KAAK,IAAI,EACf,EAAQ,EAAM,EAGpB,EAAW,EAAM,IACb,GAAS,KAAqB,EAAO,CAAK,CAChD,EAAG,GAAkB,EAGrB,OADA,EAAM,MAAM,EACL,CACL,SAAY,CACV,cAAc,CAAK,CACrB,CACF,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("@agimon-ai/doompi-telemetry");const t={leaderContributionRejected:`doom_pi_ui.leader_contribution_rejected`,leaderCommandUnavailable:`doom_pi_ui.leader_command_unavailable`,leaderActionUnavailable:`doom_pi_ui.leader_action_unavailable`,themeApplyFailed:`doom_pi_ui.theme_apply_failed`,shellInstalled:`doom_pi_ui.shell_installed`};function n(t={}){let n=(0,e.createDoomTelemetry)({serviceName:`doom-pi-ui`,packageName:`@agimon-ai/doompi-ui`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}exports.UI_EVENT=t,exports.createUiTelemetry=n;
|
|
1
|
+
let e=require("@agimon-ai/doompi-telemetry");const t={leaderContributionRejected:`doom_pi_ui.leader_contribution_rejected`,leaderCommandUnavailable:`doom_pi_ui.leader_command_unavailable`,leaderActionUnavailable:`doom_pi_ui.leader_action_unavailable`,themeApplyFailed:`doom_pi_ui.theme_apply_failed`,shellInstalled:`doom_pi_ui.shell_installed`,eventLoopStalled:`doom_pi_ui.event_loop_stalled`};function n(t={}){let n=(0,e.createDoomTelemetry)({serviceName:`doom-pi-ui`,packageName:`@agimon-ai/doompi-ui`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}exports.UI_EVENT=t,exports.createUiTelemetry=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["createDoomTelemetry"],"sources":["../../../src/services/telemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-pi-ui';\nconst PACKAGE_NAME = '@agimon-ai/doompi-ui';\n\nexport const UI_EVENT = {\n leaderContributionRejected: 'doom_pi_ui.leader_contribution_rejected',\n leaderCommandUnavailable: 'doom_pi_ui.leader_command_unavailable',\n leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable',\n themeApplyFailed: 'doom_pi_ui.theme_apply_failed',\n shellInstalled: 'doom_pi_ui.shell_installed',\n} as const;\n\nexport type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];\nexport type UiEventAttributes = Record<string, string | number | boolean>;\n\nexport interface UiTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface UiTelemetry {\n recordError(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordWarning(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordEvent(event: UiEventName, attributes?: UiEventAttributes): Promise<void>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createUiTelemetry(options: UiTelemetryOptions = {}): UiTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"6CAEA,MAGa,EAAW,CACtB,2BAA4B,0CAC5B,yBAA0B,wCAC1B,wBAAyB,uCACzB,iBAAkB,gCAClB,eAAgB,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createDoomTelemetry"],"sources":["../../../src/services/telemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-pi-ui';\nconst PACKAGE_NAME = '@agimon-ai/doompi-ui';\n\nexport const UI_EVENT = {\n leaderContributionRejected: 'doom_pi_ui.leader_contribution_rejected',\n leaderCommandUnavailable: 'doom_pi_ui.leader_command_unavailable',\n leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable',\n themeApplyFailed: 'doom_pi_ui.theme_apply_failed',\n shellInstalled: 'doom_pi_ui.shell_installed',\n eventLoopStalled: 'doom_pi_ui.event_loop_stalled',\n} as const;\n\nexport type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];\nexport type UiEventAttributes = Record<string, string | number | boolean>;\n\nexport interface UiTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface UiTelemetry {\n recordError(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordWarning(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordEvent(event: UiEventName, attributes?: UiEventAttributes): Promise<void>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createUiTelemetry(options: UiTelemetryOptions = {}): UiTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"6CAEA,MAGa,EAAW,CACtB,2BAA4B,0CAC5B,yBAA0B,wCAC1B,wBAAyB,uCACzB,iBAAkB,gCAClB,eAAgB,6BAChB,iBAAkB,+BACpB,EAqBA,SAAgB,EAAkB,EAA8B,CAAC,EAAgB,CAC/E,IAAM,GAAA,EAA2BA,EAAAA,oBAAAA,CAAoB,CACnD,YAAa,aACb,YAAa,uBACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
|
|
@@ -6,6 +6,7 @@ export declare const UI_EVENT: {
|
|
|
6
6
|
readonly leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable';
|
|
7
7
|
readonly themeApplyFailed: 'doom_pi_ui.theme_apply_failed';
|
|
8
8
|
readonly shellInstalled: 'doom_pi_ui.shell_installed';
|
|
9
|
+
readonly eventLoopStalled: 'doom_pi_ui.event_loop_stalled';
|
|
9
10
|
};
|
|
10
11
|
export type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];
|
|
11
12
|
export type UiEventAttributes = Record<string, string | number | boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/telemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;;YAGU,sBAAsB,uBAAuB;YAC7C,oBAAoB;iBAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;iBAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;wBAGE,kBAAkB,UAAS,qBAA0B"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/telemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;;YAGU,sBAAsB,uBAAuB;YAC7C,oBAAoB;iBAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;iBAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;wBAGE,kBAAkB,UAAS,qBAA0B"}
|
|
@@ -6,6 +6,7 @@ export declare const UI_EVENT: {
|
|
|
6
6
|
readonly leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable';
|
|
7
7
|
readonly themeApplyFailed: 'doom_pi_ui.theme_apply_failed';
|
|
8
8
|
readonly shellInstalled: 'doom_pi_ui.shell_installed';
|
|
9
|
+
readonly eventLoopStalled: 'doom_pi_ui.event_loop_stalled';
|
|
9
10
|
};
|
|
10
11
|
export type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];
|
|
11
12
|
export type UiEventAttributes = Record<string, string | number | boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/telemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;;YAGU,sBAAsB,uBAAuB;YAC7C,oBAAoB;iBAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;iBAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;wBAGE,kBAAkB,UAAS,qBAA0B"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/telemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;;YAGU,sBAAsB,uBAAuB;YAC7C,oBAAoB;iBAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;iBAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;wBAGE,kBAAkB,UAAS,qBAA0B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createDoomTelemetry as e}from"@agimon-ai/doompi-telemetry";const t={leaderContributionRejected:`doom_pi_ui.leader_contribution_rejected`,leaderCommandUnavailable:`doom_pi_ui.leader_command_unavailable`,leaderActionUnavailable:`doom_pi_ui.leader_action_unavailable`,themeApplyFailed:`doom_pi_ui.theme_apply_failed`,shellInstalled:`doom_pi_ui.shell_installed`};function n(t={}){let n=e({serviceName:`doom-pi-ui`,packageName:`@agimon-ai/doompi-ui`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}export{t as UI_EVENT,n as createUiTelemetry};
|
|
1
|
+
import{createDoomTelemetry as e}from"@agimon-ai/doompi-telemetry";const t={leaderContributionRejected:`doom_pi_ui.leader_contribution_rejected`,leaderCommandUnavailable:`doom_pi_ui.leader_command_unavailable`,leaderActionUnavailable:`doom_pi_ui.leader_action_unavailable`,themeApplyFailed:`doom_pi_ui.theme_apply_failed`,shellInstalled:`doom_pi_ui.shell_installed`,eventLoopStalled:`doom_pi_ui.event_loop_stalled`};function n(t={}){let n=e({serviceName:`doom-pi-ui`,packageName:`@agimon-ai/doompi-ui`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}export{t as UI_EVENT,n as createUiTelemetry};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/telemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-pi-ui';\nconst PACKAGE_NAME = '@agimon-ai/doompi-ui';\n\nexport const UI_EVENT = {\n leaderContributionRejected: 'doom_pi_ui.leader_contribution_rejected',\n leaderCommandUnavailable: 'doom_pi_ui.leader_command_unavailable',\n leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable',\n themeApplyFailed: 'doom_pi_ui.theme_apply_failed',\n shellInstalled: 'doom_pi_ui.shell_installed',\n} as const;\n\nexport type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];\nexport type UiEventAttributes = Record<string, string | number | boolean>;\n\nexport interface UiTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface UiTelemetry {\n recordError(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordWarning(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordEvent(event: UiEventName, attributes?: UiEventAttributes): Promise<void>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createUiTelemetry(options: UiTelemetryOptions = {}): UiTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"kEAEA,MAGa,EAAW,CACtB,2BAA4B,0CAC5B,yBAA0B,wCAC1B,wBAAyB,uCACzB,iBAAkB,gCAClB,eAAgB,
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/telemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-pi-ui';\nconst PACKAGE_NAME = '@agimon-ai/doompi-ui';\n\nexport const UI_EVENT = {\n leaderContributionRejected: 'doom_pi_ui.leader_contribution_rejected',\n leaderCommandUnavailable: 'doom_pi_ui.leader_command_unavailable',\n leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable',\n themeApplyFailed: 'doom_pi_ui.theme_apply_failed',\n shellInstalled: 'doom_pi_ui.shell_installed',\n eventLoopStalled: 'doom_pi_ui.event_loop_stalled',\n} as const;\n\nexport type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];\nexport type UiEventAttributes = Record<string, string | number | boolean>;\n\nexport interface UiTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface UiTelemetry {\n recordError(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordWarning(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;\n recordEvent(event: UiEventName, attributes?: UiEventAttributes): Promise<void>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createUiTelemetry(options: UiTelemetryOptions = {}): UiTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"kEAEA,MAGa,EAAW,CACtB,2BAA4B,0CAC5B,yBAA0B,wCAC1B,wBAAyB,uCACzB,iBAAkB,gCAClB,eAAgB,6BAChB,iBAAkB,+BACpB,EAqBA,SAAgB,EAAkB,EAA8B,CAAC,EAAgB,CAC/E,IAAM,EAA2B,EAAoB,CACnD,YAAa,aACb,YAAa,uBACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
|
package/dist/tui/uiRuntime.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/extensionSource/index.cjs"),n=require("../services/telemetry/index.cjs"),r=require("../models/uiState.cjs"),i=require("../services/leaderRegistry/index.cjs"),a=require("./doomEditor.cjs"),o=require("./doomFooter.cjs"),s=require("./doomHeader.cjs"),c=require("./leaderHints.cjs");require("./theme.cjs");const l=require("./toolsOverlay.cjs"),u=require("./configOverlay.cjs"),d=require("../constants/ui.cjs"),f=require("../services/uiHub/index.cjs");let
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/extensionSource/index.cjs"),n=require("../services/telemetry/index.cjs"),r=require("../models/uiState.cjs"),i=require("../services/leaderRegistry/index.cjs"),a=require("./doomEditor.cjs"),o=require("./doomFooter.cjs"),s=require("./doomHeader.cjs"),c=require("./leaderHints.cjs");require("./theme.cjs");const l=require("./toolsOverlay.cjs"),u=require("./configOverlay.cjs"),d=require("../constants/ui.cjs"),f=require("../services/eventLoopLag/index.cjs"),p=require("../services/uiHub/index.cjs");let m=require("node:path");m=e.__toESM(m,1);let h=require("@agimon-ai/doompi-core/tool-inventory"),g=require("@agimon-ai/doompi-core/mcp-status"),_=require("@agimon-ai/doompi-core/notification");function v(e,t,n,r){let i=(0,_.readDoomNotificationService)(e);if(i){try{Promise.resolve(i.request({body:n,level:r})).catch(()=>void 0)}catch{}return}t.ui.notify(n,r)}function y(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${d.TITLE_PREFIX} · ${r} · ${m.default.basename(t)||t}`}function b(e,{pi:_,telemetry:b}){let x=!1,S=new r.DoomUiState,C=new i.DoomLeaderRegistry,w=new Set,T,E,D=0,O=!1,k,A=()=>(0,g.readDoomMcpStatus)(e)?.getSnapshot().servers,j=t=>{for(let r of t){let t=r.bindingId?` (${r.bindingId})`:``,i=`Leader contribution from ${r.source}${t}: ${r.message}`;w.has(i)||(w.add(i),b.recordWarning(n.UI_EVENT.leaderContributionRejected,r.message,{"leader.source":r.source,...r.bindingId?{"leader.binding.id":r.bindingId}:{}}),E?.mode===`tui`&&v(e,E,i,d.WARNING_STYLE))}},M=p.createDoomUiHub({leaderRegistry:C,reportDiagnostics:j});return{hub:M,uiState:S,async dispose(){if(x)return;x=!0;let e=E;++D,E=void 0,M.setContext(void 0),T=void 0,k?.stop(),k=void 0,M.dispose(),S.reset(),e?.mode===`tui`&&e.ui.setWidget(d.LEADER_WIDGET_KEY,void 0,{placement:d.WIDGET_PLACEMENT}),await b.shutdown()},commands:[[d.TOOLS_COMMAND,{description:`Browse the tools available in this session`,handler:async(e,n)=>{let r=A(),i=(0,h.buildToolSources)({tools:_.getAllTools(),activeTools:_.getActiveTools(),...r?{mcpServers:r}:{},resolveExtensionName:t.extensionName,resolveExtensionPackageName:t.extensionPackageName,resolveExtensionToolSource:e=>t.extensionToolSource(_,e)});await l.openToolsOverlay(n,i)}}],[d.CONFIG_COMMAND,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await u.openConfigOverlay(t,M.config)}}]],events:{[d.SESSION_START_EVENT]:(t,r)=>{E=r,M.setContext(r);let i=++D;if(j(C.flush()),O=r.sessionManager.getEntries().some(e=>e.type===d.SESSION_MESSAGE_ENTRY),r.mode!==`tui`)return;for(let t of w)v(e,r,t,d.WARNING_STYLE);k?.stop(),k=f.startEventLoopLagSampler(e=>{b.recordWarning(n.UI_EVENT.eventLoopStalled,`Event loop stalled for ${String(e)}ms.`,{lag_ms:e})});let l=process.env.DOOMPI_THEME||`doom-pi-dark`,u=r.ui.setTheme(l);u.success||(v(e,r,`Could not apply Doom Pi theme: ${u.error}`,d.WARNING_STYLE),b.recordWarning(n.UI_EVENT.themeApplyFailed,u.error??`Unknown theme error`,{"ui.theme":l})),r.ui.setTitle(`${d.TITLE_PREFIX} · ${m.default.basename(r.cwd)||r.cwd} · pi/coding`),r.ui.setHeader((e,t)=>new s.DoomHeader(t,r.cwd,void 0,r,()=>e.terminal.rows)),r.ui.setFooter((e,t,n)=>(T=n,new o.DoomFooter(e,t,r,n,M.footer,S))),r.ui.setEditorComponent((t,o,s)=>new a.DoomEditor(t,o,s,S,e=>{if(!e.active){r.ui.setWidget(d.LEADER_WIDGET_KEY,void 0,{placement:d.WIDGET_PLACEMENT});return}r.ui.setWidget(d.LEADER_WIDGET_KEY,(t,n)=>new c.LeaderHints(n,e,r,T,S.getModes()),{placement:d.WIDGET_PLACEMENT})},void 0,r.ui.theme,{registry:C,isCommandAvailable:e=>d.BUILTIN_LEADER_COMMANDS.includes(e)||_.getCommands().some(t=>t.name===e),onLeaderAction:(t,n)=>{if(E!==r||D!==i){v(e,r,`Leader action ${n} is unavailable.`,d.WARNING_STYLE);return}M.invokeLeaderAction(t,n)},onUnavailableCommand:t=>{b.recordWarning(n.UI_EVENT.leaderCommandUnavailable,`Leader command /${t} is unavailable.`,{"ui.kind":`command`}),v(e,r,`Leader command /${t} is unavailable.`,d.WARNING_STYLE)},onUnavailableAction:t=>{b.recordWarning(n.UI_EVENT.leaderActionUnavailable,`Leader action ${t} is unavailable.`,{"ui.kind":`action`}),v(e,r,`Leader action ${t} is unavailable.`,d.WARNING_STYLE)}})),b.recordEvent(n.UI_EVENT.shellInstalled,{"ui.theme":l,"ui.theme.applied":u.success,"ui.leader.group.count":C.getGroup([])?.options.length??0})},[d.INPUT_EVENT]:(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||O)return;O=!0;let n=y(e.text,t.cwd);n&&t.ui.setTitle(n)}}}}exports.createUiRuntime=b;
|
|
2
2
|
//# sourceMappingURL=uiRuntime.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uiRuntime.cjs","names":["readDoomNotificationService","TITLE_PREFIX","path","DoomUiState","DoomLeaderRegistry","readDoomMcpStatus","UI_EVENT","WARNING_STYLE","createDoomUiHub","LEADER_WIDGET_KEY","WIDGET_PLACEMENT","TOOLS_COMMAND","buildToolSources","extensionName","extensionPackageName","extensionToolSource","openToolsOverlay","CONFIG_COMMAND","openConfigOverlay","SESSION_START_EVENT","SESSION_MESSAGE_ENTRY","DoomHeader","DoomFooter","DoomEditor","LeaderHints","BUILTIN_LEADER_COMMANDS","INPUT_EVENT"],"sources":["../../src/tui/uiRuntime.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { readDoomMcpStatus } from '@agimon-ai/doompi-core/mcp-status';\nimport { type DoomNotificationLevel, readDoomNotificationService } from '@agimon-ai/doompi-core/notification';\nimport type { PiEventHandlers } from '@agimon-ai/doompi-core/pi-extension';\nimport { buildToolSources, type McpServerStatus } from '@agimon-ai/doompi-core/tool-inventory';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\n\nimport {\n LEADER_WIDGET_KEY,\n TUI_MODE,\n WIDGET_PLACEMENT,\n WARNING_STYLE,\n THEME_ENVIRONMENT_KEY,\n TOOLS_COMMAND,\n CONFIG_COMMAND,\n SESSION_START_EVENT,\n SESSION_MESSAGE_ENTRY,\n INPUT_EVENT,\n INTERACTIVE_INPUT_SOURCE,\n TITLE_MESSAGE_MAX_LENGTH,\n TITLE_PREFIX,\n BUILTIN_LEADER_COMMANDS,\n} from '../constants/ui';\nimport { DoomUiState, type LeaderSnapshot } from '../models/uiState';\nimport { extensionName, extensionPackageName, extensionToolSource } from '../services/extensionSource';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../services/leaderRegistry';\nimport { UI_EVENT, type UiTelemetry } from '../services/telemetry';\nimport { createDoomUiHub } from '../services/uiHub';\nimport { openConfigOverlay } from './configOverlay';\nimport { DoomEditor } from './doomEditor';\nimport { DoomFooter } from './doomFooter';\nimport { DoomHeader } from './doomHeader';\nimport { LeaderHints } from './leaderHints';\nimport { DEFAULT_THEME_NAME } from './theme';\nimport { openToolsOverlay } from './toolsOverlay';\n\nfunction notify(cordis: Context, context: ExtensionContext, body: string, level: DoomNotificationLevel): void {\n const service = readDoomNotificationService(cordis);\n if (service) {\n try {\n void Promise.resolve(service.request({ body, level })).catch(() => undefined);\n } catch {\n // Notification delivery is best effort and does not fall back after routing.\n }\n return;\n }\n context.ui.notify(body, level);\n}\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\ninterface UiPluginOptions {\n readonly pi: ExtensionAPI;\n readonly telemetry: UiTelemetry;\n}\n\nexport interface UiRuntime {\n readonly hub: ReturnType<typeof createDoomUiHub>;\n readonly uiState: DoomUiState;\n readonly commands: readonly (readonly [...Parameters<ExtensionAPI['registerCommand']>])[];\n readonly events: PiEventHandlers;\n dispose(): Promise<void>;\n}\n\nexport function createUiRuntime(cordis: Context, { pi, telemetry }: UiPluginOptions): UiRuntime {\n let disposed = false;\n const uiState = new DoomUiState();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = (): readonly McpServerStatus[] | undefined => readDoomMcpStatus(cordis)?.getSnapshot().servers;\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) notify(cordis, activeContext, message, WARNING_STYLE);\n }\n };\n\n const hub = createDoomUiHub({ leaderRegistry, reportDiagnostics });\n return {\n hub,\n uiState,\n async dispose() {\n if (disposed) return;\n disposed = true;\n const context = activeContext;\n ++sessionGeneration;\n activeContext = undefined;\n hub.setContext(undefined);\n footerData = undefined;\n hub.dispose();\n uiState.reset();\n if (context?.mode === TUI_MODE) {\n context.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n }\n await telemetry.shutdown();\n },\n commands: [\n [\n TOOLS_COMMAND,\n {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionPackageName: extensionPackageName,\n resolveExtensionToolSource: (toolName) => extensionToolSource(pi, toolName),\n });\n await openToolsOverlay(ctx, sources);\n },\n },\n ],\n\n [\n CONFIG_COMMAND,\n {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, hub.config);\n },\n },\n ],\n ],\n events: {\n [SESSION_START_EVENT]: (_event, ctx) => {\n activeContext = ctx;\n hub.setContext(ctx);\n const activeGeneration = ++sessionGeneration;\n reportDiagnostics(leaderRegistry.flush());\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) notify(cordis, ctx, message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n notify(cordis, ctx, `Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, hub.footer, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) =>\n new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.includes(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n hub.invokeLeaderAction(source, action);\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n notify(cordis, ctx, `Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n },\n\n [INPUT_EVENT]: (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uiRuntime.cjs","names":["readDoomNotificationService","TITLE_PREFIX","path","DoomUiState","DoomLeaderRegistry","readDoomMcpStatus","UI_EVENT","WARNING_STYLE","createDoomUiHub","LEADER_WIDGET_KEY","WIDGET_PLACEMENT","TOOLS_COMMAND","buildToolSources","extensionName","extensionPackageName","extensionToolSource","openToolsOverlay","CONFIG_COMMAND","openConfigOverlay","SESSION_START_EVENT","SESSION_MESSAGE_ENTRY","startEventLoopLagSampler","DoomHeader","DoomFooter","DoomEditor","LeaderHints","BUILTIN_LEADER_COMMANDS","INPUT_EVENT"],"sources":["../../src/tui/uiRuntime.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { readDoomMcpStatus } from '@agimon-ai/doompi-core/mcp-status';\nimport { type DoomNotificationLevel, readDoomNotificationService } from '@agimon-ai/doompi-core/notification';\nimport type { PiEventHandlers } from '@agimon-ai/doompi-core/pi-extension';\nimport { buildToolSources, type McpServerStatus } from '@agimon-ai/doompi-core/tool-inventory';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\n\nimport {\n LEADER_WIDGET_KEY,\n TUI_MODE,\n WIDGET_PLACEMENT,\n WARNING_STYLE,\n THEME_ENVIRONMENT_KEY,\n TOOLS_COMMAND,\n CONFIG_COMMAND,\n SESSION_START_EVENT,\n SESSION_MESSAGE_ENTRY,\n INPUT_EVENT,\n INTERACTIVE_INPUT_SOURCE,\n TITLE_MESSAGE_MAX_LENGTH,\n TITLE_PREFIX,\n BUILTIN_LEADER_COMMANDS,\n} from '../constants/ui';\nimport { DoomUiState, type LeaderSnapshot } from '../models/uiState';\nimport { type EventLoopLagSampler, startEventLoopLagSampler } from '../services/eventLoopLag';\nimport { extensionName, extensionPackageName, extensionToolSource } from '../services/extensionSource';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../services/leaderRegistry';\nimport { UI_EVENT, type UiTelemetry } from '../services/telemetry';\nimport { createDoomUiHub } from '../services/uiHub';\nimport { openConfigOverlay } from './configOverlay';\nimport { DoomEditor } from './doomEditor';\nimport { DoomFooter } from './doomFooter';\nimport { DoomHeader } from './doomHeader';\nimport { LeaderHints } from './leaderHints';\nimport { DEFAULT_THEME_NAME } from './theme';\nimport { openToolsOverlay } from './toolsOverlay';\n\nfunction notify(cordis: Context, context: ExtensionContext, body: string, level: DoomNotificationLevel): void {\n const service = readDoomNotificationService(cordis);\n if (service) {\n try {\n void Promise.resolve(service.request({ body, level })).catch(() => undefined);\n } catch {\n // Notification delivery is best effort and does not fall back after routing.\n }\n return;\n }\n context.ui.notify(body, level);\n}\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\ninterface UiPluginOptions {\n readonly pi: ExtensionAPI;\n readonly telemetry: UiTelemetry;\n}\n\nexport interface UiRuntime {\n readonly hub: ReturnType<typeof createDoomUiHub>;\n readonly uiState: DoomUiState;\n readonly commands: readonly (readonly [...Parameters<ExtensionAPI['registerCommand']>])[];\n readonly events: PiEventHandlers;\n dispose(): Promise<void>;\n}\n\nexport function createUiRuntime(cordis: Context, { pi, telemetry }: UiPluginOptions): UiRuntime {\n let disposed = false;\n const uiState = new DoomUiState();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let lagSampler: EventLoopLagSampler | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = (): readonly McpServerStatus[] | undefined => readDoomMcpStatus(cordis)?.getSnapshot().servers;\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) notify(cordis, activeContext, message, WARNING_STYLE);\n }\n };\n\n const hub = createDoomUiHub({ leaderRegistry, reportDiagnostics });\n return {\n hub,\n uiState,\n async dispose() {\n if (disposed) return;\n disposed = true;\n const context = activeContext;\n ++sessionGeneration;\n activeContext = undefined;\n hub.setContext(undefined);\n footerData = undefined;\n lagSampler?.stop();\n lagSampler = undefined;\n hub.dispose();\n uiState.reset();\n if (context?.mode === TUI_MODE) {\n context.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n }\n await telemetry.shutdown();\n },\n commands: [\n [\n TOOLS_COMMAND,\n {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionPackageName: extensionPackageName,\n resolveExtensionToolSource: (toolName) => extensionToolSource(pi, toolName),\n });\n await openToolsOverlay(ctx, sources);\n },\n },\n ],\n\n [\n CONFIG_COMMAND,\n {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, hub.config);\n },\n },\n ],\n ],\n events: {\n [SESSION_START_EVENT]: (_event, ctx) => {\n activeContext = ctx;\n hub.setContext(ctx);\n const activeGeneration = ++sessionGeneration;\n reportDiagnostics(leaderRegistry.flush());\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) notify(cordis, ctx, message, WARNING_STYLE);\n\n // A resumed or forked session runs this again, and two samplers would\n // double every report.\n lagSampler?.stop();\n lagSampler = startEventLoopLagSampler((lagMs) => {\n void telemetry.recordWarning(UI_EVENT.eventLoopStalled, `Event loop stalled for ${String(lagMs)}ms.`, {\n lag_ms: lagMs,\n });\n });\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n notify(cordis, ctx, `Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, hub.footer, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) =>\n new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.includes(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n hub.invokeLeaderAction(source, action);\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n notify(cordis, ctx, `Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n },\n\n [INPUT_EVENT]: (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n },\n },\n };\n}\n"],"mappings":"8vBAuCA,SAAS,EAAO,EAAiB,EAA2B,EAAc,EAAoC,CAC5G,IAAM,GAAA,EAAUA,EAAAA,4BAAAA,CAA4B,CAAM,EAClD,GAAI,EAAS,CACX,GAAI,CACF,QAAa,QAAQ,EAAQ,QAAQ,CAAE,OAAM,OAAM,CAAC,CAAC,CAAC,CAAC,UAAY,IAAA,EAAS,CAC9E,MAAQ,CAER,CACA,MACF,CACA,EAAQ,GAAG,OAAO,EAAM,CAAK,CAC/B,CAEA,SAAS,EAAmB,EAAiB,EAAiC,CAC5E,IAAM,EAAoB,EAAQ,KAAK,CAAC,CAAC,QAAQ,OAAQ,GAAG,EAC5D,GAAI,CAAC,EAAmB,OACxB,IAAM,EAAe,EAAkB,MAAM,EAAA,EAA2B,CAAC,CAAC,QAAQ,EAClF,MAAO,GAAGC,EAAAA,aAAa,KAAK,EAAa,KAAKC,EAAAA,QAAK,SAAS,CAAG,GAAK,GACtE,CAeA,SAAgB,EAAgB,EAAiB,CAAE,KAAI,aAAyC,CAC9F,IAAI,EAAW,GACT,EAAU,IAAIC,EAAAA,YACd,EAAiB,IAAIC,EAAAA,mBACrB,EAAqB,IAAI,IAC3B,EACA,EACA,EAAoB,EACpB,EAAoB,GACpB,EAQE,OAAA,EAA+DC,EAAAA,kBAAAA,CAAkB,CAAM,CAAC,EAAE,YAAY,CAAC,CAAC,QAExG,EAAqB,GAAuD,CAChF,IAAK,IAAM,KAAc,EAAa,CACpC,IAAM,EAAU,EAAW,UAAY,KAAK,EAAW,UAAU,GAAK,GAChE,EAAU,4BAA4B,EAAW,SAAS,EAAQ,IAAI,EAAW,UACnF,EAAmB,IAAI,CAAO,IAClC,EAAmB,IAAI,CAAO,EAG9B,EAAe,cAAcC,EAAAA,SAAS,2BAA4B,EAAW,QAAS,CACpF,gBAAiB,EAAW,OAC5B,GAAI,EAAW,UAAY,CAAE,oBAAqB,EAAW,SAAU,EAAI,CAAC,CAC9E,CAAC,EACG,GAAe,OAAA,OAAmB,EAAO,EAAQ,EAAe,EAASC,EAAAA,aAAa,EAC5F,CACF,EAEM,EAAMC,EAAAA,gBAAgB,CAAE,iBAAgB,mBAAkB,CAAC,EACjE,MAAO,CACL,MACA,UACA,MAAM,SAAU,CACd,GAAI,EAAU,OACd,EAAW,GACX,IAAM,EAAU,EAChB,EAAE,EACF,EAAgB,IAAA,GAChB,EAAI,WAAW,IAAA,EAAS,EACxB,EAAa,IAAA,GACb,GAAY,KAAK,EACjB,EAAa,IAAA,GACb,EAAI,QAAQ,EACZ,EAAQ,MAAM,EACV,GAAS,OAAA,OACX,EAAQ,GAAG,UAAUC,EAAAA,kBAAmB,IAAA,GAAW,CAAE,UAAWC,EAAAA,gBAAiB,CAAC,EAEpF,MAAM,EAAU,SAAS,CAC3B,EACA,SAAU,CACR,CACEC,EAAAA,cACA,CACE,YAAa,6CACb,QAAS,MAAO,EAAO,IAAQ,CAG7B,IAAM,EAAa,EAAe,EAC5B,GAAA,EAAUC,EAAAA,iBAAAA,CAAiB,CAC/B,MAAO,EAAG,YAAY,EACtB,YAAa,EAAG,eAAe,EAC/B,GAAI,EAAa,CAAE,YAAW,EAAI,CAAC,EACnC,qBAAsBC,EAAAA,cACtB,4BAA6BC,EAAAA,qBAC7B,2BAA6B,GAAaC,EAAAA,oBAAoB,EAAI,CAAQ,CAC5E,CAAC,EACD,MAAMC,EAAAA,iBAAiB,EAAK,CAAO,CACrC,CACF,CACF,EAEA,CACEC,EAAAA,eACA,CACE,YAAa,uDACb,QAAS,MAAO,EAAO,IAAQ,CAI7B,MAAMC,EAAAA,kBAAkB,EAAK,EAAI,MAAM,CACzC,CACF,CACF,CACF,EACA,OAAQ,EACLC,EAAAA,sBAAuB,EAAQ,IAAQ,CACtC,EAAgB,EAChB,EAAI,WAAW,CAAG,EAClB,IAAM,EAAmB,EAAE,EAG3B,GAFA,EAAkB,EAAe,MAAM,CAAC,EACxC,EAAoB,EAAI,eAAe,WAAW,CAAC,CAAC,KAAM,GAAU,EAAM,OAASC,EAAAA,qBAAqB,EACpG,EAAI,OAAA,MAAmB,OAC3B,IAAK,IAAM,KAAW,EAAoB,EAAO,EAAQ,EAAK,EAASb,EAAAA,aAAa,EAIpF,GAAY,KAAK,EACjB,EAAac,EAAAA,yBAA0B,GAAU,CAC/C,EAAe,cAAcf,EAAAA,SAAS,iBAAkB,0BAA0B,OAAO,CAAK,EAAE,KAAM,CACpG,OAAQ,CACV,CAAC,CACH,CAAC,EAED,IAAM,EAAY,QAAQ,IAAA,cAAA,eACpB,EAAc,EAAI,GAAG,SAAS,CAAS,EACxC,EAAY,UACf,EAAO,EAAQ,EAAK,kCAAkC,EAAY,QAASC,EAAAA,aAAa,EACxF,EAAe,cAAcD,EAAAA,SAAS,iBAAkB,EAAY,OAAS,sBAAuB,CAClG,WAAY,CACd,CAAC,GAGH,EAAI,GAAG,SAAS,GAAGL,EAAAA,aAAa,KAAKC,EAAAA,QAAK,SAAS,EAAI,GAAG,GAAK,EAAI,IAAI,aAAa,EACpF,EAAI,GAAG,WAAW,EAAK,IAAU,IAAIoB,EAAAA,WAAW,EAAO,EAAI,IAAK,IAAA,GAAW,MAAW,EAAI,SAAS,IAAI,CAAC,EACxG,EAAI,GAAG,WAAW,EAAK,EAAO,KAC5B,EAAa,EACN,IAAIC,EAAAA,WAAW,EAAK,EAAO,EAAK,EAAM,EAAI,OAAQ,CAAO,EACjE,EACD,EAAI,GAAG,oBACJ,EAAK,EAAa,IACjB,IAAIC,EAAAA,WACF,EACA,EACA,EACA,EACC,GAA6B,CAC5B,GAAI,CAAC,EAAS,OAAQ,CACpB,EAAI,GAAG,UAAUf,EAAAA,kBAAmB,IAAA,GAAW,CAAE,UAAWC,EAAAA,gBAAiB,CAAC,EAC9E,MACF,CACA,EAAI,GAAG,UACLD,EAAAA,mBACC,EAAY,IACX,IAAIgB,EAAAA,YAAY,EAAa,EAAU,EAAK,EAAY,EAAQ,SAAS,CAAC,EAC5E,CAAE,UAAWf,EAAAA,gBAAiB,CAChC,CACF,EACA,IAAA,GACA,EAAI,GAAG,MACP,CACE,SAAU,EACV,mBAAqB,GACnBgB,EAAAA,wBAAwB,SAAS,CAAW,GAC5C,EAAG,YAAY,CAAC,CAAC,KAAM,GAAY,EAAQ,OAAS,CAAW,EACjE,gBAAiB,EAAQ,IAAW,CAClC,GAAI,IAAkB,GAAO,IAAsB,EAAkB,CACnE,EAAO,EAAQ,EAAK,iBAAiB,EAAO,kBAAmBnB,EAAAA,aAAa,EAC5E,MACF,CACA,EAAI,mBAAmB,EAAQ,CAAM,CACvC,EACA,qBAAuB,GAAgB,CACrC,EAAe,cACbD,EAAAA,SAAS,yBACT,mBAAmB,EAAY,kBAC/B,CAAE,UAAW,SAAU,CACzB,EACA,EAAO,EAAQ,EAAK,mBAAmB,EAAY,kBAAmBC,EAAAA,aAAa,CACrF,EACA,oBAAsB,GAAW,CAC/B,EAAe,cACbD,EAAAA,SAAS,wBACT,iBAAiB,EAAO,kBACxB,CACE,UAAW,QACb,CACF,EACA,EAAO,EAAQ,EAAK,iBAAiB,EAAO,kBAAmBC,EAAAA,aAAa,CAC9E,CACF,CACF,CACJ,EAEA,EAAe,YAAYD,EAAAA,SAAS,eAAgB,CAClD,WAAY,EACZ,mBAAoB,EAAY,QAChC,wBAAyB,EAAe,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,QAAU,CAC1E,CAAC,CACH,GAECqB,EAAAA,cAAe,EAAO,IAAQ,CAC7B,GAAI,EAAI,OAAA,OAAqB,EAAM,SAAA,eAAuC,EAAmB,OAC7F,EAAoB,GACpB,IAAM,EAAQ,EAAmB,EAAM,KAAM,EAAI,GAAG,EAChD,GAAO,EAAI,GAAG,SAAS,CAAK,CAClC,CACF,CACF,CACF"}
|
package/dist/tui/uiRuntime.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{extensionName as e,extensionPackageName as t,extensionToolSource as n}from"../services/extensionSource/index.mjs";import{UI_EVENT as r}from"../services/telemetry/index.mjs";import{DoomUiState as i}from"../models/uiState.mjs";import{DoomLeaderRegistry as a}from"../services/leaderRegistry/index.mjs";import{DoomEditor as o}from"./doomEditor.mjs";import{DoomFooter as s}from"./doomFooter.mjs";import{DoomHeader as c}from"./doomHeader.mjs";import{LeaderHints as l}from"./leaderHints.mjs";import"./theme.mjs";import{openToolsOverlay as u}from"./toolsOverlay.mjs";import{openConfigOverlay as d}from"./configOverlay.mjs";import{BUILTIN_LEADER_COMMANDS as f,CONFIG_COMMAND as p,INPUT_EVENT as m,LEADER_WIDGET_KEY as h,SESSION_MESSAGE_ENTRY as g,SESSION_START_EVENT as _,TITLE_PREFIX as v,TOOLS_COMMAND as y,WARNING_STYLE as b,WIDGET_PLACEMENT as x}from"../constants/ui.mjs";import{
|
|
1
|
+
import{extensionName as e,extensionPackageName as t,extensionToolSource as n}from"../services/extensionSource/index.mjs";import{UI_EVENT as r}from"../services/telemetry/index.mjs";import{DoomUiState as i}from"../models/uiState.mjs";import{DoomLeaderRegistry as a}from"../services/leaderRegistry/index.mjs";import{DoomEditor as o}from"./doomEditor.mjs";import{DoomFooter as s}from"./doomFooter.mjs";import{DoomHeader as c}from"./doomHeader.mjs";import{LeaderHints as l}from"./leaderHints.mjs";import"./theme.mjs";import{openToolsOverlay as u}from"./toolsOverlay.mjs";import{openConfigOverlay as d}from"./configOverlay.mjs";import{BUILTIN_LEADER_COMMANDS as f,CONFIG_COMMAND as p,INPUT_EVENT as m,LEADER_WIDGET_KEY as h,SESSION_MESSAGE_ENTRY as g,SESSION_START_EVENT as _,TITLE_PREFIX as v,TOOLS_COMMAND as y,WARNING_STYLE as b,WIDGET_PLACEMENT as x}from"../constants/ui.mjs";import{startEventLoopLagSampler as S}from"../services/eventLoopLag/index.mjs";import{createDoomUiHub as C}from"../services/uiHub/index.mjs";import w from"node:path";import{buildToolSources as T}from"@agimon-ai/doompi-core/tool-inventory";import{readDoomMcpStatus as E}from"@agimon-ai/doompi-core/mcp-status";import{readDoomNotificationService as D}from"@agimon-ai/doompi-core/notification";function O(e,t,n,r){let i=D(e);if(i){try{Promise.resolve(i.request({body:n,level:r})).catch(()=>void 0)}catch{}return}t.ui.notify(n,r)}function k(e,t){let n=e.trim().replace(/\s+/g,` `);if(!n)return;let r=n.slice(0,64).trimEnd();return`${v} · ${r} · ${w.basename(t)||t}`}function A(D,{pi:A,telemetry:j}){let M=!1,N=new i,P=new a,F=new Set,I,L,R=0,z=!1,B,V=()=>E(D)?.getSnapshot().servers,H=e=>{for(let t of e){let e=t.bindingId?` (${t.bindingId})`:``,n=`Leader contribution from ${t.source}${e}: ${t.message}`;F.has(n)||(F.add(n),j.recordWarning(r.leaderContributionRejected,t.message,{"leader.source":t.source,...t.bindingId?{"leader.binding.id":t.bindingId}:{}}),L?.mode===`tui`&&O(D,L,n,b))}},U=C({leaderRegistry:P,reportDiagnostics:H});return{hub:U,uiState:N,async dispose(){if(M)return;M=!0;let e=L;++R,L=void 0,U.setContext(void 0),I=void 0,B?.stop(),B=void 0,U.dispose(),N.reset(),e?.mode===`tui`&&e.ui.setWidget(h,void 0,{placement:x}),await j.shutdown()},commands:[[y,{description:`Browse the tools available in this session`,handler:async(r,i)=>{let a=V(),o=T({tools:A.getAllTools(),activeTools:A.getActiveTools(),...a?{mcpServers:a}:{},resolveExtensionName:e,resolveExtensionPackageName:t,resolveExtensionToolSource:e=>n(A,e)});await u(i,o)}}],[p,{description:`Browse and change the settings extensions contribute`,handler:async(e,t)=>{await d(t,U.config)}}]],events:{[_]:(e,t)=>{L=t,U.setContext(t);let n=++R;if(H(P.flush()),z=t.sessionManager.getEntries().some(e=>e.type===g),t.mode!==`tui`)return;for(let e of F)O(D,t,e,b);B?.stop(),B=S(e=>{j.recordWarning(r.eventLoopStalled,`Event loop stalled for ${String(e)}ms.`,{lag_ms:e})});let i=process.env.DOOMPI_THEME||`doom-pi-dark`,a=t.ui.setTheme(i);a.success||(O(D,t,`Could not apply Doom Pi theme: ${a.error}`,b),j.recordWarning(r.themeApplyFailed,a.error??`Unknown theme error`,{"ui.theme":i})),t.ui.setTitle(`${v} · ${w.basename(t.cwd)||t.cwd} · pi/coding`),t.ui.setHeader((e,n)=>new c(n,t.cwd,void 0,t,()=>e.terminal.rows)),t.ui.setFooter((e,n,r)=>(I=r,new s(e,n,t,r,U.footer,N))),t.ui.setEditorComponent((e,i,a)=>new o(e,i,a,N,e=>{if(!e.active){t.ui.setWidget(h,void 0,{placement:x});return}t.ui.setWidget(h,(n,r)=>new l(r,e,t,I,N.getModes()),{placement:x})},void 0,t.ui.theme,{registry:P,isCommandAvailable:e=>f.includes(e)||A.getCommands().some(t=>t.name===e),onLeaderAction:(e,r)=>{if(L!==t||R!==n){O(D,t,`Leader action ${r} is unavailable.`,b);return}U.invokeLeaderAction(e,r)},onUnavailableCommand:e=>{j.recordWarning(r.leaderCommandUnavailable,`Leader command /${e} is unavailable.`,{"ui.kind":`command`}),O(D,t,`Leader command /${e} is unavailable.`,b)},onUnavailableAction:e=>{j.recordWarning(r.leaderActionUnavailable,`Leader action ${e} is unavailable.`,{"ui.kind":`action`}),O(D,t,`Leader action ${e} is unavailable.`,b)}})),j.recordEvent(r.shellInstalled,{"ui.theme":i,"ui.theme.applied":a.success,"ui.leader.group.count":P.getGroup([])?.options.length??0})},[m]:(e,t)=>{if(t.mode!==`tui`||e.source!==`interactive`||z)return;z=!0;let n=k(e.text,t.cwd);n&&t.ui.setTitle(n)}}}}export{A as createUiRuntime};
|
|
2
2
|
//# sourceMappingURL=uiRuntime.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uiRuntime.mjs","names":[],"sources":["../../src/tui/uiRuntime.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { readDoomMcpStatus } from '@agimon-ai/doompi-core/mcp-status';\nimport { type DoomNotificationLevel, readDoomNotificationService } from '@agimon-ai/doompi-core/notification';\nimport type { PiEventHandlers } from '@agimon-ai/doompi-core/pi-extension';\nimport { buildToolSources, type McpServerStatus } from '@agimon-ai/doompi-core/tool-inventory';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\n\nimport {\n LEADER_WIDGET_KEY,\n TUI_MODE,\n WIDGET_PLACEMENT,\n WARNING_STYLE,\n THEME_ENVIRONMENT_KEY,\n TOOLS_COMMAND,\n CONFIG_COMMAND,\n SESSION_START_EVENT,\n SESSION_MESSAGE_ENTRY,\n INPUT_EVENT,\n INTERACTIVE_INPUT_SOURCE,\n TITLE_MESSAGE_MAX_LENGTH,\n TITLE_PREFIX,\n BUILTIN_LEADER_COMMANDS,\n} from '../constants/ui';\nimport { DoomUiState, type LeaderSnapshot } from '../models/uiState';\nimport { extensionName, extensionPackageName, extensionToolSource } from '../services/extensionSource';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../services/leaderRegistry';\nimport { UI_EVENT, type UiTelemetry } from '../services/telemetry';\nimport { createDoomUiHub } from '../services/uiHub';\nimport { openConfigOverlay } from './configOverlay';\nimport { DoomEditor } from './doomEditor';\nimport { DoomFooter } from './doomFooter';\nimport { DoomHeader } from './doomHeader';\nimport { LeaderHints } from './leaderHints';\nimport { DEFAULT_THEME_NAME } from './theme';\nimport { openToolsOverlay } from './toolsOverlay';\n\nfunction notify(cordis: Context, context: ExtensionContext, body: string, level: DoomNotificationLevel): void {\n const service = readDoomNotificationService(cordis);\n if (service) {\n try {\n void Promise.resolve(service.request({ body, level })).catch(() => undefined);\n } catch {\n // Notification delivery is best effort and does not fall back after routing.\n }\n return;\n }\n context.ui.notify(body, level);\n}\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\ninterface UiPluginOptions {\n readonly pi: ExtensionAPI;\n readonly telemetry: UiTelemetry;\n}\n\nexport interface UiRuntime {\n readonly hub: ReturnType<typeof createDoomUiHub>;\n readonly uiState: DoomUiState;\n readonly commands: readonly (readonly [...Parameters<ExtensionAPI['registerCommand']>])[];\n readonly events: PiEventHandlers;\n dispose(): Promise<void>;\n}\n\nexport function createUiRuntime(cordis: Context, { pi, telemetry }: UiPluginOptions): UiRuntime {\n let disposed = false;\n const uiState = new DoomUiState();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = (): readonly McpServerStatus[] | undefined => readDoomMcpStatus(cordis)?.getSnapshot().servers;\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) notify(cordis, activeContext, message, WARNING_STYLE);\n }\n };\n\n const hub = createDoomUiHub({ leaderRegistry, reportDiagnostics });\n return {\n hub,\n uiState,\n async dispose() {\n if (disposed) return;\n disposed = true;\n const context = activeContext;\n ++sessionGeneration;\n activeContext = undefined;\n hub.setContext(undefined);\n footerData = undefined;\n hub.dispose();\n uiState.reset();\n if (context?.mode === TUI_MODE) {\n context.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n }\n await telemetry.shutdown();\n },\n commands: [\n [\n TOOLS_COMMAND,\n {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionPackageName: extensionPackageName,\n resolveExtensionToolSource: (toolName) => extensionToolSource(pi, toolName),\n });\n await openToolsOverlay(ctx, sources);\n },\n },\n ],\n\n [\n CONFIG_COMMAND,\n {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, hub.config);\n },\n },\n ],\n ],\n events: {\n [SESSION_START_EVENT]: (_event, ctx) => {\n activeContext = ctx;\n hub.setContext(ctx);\n const activeGeneration = ++sessionGeneration;\n reportDiagnostics(leaderRegistry.flush());\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) notify(cordis, ctx, message, WARNING_STYLE);\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n notify(cordis, ctx, `Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, hub.footer, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) =>\n new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.includes(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n hub.invokeLeaderAction(source, action);\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n notify(cordis, ctx, `Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n },\n\n [INPUT_EVENT]: (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uiRuntime.mjs","names":[],"sources":["../../src/tui/uiRuntime.ts"],"sourcesContent":["import path from 'node:path';\n\nimport { readDoomMcpStatus } from '@agimon-ai/doompi-core/mcp-status';\nimport { type DoomNotificationLevel, readDoomNotificationService } from '@agimon-ai/doompi-core/notification';\nimport type { PiEventHandlers } from '@agimon-ai/doompi-core/pi-extension';\nimport { buildToolSources, type McpServerStatus } from '@agimon-ai/doompi-core/tool-inventory';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, ReadonlyFooterDataProvider } from '@earendil-works/pi-coding-agent';\n\nimport {\n LEADER_WIDGET_KEY,\n TUI_MODE,\n WIDGET_PLACEMENT,\n WARNING_STYLE,\n THEME_ENVIRONMENT_KEY,\n TOOLS_COMMAND,\n CONFIG_COMMAND,\n SESSION_START_EVENT,\n SESSION_MESSAGE_ENTRY,\n INPUT_EVENT,\n INTERACTIVE_INPUT_SOURCE,\n TITLE_MESSAGE_MAX_LENGTH,\n TITLE_PREFIX,\n BUILTIN_LEADER_COMMANDS,\n} from '../constants/ui';\nimport { DoomUiState, type LeaderSnapshot } from '../models/uiState';\nimport { type EventLoopLagSampler, startEventLoopLagSampler } from '../services/eventLoopLag';\nimport { extensionName, extensionPackageName, extensionToolSource } from '../services/extensionSource';\nimport { type DoomLeaderDiagnostic, DoomLeaderRegistry } from '../services/leaderRegistry';\nimport { UI_EVENT, type UiTelemetry } from '../services/telemetry';\nimport { createDoomUiHub } from '../services/uiHub';\nimport { openConfigOverlay } from './configOverlay';\nimport { DoomEditor } from './doomEditor';\nimport { DoomFooter } from './doomFooter';\nimport { DoomHeader } from './doomHeader';\nimport { LeaderHints } from './leaderHints';\nimport { DEFAULT_THEME_NAME } from './theme';\nimport { openToolsOverlay } from './toolsOverlay';\n\nfunction notify(cordis: Context, context: ExtensionContext, body: string, level: DoomNotificationLevel): void {\n const service = readDoomNotificationService(cordis);\n if (service) {\n try {\n void Promise.resolve(service.request({ body, level })).catch(() => undefined);\n } catch {\n // Notification delivery is best effort and does not fall back after routing.\n }\n return;\n }\n context.ui.notify(body, level);\n}\n\nfunction createMessageTitle(message: string, cwd: string): string | undefined {\n const normalizedMessage = message.trim().replace(/\\s+/g, ' ');\n if (!normalizedMessage) return undefined;\n const messageTitle = normalizedMessage.slice(0, TITLE_MESSAGE_MAX_LENGTH).trimEnd();\n return `${TITLE_PREFIX} · ${messageTitle} · ${path.basename(cwd) || cwd}`;\n}\n\ninterface UiPluginOptions {\n readonly pi: ExtensionAPI;\n readonly telemetry: UiTelemetry;\n}\n\nexport interface UiRuntime {\n readonly hub: ReturnType<typeof createDoomUiHub>;\n readonly uiState: DoomUiState;\n readonly commands: readonly (readonly [...Parameters<ExtensionAPI['registerCommand']>])[];\n readonly events: PiEventHandlers;\n dispose(): Promise<void>;\n}\n\nexport function createUiRuntime(cordis: Context, { pi, telemetry }: UiPluginOptions): UiRuntime {\n let disposed = false;\n const uiState = new DoomUiState();\n const leaderRegistry = new DoomLeaderRegistry();\n const pendingDiagnostics = new Set<string>();\n let footerData: ReadonlyFooterDataProvider | undefined;\n let activeContext: ExtensionContext | undefined;\n let sessionGeneration = 0;\n let hasSessionMessage = false;\n let lagSampler: EventLoopLagSampler | undefined;\n\n /**\n * Asks the MCP extension what it is currently connected to.\n *\n * No answer is a normal session: `--no-mcp` leaves nobody providing the query,\n * and the panel simply lists MCP tools under the extension that registered them.\n */\n const readMcpServers = (): readonly McpServerStatus[] | undefined => readDoomMcpStatus(cordis)?.getSnapshot().servers;\n\n const reportDiagnostics = (diagnostics: readonly DoomLeaderDiagnostic[]): void => {\n for (const diagnostic of diagnostics) {\n const binding = diagnostic.bindingId ? ` (${diagnostic.bindingId})` : '';\n const message = `Leader contribution from ${diagnostic.source}${binding}: ${diagnostic.message}`;\n if (pendingDiagnostics.has(message)) continue;\n pendingDiagnostics.add(message);\n // A rejected contribution silently drops another extension's keybindings,\n // and the notice below only reaches a run that has a TUI attached.\n void telemetry.recordWarning(UI_EVENT.leaderContributionRejected, diagnostic.message, {\n 'leader.source': diagnostic.source,\n ...(diagnostic.bindingId ? { 'leader.binding.id': diagnostic.bindingId } : {}),\n });\n if (activeContext?.mode === TUI_MODE) notify(cordis, activeContext, message, WARNING_STYLE);\n }\n };\n\n const hub = createDoomUiHub({ leaderRegistry, reportDiagnostics });\n return {\n hub,\n uiState,\n async dispose() {\n if (disposed) return;\n disposed = true;\n const context = activeContext;\n ++sessionGeneration;\n activeContext = undefined;\n hub.setContext(undefined);\n footerData = undefined;\n lagSampler?.stop();\n lagSampler = undefined;\n hub.dispose();\n uiState.reset();\n if (context?.mode === TUI_MODE) {\n context.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n }\n await telemetry.shutdown();\n },\n commands: [\n [\n TOOLS_COMMAND,\n {\n description: 'Browse the tools available in this session',\n handler: async (_args, ctx) => {\n // Read at open time so a reconnected server or a plan-mode tool swap shows\n // up without restarting the session.\n const mcpServers = readMcpServers();\n const sources = buildToolSources({\n tools: pi.getAllTools(),\n activeTools: pi.getActiveTools(),\n ...(mcpServers ? { mcpServers } : {}),\n resolveExtensionName: extensionName,\n resolveExtensionPackageName: extensionPackageName,\n resolveExtensionToolSource: (toolName) => extensionToolSource(pi, toolName),\n });\n await openToolsOverlay(ctx, sources);\n },\n },\n ],\n\n [\n CONFIG_COMMAND,\n {\n description: 'Browse and change the settings extensions contribute',\n handler: async (_args, ctx) => {\n // The registry is passed live rather than snapshotted: a contributor can be\n // fetching or installing something while the panel is open, and that\n // progress is meant to land in it.\n await openConfigOverlay(ctx, hub.config);\n },\n },\n ],\n ],\n events: {\n [SESSION_START_EVENT]: (_event, ctx) => {\n activeContext = ctx;\n hub.setContext(ctx);\n const activeGeneration = ++sessionGeneration;\n reportDiagnostics(leaderRegistry.flush());\n hasSessionMessage = ctx.sessionManager.getEntries().some((entry) => entry.type === SESSION_MESSAGE_ENTRY);\n if (ctx.mode !== TUI_MODE) return;\n for (const message of pendingDiagnostics) notify(cordis, ctx, message, WARNING_STYLE);\n\n // A resumed or forked session runs this again, and two samplers would\n // double every report.\n lagSampler?.stop();\n lagSampler = startEventLoopLagSampler((lagMs) => {\n void telemetry.recordWarning(UI_EVENT.eventLoopStalled, `Event loop stalled for ${String(lagMs)}ms.`, {\n lag_ms: lagMs,\n });\n });\n\n const themeName = process.env[THEME_ENVIRONMENT_KEY] || DEFAULT_THEME_NAME;\n const themeResult = ctx.ui.setTheme(themeName);\n if (!themeResult.success) {\n notify(cordis, ctx, `Could not apply Doom Pi theme: ${themeResult.error}`, WARNING_STYLE);\n void telemetry.recordWarning(UI_EVENT.themeApplyFailed, themeResult.error ?? 'Unknown theme error', {\n 'ui.theme': themeName,\n });\n }\n\n ctx.ui.setTitle(`${TITLE_PREFIX} · ${path.basename(ctx.cwd) || ctx.cwd} · pi/coding`);\n ctx.ui.setHeader((tui, theme) => new DoomHeader(theme, ctx.cwd, undefined, ctx, () => tui.terminal.rows));\n ctx.ui.setFooter((tui, theme, data) => {\n footerData = data;\n return new DoomFooter(tui, theme, ctx, data, hub.footer, uiState);\n });\n ctx.ui.setEditorComponent(\n (tui, editorTheme, keybindings) =>\n new DoomEditor(\n tui,\n editorTheme,\n keybindings,\n uiState,\n (snapshot: LeaderSnapshot) => {\n if (!snapshot.active) {\n ctx.ui.setWidget(LEADER_WIDGET_KEY, undefined, { placement: WIDGET_PLACEMENT });\n return;\n }\n ctx.ui.setWidget(\n LEADER_WIDGET_KEY,\n (_widgetTui, widgetTheme) =>\n new LeaderHints(widgetTheme, snapshot, ctx, footerData, uiState.getModes()),\n { placement: WIDGET_PLACEMENT },\n );\n },\n undefined,\n ctx.ui.theme,\n {\n registry: leaderRegistry,\n isCommandAvailable: (commandName) =>\n BUILTIN_LEADER_COMMANDS.includes(commandName) ||\n pi.getCommands().some((command) => command.name === commandName),\n onLeaderAction: (source, action) => {\n if (activeContext !== ctx || sessionGeneration !== activeGeneration) {\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n return;\n }\n hub.invokeLeaderAction(source, action);\n },\n onUnavailableCommand: (commandName) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderCommandUnavailable,\n `Leader command /${commandName} is unavailable.`,\n { 'ui.kind': 'command' },\n );\n notify(cordis, ctx, `Leader command /${commandName} is unavailable.`, WARNING_STYLE);\n },\n onUnavailableAction: (action) => {\n void telemetry.recordWarning(\n UI_EVENT.leaderActionUnavailable,\n `Leader action ${action} is unavailable.`,\n {\n 'ui.kind': 'action',\n },\n );\n notify(cordis, ctx, `Leader action ${action} is unavailable.`, WARNING_STYLE);\n },\n },\n ),\n );\n\n void telemetry.recordEvent(UI_EVENT.shellInstalled, {\n 'ui.theme': themeName,\n 'ui.theme.applied': themeResult.success,\n 'ui.leader.group.count': leaderRegistry.getGroup([])?.options.length ?? 0,\n });\n },\n\n [INPUT_EVENT]: (event, ctx) => {\n if (ctx.mode !== TUI_MODE || event.source !== INTERACTIVE_INPUT_SOURCE || hasSessionMessage) return;\n hasSessionMessage = true;\n const title = createMessageTitle(event.text, ctx.cwd);\n if (title) ctx.ui.setTitle(title);\n },\n },\n };\n}\n"],"mappings":"gvCAuCA,SAAS,EAAO,EAAiB,EAA2B,EAAc,EAAoC,CAC5G,IAAM,EAAU,EAA4B,CAAM,EAClD,GAAI,EAAS,CACX,GAAI,CACF,QAAa,QAAQ,EAAQ,QAAQ,CAAE,OAAM,OAAM,CAAC,CAAC,CAAC,CAAC,UAAY,IAAA,EAAS,CAC9E,MAAQ,CAER,CACA,MACF,CACA,EAAQ,GAAG,OAAO,EAAM,CAAK,CAC/B,CAEA,SAAS,EAAmB,EAAiB,EAAiC,CAC5E,IAAM,EAAoB,EAAQ,KAAK,CAAC,CAAC,QAAQ,OAAQ,GAAG,EAC5D,GAAI,CAAC,EAAmB,OACxB,IAAM,EAAe,EAAkB,MAAM,EAAA,EAA2B,CAAC,CAAC,QAAQ,EAClF,MAAO,GAAG,EAAa,KAAK,EAAa,KAAK,EAAK,SAAS,CAAG,GAAK,GACtE,CAeA,SAAgB,EAAgB,EAAiB,CAAE,KAAI,aAAyC,CAC9F,IAAI,EAAW,GACT,EAAU,IAAI,EACd,EAAiB,IAAI,EACrB,EAAqB,IAAI,IAC3B,EACA,EACA,EAAoB,EACpB,EAAoB,GACpB,EAQE,MAA+D,EAAkB,CAAM,CAAC,EAAE,YAAY,CAAC,CAAC,QAExG,EAAqB,GAAuD,CAChF,IAAK,IAAM,KAAc,EAAa,CACpC,IAAM,EAAU,EAAW,UAAY,KAAK,EAAW,UAAU,GAAK,GAChE,EAAU,4BAA4B,EAAW,SAAS,EAAQ,IAAI,EAAW,UACnF,EAAmB,IAAI,CAAO,IAClC,EAAmB,IAAI,CAAO,EAG9B,EAAe,cAAc,EAAS,2BAA4B,EAAW,QAAS,CACpF,gBAAiB,EAAW,OAC5B,GAAI,EAAW,UAAY,CAAE,oBAAqB,EAAW,SAAU,EAAI,CAAC,CAC9E,CAAC,EACG,GAAe,OAAA,OAAmB,EAAO,EAAQ,EAAe,EAAS,CAAa,EAC5F,CACF,EAEM,EAAM,EAAgB,CAAE,iBAAgB,mBAAkB,CAAC,EACjE,MAAO,CACL,MACA,UACA,MAAM,SAAU,CACd,GAAI,EAAU,OACd,EAAW,GACX,IAAM,EAAU,EAChB,EAAE,EACF,EAAgB,IAAA,GAChB,EAAI,WAAW,IAAA,EAAS,EACxB,EAAa,IAAA,GACb,GAAY,KAAK,EACjB,EAAa,IAAA,GACb,EAAI,QAAQ,EACZ,EAAQ,MAAM,EACV,GAAS,OAAA,OACX,EAAQ,GAAG,UAAU,EAAmB,IAAA,GAAW,CAAE,UAAW,CAAiB,CAAC,EAEpF,MAAM,EAAU,SAAS,CAC3B,EACA,SAAU,CACR,CACE,EACA,CACE,YAAa,6CACb,QAAS,MAAO,EAAO,IAAQ,CAG7B,IAAM,EAAa,EAAe,EAC5B,EAAU,EAAiB,CAC/B,MAAO,EAAG,YAAY,EACtB,YAAa,EAAG,eAAe,EAC/B,GAAI,EAAa,CAAE,YAAW,EAAI,CAAC,EACnC,qBAAsB,EACtB,4BAA6B,EAC7B,2BAA6B,GAAa,EAAoB,EAAI,CAAQ,CAC5E,CAAC,EACD,MAAM,EAAiB,EAAK,CAAO,CACrC,CACF,CACF,EAEA,CACE,EACA,CACE,YAAa,uDACb,QAAS,MAAO,EAAO,IAAQ,CAI7B,MAAM,EAAkB,EAAK,EAAI,MAAM,CACzC,CACF,CACF,CACF,EACA,OAAQ,EACL,IAAuB,EAAQ,IAAQ,CACtC,EAAgB,EAChB,EAAI,WAAW,CAAG,EAClB,IAAM,EAAmB,EAAE,EAG3B,GAFA,EAAkB,EAAe,MAAM,CAAC,EACxC,EAAoB,EAAI,eAAe,WAAW,CAAC,CAAC,KAAM,GAAU,EAAM,OAAS,CAAqB,EACpG,EAAI,OAAA,MAAmB,OAC3B,IAAK,IAAM,KAAW,EAAoB,EAAO,EAAQ,EAAK,EAAS,CAAa,EAIpF,GAAY,KAAK,EACjB,EAAa,EAA0B,GAAU,CAC/C,EAAe,cAAc,EAAS,iBAAkB,0BAA0B,OAAO,CAAK,EAAE,KAAM,CACpG,OAAQ,CACV,CAAC,CACH,CAAC,EAED,IAAM,EAAY,QAAQ,IAAA,cAAA,eACpB,EAAc,EAAI,GAAG,SAAS,CAAS,EACxC,EAAY,UACf,EAAO,EAAQ,EAAK,kCAAkC,EAAY,QAAS,CAAa,EACxF,EAAe,cAAc,EAAS,iBAAkB,EAAY,OAAS,sBAAuB,CAClG,WAAY,CACd,CAAC,GAGH,EAAI,GAAG,SAAS,GAAG,EAAa,KAAK,EAAK,SAAS,EAAI,GAAG,GAAK,EAAI,IAAI,aAAa,EACpF,EAAI,GAAG,WAAW,EAAK,IAAU,IAAI,EAAW,EAAO,EAAI,IAAK,IAAA,GAAW,MAAW,EAAI,SAAS,IAAI,CAAC,EACxG,EAAI,GAAG,WAAW,EAAK,EAAO,KAC5B,EAAa,EACN,IAAI,EAAW,EAAK,EAAO,EAAK,EAAM,EAAI,OAAQ,CAAO,EACjE,EACD,EAAI,GAAG,oBACJ,EAAK,EAAa,IACjB,IAAI,EACF,EACA,EACA,EACA,EACC,GAA6B,CAC5B,GAAI,CAAC,EAAS,OAAQ,CACpB,EAAI,GAAG,UAAU,EAAmB,IAAA,GAAW,CAAE,UAAW,CAAiB,CAAC,EAC9E,MACF,CACA,EAAI,GAAG,UACL,GACC,EAAY,IACX,IAAI,EAAY,EAAa,EAAU,EAAK,EAAY,EAAQ,SAAS,CAAC,EAC5E,CAAE,UAAW,CAAiB,CAChC,CACF,EACA,IAAA,GACA,EAAI,GAAG,MACP,CACE,SAAU,EACV,mBAAqB,GACnB,EAAwB,SAAS,CAAW,GAC5C,EAAG,YAAY,CAAC,CAAC,KAAM,GAAY,EAAQ,OAAS,CAAW,EACjE,gBAAiB,EAAQ,IAAW,CAClC,GAAI,IAAkB,GAAO,IAAsB,EAAkB,CACnE,EAAO,EAAQ,EAAK,iBAAiB,EAAO,kBAAmB,CAAa,EAC5E,MACF,CACA,EAAI,mBAAmB,EAAQ,CAAM,CACvC,EACA,qBAAuB,GAAgB,CACrC,EAAe,cACb,EAAS,yBACT,mBAAmB,EAAY,kBAC/B,CAAE,UAAW,SAAU,CACzB,EACA,EAAO,EAAQ,EAAK,mBAAmB,EAAY,kBAAmB,CAAa,CACrF,EACA,oBAAsB,GAAW,CAC/B,EAAe,cACb,EAAS,wBACT,iBAAiB,EAAO,kBACxB,CACE,UAAW,QACb,CACF,EACA,EAAO,EAAQ,EAAK,iBAAiB,EAAO,kBAAmB,CAAa,CAC9E,CACF,CACF,CACJ,EAEA,EAAe,YAAY,EAAS,eAAgB,CAClD,WAAY,EACZ,mBAAoB,EAAY,QAChC,wBAAyB,EAAe,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,QAAU,CAC1E,CAAC,CACH,GAEC,IAAe,EAAO,IAAQ,CAC7B,GAAI,EAAI,OAAA,OAAqB,EAAM,SAAA,eAAuC,EAAmB,OAC7F,EAAoB,GACpB,IAAM,EAAQ,EAAmB,EAAM,KAAM,EAAI,GAAG,EAChD,GAAO,EAAI,GAAG,SAAS,CAAK,CAClC,CACF,CACF,CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-ui",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.72",
|
|
4
4
|
"description": "Leader-key menus, themes, and TUI components for DoomPi and Pi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -169,34 +169,34 @@
|
|
|
169
169
|
"access": "public"
|
|
170
170
|
},
|
|
171
171
|
"dependencies": {
|
|
172
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.72",
|
|
173
|
+
"@agimon-ai/doompi-hashline": "0.0.1-alpha.41",
|
|
174
|
+
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.72",
|
|
175
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.69",
|
|
172
176
|
"@deepseek-ai/cordis": "4.0.2",
|
|
173
|
-
"yaml": "2.9.0"
|
|
174
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.71",
|
|
175
|
-
"@agimon-ai/doompi-hashline": "0.0.1-alpha.40",
|
|
176
|
-
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.71",
|
|
177
|
-
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.68"
|
|
177
|
+
"yaml": "2.9.0"
|
|
178
178
|
},
|
|
179
179
|
"devDependencies": {
|
|
180
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.72",
|
|
181
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.30",
|
|
180
182
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
181
183
|
"@earendil-works/pi-tui": "0.85.1",
|
|
182
184
|
"@tanstack/react-store": "0.11.1",
|
|
183
185
|
"@tanstack/store": "0.11.1",
|
|
184
|
-
"@types/node": "26.
|
|
185
|
-
"@types/react": "19.
|
|
186
|
+
"@types/node": "26.5.1",
|
|
187
|
+
"@types/react": "19.3.0",
|
|
186
188
|
"@vitest/coverage-v8": "5.0.0",
|
|
187
|
-
"react": "19.
|
|
188
|
-
"react-dom": "19.
|
|
189
|
+
"react": "19.3.0",
|
|
190
|
+
"react-dom": "19.3.0",
|
|
189
191
|
"tsdown": "0.23.0",
|
|
190
192
|
"typescript": "7.0.2",
|
|
191
|
-
"vitest": "5.0.0"
|
|
192
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.71",
|
|
193
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.29"
|
|
193
|
+
"vitest": "5.0.0"
|
|
194
194
|
},
|
|
195
195
|
"peerDependencies": {
|
|
196
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.72",
|
|
197
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.30",
|
|
196
198
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
197
|
-
"@earendil-works/pi-tui": "0.85.1"
|
|
198
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.71",
|
|
199
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.29"
|
|
199
|
+
"@earendil-works/pi-tui": "0.85.1"
|
|
200
200
|
},
|
|
201
201
|
"peerDependenciesMeta": {
|
|
202
202
|
"@agimon-ai/doompi-web-components": {
|