@agimon-ai/po-ui 0.0.0-alpha.2 → 0.0.0-alpha.21
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/LICENSE +149 -21
- package/README.md +1 -1
- package/dist/apiContracts.cjs +1 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts +1 -1
- package/dist/apiContracts.mjs +1 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +1 -2
- package/dist/extensionName.cjs +66 -16
- package/dist/extensionName.cjs.map +1 -1
- package/dist/extensionName.d.mts +13 -1
- package/dist/extensionName.d.mts.map +1 -1
- package/dist/extensionName.mjs +64 -16
- package/dist/extensionName.mjs.map +1 -1
- package/dist/extensions/mcp-ui.mjs.map +1 -1
- package/dist/extensions/mcp.cjs +3 -3
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.d.mts +1 -1
- package/dist/extensions/mcp.mjs +4 -4
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/server.cjs +7 -7
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +7 -7
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +11 -11
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/footer.d.mts +2 -2
- package/dist/footer.mjs +1 -2
- package/dist/{harnessMetadata-Dw9Rb1nW.cjs → harnessMetadata-B3mBGrS3.cjs} +4 -4
- package/dist/harnessMetadata-B3mBGrS3.cjs.map +1 -0
- package/dist/{harnessMetadata-CzsdGAxL.d.mts → harnessMetadata-BzMgOB0W.d.mts} +4 -4
- package/dist/harnessMetadata-BzMgOB0W.d.mts.map +1 -0
- package/dist/{harnessMetadata-DkMSJutN.mjs → harnessMetadata-Ccv_j7WP.mjs} +3 -3
- package/dist/harnessMetadata-Ccv_j7WP.mjs.map +1 -0
- package/dist/harnessMetadata.cjs +2 -2
- package/dist/harnessMetadata.d.mts +2 -2
- package/dist/harnessMetadata.mjs +1 -2
- package/dist/{index-Bx49wmE7.d.mts → index-2GW2dj0I.d.mts} +9 -9
- package/dist/{index-Bx49wmE7.d.mts.map → index-2GW2dj0I.d.mts.map} +1 -1
- package/dist/{index-Dpzvl-vg.d.mts → index-DFSkSBBh.d.mts} +19 -11
- package/dist/index-DFSkSBBh.d.mts.map +1 -0
- package/dist/index.cjs +6 -6
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +5 -5
- package/dist/leader.d.mts +2 -2
- package/dist/leaderRegistry.cjs +2 -2
- package/dist/leaderRegistry.cjs.map +1 -1
- package/dist/leaderRegistry.d.mts +15 -15
- package/dist/leaderRegistry.d.mts.map +1 -1
- package/dist/leaderRegistry.mjs +2 -2
- package/dist/leaderRegistry.mjs.map +1 -1
- package/dist/logSinkTelemetry.cjs +1 -1
- package/dist/logSinkTelemetry.d.mts +1 -1
- package/dist/logSinkTelemetry.mjs +1 -2
- package/dist/skills.cjs +8 -8
- package/dist/skills.d.mts +2 -2
- package/dist/skills.mjs +1 -2
- package/dist/{telemetry-DMR6cIT1.cjs → telemetry-EXlQc9s0.cjs} +8 -8
- package/dist/telemetry-EXlQc9s0.cjs.map +1 -0
- package/dist/{telemetry--EgKB9ei.mjs → telemetry-RiFqd0cg.mjs} +9 -9
- package/dist/telemetry-RiFqd0cg.mjs.map +1 -0
- package/dist/{theme-Byj_dBlT.mjs → theme-BX_hfErv.mjs} +60 -40
- package/dist/theme-BX_hfErv.mjs.map +1 -0
- package/dist/{theme-2wveit5V.cjs → theme-BfC_GGQ4.cjs} +66 -40
- package/dist/theme-BfC_GGQ4.cjs.map +1 -0
- package/dist/theme.cjs +2 -1
- package/dist/theme.d.mts +2 -2
- package/dist/theme.mjs +1 -2
- package/dist/toolInventory.mjs +1 -2
- package/dist/{uiState-G_Pso-5i.mjs → uiState-C7I5WcMl.mjs} +3 -3
- package/dist/uiState-C7I5WcMl.mjs.map +1 -0
- package/dist/{uiState-rUwgKslb.cjs → uiState-CCytmxyX.cjs} +4 -4
- package/dist/uiState-CCytmxyX.cjs.map +1 -0
- package/dist/{uiState-Binu4nUb.d.mts → uiState-DbjaVyxl.d.mts} +3 -3
- package/dist/{uiState-Binu4nUb.d.mts.map → uiState-DbjaVyxl.d.mts.map} +1 -1
- package/dist/uiState.cjs +2 -2
- package/dist/uiState.d.mts +2 -2
- package/dist/uiState.mjs +1 -2
- package/package.json +19 -19
- package/dist/harnessMetadata-CzsdGAxL.d.mts.map +0 -1
- package/dist/harnessMetadata-DkMSJutN.mjs.map +0 -1
- package/dist/harnessMetadata-Dw9Rb1nW.cjs.map +0 -1
- package/dist/index-Dpzvl-vg.d.mts.map +0 -1
- package/dist/telemetry--EgKB9ei.mjs.map +0 -1
- package/dist/telemetry-DMR6cIT1.cjs.map +0 -1
- package/dist/theme-2wveit5V.cjs.map +0 -1
- package/dist/theme-Byj_dBlT.mjs.map +0 -1
- package/dist/uiState-G_Pso-5i.mjs.map +0 -1
- package/dist/uiState-rUwgKslb.cjs.map +0 -1
package/dist/footer.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { FooterStatusItemSchema, FooterStatusPlacementSchema, FooterTextColorSchema, FooterTextSegmentSchema };
|
|
1
|
+
export { FooterStatusItemSchema, FooterStatusPlacementSchema, FooterTextColorSchema, FooterTextSegmentSchema } from "@agimon-ai/po-core/footer";
|
|
@@ -10,7 +10,7 @@ const DEFAULT_MAJOR_MODE = "copilot";
|
|
|
10
10
|
function parseList(value) {
|
|
11
11
|
return value ? value.split(",").map((item) => item.trim()).filter(Boolean) : [];
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function readPoHarnessMetadata(environment = process.env) {
|
|
14
14
|
return {
|
|
15
15
|
root: environment.PO_ROOT,
|
|
16
16
|
majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,
|
|
@@ -20,11 +20,11 @@ function readDoomHarnessMetadata(environment = process.env) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
|
-
Object.defineProperty(exports, "
|
|
23
|
+
Object.defineProperty(exports, "readPoHarnessMetadata", {
|
|
24
24
|
enumerable: true,
|
|
25
25
|
get: function() {
|
|
26
|
-
return
|
|
26
|
+
return readPoHarnessMetadata;
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
//# sourceMappingURL=harnessMetadata-
|
|
30
|
+
//# sourceMappingURL=harnessMetadata-B3mBGrS3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessMetadata-B3mBGrS3.cjs","names":[],"sources":["../src/types/harnessMetadata.ts"],"sourcesContent":["/**\n * The slice of harness state the header renders.\n *\n * A projection of the store rather than its own reader. This used to\n * re-implement five of the state keys with its own list parser and its own\n * default mode, which is two definitions of one protocol to keep in step.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\n\nexport interface PoHarnessMetadata {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nexport function readPoHarnessMetadata(environment: NodeJS.ProcessEnv = process.env): PoHarnessMetadata {\n return {\n root: environment.PO_ROOT,\n majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,\n domains: parseList(environment.PO_DOMAINS),\n layers: parseList(environment.PO_LAYERS),\n profile: environment.PO_PROFILE?.trim() || undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,qBAAqB;AAY3B,SAAS,UAAU,OAAqC;CACtD,OAAO,QACH,MACG,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,IACjB,CAAC;AACP;AAEA,SAAgB,sBAAsB,cAAiC,QAAQ,KAAwB;CACrG,OAAO;EACL,MAAM,YAAY;EAClB,WAAW,YAAY,eAAe,KAAK,KAAK;EAChD,SAAS,UAAU,YAAY,UAAU;EACzC,QAAQ,UAAU,YAAY,SAAS;EACvC,SAAS,YAAY,YAAY,KAAK,KAAK,KAAA;CAC7C;AACF"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* re-implement five of the state keys with its own list parser and its own
|
|
7
7
|
* default mode, which is two definitions of one protocol to keep in step.
|
|
8
8
|
*/
|
|
9
|
-
interface
|
|
9
|
+
interface PoHarnessMetadata {
|
|
10
10
|
root?: string;
|
|
11
11
|
/** The one named major mode this session runs under. */
|
|
12
12
|
majorMode: string;
|
|
@@ -15,7 +15,7 @@ interface DoomHarnessMetadata {
|
|
|
15
15
|
layers: string[];
|
|
16
16
|
profile?: string;
|
|
17
17
|
}
|
|
18
|
-
declare function
|
|
18
|
+
declare function readPoHarnessMetadata(environment?: NodeJS.ProcessEnv): PoHarnessMetadata;
|
|
19
19
|
//#endregion
|
|
20
|
-
export {
|
|
21
|
-
//# sourceMappingURL=harnessMetadata-
|
|
20
|
+
export { readPoHarnessMetadata as n, PoHarnessMetadata as t };
|
|
21
|
+
//# sourceMappingURL=harnessMetadata-BzMgOB0W.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessMetadata-BzMgOB0W.d.mts","names":[],"sources":["../src/types/harnessMetadata.ts"],"mappings":";;;;;;;;UAUiB;EACf;;EAEA;EACA;;EAEA;EACA;;iBAYc,sBAAsB,cAAa,OAAO,aAA2B"}
|
|
@@ -10,7 +10,7 @@ const DEFAULT_MAJOR_MODE = "copilot";
|
|
|
10
10
|
function parseList(value) {
|
|
11
11
|
return value ? value.split(",").map((item) => item.trim()).filter(Boolean) : [];
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function readPoHarnessMetadata(environment = process.env) {
|
|
14
14
|
return {
|
|
15
15
|
root: environment.PO_ROOT,
|
|
16
16
|
majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,
|
|
@@ -20,6 +20,6 @@ function readDoomHarnessMetadata(environment = process.env) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
|
-
export {
|
|
23
|
+
export { readPoHarnessMetadata as t };
|
|
24
24
|
|
|
25
|
-
//# sourceMappingURL=harnessMetadata-
|
|
25
|
+
//# sourceMappingURL=harnessMetadata-Ccv_j7WP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harnessMetadata-Ccv_j7WP.mjs","names":[],"sources":["../src/types/harnessMetadata.ts"],"sourcesContent":["/**\n * The slice of harness state the header renders.\n *\n * A projection of the store rather than its own reader. This used to\n * re-implement five of the state keys with its own list parser and its own\n * default mode, which is two definitions of one protocol to keep in step.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\n\nexport interface PoHarnessMetadata {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nexport function readPoHarnessMetadata(environment: NodeJS.ProcessEnv = process.env): PoHarnessMetadata {\n return {\n root: environment.PO_ROOT,\n majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,\n domains: parseList(environment.PO_DOMAINS),\n layers: parseList(environment.PO_LAYERS),\n profile: environment.PO_PROFILE?.trim() || undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,qBAAqB;AAY3B,SAAS,UAAU,OAAqC;CACtD,OAAO,QACH,MACG,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,IACjB,CAAC;AACP;AAEA,SAAgB,sBAAsB,cAAiC,QAAQ,KAAwB;CACrG,OAAO;EACL,MAAM,YAAY;EAClB,WAAW,YAAY,eAAe,KAAK,KAAK;EAChD,SAAS,UAAU,YAAY,UAAU;EACzC,QAAQ,UAAU,YAAY,SAAS;EACvC,SAAS,YAAY,YAAY,KAAK,KAAK,KAAA;CAC7C;AACF"}
|
package/dist/harnessMetadata.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_harnessMetadata = require("./harnessMetadata-
|
|
3
|
-
exports.
|
|
2
|
+
const require_harnessMetadata = require("./harnessMetadata-B3mBGrS3.cjs");
|
|
3
|
+
exports.readPoHarnessMetadata = require_harnessMetadata.readPoHarnessMetadata;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
export { type
|
|
1
|
+
import { n as readPoHarnessMetadata, t as PoHarnessMetadata } from "./harnessMetadata-BzMgOB0W.mjs";
|
|
2
|
+
export { type PoHarnessMetadata, readPoHarnessMetadata };
|
package/dist/harnessMetadata.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { readDoomHarnessMetadata };
|
|
1
|
+
export { t as readPoHarnessMetadata } from "./harnessMetadata-Ccv_j7WP.mjs";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PoTelemetryOptions } from "@agimon-ai/po-telemetry";
|
|
2
2
|
//#region src/services/telemetry/index.d.ts
|
|
3
3
|
declare const UI_EVENT: {
|
|
4
|
-
readonly leaderContributionRejected: '
|
|
5
|
-
readonly leaderCommandUnavailable: '
|
|
6
|
-
readonly leaderActionUnavailable: '
|
|
7
|
-
readonly themeApplyFailed: '
|
|
8
|
-
readonly shellInstalled: '
|
|
9
|
-
readonly eventLoopStalled: '
|
|
4
|
+
readonly leaderContributionRejected: 'po_pi_ui.leader_contribution_rejected';
|
|
5
|
+
readonly leaderCommandUnavailable: 'po_pi_ui.leader_command_unavailable';
|
|
6
|
+
readonly leaderActionUnavailable: 'po_pi_ui.leader_action_unavailable';
|
|
7
|
+
readonly themeApplyFailed: 'po_pi_ui.theme_apply_failed';
|
|
8
|
+
readonly shellInstalled: 'po_pi_ui.shell_installed';
|
|
9
|
+
readonly eventLoopStalled: 'po_pi_ui.event_loop_stalled';
|
|
10
10
|
};
|
|
11
11
|
type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];
|
|
12
12
|
type UiEventAttributes = Record<string, string | number | boolean>;
|
|
@@ -14,7 +14,7 @@ interface UiTelemetryOptions {
|
|
|
14
14
|
cwd?: string;
|
|
15
15
|
workspaceRoot?: string;
|
|
16
16
|
env?: NodeJS.ProcessEnv;
|
|
17
|
-
telemetryFactory?: NonNullable<
|
|
17
|
+
telemetryFactory?: NonNullable<PoTelemetryOptions['telemetryFactory']>;
|
|
18
18
|
warn?: (message: string) => void;
|
|
19
19
|
}
|
|
20
20
|
interface UiTelemetry {
|
|
@@ -27,4 +27,4 @@ interface UiTelemetry {
|
|
|
27
27
|
declare function createUiTelemetry(options?: UiTelemetryOptions): UiTelemetry;
|
|
28
28
|
//#endregion
|
|
29
29
|
export { UiTelemetryOptions as a, UiTelemetry as i, UiEventAttributes as n, createUiTelemetry as o, UiEventName as r, UI_EVENT as t };
|
|
30
|
-
//# sourceMappingURL=index-
|
|
30
|
+
//# sourceMappingURL=index-2GW2dj0I.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-2GW2dj0I.d.mts","names":[],"sources":["../src/services/telemetry/index.ts"],"mappings":";;cAKa;WACX;WACA;WACA;WACA;WACA;WACA;;KAGU,sBAAsB,uBAAuB;KAC7C,oBAAoB;UAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;UAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;iBAGE,kBAAkB,UAAS,qBAA0B"}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { FooterTextColor } from "@agimon-ai/po-core/footer";
|
|
2
|
-
|
|
2
|
+
import { FileSystem } from "@agimon-ai/po-core/platform";
|
|
3
|
+
//#region src/services/theme/defaultTheme.d.ts
|
|
3
4
|
declare const DEFAULT_THEME_NAME = "po-dark";
|
|
4
|
-
/** Stable semantic color shared by every UI surface that identifies an agent run. */
|
|
5
|
-
declare function agentIdentityColor(identity: string): FooterTextColor;
|
|
6
|
-
/**
|
|
7
|
-
* Prefer the identity's stable color, then walk the palette to avoid reusing a
|
|
8
|
-
* color already visible on the same surface. Once every color is occupied,
|
|
9
|
-
* reuse the stable preference rather than changing existing assignments.
|
|
10
|
-
*/
|
|
11
|
-
declare function allocateAgentIdentityColor(identity: string, occupied: ReadonlySet<FooterTextColor>): FooterTextColor;
|
|
12
5
|
declare const DEFAULT_THEME: {
|
|
13
6
|
readonly $schema: 'https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json';
|
|
14
7
|
readonly name: "po-dark";
|
|
@@ -97,7 +90,22 @@ declare const DEFAULT_THEME: {
|
|
|
97
90
|
readonly infoBg: '#3b3526';
|
|
98
91
|
};
|
|
99
92
|
};
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/services/theme/sync.d.ts
|
|
95
|
+
/** @deprecated Node-only sync shim; use writeDefaultThemeFile. Removed in M2. */
|
|
100
96
|
declare function writeDefaultTheme(temporaryDirectory: string): Promise<string>;
|
|
101
97
|
//#endregion
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
//#region src/services/theme/index.d.ts
|
|
99
|
+
/** Stable semantic color shared by every UI surface that identifies an agent run. */
|
|
100
|
+
declare function agentIdentityColor(identity: string): FooterTextColor;
|
|
101
|
+
/**
|
|
102
|
+
* Prefer the identity's stable color, then walk the palette to avoid reusing a
|
|
103
|
+
* color already visible on the same surface. Once every color is occupied,
|
|
104
|
+
* reuse the stable preference rather than changing existing assignments.
|
|
105
|
+
*/
|
|
106
|
+
declare function allocateAgentIdentityColor(identity: string, occupied: ReadonlySet<FooterTextColor>): FooterTextColor;
|
|
107
|
+
/** Writes the default theme into `temporaryDirectory` through `fs`, readable by its owner only, and returns its path. */
|
|
108
|
+
declare function writeDefaultThemeFile(fs: FileSystem, temporaryDirectory: string, context: Parameters<FileSystem['writeFile']>[2]): Promise<string>;
|
|
109
|
+
//#endregion
|
|
110
|
+
export { DEFAULT_THEME as a, writeDefaultTheme as i, allocateAgentIdentityColor as n, DEFAULT_THEME_NAME as o, writeDefaultThemeFile as r, agentIdentityColor as t };
|
|
111
|
+
//# sourceMappingURL=index-DFSkSBBh.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-DFSkSBBh.d.mts","names":[],"sources":["../src/services/theme/defaultTheme.ts","../src/services/theme/sync.ts","../src/services/theme/index.ts"],"mappings":";;;cAEa;cAKA;WACX;WAEA;WAGA;aACE;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aAEA;aACA;;WAEF;aACE;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aAEA;aACA;aACA;aACA;aACA;aACA;aACA;aAGA;aACA;aACA;aACA;aAEA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aAEA;aACA;aACA;aAEA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aACA;aAGA;aACA;aACA;aACA;aACA;aACA;aACA;aAEA;;WAEF;aACE;aACA;aACA;;;;;;iBCpGkB,kBAAkB,6BAA6B;;;;iBCsBrD,mBAAmB,mBAAmB;;;;;;iBAStC,2BAA2B,kBAAkB,UAAU,YAAY,mBAAmB;;iBAUhF,sBACpB,IAAI,YACJ,4BACA,SAAS,WAAW,8BACnB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_harnessMetadata = require("./harnessMetadata-
|
|
3
|
-
const require_telemetry = require("./telemetry-
|
|
4
|
-
const require_uiState = require("./uiState-
|
|
5
|
-
const require_theme = require("./theme-
|
|
2
|
+
const require_harnessMetadata = require("./harnessMetadata-B3mBGrS3.cjs");
|
|
3
|
+
const require_telemetry = require("./telemetry-EXlQc9s0.cjs");
|
|
4
|
+
const require_uiState = require("./uiState-CCytmxyX.cjs");
|
|
5
|
+
const require_theme = require("./theme-BfC_GGQ4.cjs");
|
|
6
6
|
exports.DEFAULT_THEME = require_theme.DEFAULT_THEME;
|
|
7
7
|
exports.DEFAULT_THEME_NAME = require_theme.DEFAULT_THEME_NAME;
|
|
8
|
-
exports.
|
|
8
|
+
exports.PoUiState = require_uiState.PoUiState;
|
|
9
9
|
exports.UI_EVENT = require_telemetry.UI_EVENT;
|
|
10
10
|
exports.createUiTelemetry = require_telemetry.createUiTelemetry;
|
|
11
|
-
exports.
|
|
11
|
+
exports.readPoHarnessMetadata = require_harnessMetadata.readPoHarnessMetadata;
|
|
12
12
|
exports.writeDefaultTheme = require_theme.writeDefaultTheme;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { a as UiTelemetryOptions, i as UiTelemetry, n as UiEventAttributes, o as createUiTelemetry, r as UiEventName, t as UI_EVENT } from "./index-
|
|
3
|
-
import { n as
|
|
4
|
-
import { a as
|
|
5
|
-
import { ConfigChoice, ConfigField, ConfigSection, ConfigStep,
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
export { type ConfigChoice, type ConfigField, type ConfigSection, type ConfigStep, DEFAULT_THEME, DEFAULT_THEME_NAME, type
|
|
1
|
+
import { n as readPoHarnessMetadata, t as PoHarnessMetadata } from "./harnessMetadata-BzMgOB0W.mjs";
|
|
2
|
+
import { a as UiTelemetryOptions, i as UiTelemetry, n as UiEventAttributes, o as createUiTelemetry, r as UiEventName, t as UI_EVENT } from "./index-2GW2dj0I.mjs";
|
|
3
|
+
import { n as LeaderSnapshot, r as PoUiState, t as LeaderOption } from "./uiState-DbjaVyxl.mjs";
|
|
4
|
+
import { a as DEFAULT_THEME, i as writeDefaultTheme, o as DEFAULT_THEME_NAME } from "./index-DFSkSBBh.mjs";
|
|
5
|
+
import { ConfigChoice, ConfigField, ConfigSection, ConfigStep, PoConfigActionInput, PoConfigContributionHandle, PoConfigContributionOptions } from "@agimon-ai/po-core/config";
|
|
6
|
+
import { PoFooterContributionDefinition, PoFooterContributionHandle, PoFooterContributionValue } from "@agimon-ai/po-core/footer";
|
|
7
|
+
import { LeaderBinding as PoLeaderBinding, LeaderCommand as PoLeaderCommand, LeaderContribution as PoLeaderContribution, LeaderSegment as PoLeaderSegment, PoLeaderContributionHandle } from "@agimon-ai/po-core/leader";
|
|
8
|
+
export { type ConfigChoice, type ConfigField, type ConfigSection, type ConfigStep, DEFAULT_THEME, DEFAULT_THEME_NAME, type LeaderOption, type LeaderSnapshot, type PoConfigActionInput, type PoConfigContributionHandle, type PoConfigContributionOptions, type PoFooterContributionDefinition, type PoFooterContributionHandle, type PoFooterContributionValue, type PoHarnessMetadata, type PoLeaderBinding, type PoLeaderCommand, type PoLeaderContribution, type PoLeaderContributionHandle, type PoLeaderSegment, PoUiState, UI_EVENT, type UiEventAttributes, type UiEventName, type UiTelemetry, type UiTelemetryOptions, createUiTelemetry, readPoHarnessMetadata, writeDefaultTheme };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { n as createUiTelemetry, t as UI_EVENT } from "./telemetry
|
|
3
|
-
import { t as
|
|
4
|
-
import { a as
|
|
5
|
-
export { DEFAULT_THEME, DEFAULT_THEME_NAME,
|
|
1
|
+
import { t as readPoHarnessMetadata } from "./harnessMetadata-Ccv_j7WP.mjs";
|
|
2
|
+
import { n as createUiTelemetry, t as UI_EVENT } from "./telemetry-RiFqd0cg.mjs";
|
|
3
|
+
import { t as PoUiState } from "./uiState-C7I5WcMl.mjs";
|
|
4
|
+
import { a as DEFAULT_THEME, i as writeDefaultTheme, o as DEFAULT_THEME_NAME } from "./theme-BX_hfErv.mjs";
|
|
5
|
+
export { DEFAULT_THEME, DEFAULT_THEME_NAME, PoUiState, UI_EVENT, createUiTelemetry, readPoHarnessMetadata, writeDefaultTheme };
|
package/dist/leader.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type {
|
|
1
|
+
import { LeaderAction as PoLeaderExtensionAction, LeaderBinding as PoLeaderBinding, LeaderCommand as PoLeaderCommand, LeaderContribution as PoLeaderContribution, LeaderSegment as PoLeaderSegment, PoLeaderActionHandlerOptions, PoLeaderContributionHandle } from "@agimon-ai/po-core/leader";
|
|
2
|
+
export type { PoLeaderActionHandlerOptions, PoLeaderBinding, PoLeaderCommand, PoLeaderContribution, PoLeaderContributionHandle, PoLeaderExtensionAction, PoLeaderSegment };
|
package/dist/leaderRegistry.cjs
CHANGED
|
@@ -414,7 +414,7 @@ function insertBinding(root, binding) {
|
|
|
414
414
|
current.owner = binding.source;
|
|
415
415
|
return diagnostics;
|
|
416
416
|
}
|
|
417
|
-
var
|
|
417
|
+
var PoLeaderRegistry = class {
|
|
418
418
|
root = createRootNode();
|
|
419
419
|
contributions = /* @__PURE__ */ new Map();
|
|
420
420
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -510,6 +510,6 @@ var DoomLeaderRegistry = class {
|
|
|
510
510
|
}
|
|
511
511
|
};
|
|
512
512
|
//#endregion
|
|
513
|
-
exports.
|
|
513
|
+
exports.PoLeaderRegistry = PoLeaderRegistry;
|
|
514
514
|
|
|
515
515
|
//# sourceMappingURL=leaderRegistry.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leaderRegistry.cjs","names":[],"sources":["../src/services/leaderRegistry/index.ts"],"sourcesContent":["type AppKeybinding =\n | 'app.model.select'\n | 'app.model.cycleForward'\n | 'app.thinking.cycle'\n | 'app.session.new'\n | 'app.session.resume'\n | 'app.session.tree'\n | 'app.session.fork'\n | 'app.editor.external'\n | 'app.exit';\n\nimport type {\n LeaderBinding as DoomLeaderBinding,\n LeaderCommand as DoomLeaderCommand,\n LeaderContribution as DoomLeaderContribution,\n LeaderAction as DoomLeaderExtensionAction,\n LeaderSegment as DoomLeaderSegment,\n LeaderTone as DoomLeaderTone,\n} from '@agimon-ai/po-core/leader';\n\ninterface AppLeaderAction {\n type: 'app';\n action: AppKeybinding;\n}\n\ninterface CommandLeaderAction {\n type: 'command';\n command: DoomLeaderCommand;\n}\n\ninterface ExtensionLeaderAction {\n type: 'extension';\n source: string;\n action: DoomLeaderExtensionAction;\n}\n\nexport type DoomLeaderAction = AppLeaderAction | CommandLeaderAction | ExtensionLeaderAction;\n\nexport interface DoomLeaderResolvedOption {\n key: string;\n label: string;\n detail?: string;\n tone?: DoomLeaderTone;\n hasChildren: boolean;\n action?: DoomLeaderAction;\n}\n\nexport interface DoomLeaderGroup {\n label: string;\n options: readonly DoomLeaderResolvedOption[];\n}\n\nexport interface DoomLeaderDiagnostic {\n source: string;\n bindingId?: string;\n message: string;\n}\n\nexport interface DoomLeaderRegistrationResult {\n accepted: boolean;\n diagnostics: readonly DoomLeaderDiagnostic[];\n}\n\ninterface InternalLeaderBinding {\n id: string;\n source: string;\n path: readonly [DoomLeaderSegment, ...DoomLeaderSegment[]];\n action: DoomLeaderAction;\n}\n\ninterface LeaderNode {\n key: string;\n label: string;\n detail?: string;\n tone?: DoomLeaderTone;\n order: number;\n owner: string;\n bindingId?: string;\n children: Map<string, LeaderNode>;\n action?: DoomLeaderAction;\n}\n\ninterface ParsedContribution {\n contribution?: DoomLeaderContribution;\n diagnostics: DoomLeaderDiagnostic[];\n}\n\nconst CORE_SOURCE = '@agimon-ai/po-ui';\nconst UNKNOWN_SOURCE = 'unknown';\nconst ROOT_LABEL = 'leader';\nconst DEFAULT_OPTION_ORDER = 500;\nconst MAX_OPTION_ORDER = 1000;\nconst MAX_PATH_LENGTH = 4;\nconst MAX_SOURCE_LENGTH = 128;\nconst MAX_BINDING_ID_LENGTH = 128;\nconst MAX_LABEL_LENGTH = 32;\nconst MAX_DETAIL_LENGTH = 80;\nconst MAX_COMMAND_NAME_LENGTH = 64;\nconst MAX_COMMAND_ARGUMENT_LENGTH = 256;\nconst MAX_ACTION_NAME_LENGTH = 128;\nconst SAFE_KEY = /^[a-z0-9]$/;\nconst SAFE_IDENTIFIER = /^[a-z0-9][a-z0-9._:-]*$/;\nconst SAFE_SOURCE = /^[A-Za-z0-9@][A-Za-z0-9@/._:-]*$/;\nconst SAFE_COMMAND_NAME = /^[a-z0-9][a-z0-9:_-]*$/;\nconst C0_CONTROL_MAX = 31;\nconst DELETE_CHARACTER = 127;\nconst MODEL_GROUP = { key: 'm', label: 'models', detail: 'model and thinking level', order: 10 } as const;\nconst SESSION_GROUP = { key: 's', label: 'sessions', detail: 'history, forks and branches', order: 30 } as const;\nconst EXTENSION_GROUP = { key: 'e', label: 'extension', detail: 'tools, skills and config', order: 50 } as const;\nconst HELP_GROUP = { key: 'h', label: 'help', detail: 'package docs and logs', order: 70 } as const;\nconst QUIT_GROUP = { key: 'q', label: 'quit', detail: 'leave the session', order: 90 } as const;\n\nfunction coreBinding(\n id: string,\n path: readonly [DoomLeaderSegment, ...DoomLeaderSegment[]],\n action: DoomLeaderAction,\n): InternalLeaderBinding {\n return { id, source: CORE_SOURCE, path, action };\n}\n\nconst CORE_BINDINGS: readonly InternalLeaderBinding[] = [\n coreBinding('model.select', [MODEL_GROUP, { key: 'm', label: 'select', detail: 'choose model', order: 10 }], {\n type: 'app',\n action: 'app.model.select',\n }),\n coreBinding('model.next', [MODEL_GROUP, { key: 'n', label: 'next', detail: 'cycle model', order: 20 }], {\n type: 'app',\n action: 'app.model.cycleForward',\n }),\n coreBinding('thinking.cycle', [MODEL_GROUP, { key: 't', label: 'thinking', detail: 'cycle level', order: 30 }], {\n type: 'app',\n action: 'app.thinking.cycle',\n }),\n coreBinding('tools.open', [EXTENSION_GROUP, { key: 't', label: 'tools', detail: 'browse tools', order: 20 }], {\n type: 'command',\n command: { name: 'tools' },\n }),\n // Core rather than contributed, so no extension owns the key and the panel is\n // reachable even when nothing has contributed a section to it yet.\n coreBinding('config.open', [EXTENSION_GROUP, { key: 'c', label: 'config', detail: 'settings', order: 30 }], {\n type: 'command',\n command: { name: 'config' },\n }),\n coreBinding('session.new', [SESSION_GROUP, { key: 'n', label: 'new', detail: 'fresh session', order: 10 }], {\n type: 'app',\n action: 'app.session.new',\n }),\n coreBinding('session.resume', [SESSION_GROUP, { key: 'r', label: 'resume', detail: 'open history', order: 20 }], {\n type: 'app',\n action: 'app.session.resume',\n }),\n coreBinding('session.tree', [SESSION_GROUP, { key: 't', label: 'tree', detail: 'branch view', order: 30 }], {\n type: 'app',\n action: 'app.session.tree',\n }),\n coreBinding('session.fork', [SESSION_GROUP, { key: 'f', label: 'fork', detail: 'from selection', order: 40 }], {\n type: 'app',\n action: 'app.session.fork',\n }),\n coreBinding('help.hotkeys', [HELP_GROUP, { key: 'h', label: 'hotkeys', detail: 'show bindings' }], {\n type: 'command',\n command: { name: 'hotkeys' },\n }),\n coreBinding('app.exit', [QUIT_GROUP, { key: 'q', label: 'quit', detail: 'exit Pi' }], {\n type: 'app',\n action: 'app.exit',\n }),\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction diagnostic(source: string, message: string, bindingId?: string): DoomLeaderDiagnostic {\n return { source, message, ...(bindingId ? { bindingId } : {}) };\n}\n\nfunction containsControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const codeUnit = value.charCodeAt(index);\n if (codeUnit <= C0_CONTROL_MAX || codeUnit === DELETE_CHARACTER) return true;\n }\n return false;\n}\n\nfunction readRequiredText(\n value: unknown,\n field: string,\n maximumLength: number,\n source: string,\n diagnostics: DoomLeaderDiagnostic[],\n bindingId?: string,\n): string | undefined {\n if (typeof value !== 'string' || !value.trim()) {\n diagnostics.push(diagnostic(source, `${field} must be a non-empty string.`, bindingId));\n return undefined;\n }\n const text = value.trim();\n if (text.length > maximumLength || containsControlCharacter(text)) {\n diagnostics.push(\n diagnostic(\n source,\n `${field} must be at most ${maximumLength} characters and contain no control characters.`,\n bindingId,\n ),\n );\n return undefined;\n }\n return text;\n}\n\nfunction readOptionalText(\n value: unknown,\n field: string,\n maximumLength: number,\n source: string,\n diagnostics: DoomLeaderDiagnostic[],\n bindingId: string,\n): string | undefined {\n if (value === undefined) return undefined;\n return readRequiredText(value, field, maximumLength, source, diagnostics, bindingId);\n}\n\nfunction parseSegment(\n value: unknown,\n source: string,\n bindingId: string,\n index: number,\n diagnostics: DoomLeaderDiagnostic[],\n): DoomLeaderSegment | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, `bindings[].path[${index}] must be an object.`, bindingId));\n return undefined;\n }\n\n const key = readRequiredText(value.key, `bindings[].path[${index}].key`, 1, source, diagnostics, bindingId);\n const label = readRequiredText(\n value.label,\n `bindings[].path[${index}].label`,\n MAX_LABEL_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n const detail = readOptionalText(\n value.detail,\n `bindings[].path[${index}].detail`,\n MAX_DETAIL_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n // An unrecognised tone is ignored, not diagnosed. Every other malformed field\n // here rejects the whole contribution, which is right for a key or a label but\n // not for a badge colour: it would mean a package compiled against a later\n // contract loses its entire menu on an older host over a cosmetic value. The\n // union type already catches a typo at every call site built against this\n // contract, which is the only place a typo can come from.\n const tone: DoomLeaderTone | undefined = value.tone === 'default' || value.tone === 'exit' ? value.tone : undefined;\n let order: number | undefined;\n if (value.order !== undefined) {\n if (!Number.isInteger(value.order) || (value.order as number) < 0 || (value.order as number) > MAX_OPTION_ORDER) {\n diagnostics.push(\n diagnostic(\n source,\n `bindings[].path[${index}].order must be an integer from 0 to ${MAX_OPTION_ORDER}.`,\n bindingId,\n ),\n );\n } else {\n order = value.order as number;\n }\n }\n if (!key || !label || !SAFE_KEY.test(key)) {\n if (key && !SAFE_KEY.test(key)) {\n diagnostics.push(diagnostic(source, `bindings[].path[${index}].key must match ${SAFE_KEY}.`, bindingId));\n }\n return undefined;\n }\n return {\n key,\n label,\n ...(detail ? { detail } : {}),\n ...(tone ? { tone } : {}),\n ...(order === undefined ? {} : { order }),\n };\n}\n\nfunction parseCommand(\n value: unknown,\n source: string,\n bindingId: string,\n diagnostics: DoomLeaderDiagnostic[],\n): DoomLeaderCommand | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[].command must be an object.', bindingId));\n return undefined;\n }\n const name = readRequiredText(\n value.name,\n 'bindings[].command.name',\n MAX_COMMAND_NAME_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n const args = readOptionalText(\n value.args,\n 'bindings[].command.args',\n MAX_COMMAND_ARGUMENT_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n if (!name || !SAFE_COMMAND_NAME.test(name)) {\n if (name && !SAFE_COMMAND_NAME.test(name)) {\n diagnostics.push(diagnostic(source, `bindings[].command.name must match ${SAFE_COMMAND_NAME}.`, bindingId));\n }\n return undefined;\n }\n return { name, ...(args ? { args } : {}) };\n}\n\nfunction parseExtensionAction(\n value: unknown,\n source: string,\n bindingId: string,\n diagnostics: DoomLeaderDiagnostic[],\n): DoomLeaderExtensionAction | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[].action must be an object.', bindingId));\n return undefined;\n }\n const name = readRequiredText(\n value.name,\n 'bindings[].action.name',\n MAX_ACTION_NAME_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n if (!name || !SAFE_IDENTIFIER.test(name)) {\n if (name && !SAFE_IDENTIFIER.test(name)) {\n diagnostics.push(diagnostic(source, `bindings[].action.name must match ${SAFE_IDENTIFIER}.`, bindingId));\n }\n return undefined;\n }\n return { name };\n}\n\nfunction parseBinding(\n value: unknown,\n source: string,\n diagnostics: DoomLeaderDiagnostic[],\n): DoomLeaderBinding | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[] must be an object.'));\n return undefined;\n }\n const bindingId = readRequiredText(value.id, 'bindings[].id', MAX_BINDING_ID_LENGTH, source, diagnostics);\n if (!bindingId) return undefined;\n if (!SAFE_IDENTIFIER.test(bindingId)) {\n diagnostics.push(diagnostic(source, `bindings[].id must match ${SAFE_IDENTIFIER}.`, bindingId));\n return undefined;\n }\n if (!Array.isArray(value.path) || value.path.length === 0 || value.path.length > MAX_PATH_LENGTH) {\n diagnostics.push(\n diagnostic(source, `bindings[].path must contain between 1 and ${MAX_PATH_LENGTH} segments.`, bindingId),\n );\n return undefined;\n }\n\n const path = value.path.map((segment, index) => parseSegment(segment, source, bindingId, index, diagnostics));\n const hasCommand = Object.hasOwn(value, 'command');\n const hasAction = Object.hasOwn(value, 'action');\n if (hasCommand === hasAction) {\n diagnostics.push(diagnostic(source, 'bindings[] must contain exactly one of command or action.', bindingId));\n return undefined;\n }\n const target = hasCommand\n ? { command: parseCommand(value.command, source, bindingId, diagnostics) }\n : { action: parseExtensionAction(value.action, source, bindingId, diagnostics) };\n if (path.some((segment) => segment === undefined)) return undefined;\n if ('command' in target) {\n if (!target.command) return undefined;\n return {\n id: bindingId,\n path: path as [DoomLeaderSegment, ...DoomLeaderSegment[]],\n command: target.command,\n };\n }\n if (!target.action) return undefined;\n return {\n id: bindingId,\n path: path as [DoomLeaderSegment, ...DoomLeaderSegment[]],\n action: target.action,\n };\n}\n\nfunction parseContribution(value: unknown): ParsedContribution {\n const diagnostics: DoomLeaderDiagnostic[] = [];\n if (!isRecord(value)) {\n return { diagnostics: [diagnostic(UNKNOWN_SOURCE, 'Leader contribution must be an object.')] };\n }\n const source = readRequiredText(value.source, 'source', MAX_SOURCE_LENGTH, UNKNOWN_SOURCE, diagnostics);\n if (!source) return { diagnostics };\n if (!SAFE_SOURCE.test(source)) {\n diagnostics.push(diagnostic(source, `source must match ${SAFE_SOURCE}.`));\n return { diagnostics };\n }\n if (!Array.isArray(value.bindings)) {\n return { diagnostics: [diagnostic(source, 'bindings must be an array.')] };\n }\n\n const bindings = value.bindings.map((binding) => parseBinding(binding, source, diagnostics));\n const duplicateIds = bindings\n .flatMap((binding) => (binding ? [binding.id] : []))\n .filter((id, index, ids) => ids.indexOf(id) !== index);\n for (const id of new Set(duplicateIds)) {\n diagnostics.push(diagnostic(source, `Binding id '${id}' is duplicated.`, id));\n }\n if (diagnostics.length > 0 || bindings.some((binding) => binding === undefined)) return { diagnostics };\n\n return {\n contribution: {\n source,\n bindings: bindings as DoomLeaderBinding[],\n },\n diagnostics,\n };\n}\n\nfunction optionOrder(segment: DoomLeaderSegment): number {\n return segment.order ?? DEFAULT_OPTION_ORDER;\n}\n\nfunction cloneAction(action: DoomLeaderAction): DoomLeaderAction {\n if (action.type === 'command') return { type: 'command', command: { ...action.command } };\n if (action.type === 'app') return { type: 'app', action: action.action };\n return { type: 'extension', source: action.source, action: { ...action.action } };\n}\n\nfunction createRootNode(): LeaderNode {\n return {\n key: '',\n label: ROOT_LABEL,\n order: 0,\n owner: CORE_SOURCE,\n children: new Map(),\n };\n}\n\nfunction pathLabel(path: readonly DoomLeaderSegment[]): string {\n return `SPC ${path.map((segment) => segment.key).join(' ')}`;\n}\n\n/**\n * Whether a shared group prefix is worded the same way by both contributors.\n *\n * `detail` is left out on purpose: it is a subtitle, and these packages ship on\n * independent npm versions, so comparing it means one upgraded package disagrees\n * with every package that has not caught up.\n *\n * A mismatch is REPORTED, never fatal. Losing `SPC e s` because two packages\n * spell the `SPC e` group differently costs the user a key they can no longer\n * press, which is worse than a menu row worded by whoever registered first.\n */\nfunction metadataMatches(node: LeaderNode, segment: DoomLeaderSegment): boolean {\n return node.label === segment.label && node.order === optionOrder(segment);\n}\n\n/** Every binding under a node, for a takeover message that says what it displaced. */\nfunction leafCount(node: LeaderNode): number {\n if (node.children.size === 0) return node.action ? 1 : 0;\n let total = 0;\n for (const child of node.children.values()) total += leafCount(child);\n return total;\n}\n\n/**\n * Inserts one binding, taking a key over from whoever holds it.\n *\n * LAST REGISTRATION WINS, and the diagnostics say who lost what. The rule this\n * replaced rejected the newcomer, which read as \"warning plus nothing happened\":\n * the key stayed bound to the first registrant, or - when the clash was only a\n * group label - to nobody at all. A takeover is recoverable in a way a dropped\n * binding is not: the tree is rebuilt from every stored contribution, so when\n * the winner unregisters, the displaced binding comes back on the next rebuild.\n *\n * Returns diagnostics rather than one issue, because a single insert can both\n * disagree about a group's wording and take a key from someone.\n */\nfunction insertBinding(root: LeaderNode, binding: InternalLeaderBinding): DoomLeaderDiagnostic[] {\n const diagnostics: DoomLeaderDiagnostic[] = [];\n let current = root;\n let firstMissing = -1;\n\n for (const [index, segment] of binding.path.entries()) {\n const existing = current.children.get(segment.key);\n if (!existing) {\n firstMissing = index;\n break;\n }\n if (!metadataMatches(existing, segment)) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path.slice(0, index + 1))} keeps the label from ${existing.owner}; the binding is registered.`,\n binding.id,\n ),\n );\n }\n // First writer wins for the subtitle, but a group created without one still\n // adopts the first that is offered, so the wording does not depend on which\n // package happened to register first.\n if (!existing.detail && segment.detail) existing.detail = segment.detail;\n\n const isLeaf = index === binding.path.length - 1;\n const displaced = leafCount(existing);\n if (isLeaf && displaced > 0) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path)} taken over from ${existing.owner}` +\n `${displaced > 1 ? `, displacing ${displaced} bindings` : ''}.`,\n binding.id,\n ),\n );\n existing.children.clear();\n delete existing.action;\n delete existing.bindingId;\n } else if (!isLeaf && existing.action) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path.slice(0, index + 1))} taken over from ${existing.owner} to open a group.`,\n binding.id,\n ),\n );\n delete existing.action;\n delete existing.bindingId;\n }\n if (isLeaf || existing.action === undefined) existing.owner = binding.source;\n current = existing;\n }\n\n const start = firstMissing === -1 ? binding.path.length : firstMissing;\n for (let index = start; index < binding.path.length; index += 1) {\n const segment = binding.path[index] as DoomLeaderSegment;\n const node: LeaderNode = {\n key: segment.key,\n label: segment.label,\n ...(segment.detail ? { detail: segment.detail } : {}),\n ...(segment.tone ? { tone: segment.tone } : {}),\n order: optionOrder(segment),\n owner: binding.source,\n children: new Map(),\n };\n current.children.set(segment.key, node);\n current = node;\n }\n\n current.action = cloneAction(binding.action);\n current.bindingId = binding.id;\n current.owner = binding.source;\n return diagnostics;\n}\n\nexport class DoomLeaderRegistry {\n private root = createRootNode();\n private readonly contributions = new Map<string, readonly DoomLeaderBinding[]>();\n private readonly listeners = new Set<() => void>();\n private diagnostics: DoomLeaderDiagnostic[] = [];\n private dirty = false;\n\n constructor() {\n this.rebuild();\n }\n\n register(value: unknown): DoomLeaderRegistrationResult {\n const result = this.apply(value);\n if (!result.accepted) return result;\n this.rebuild();\n return { accepted: true, diagnostics: this.getDiagnostics() };\n }\n\n /** Records a contribution without rebuilding the whole tree immediately. */\n registerDeferred(value: unknown): DoomLeaderRegistrationResult {\n return this.apply(value);\n }\n\n private apply(value: unknown): DoomLeaderRegistrationResult {\n const parsed = parseContribution(value);\n if (!parsed.contribution) return { accepted: false, diagnostics: parsed.diagnostics };\n\n // Deleted before it is set again, so re-registering moves a source to the\n // back of the insertion order: registering again IS claiming again.\n this.contributions.delete(parsed.contribution.source);\n if (parsed.contribution.bindings.length > 0) {\n this.contributions.set(parsed.contribution.source, parsed.contribution.bindings);\n }\n this.dirty = true;\n return { accepted: true, diagnostics: parsed.diagnostics };\n }\n\n /** Rebuilds one batch and returns its deterministic conflict diagnostics. */\n flush(): DoomLeaderDiagnostic[] {\n if (this.dirty) this.rebuild();\n return this.diagnostics.map((item) => ({ ...item }));\n }\n\n getGroup(path: readonly string[]): DoomLeaderGroup | undefined {\n this.flush();\n let current = this.root;\n for (const key of path) {\n const next = current.children.get(key);\n if (!next || next.action) return undefined;\n current = next;\n }\n\n // The key is the sort, at every level. A reader looking for a chord knows the\n // key, not the number some contributor picked for it, and those numbers live\n // across nine packages so no one of them can see the sequence they produce.\n // `order` survives only as group identity: co-contributors to a shared prefix\n // must still agree on it, which is what `metadataMatches` checks.\n const options = [...current.children.values()]\n .sort((left, right) => left.key.localeCompare(right.key))\n .map((node): DoomLeaderResolvedOption => ({\n key: node.key,\n label: node.label,\n ...(node.detail ? { detail: node.detail } : {}),\n ...(node.tone ? { tone: node.tone } : {}),\n hasChildren: node.children.size > 0,\n ...(node.action ? { action: cloneAction(node.action) } : {}),\n }));\n return { label: current.label, options };\n }\n\n getDiagnostics(): DoomLeaderDiagnostic[] {\n return this.flush();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private rebuild(): void {\n const nextRoot = createRootNode();\n const diagnostics: DoomLeaderDiagnostic[] = [];\n for (const binding of CORE_BINDINGS) {\n // Core bindings land in an empty tree, so anything reported here is two\n // core bindings disagreeing with each other: a defect, not a contribution.\n const [issue] = insertBinding(nextRoot, binding);\n if (issue) throw new Error(`Invalid core leader binding: ${issue.message}`);\n }\n\n // Registration order, not alphabetical: the key belongs to whoever claimed\n // it last, and `apply` re-seats a source that registers again so a reload\n // counts as a fresh claim. Bindings inside one contribution stay sorted by\n // id, so a single source's own output is still deterministic.\n for (const [source, bindings] of this.contributions.entries()) {\n for (const binding of [...bindings].sort((left, right) => left.id.localeCompare(right.id))) {\n diagnostics.push(\n ...insertBinding(nextRoot, {\n id: binding.id,\n source,\n path: binding.path,\n action:\n 'command' in binding\n ? { type: 'command', command: binding.command }\n : { type: 'extension', source, action: binding.action },\n }),\n );\n }\n }\n\n this.root = nextRoot;\n this.diagnostics = diagnostics;\n this.dirty = false;\n for (const listener of this.listeners) listener();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"leaderRegistry.cjs","names":[],"sources":["../src/services/leaderRegistry/index.ts"],"sourcesContent":["type AppKeybinding =\n | 'app.model.select'\n | 'app.model.cycleForward'\n | 'app.thinking.cycle'\n | 'app.session.new'\n | 'app.session.resume'\n | 'app.session.tree'\n | 'app.session.fork'\n | 'app.editor.external'\n | 'app.exit';\n\nimport type {\n LeaderBinding as PoLeaderBinding,\n LeaderCommand as PoLeaderCommand,\n LeaderContribution as PoLeaderContribution,\n LeaderAction as PoLeaderExtensionAction,\n LeaderSegment as PoLeaderSegment,\n LeaderTone as PoLeaderTone,\n} from '@agimon-ai/po-core/leader';\n\ninterface AppLeaderAction {\n type: 'app';\n action: AppKeybinding;\n}\n\ninterface CommandLeaderAction {\n type: 'command';\n command: PoLeaderCommand;\n}\n\ninterface ExtensionLeaderAction {\n type: 'extension';\n source: string;\n action: PoLeaderExtensionAction;\n}\n\nexport type PoLeaderAction = AppLeaderAction | CommandLeaderAction | ExtensionLeaderAction;\n\nexport interface PoLeaderResolvedOption {\n key: string;\n label: string;\n detail?: string;\n tone?: PoLeaderTone;\n hasChildren: boolean;\n action?: PoLeaderAction;\n}\n\nexport interface PoLeaderGroup {\n label: string;\n options: readonly PoLeaderResolvedOption[];\n}\n\nexport interface PoLeaderDiagnostic {\n source: string;\n bindingId?: string;\n message: string;\n}\n\nexport interface PoLeaderRegistrationResult {\n accepted: boolean;\n diagnostics: readonly PoLeaderDiagnostic[];\n}\n\ninterface InternalLeaderBinding {\n id: string;\n source: string;\n path: readonly [PoLeaderSegment, ...PoLeaderSegment[]];\n action: PoLeaderAction;\n}\n\ninterface LeaderNode {\n key: string;\n label: string;\n detail?: string;\n tone?: PoLeaderTone;\n order: number;\n owner: string;\n bindingId?: string;\n children: Map<string, LeaderNode>;\n action?: PoLeaderAction;\n}\n\ninterface ParsedContribution {\n contribution?: PoLeaderContribution;\n diagnostics: PoLeaderDiagnostic[];\n}\n\nconst CORE_SOURCE = '@agimon-ai/po-ui';\nconst UNKNOWN_SOURCE = 'unknown';\nconst ROOT_LABEL = 'leader';\nconst DEFAULT_OPTION_ORDER = 500;\nconst MAX_OPTION_ORDER = 1000;\nconst MAX_PATH_LENGTH = 4;\nconst MAX_SOURCE_LENGTH = 128;\nconst MAX_BINDING_ID_LENGTH = 128;\nconst MAX_LABEL_LENGTH = 32;\nconst MAX_DETAIL_LENGTH = 80;\nconst MAX_COMMAND_NAME_LENGTH = 64;\nconst MAX_COMMAND_ARGUMENT_LENGTH = 256;\nconst MAX_ACTION_NAME_LENGTH = 128;\nconst SAFE_KEY = /^[a-z0-9]$/;\nconst SAFE_IDENTIFIER = /^[a-z0-9][a-z0-9._:-]*$/;\nconst SAFE_SOURCE = /^[A-Za-z0-9@][A-Za-z0-9@/._:-]*$/;\nconst SAFE_COMMAND_NAME = /^[a-z0-9][a-z0-9:_-]*$/;\nconst C0_CONTROL_MAX = 31;\nconst DELETE_CHARACTER = 127;\nconst MODEL_GROUP = { key: 'm', label: 'models', detail: 'model and thinking level', order: 10 } as const;\nconst SESSION_GROUP = { key: 's', label: 'sessions', detail: 'history, forks and branches', order: 30 } as const;\nconst EXTENSION_GROUP = { key: 'e', label: 'extension', detail: 'tools, skills and config', order: 50 } as const;\nconst HELP_GROUP = { key: 'h', label: 'help', detail: 'package docs and logs', order: 70 } as const;\nconst QUIT_GROUP = { key: 'q', label: 'quit', detail: 'leave the session', order: 90 } as const;\n\nfunction coreBinding(\n id: string,\n path: readonly [PoLeaderSegment, ...PoLeaderSegment[]],\n action: PoLeaderAction,\n): InternalLeaderBinding {\n return { id, source: CORE_SOURCE, path, action };\n}\n\nconst CORE_BINDINGS: readonly InternalLeaderBinding[] = [\n coreBinding('model.select', [MODEL_GROUP, { key: 'm', label: 'select', detail: 'choose model', order: 10 }], {\n type: 'app',\n action: 'app.model.select',\n }),\n coreBinding('model.next', [MODEL_GROUP, { key: 'n', label: 'next', detail: 'cycle model', order: 20 }], {\n type: 'app',\n action: 'app.model.cycleForward',\n }),\n coreBinding('thinking.cycle', [MODEL_GROUP, { key: 't', label: 'thinking', detail: 'cycle level', order: 30 }], {\n type: 'app',\n action: 'app.thinking.cycle',\n }),\n coreBinding('tools.open', [EXTENSION_GROUP, { key: 't', label: 'tools', detail: 'browse tools', order: 20 }], {\n type: 'command',\n command: { name: 'tools' },\n }),\n // Core rather than contributed, so no extension owns the key and the panel is\n // reachable even when nothing has contributed a section to it yet.\n coreBinding('config.open', [EXTENSION_GROUP, { key: 'c', label: 'config', detail: 'settings', order: 30 }], {\n type: 'command',\n command: { name: 'config' },\n }),\n coreBinding('session.new', [SESSION_GROUP, { key: 'n', label: 'new', detail: 'fresh session', order: 10 }], {\n type: 'app',\n action: 'app.session.new',\n }),\n coreBinding('session.resume', [SESSION_GROUP, { key: 'r', label: 'resume', detail: 'open history', order: 20 }], {\n type: 'app',\n action: 'app.session.resume',\n }),\n coreBinding('session.tree', [SESSION_GROUP, { key: 't', label: 'tree', detail: 'branch view', order: 30 }], {\n type: 'app',\n action: 'app.session.tree',\n }),\n coreBinding('session.fork', [SESSION_GROUP, { key: 'f', label: 'fork', detail: 'from selection', order: 40 }], {\n type: 'app',\n action: 'app.session.fork',\n }),\n coreBinding('help.hotkeys', [HELP_GROUP, { key: 'h', label: 'hotkeys', detail: 'show bindings' }], {\n type: 'command',\n command: { name: 'hotkeys' },\n }),\n coreBinding('app.exit', [QUIT_GROUP, { key: 'q', label: 'quit', detail: 'exit Pi' }], {\n type: 'app',\n action: 'app.exit',\n }),\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction diagnostic(source: string, message: string, bindingId?: string): PoLeaderDiagnostic {\n return { source, message, ...(bindingId ? { bindingId } : {}) };\n}\n\nfunction containsControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const codeUnit = value.charCodeAt(index);\n if (codeUnit <= C0_CONTROL_MAX || codeUnit === DELETE_CHARACTER) return true;\n }\n return false;\n}\n\nfunction readRequiredText(\n value: unknown,\n field: string,\n maximumLength: number,\n source: string,\n diagnostics: PoLeaderDiagnostic[],\n bindingId?: string,\n): string | undefined {\n if (typeof value !== 'string' || !value.trim()) {\n diagnostics.push(diagnostic(source, `${field} must be a non-empty string.`, bindingId));\n return undefined;\n }\n const text = value.trim();\n if (text.length > maximumLength || containsControlCharacter(text)) {\n diagnostics.push(\n diagnostic(\n source,\n `${field} must be at most ${maximumLength} characters and contain no control characters.`,\n bindingId,\n ),\n );\n return undefined;\n }\n return text;\n}\n\nfunction readOptionalText(\n value: unknown,\n field: string,\n maximumLength: number,\n source: string,\n diagnostics: PoLeaderDiagnostic[],\n bindingId: string,\n): string | undefined {\n if (value === undefined) return undefined;\n return readRequiredText(value, field, maximumLength, source, diagnostics, bindingId);\n}\n\nfunction parseSegment(\n value: unknown,\n source: string,\n bindingId: string,\n index: number,\n diagnostics: PoLeaderDiagnostic[],\n): PoLeaderSegment | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, `bindings[].path[${index}] must be an object.`, bindingId));\n return undefined;\n }\n\n const key = readRequiredText(value.key, `bindings[].path[${index}].key`, 1, source, diagnostics, bindingId);\n const label = readRequiredText(\n value.label,\n `bindings[].path[${index}].label`,\n MAX_LABEL_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n const detail = readOptionalText(\n value.detail,\n `bindings[].path[${index}].detail`,\n MAX_DETAIL_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n // An unrecognised tone is ignored, not diagnosed. Every other malformed field\n // here rejects the whole contribution, which is right for a key or a label but\n // not for a badge colour: it would mean a package compiled against a later\n // contract loses its entire menu on an older host over a cosmetic value. The\n // union type already catches a typo at every call site built against this\n // contract, which is the only place a typo can come from.\n const tone: PoLeaderTone | undefined = value.tone === 'default' || value.tone === 'exit' ? value.tone : undefined;\n let order: number | undefined;\n if (value.order !== undefined) {\n if (!Number.isInteger(value.order) || (value.order as number) < 0 || (value.order as number) > MAX_OPTION_ORDER) {\n diagnostics.push(\n diagnostic(\n source,\n `bindings[].path[${index}].order must be an integer from 0 to ${MAX_OPTION_ORDER}.`,\n bindingId,\n ),\n );\n } else {\n order = value.order as number;\n }\n }\n if (!key || !label || !SAFE_KEY.test(key)) {\n if (key && !SAFE_KEY.test(key)) {\n diagnostics.push(diagnostic(source, `bindings[].path[${index}].key must match ${SAFE_KEY}.`, bindingId));\n }\n return undefined;\n }\n return {\n key,\n label,\n ...(detail ? { detail } : {}),\n ...(tone ? { tone } : {}),\n ...(order === undefined ? {} : { order }),\n };\n}\n\nfunction parseCommand(\n value: unknown,\n source: string,\n bindingId: string,\n diagnostics: PoLeaderDiagnostic[],\n): PoLeaderCommand | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[].command must be an object.', bindingId));\n return undefined;\n }\n const name = readRequiredText(\n value.name,\n 'bindings[].command.name',\n MAX_COMMAND_NAME_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n const args = readOptionalText(\n value.args,\n 'bindings[].command.args',\n MAX_COMMAND_ARGUMENT_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n if (!name || !SAFE_COMMAND_NAME.test(name)) {\n if (name && !SAFE_COMMAND_NAME.test(name)) {\n diagnostics.push(diagnostic(source, `bindings[].command.name must match ${SAFE_COMMAND_NAME}.`, bindingId));\n }\n return undefined;\n }\n return { name, ...(args ? { args } : {}) };\n}\n\nfunction parseExtensionAction(\n value: unknown,\n source: string,\n bindingId: string,\n diagnostics: PoLeaderDiagnostic[],\n): PoLeaderExtensionAction | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[].action must be an object.', bindingId));\n return undefined;\n }\n const name = readRequiredText(\n value.name,\n 'bindings[].action.name',\n MAX_ACTION_NAME_LENGTH,\n source,\n diagnostics,\n bindingId,\n );\n if (!name || !SAFE_IDENTIFIER.test(name)) {\n if (name && !SAFE_IDENTIFIER.test(name)) {\n diagnostics.push(diagnostic(source, `bindings[].action.name must match ${SAFE_IDENTIFIER}.`, bindingId));\n }\n return undefined;\n }\n return { name };\n}\n\nfunction parseBinding(value: unknown, source: string, diagnostics: PoLeaderDiagnostic[]): PoLeaderBinding | undefined {\n if (!isRecord(value)) {\n diagnostics.push(diagnostic(source, 'bindings[] must be an object.'));\n return undefined;\n }\n const bindingId = readRequiredText(value.id, 'bindings[].id', MAX_BINDING_ID_LENGTH, source, diagnostics);\n if (!bindingId) return undefined;\n if (!SAFE_IDENTIFIER.test(bindingId)) {\n diagnostics.push(diagnostic(source, `bindings[].id must match ${SAFE_IDENTIFIER}.`, bindingId));\n return undefined;\n }\n if (!Array.isArray(value.path) || value.path.length === 0 || value.path.length > MAX_PATH_LENGTH) {\n diagnostics.push(\n diagnostic(source, `bindings[].path must contain between 1 and ${MAX_PATH_LENGTH} segments.`, bindingId),\n );\n return undefined;\n }\n\n const path = value.path.map((segment, index) => parseSegment(segment, source, bindingId, index, diagnostics));\n const hasCommand = Object.hasOwn(value, 'command');\n const hasAction = Object.hasOwn(value, 'action');\n if (hasCommand === hasAction) {\n diagnostics.push(diagnostic(source, 'bindings[] must contain exactly one of command or action.', bindingId));\n return undefined;\n }\n const target = hasCommand\n ? { command: parseCommand(value.command, source, bindingId, diagnostics) }\n : { action: parseExtensionAction(value.action, source, bindingId, diagnostics) };\n if (path.some((segment) => segment === undefined)) return undefined;\n if ('command' in target) {\n if (!target.command) return undefined;\n return {\n id: bindingId,\n path: path as [PoLeaderSegment, ...PoLeaderSegment[]],\n command: target.command,\n };\n }\n if (!target.action) return undefined;\n return {\n id: bindingId,\n path: path as [PoLeaderSegment, ...PoLeaderSegment[]],\n action: target.action,\n };\n}\n\nfunction parseContribution(value: unknown): ParsedContribution {\n const diagnostics: PoLeaderDiagnostic[] = [];\n if (!isRecord(value)) {\n return { diagnostics: [diagnostic(UNKNOWN_SOURCE, 'Leader contribution must be an object.')] };\n }\n const source = readRequiredText(value.source, 'source', MAX_SOURCE_LENGTH, UNKNOWN_SOURCE, diagnostics);\n if (!source) return { diagnostics };\n if (!SAFE_SOURCE.test(source)) {\n diagnostics.push(diagnostic(source, `source must match ${SAFE_SOURCE}.`));\n return { diagnostics };\n }\n if (!Array.isArray(value.bindings)) {\n return { diagnostics: [diagnostic(source, 'bindings must be an array.')] };\n }\n\n const bindings = value.bindings.map((binding) => parseBinding(binding, source, diagnostics));\n const duplicateIds = bindings\n .flatMap((binding) => (binding ? [binding.id] : []))\n .filter((id, index, ids) => ids.indexOf(id) !== index);\n for (const id of new Set(duplicateIds)) {\n diagnostics.push(diagnostic(source, `Binding id '${id}' is duplicated.`, id));\n }\n if (diagnostics.length > 0 || bindings.some((binding) => binding === undefined)) return { diagnostics };\n\n return {\n contribution: {\n source,\n bindings: bindings as PoLeaderBinding[],\n },\n diagnostics,\n };\n}\n\nfunction optionOrder(segment: PoLeaderSegment): number {\n return segment.order ?? DEFAULT_OPTION_ORDER;\n}\n\nfunction cloneAction(action: PoLeaderAction): PoLeaderAction {\n if (action.type === 'command') return { type: 'command', command: { ...action.command } };\n if (action.type === 'app') return { type: 'app', action: action.action };\n return { type: 'extension', source: action.source, action: { ...action.action } };\n}\n\nfunction createRootNode(): LeaderNode {\n return {\n key: '',\n label: ROOT_LABEL,\n order: 0,\n owner: CORE_SOURCE,\n children: new Map(),\n };\n}\n\nfunction pathLabel(path: readonly PoLeaderSegment[]): string {\n return `SPC ${path.map((segment) => segment.key).join(' ')}`;\n}\n\n/**\n * Whether a shared group prefix is worded the same way by both contributors.\n *\n * `detail` is left out on purpose: it is a subtitle, and these packages ship on\n * independent npm versions, so comparing it means one upgraded package disagrees\n * with every package that has not caught up.\n *\n * A mismatch is REPORTED, never fatal. Losing `SPC e s` because two packages\n * spell the `SPC e` group differently costs the user a key they can no longer\n * press, which is worse than a menu row worded by whoever registered first.\n */\nfunction metadataMatches(node: LeaderNode, segment: PoLeaderSegment): boolean {\n return node.label === segment.label && node.order === optionOrder(segment);\n}\n\n/** Every binding under a node, for a takeover message that says what it displaced. */\nfunction leafCount(node: LeaderNode): number {\n if (node.children.size === 0) return node.action ? 1 : 0;\n let total = 0;\n for (const child of node.children.values()) total += leafCount(child);\n return total;\n}\n\n/**\n * Inserts one binding, taking a key over from whoever holds it.\n *\n * LAST REGISTRATION WINS, and the diagnostics say who lost what. The rule this\n * replaced rejected the newcomer, which read as \"warning plus nothing happened\":\n * the key stayed bound to the first registrant, or - when the clash was only a\n * group label - to nobody at all. A takeover is recoverable in a way a dropped\n * binding is not: the tree is rebuilt from every stored contribution, so when\n * the winner unregisters, the displaced binding comes back on the next rebuild.\n *\n * Returns diagnostics rather than one issue, because a single insert can both\n * disagree about a group's wording and take a key from someone.\n */\nfunction insertBinding(root: LeaderNode, binding: InternalLeaderBinding): PoLeaderDiagnostic[] {\n const diagnostics: PoLeaderDiagnostic[] = [];\n let current = root;\n let firstMissing = -1;\n\n for (const [index, segment] of binding.path.entries()) {\n const existing = current.children.get(segment.key);\n if (!existing) {\n firstMissing = index;\n break;\n }\n if (!metadataMatches(existing, segment)) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path.slice(0, index + 1))} keeps the label from ${existing.owner}; the binding is registered.`,\n binding.id,\n ),\n );\n }\n // First writer wins for the subtitle, but a group created without one still\n // adopts the first that is offered, so the wording does not depend on which\n // package happened to register first.\n if (!existing.detail && segment.detail) existing.detail = segment.detail;\n\n const isLeaf = index === binding.path.length - 1;\n const displaced = leafCount(existing);\n if (isLeaf && displaced > 0) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path)} taken over from ${existing.owner}` +\n `${displaced > 1 ? `, displacing ${displaced} bindings` : ''}.`,\n binding.id,\n ),\n );\n existing.children.clear();\n delete existing.action;\n delete existing.bindingId;\n } else if (!isLeaf && existing.action) {\n diagnostics.push(\n diagnostic(\n binding.source,\n `${pathLabel(binding.path.slice(0, index + 1))} taken over from ${existing.owner} to open a group.`,\n binding.id,\n ),\n );\n delete existing.action;\n delete existing.bindingId;\n }\n if (isLeaf || existing.action === undefined) existing.owner = binding.source;\n current = existing;\n }\n\n const start = firstMissing === -1 ? binding.path.length : firstMissing;\n for (let index = start; index < binding.path.length; index += 1) {\n const segment = binding.path[index] as PoLeaderSegment;\n const node: LeaderNode = {\n key: segment.key,\n label: segment.label,\n ...(segment.detail ? { detail: segment.detail } : {}),\n ...(segment.tone ? { tone: segment.tone } : {}),\n order: optionOrder(segment),\n owner: binding.source,\n children: new Map(),\n };\n current.children.set(segment.key, node);\n current = node;\n }\n\n current.action = cloneAction(binding.action);\n current.bindingId = binding.id;\n current.owner = binding.source;\n return diagnostics;\n}\n\nexport class PoLeaderRegistry {\n private root = createRootNode();\n private readonly contributions = new Map<string, readonly PoLeaderBinding[]>();\n private readonly listeners = new Set<() => void>();\n private diagnostics: PoLeaderDiagnostic[] = [];\n private dirty = false;\n\n constructor() {\n this.rebuild();\n }\n\n register(value: unknown): PoLeaderRegistrationResult {\n const result = this.apply(value);\n if (!result.accepted) return result;\n this.rebuild();\n return { accepted: true, diagnostics: this.getDiagnostics() };\n }\n\n /** Records a contribution without rebuilding the whole tree immediately. */\n registerDeferred(value: unknown): PoLeaderRegistrationResult {\n return this.apply(value);\n }\n\n private apply(value: unknown): PoLeaderRegistrationResult {\n const parsed = parseContribution(value);\n if (!parsed.contribution) return { accepted: false, diagnostics: parsed.diagnostics };\n\n // Deleted before it is set again, so re-registering moves a source to the\n // back of the insertion order: registering again IS claiming again.\n this.contributions.delete(parsed.contribution.source);\n if (parsed.contribution.bindings.length > 0) {\n this.contributions.set(parsed.contribution.source, parsed.contribution.bindings);\n }\n this.dirty = true;\n return { accepted: true, diagnostics: parsed.diagnostics };\n }\n\n /** Rebuilds one batch and returns its deterministic conflict diagnostics. */\n flush(): PoLeaderDiagnostic[] {\n if (this.dirty) this.rebuild();\n return this.diagnostics.map((item) => ({ ...item }));\n }\n\n getGroup(path: readonly string[]): PoLeaderGroup | undefined {\n this.flush();\n let current = this.root;\n for (const key of path) {\n const next = current.children.get(key);\n if (!next || next.action) return undefined;\n current = next;\n }\n\n // The key is the sort, at every level. A reader looking for a chord knows the\n // key, not the number some contributor picked for it, and those numbers live\n // across nine packages so no one of them can see the sequence they produce.\n // `order` survives only as group identity: co-contributors to a shared prefix\n // must still agree on it, which is what `metadataMatches` checks.\n const options = [...current.children.values()]\n .sort((left, right) => left.key.localeCompare(right.key))\n .map((node): PoLeaderResolvedOption => ({\n key: node.key,\n label: node.label,\n ...(node.detail ? { detail: node.detail } : {}),\n ...(node.tone ? { tone: node.tone } : {}),\n hasChildren: node.children.size > 0,\n ...(node.action ? { action: cloneAction(node.action) } : {}),\n }));\n return { label: current.label, options };\n }\n\n getDiagnostics(): PoLeaderDiagnostic[] {\n return this.flush();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private rebuild(): void {\n const nextRoot = createRootNode();\n const diagnostics: PoLeaderDiagnostic[] = [];\n for (const binding of CORE_BINDINGS) {\n // Core bindings land in an empty tree, so anything reported here is two\n // core bindings disagreeing with each other: a defect, not a contribution.\n const [issue] = insertBinding(nextRoot, binding);\n if (issue) throw new Error(`Invalid core leader binding: ${issue.message}`);\n }\n\n // Registration order, not alphabetical: the key belongs to whoever claimed\n // it last, and `apply` re-seats a source that registers again so a reload\n // counts as a fresh claim. Bindings inside one contribution stay sorted by\n // id, so a single source's own output is still deterministic.\n for (const [source, bindings] of this.contributions.entries()) {\n for (const binding of [...bindings].sort((left, right) => left.id.localeCompare(right.id))) {\n diagnostics.push(\n ...insertBinding(nextRoot, {\n id: binding.id,\n source,\n path: binding.path,\n action:\n 'command' in binding\n ? { type: 'command', command: binding.command }\n : { type: 'extension', source, action: binding.action },\n }),\n );\n }\n }\n\n this.root = nextRoot;\n this.diagnostics = diagnostics;\n this.dirty = false;\n for (const listener of this.listeners) listener();\n }\n}\n"],"mappings":"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"}
|
|
@@ -14,46 +14,46 @@ interface ExtensionLeaderAction {
|
|
|
14
14
|
source: string;
|
|
15
15
|
action: LeaderAction;
|
|
16
16
|
}
|
|
17
|
-
type
|
|
18
|
-
interface
|
|
17
|
+
type PoLeaderAction = AppLeaderAction | CommandLeaderAction | ExtensionLeaderAction;
|
|
18
|
+
interface PoLeaderResolvedOption {
|
|
19
19
|
key: string;
|
|
20
20
|
label: string;
|
|
21
21
|
detail?: string;
|
|
22
22
|
tone?: LeaderTone;
|
|
23
23
|
hasChildren: boolean;
|
|
24
|
-
action?:
|
|
24
|
+
action?: PoLeaderAction;
|
|
25
25
|
}
|
|
26
|
-
interface
|
|
26
|
+
interface PoLeaderGroup {
|
|
27
27
|
label: string;
|
|
28
|
-
options: readonly
|
|
28
|
+
options: readonly PoLeaderResolvedOption[];
|
|
29
29
|
}
|
|
30
|
-
interface
|
|
30
|
+
interface PoLeaderDiagnostic {
|
|
31
31
|
source: string;
|
|
32
32
|
bindingId?: string;
|
|
33
33
|
message: string;
|
|
34
34
|
}
|
|
35
|
-
interface
|
|
35
|
+
interface PoLeaderRegistrationResult {
|
|
36
36
|
accepted: boolean;
|
|
37
|
-
diagnostics: readonly
|
|
37
|
+
diagnostics: readonly PoLeaderDiagnostic[];
|
|
38
38
|
}
|
|
39
|
-
export declare class
|
|
39
|
+
export declare class PoLeaderRegistry {
|
|
40
40
|
private root;
|
|
41
41
|
private readonly contributions;
|
|
42
42
|
private readonly listeners;
|
|
43
43
|
private diagnostics;
|
|
44
44
|
private dirty;
|
|
45
45
|
constructor();
|
|
46
|
-
register(value: unknown):
|
|
46
|
+
register(value: unknown): PoLeaderRegistrationResult;
|
|
47
47
|
/** Records a contribution without rebuilding the whole tree immediately. */
|
|
48
|
-
registerDeferred(value: unknown):
|
|
48
|
+
registerDeferred(value: unknown): PoLeaderRegistrationResult;
|
|
49
49
|
private apply;
|
|
50
50
|
/** Rebuilds one batch and returns its deterministic conflict diagnostics. */
|
|
51
|
-
flush():
|
|
52
|
-
getGroup(path: readonly string[]):
|
|
53
|
-
getDiagnostics():
|
|
51
|
+
flush(): PoLeaderDiagnostic[];
|
|
52
|
+
getGroup(path: readonly string[]): PoLeaderGroup | undefined;
|
|
53
|
+
getDiagnostics(): PoLeaderDiagnostic[];
|
|
54
54
|
subscribe(listener: () => void): () => void;
|
|
55
55
|
private rebuild;
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
|
-
export type {
|
|
58
|
+
export type { PoLeaderAction, PoLeaderDiagnostic, PoLeaderGroup, PoLeaderRegistrationResult, PoLeaderResolvedOption };
|
|
59
59
|
//# sourceMappingURL=leaderRegistry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leaderRegistry.d.mts","names":["
|
|
1
|
+
{"version":3,"file":"leaderRegistry.d.mts","names":["PoLeaderCommand","PoLeaderExtensionAction","PoLeaderTone"],"sources":["../src/services/leaderRegistry/index.ts"],"mappings":";;KAAK;UAoBK;EACR;EACA,QAAQ;;UAGA;EACR;EACA,SAASA;;UAGD;EACR;EACA;EACA,QAAQC;;KAGE,iBAAiB,kBAAkB,sBAAsB;UAEpD;EACf;EACA;EACA;EACA,OAAOC;EACP;EACA,SAAS;;UAGM;EACf;EACA,kBAAkB;;UAGH;EACf;EACA;EACA;;UAGe;EACf;EACA,sBAAsB;;qBAwfX;UACH;mBACS;mBACA;UACT;UACA;EAER;EAIA,SAAS,iBAAiB;;EAQ1B,iBAAiB,iBAAiB;UAI1B;;EAeR,SAAS;EAKT,SAAS,0BAA0B;EA2BnC,kBAAkB;EAIlB,UAAU;UAKF"}
|
package/dist/leaderRegistry.mjs
CHANGED
|
@@ -413,7 +413,7 @@ function insertBinding(root, binding) {
|
|
|
413
413
|
current.owner = binding.source;
|
|
414
414
|
return diagnostics;
|
|
415
415
|
}
|
|
416
|
-
var
|
|
416
|
+
var PoLeaderRegistry = class {
|
|
417
417
|
root = createRootNode();
|
|
418
418
|
contributions = /* @__PURE__ */ new Map();
|
|
419
419
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -509,6 +509,6 @@ var DoomLeaderRegistry = class {
|
|
|
509
509
|
}
|
|
510
510
|
};
|
|
511
511
|
//#endregion
|
|
512
|
-
export {
|
|
512
|
+
export { PoLeaderRegistry };
|
|
513
513
|
|
|
514
514
|
//# sourceMappingURL=leaderRegistry.mjs.map
|