@agimon-ai/po-config 0.0.0-alpha.0
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 +21 -0
- package/README.md +170 -0
- package/dist/agentPluginMcp.cjs +322 -0
- package/dist/agentPluginMcp.cjs.map +1 -0
- package/dist/agentPluginMcp.d.mts +38 -0
- package/dist/agentPluginMcp.d.mts.map +1 -0
- package/dist/agentPluginMcp.mjs +318 -0
- package/dist/agentPluginMcp.mjs.map +1 -0
- package/dist/apiContracts.cjs +203 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +198 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/atomicJson-1W0WhuFF.mjs +44 -0
- package/dist/atomicJson-1W0WhuFF.mjs.map +1 -0
- package/dist/atomicJson-Dt2z_DXl.cjs +52 -0
- package/dist/atomicJson-Dt2z_DXl.cjs.map +1 -0
- package/dist/atomicJson.cjs +3 -0
- package/dist/atomicJson.d.mts +2 -0
- package/dist/atomicJson.mjs +2 -0
- package/dist/config-BUw5kHsx.cjs +219 -0
- package/dist/config-BUw5kHsx.cjs.map +1 -0
- package/dist/config-CKA07FxG.mjs +162 -0
- package/dist/config-CKA07FxG.mjs.map +1 -0
- package/dist/config-Cm3EV1jp.d.mts +320 -0
- package/dist/config-Cm3EV1jp.d.mts.map +1 -0
- package/dist/config-NSHRd6na.mjs +2 -0
- package/dist/config-zZz80Mh5.cjs +1 -0
- package/dist/config.cjs +24 -0
- package/dist/config.d.mts +3 -0
- package/dist/config.mjs +3 -0
- package/dist/configPolicy--TNX7feH.mjs +718 -0
- package/dist/configPolicy--TNX7feH.mjs.map +1 -0
- package/dist/configPolicy-DmsZEp0t.cjs +795 -0
- package/dist/configPolicy-DmsZEp0t.cjs.map +1 -0
- package/dist/configSchema.cjs +0 -0
- package/dist/configSchema.d.mts +2 -0
- package/dist/configSchema.mjs +1 -0
- package/dist/configWriter-BTuinLjs.cjs +150 -0
- package/dist/configWriter-BTuinLjs.cjs.map +1 -0
- package/dist/configWriter-BgkGaLrf.mjs +130 -0
- package/dist/configWriter-BgkGaLrf.mjs.map +1 -0
- package/dist/configWriter.cjs +5 -0
- package/dist/configWriter.d.mts +2 -0
- package/dist/configWriter.mjs +2 -0
- package/dist/domains-CBYkuxs5.cjs +727 -0
- package/dist/domains-CBYkuxs5.cjs.map +1 -0
- package/dist/domains-DZOu9vYM.mjs +633 -0
- package/dist/domains-DZOu9vYM.mjs.map +1 -0
- package/dist/domains.cjs +19 -0
- package/dist/domains.d.mts +3 -0
- package/dist/domains.mjs +3 -0
- package/dist/extensions/mcp-ui.mjs +101 -0
- package/dist/extensions/mcp-ui.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +171 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +166 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +504 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +499 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/harnessState-CCyBeutB.cjs +188 -0
- package/dist/harnessState-CCyBeutB.cjs.map +1 -0
- package/dist/harnessState-Dn_S7fB9.mjs +163 -0
- package/dist/harnessState-Dn_S7fB9.mjs.map +1 -0
- package/dist/harnessState.cjs +6 -0
- package/dist/harnessState.d.mts +2 -0
- package/dist/harnessState.mjs +2 -0
- package/dist/harnessStore-CJSxdSkV.cjs +343 -0
- package/dist/harnessStore-CJSxdSkV.cjs.map +1 -0
- package/dist/harnessStore-CltwLB7M.mjs +262 -0
- package/dist/harnessStore-CltwLB7M.mjs.map +1 -0
- package/dist/harnessStore.cjs +15 -0
- package/dist/harnessStore.d.mts +2 -0
- package/dist/harnessStore.mjs +2 -0
- package/dist/index-BAaTySaM.d.mts +35 -0
- package/dist/index-BAaTySaM.d.mts.map +1 -0
- package/dist/index-BT29GZx5.d.mts +142 -0
- package/dist/index-BT29GZx5.d.mts.map +1 -0
- package/dist/index-B_lp0W3U.d.mts +114 -0
- package/dist/index-B_lp0W3U.d.mts.map +1 -0
- package/dist/index-C6GaYjq-.d.mts +6 -0
- package/dist/index-C6GaYjq-.d.mts.map +1 -0
- package/dist/index-CIQrKS1A.d.mts +50 -0
- package/dist/index-CIQrKS1A.d.mts.map +1 -0
- package/dist/index-CRcoVYXz.d.mts +39 -0
- package/dist/index-CRcoVYXz.d.mts.map +1 -0
- package/dist/index-CVlciCJF.d.mts +40 -0
- package/dist/index-CVlciCJF.d.mts.map +1 -0
- package/dist/index-CeOk2kqs.d.mts +118 -0
- package/dist/index-CeOk2kqs.d.mts.map +1 -0
- package/dist/index-Ch7ptOkW.d.mts +54 -0
- package/dist/index-Ch7ptOkW.d.mts.map +1 -0
- package/dist/index-Cvdt-Y-i.d.mts +66 -0
- package/dist/index-Cvdt-Y-i.d.mts.map +1 -0
- package/dist/index-DJpG-I9K.d.mts +122 -0
- package/dist/index-DJpG-I9K.d.mts.map +1 -0
- package/dist/index-DNk4q0Qm.d.mts +81 -0
- package/dist/index-DNk4q0Qm.d.mts.map +1 -0
- package/dist/index.cjs +121 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.mjs +15 -0
- package/dist/init-C_9nyp3-.cjs +448 -0
- package/dist/init-C_9nyp3-.cjs.map +1 -0
- package/dist/init-DJ6wm-dr.mjs +415 -0
- package/dist/init-DJ6wm-dr.mjs.map +1 -0
- package/dist/init.cjs +7 -0
- package/dist/init.d.mts +2 -0
- package/dist/init.mjs +2 -0
- package/dist/layeredConfig-B922ibgn.mjs +67 -0
- package/dist/layeredConfig-B922ibgn.mjs.map +1 -0
- package/dist/layeredConfig-DdI5ysUf.cjs +94 -0
- package/dist/layeredConfig-DdI5ysUf.cjs.map +1 -0
- package/dist/layeredConfig.cjs +6 -0
- package/dist/layeredConfig.d.mts +2 -0
- package/dist/layeredConfig.mjs +2 -0
- package/dist/majorModes-CmPLEpMT.mjs +333 -0
- package/dist/majorModes-CmPLEpMT.mjs.map +1 -0
- package/dist/majorModes-DPhVMuhT.cjs +383 -0
- package/dist/majorModes-DPhVMuhT.cjs.map +1 -0
- package/dist/majorModes.cjs +10 -0
- package/dist/majorModes.d.mts +2 -0
- package/dist/majorModes.mjs +2 -0
- package/dist/piConfig-Bx26HMb_.d.mts +33 -0
- package/dist/piConfig-Bx26HMb_.d.mts.map +1 -0
- package/dist/piConfig-CCBdZXQr.cjs +260 -0
- package/dist/piConfig-CCBdZXQr.cjs.map +1 -0
- package/dist/piConfig-qGyCbcVj.mjs +197 -0
- package/dist/piConfig-qGyCbcVj.mjs.map +1 -0
- package/dist/piConfig.cjs +12 -0
- package/dist/piConfig.d.mts +2 -0
- package/dist/piConfig.mjs +2 -0
- package/dist/piContext.cjs +18 -0
- package/dist/piContext.d.mts +3 -0
- package/dist/piContext.mjs +2 -0
- package/dist/profiles-CTrUCmIh.d.mts +27 -0
- package/dist/profiles-CTrUCmIh.d.mts.map +1 -0
- package/dist/profiles-DnF9DBpd.cjs +552 -0
- package/dist/profiles-DnF9DBpd.cjs.map +1 -0
- package/dist/profiles-fujQKrS0.mjs +483 -0
- package/dist/profiles-fujQKrS0.mjs.map +1 -0
- package/dist/profiles.cjs +13 -0
- package/dist/profiles.d.mts +25 -0
- package/dist/profiles.d.mts.map +1 -0
- package/dist/profiles.mjs +2 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/dist/selectionSwitch.cjs +70 -0
- package/dist/selectionSwitch.cjs.map +1 -0
- package/dist/selectionSwitch.d.mts +30 -0
- package/dist/selectionSwitch.d.mts.map +1 -0
- package/dist/selectionSwitch.mjs +64 -0
- package/dist/selectionSwitch.mjs.map +1 -0
- package/dist/sessionConfig-Boh4Fdje.cjs +342 -0
- package/dist/sessionConfig-Boh4Fdje.cjs.map +1 -0
- package/dist/sessionConfig-CtLoc-lO.mjs +240 -0
- package/dist/sessionConfig-CtLoc-lO.mjs.map +1 -0
- package/dist/types.cjs +9 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +2 -0
- package/llms.txt +12 -0
- package/package.json +206 -0
- package/src/prompts/po-author-config/SKILL.md +26 -0
- package/src/prompts/po-author-config/agents/openai.yaml +4 -0
- package/src/prompts/po-author-config/references/config-contract.md +201 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_layeredConfig = require("./layeredConfig-DdI5ysUf.cjs");
|
|
3
|
+
exports.DOOM_DIR = require_layeredConfig.DOOM_DIR;
|
|
4
|
+
exports.doomConfigCandidates = require_layeredConfig.doomConfigCandidates;
|
|
5
|
+
exports.mergeNamedSources = require_layeredConfig.mergeNamedSources;
|
|
6
|
+
exports.readDoomConfigSources = require_layeredConfig.readDoomConfigSources;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as mergeNamedSources, i as doomConfigCandidates, n as DoomConfigProvenance, o as readDoomConfigSources, r as DoomConfigSource, t as DOOM_DIR } from "./index-Ch7ptOkW.mjs";
|
|
2
|
+
export { DOOM_DIR, type DoomConfigProvenance, type DoomConfigSource, doomConfigCandidates, mergeNamedSources, readDoomConfigSources };
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { i as readDoomConfigSources } from "./layeredConfig-B922ibgn.mjs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
//#region src/services/majorModes/index.ts
|
|
5
|
+
const MODES_FILE = "modes.yaml";
|
|
6
|
+
const FALLBACK_MAJOR_MODE = "copilot";
|
|
7
|
+
const MAJOR_MODES_RELATIVE_PATH = path.join(".po", MODES_FILE);
|
|
8
|
+
const RELATIVE_PREFIXES = ["./", "../"];
|
|
9
|
+
const DEFAULT_KEYS = ["packages"];
|
|
10
|
+
/**
|
|
11
|
+
* Whether a layer value names a path rather than a built-in or installed package.
|
|
12
|
+
*
|
|
13
|
+
* The same rule Node applies to import specifiers, so a bare name is always a
|
|
14
|
+
* logical name and a path always looks like one.
|
|
15
|
+
*/
|
|
16
|
+
function isLocalPackageSpecifier(specifier) {
|
|
17
|
+
return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));
|
|
18
|
+
}
|
|
19
|
+
const LAYER_PACKAGE_KEYS = [
|
|
20
|
+
"name",
|
|
21
|
+
"optional",
|
|
22
|
+
"config"
|
|
23
|
+
];
|
|
24
|
+
const MAJOR_MODE_KEYS = ["description", "layers"];
|
|
25
|
+
function isRecord(value) {
|
|
26
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Where a lenient load collects unknown keys instead of throwing.
|
|
30
|
+
*
|
|
31
|
+
* Same shape as the sink in configPolicy, for the same reason: `assertKnownKeys`
|
|
32
|
+
* is the only reader and the whole load is synchronous.
|
|
33
|
+
*/
|
|
34
|
+
let unknownKeySink;
|
|
35
|
+
function assertKnownKeys(value, keys, location) {
|
|
36
|
+
const unsupported = Object.keys(value).filter((key) => !keys.includes(key));
|
|
37
|
+
if (unsupported.length === 0) return;
|
|
38
|
+
if (unknownKeySink !== void 0) {
|
|
39
|
+
for (const key of unsupported) unknownKeySink.push({
|
|
40
|
+
filePath: MAJOR_MODES_RELATIVE_PATH,
|
|
41
|
+
path: key,
|
|
42
|
+
message: `${location} has unsupported field`
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`${location} has unsupported field(s): ${unsupported.join(", ")}`);
|
|
47
|
+
}
|
|
48
|
+
function parseLayerPackage(layerName, value, index) {
|
|
49
|
+
const location = `Layer "${layerName}" package[${index}] in ${MAJOR_MODES_RELATIVE_PATH}`;
|
|
50
|
+
if (typeof value === "string") {
|
|
51
|
+
if (!value.trim()) throw new Error(`${location} must be a non-empty string or mapping`);
|
|
52
|
+
return value.trim();
|
|
53
|
+
}
|
|
54
|
+
if (!isRecord(value)) throw new Error(`${location} must be a non-empty string or mapping`);
|
|
55
|
+
assertKnownKeys(value, LAYER_PACKAGE_KEYS, location);
|
|
56
|
+
if (typeof value.name !== "string" || !value.name.trim()) throw new Error(`${location}.name must be a non-empty string`);
|
|
57
|
+
if (value.optional !== void 0 && typeof value.optional !== "boolean") throw new Error(`${location}.optional must be a boolean`);
|
|
58
|
+
if (value.config !== void 0 && !isRecord(value.config)) throw new Error(`${location}.config must be a mapping`);
|
|
59
|
+
return {
|
|
60
|
+
name: value.name.trim(),
|
|
61
|
+
...value.optional === true ? { optional: true } : {},
|
|
62
|
+
...value.config ? { config: { ...value.config } } : {}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function parseLayerExtensions(layerName, value) {
|
|
66
|
+
if (value === void 0) return void 0;
|
|
67
|
+
const location = `Layer "${layerName}" extensions in ${MAJOR_MODES_RELATIVE_PATH}`;
|
|
68
|
+
if (!Array.isArray(value)) throw new Error(`${location} must be an array`);
|
|
69
|
+
return value.map((entry, index) => {
|
|
70
|
+
if (typeof entry !== "string" || !entry.trim()) throw new Error(`${location}[${index}] must be a non-empty string`);
|
|
71
|
+
return entry.trim();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function parseLayerPackages(layerName, value) {
|
|
75
|
+
if (value === void 0) return void 0;
|
|
76
|
+
if (!Array.isArray(value)) throw new Error(`Layer "${layerName}" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);
|
|
77
|
+
return value.map((entry, index) => parseLayerPackage(layerName, entry, index));
|
|
78
|
+
}
|
|
79
|
+
function parseDefaultMajorMode(value) {
|
|
80
|
+
if (typeof value !== "string" || !value.trim()) throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);
|
|
81
|
+
return value.trim();
|
|
82
|
+
}
|
|
83
|
+
function parseMajorModeLayers(modeName, value) {
|
|
84
|
+
const location = `Major mode "${modeName}" layers in ${MAJOR_MODES_RELATIVE_PATH}`;
|
|
85
|
+
if (!Array.isArray(value)) throw new Error(`${location} must be an array`);
|
|
86
|
+
return value.map((layerName, index) => {
|
|
87
|
+
if (typeof layerName !== "string" || !layerName.trim()) throw new Error(`${location}[${index}] must be a non-empty string`);
|
|
88
|
+
return layerName.trim();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function legacyMajorModeDescription(layers) {
|
|
92
|
+
return layers.length > 0 ? `Uses layers: ${layers.join(", ")}.` : "Uses Doom Pi core extensions only.";
|
|
93
|
+
}
|
|
94
|
+
function parseMajorMode(name, value) {
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
const layers = parseMajorModeLayers(name, value);
|
|
97
|
+
return {
|
|
98
|
+
description: legacyMajorModeDescription(layers),
|
|
99
|
+
layers
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const location = `Major mode "${name}" in ${MAJOR_MODES_RELATIVE_PATH}`;
|
|
103
|
+
if (!isRecord(value)) throw new Error(`${location} must be a mapping with description and layers`);
|
|
104
|
+
assertKnownKeys(value, MAJOR_MODE_KEYS, location);
|
|
105
|
+
if (typeof value.description !== "string" || !value.description.trim()) throw new Error(`${location}.description must be a non-empty string`);
|
|
106
|
+
return {
|
|
107
|
+
description: value.description.trim(),
|
|
108
|
+
layers: parseMajorModeLayers(name, value.layers)
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function parseMajorModes(value) {
|
|
112
|
+
if (value === void 0) return {};
|
|
113
|
+
if (!isRecord(value)) throw new Error(`majorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);
|
|
114
|
+
return Object.fromEntries(Object.entries(value).map(([name, definition]) => [name, definition === null ? null : parseMajorMode(name, definition)]));
|
|
115
|
+
}
|
|
116
|
+
function parseLayer(name, definition) {
|
|
117
|
+
if (!isRecord(definition)) throw new Error(`Layer "${name}" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);
|
|
118
|
+
if ("targets" in definition) throw new Error(`Layer "${name}" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field "targets"; select availability through major modes`);
|
|
119
|
+
if ("config" in definition) throw new Error(`Layer "${name}" in ${MAJOR_MODES_RELATIVE_PATH} uses unsupported field "config"; move it under the package entry that owns it`);
|
|
120
|
+
const extensions = parseLayerExtensions(name, definition.extensions);
|
|
121
|
+
const packages = parseLayerPackages(name, definition.packages);
|
|
122
|
+
return {
|
|
123
|
+
...definition,
|
|
124
|
+
...extensions === void 0 ? {} : { extensions },
|
|
125
|
+
...packages === void 0 ? {} : { packages }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function parseLayers(value) {
|
|
129
|
+
if (value === void 0) return {};
|
|
130
|
+
if (!isRecord(value)) throw new Error(`layers in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);
|
|
131
|
+
return Object.fromEntries(Object.entries(value).map(([name, definition]) => [name, definition === null ? null : parseLayer(name, definition)]));
|
|
132
|
+
}
|
|
133
|
+
function parseDefault(value) {
|
|
134
|
+
const location = `default in ${MAJOR_MODES_RELATIVE_PATH}`;
|
|
135
|
+
if (!isRecord(value)) throw new Error(`${location} must be a mapping with packages`);
|
|
136
|
+
assertKnownKeys(value, DEFAULT_KEYS, location);
|
|
137
|
+
if (!Object.hasOwn(value, "packages")) throw new Error(`Layer "default" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);
|
|
138
|
+
return { packages: parseLayerPackages("default", value.packages) };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Reads layers and major modes from the global and repository configs.
|
|
142
|
+
*
|
|
143
|
+
* The repository is read last, so it replaces a global layer or major mode of
|
|
144
|
+
* the same name. Layers keep the root they were declared under so that a
|
|
145
|
+
* global layer naming `./extensions/x` still points beside the global config
|
|
146
|
+
* once it is loaded from inside some other repository.
|
|
147
|
+
*/
|
|
148
|
+
function loadMajorModesConfig(repoRoot, homeDirectory = os.homedir(), environment = process.env) {
|
|
149
|
+
const sources = readDoomConfigSources(MODES_FILE, repoRoot, homeDirectory);
|
|
150
|
+
let defaultDefinition;
|
|
151
|
+
const layers = {};
|
|
152
|
+
const majorMode = {};
|
|
153
|
+
const majorModeSources = {};
|
|
154
|
+
let defaultMajorMode = FALLBACK_MAJOR_MODE;
|
|
155
|
+
let defaultMajorModeSource;
|
|
156
|
+
let hasConfiguredDefault = false;
|
|
157
|
+
for (const source of sources) {
|
|
158
|
+
if (Object.hasOwn(source.document, "default")) defaultDefinition = {
|
|
159
|
+
...parseDefault(source.document.default),
|
|
160
|
+
baseDirectory: source.baseDirectory,
|
|
161
|
+
filePath: source.filePath
|
|
162
|
+
};
|
|
163
|
+
for (const [name, definition] of Object.entries(parseLayers(source.document.layers))) {
|
|
164
|
+
if (definition === null) {
|
|
165
|
+
delete layers[name];
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
layers[name] = {
|
|
169
|
+
...definition,
|
|
170
|
+
baseDirectory: source.baseDirectory,
|
|
171
|
+
filePath: source.filePath
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (Object.hasOwn(source.document, "defaultMajorMode")) {
|
|
175
|
+
defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);
|
|
176
|
+
defaultMajorModeSource = {
|
|
177
|
+
filePath: source.filePath,
|
|
178
|
+
baseDirectory: source.baseDirectory
|
|
179
|
+
};
|
|
180
|
+
hasConfiguredDefault = true;
|
|
181
|
+
}
|
|
182
|
+
for (const [name, definition] of Object.entries(parseMajorModes(source.document.majorMode))) {
|
|
183
|
+
if (definition === null) {
|
|
184
|
+
delete majorMode[name];
|
|
185
|
+
delete majorModeSources[name];
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
majorMode[name] = definition;
|
|
189
|
+
majorModeSources[name] = {
|
|
190
|
+
filePath: source.filePath,
|
|
191
|
+
baseDirectory: source.baseDirectory
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const [modeName, definition] of Object.entries(majorMode)) for (const name of definition.layers) if (!layers[name]) throw new Error(`Unknown layer "${name}" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);
|
|
196
|
+
if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) throw new Error(`Unknown default major mode "${defaultMajorMode}" in ${MAJOR_MODES_RELATIVE_PATH}`);
|
|
197
|
+
if (environment.PO_DISTRIBUTION === "desktop") {
|
|
198
|
+
const computerUsePackage = "@agimon-ai/po-computer-use";
|
|
199
|
+
const packages = defaultDefinition?.packages ?? [];
|
|
200
|
+
if (!packages.some((entry) => (typeof entry === "string" ? entry : entry.name) === computerUsePackage)) defaultDefinition = {
|
|
201
|
+
...defaultDefinition ?? { baseDirectory: repoRoot },
|
|
202
|
+
packages: [...packages, computerUsePackage]
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
...defaultDefinition ? { default: defaultDefinition } : {},
|
|
207
|
+
layers,
|
|
208
|
+
defaultMajorMode,
|
|
209
|
+
...defaultMajorModeSource ? { defaultMajorModeSource } : {},
|
|
210
|
+
majorMode,
|
|
211
|
+
majorModeSources
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** Finds configuration owned by one package while preserving layer and package order. */
|
|
215
|
+
function resolvePackageConfigurations(config, names, packageName) {
|
|
216
|
+
const normalizedPackageName = packageName.trim();
|
|
217
|
+
if (!normalizedPackageName) throw new Error("Package name must be a non-empty string");
|
|
218
|
+
const configurations = [];
|
|
219
|
+
const definitions = [];
|
|
220
|
+
if (config.default) definitions.push({
|
|
221
|
+
name: "default",
|
|
222
|
+
definition: config.default
|
|
223
|
+
});
|
|
224
|
+
for (const name of names) {
|
|
225
|
+
const definition = config.layers[name];
|
|
226
|
+
if (!definition) throw new Error(`Unknown layer: ${name}`);
|
|
227
|
+
definitions.push({
|
|
228
|
+
name,
|
|
229
|
+
definition
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
for (const { name, definition } of definitions) for (const entry of definition.packages ?? []) {
|
|
233
|
+
if (typeof entry === "string" || entry.config === void 0) continue;
|
|
234
|
+
if (entry.name !== normalizedPackageName && !entry.name.startsWith(`${normalizedPackageName}/`)) continue;
|
|
235
|
+
configurations.push({
|
|
236
|
+
layer: name,
|
|
237
|
+
specifier: entry.name,
|
|
238
|
+
config: { ...entry.config },
|
|
239
|
+
baseDirectory: definition.baseDirectory,
|
|
240
|
+
...definition.filePath ? { filePath: definition.filePath } : {}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return configurations;
|
|
244
|
+
}
|
|
245
|
+
/** Resolves one named major mode into its configured layer components. */
|
|
246
|
+
function resolveLayers(config, majorMode) {
|
|
247
|
+
if (!Object.hasOwn(config.majorMode, majorMode)) throw new Error(`Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(", ")}`);
|
|
248
|
+
return [...config.majorMode[majorMode].layers];
|
|
249
|
+
}
|
|
250
|
+
function resolveLocalEntries(resolvers, specifier, baseDirectory) {
|
|
251
|
+
const resolved = resolvers.localEntries?.(specifier, baseDirectory);
|
|
252
|
+
if (resolved !== void 0) return resolved;
|
|
253
|
+
const single = resolvers.localEntry(specifier, baseDirectory);
|
|
254
|
+
return single ? [single] : void 0;
|
|
255
|
+
}
|
|
256
|
+
/** Resolves one layer's extension and package entries to absolute paths. */
|
|
257
|
+
function layerEntries(config, name, resolvers) {
|
|
258
|
+
const layer = config.layers[name];
|
|
259
|
+
if (!layer) throw new Error(`Unknown layer: ${name}`);
|
|
260
|
+
const entries = [];
|
|
261
|
+
for (const entry of layer.extensions ?? []) {
|
|
262
|
+
if (!isLocalPackageSpecifier(entry)) {
|
|
263
|
+
entries.push(resolvers.ownEntry(entry));
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const resolved = resolveLocalEntries(resolvers, entry, layer.baseDirectory);
|
|
267
|
+
if (!resolved?.length) throw new Error(`Layer "${name}" extension "${entry}" does not resolve under ${layer.baseDirectory}. Point it at a Pi extension file or directory.`);
|
|
268
|
+
entries.push(...resolved);
|
|
269
|
+
}
|
|
270
|
+
for (const entry of layer.packages ?? []) {
|
|
271
|
+
const specifier = typeof entry === "string" ? entry : entry.name;
|
|
272
|
+
const optional = typeof entry === "string" ? false : entry.optional === true;
|
|
273
|
+
if (isLocalPackageSpecifier(specifier)) {
|
|
274
|
+
const resolved = resolveLocalEntries(resolvers, specifier, layer.baseDirectory);
|
|
275
|
+
if (resolved?.length) entries.push(...resolved);
|
|
276
|
+
else if (!optional) throw new Error(`Layer "${name}" package "${specifier}" does not resolve under ${layer.baseDirectory}. Point it at an extension file, or a directory whose package.json declares pi.extensions.`);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (optional) {
|
|
280
|
+
let resolved = resolvers.optionalPackageEntries?.(specifier);
|
|
281
|
+
if (resolved === void 0) {
|
|
282
|
+
const single = resolvers.optionalPackageEntry(specifier);
|
|
283
|
+
resolved = single ? [single] : void 0;
|
|
284
|
+
}
|
|
285
|
+
if (resolved) entries.push(...resolved);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const resolved = resolvers.packageEntries?.(specifier) ?? [resolvers.packageEntry(specifier)];
|
|
289
|
+
if (resolved.length === 0) throw new Error(`Layer "${name}" package "${specifier}" declares no Pi extensions.`);
|
|
290
|
+
entries.push(...resolved);
|
|
291
|
+
}
|
|
292
|
+
return entries;
|
|
293
|
+
}
|
|
294
|
+
/** Hook group ids contributed by the selected layers, deduped. */
|
|
295
|
+
function layerHookGroups(config, names) {
|
|
296
|
+
const groups = /* @__PURE__ */ new Set();
|
|
297
|
+
for (const name of names) for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);
|
|
298
|
+
return [...groups];
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Suppress layers that exist to contribute hook groups when hooks are disabled.
|
|
302
|
+
*
|
|
303
|
+
* Lives beside layerHookGroups because it is the inverse question about the same
|
|
304
|
+
* field, and because every caller that resolves layers has to ask it.
|
|
305
|
+
*/
|
|
306
|
+
function filterHookDisabledLayers(config, layers, hooks) {
|
|
307
|
+
if (hooks) return [...layers];
|
|
308
|
+
return layers.filter((layer) => (config.layers[layer]?.hookGroups?.length ?? 0) === 0);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Reads layers and major modes, tolerating unknown keys.
|
|
312
|
+
*
|
|
313
|
+
* `po sync` uses this so a modes.yaml written against a different set of
|
|
314
|
+
* layer packages cannot break a build. Every other caller keeps the strict
|
|
315
|
+
* `loadMajorModesConfig`, and `po doctor` still reports what was tolerated.
|
|
316
|
+
*/
|
|
317
|
+
function loadMajorModesConfigLenient(repoRoot, homeDirectory = os.homedir(), environment = process.env) {
|
|
318
|
+
const diagnostics = [];
|
|
319
|
+
const previous = unknownKeySink;
|
|
320
|
+
unknownKeySink = diagnostics;
|
|
321
|
+
try {
|
|
322
|
+
return {
|
|
323
|
+
config: loadMajorModesConfig(repoRoot, homeDirectory, environment),
|
|
324
|
+
diagnostics
|
|
325
|
+
};
|
|
326
|
+
} finally {
|
|
327
|
+
unknownKeySink = previous;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//#endregion
|
|
331
|
+
export { loadMajorModesConfig as a, resolvePackageConfigurations as c, layerHookGroups as i, isLocalPackageSpecifier as n, loadMajorModesConfigLenient as o, layerEntries as r, resolveLayers as s, filterHookDisabledLayers as t };
|
|
332
|
+
|
|
333
|
+
//# sourceMappingURL=majorModes-CmPLEpMT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModes-CmPLEpMT.mjs","names":[],"sources":["../src/services/majorModes/index.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nimport type { ConfigDiagnostic } from '../../types/config';\nimport { DOOM_DIR, type DoomConfigProvenance, readDoomConfigSources } from '../layeredConfig';\n\nexport type LayerPackageConfig = Record<string, unknown>;\n\n/** One package selected by a layer, plus configuration owned by that package. */\nexport interface LayerPackage {\n name: string;\n optional?: boolean;\n config?: LayerPackageConfig;\n}\n\n/** One configured package found while walking selected layers in order. */\nexport interface ResolvedPackageConfiguration {\n layer: string;\n specifier: string;\n config: LayerPackageConfig;\n baseDirectory: string;\n filePath?: string;\n}\n\nexport interface LayerDefinition {\n /**\n * Po built-in names, or Pi-compatible local extension paths.\n * Bare names resolve from Po's own extension entries. Paths beginning\n * with `./` or `../`, plus absolute paths, resolve against the config that\n * declares the layer and may name a script file or extension directory.\n */\n extensions?: string[];\n /**\n * npm specifiers, or local package paths retained for compatibility.\n * Relative paths resolve against the repository root for `.po/modes.yaml`\n * and against the global `.po` directory for\n * `~/.po/modes.yaml`.\n */\n packages?: Array<string | LayerPackage>;\n hookGroups?: string[];\n}\n\n/** A layer plus the root its relative extension and package paths resolve against. */\nexport interface ResolvedLayerDefinition extends LayerDefinition {\n baseDirectory: string;\n /** Absolute path of the modes file that declared this layer. */\n filePath?: string;\n}\n\nexport interface MajorModeDefinition {\n /** Human-readable purpose used by pickers and agent-facing catalogs. */\n description: string;\n /** Ordered layer names activated by this mode. */\n layers: string[];\n}\n\nexport interface MajorModesConfig {\n /** Unconditional package bundle loaded before packages from selected named layers. */\n default?: ResolvedLayerDefinition;\n layers: Record<string, ResolvedLayerDefinition>;\n /** The mode selected when neither a flag nor the environment names one. */\n defaultMajorMode: string;\n /** Source that last declared the default, absent for the built-in fallback. */\n defaultMajorModeSource?: DoomConfigProvenance;\n /** Named major modes, including their purpose and ordered layers. */\n majorMode: Record<string, MajorModeDefinition>;\n /** Declaring source for each surviving named mode. */\n majorModeSources?: Record<string, DoomConfigProvenance>;\n}\n\nexport interface LayerResolvers {\n ownEntry: (name: string) => string;\n packageEntry: (name: string) => string;\n optionalPackageEntry: (name: string) => string | undefined;\n /** Resolves every standard package.json pi.extensions entry for a package root. */\n packageEntries?: (name: string) => string[];\n /** Optional counterpart to packageEntries. */\n optionalPackageEntries?: (name: string) => string[] | undefined;\n /** Resolves one path-style layer entry against the config that declared it. */\n localEntry: (specifier: string, baseDirectory: string) => string | undefined;\n /** Resolves every Pi extension entry contributed by a local file or directory. */\n localEntries?: (specifier: string, baseDirectory: string) => string[] | undefined;\n}\n\ninterface ModesDocument {\n default?: unknown;\n layers?: unknown;\n defaultMajorMode?: unknown;\n majorMode?: unknown;\n}\n\nconst MODES_FILE = 'modes.yaml';\nconst FALLBACK_MAJOR_MODE = 'copilot';\nconst MAJOR_MODES_RELATIVE_PATH = path.join(DOOM_DIR, MODES_FILE);\nconst RELATIVE_PREFIXES = ['./', '../'] as const;\nconst DEFAULT_KEYS = ['packages'] as const;\n\n/**\n * Whether a layer value names a path rather than a built-in or installed package.\n *\n * The same rule Node applies to import specifiers, so a bare name is always a\n * logical name and a path always looks like one.\n */\nexport function isLocalPackageSpecifier(specifier: string): boolean {\n return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));\n}\nconst LAYER_PACKAGE_KEYS = ['name', 'optional', 'config'] as const;\nconst MAJOR_MODE_KEYS = ['description', 'layers'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Where a lenient load collects unknown keys instead of throwing.\n *\n * Same shape as the sink in configPolicy, for the same reason: `assertKnownKeys`\n * is the only reader and the whole load is synchronous.\n */\nlet unknownKeySink: ConfigDiagnostic[] | undefined;\n\nfunction assertKnownKeys(value: Record<string, unknown>, keys: readonly string[], location: string): void {\n const unsupported = Object.keys(value).filter((key) => !keys.includes(key));\n if (unsupported.length === 0) return;\n if (unknownKeySink !== undefined) {\n for (const key of unsupported) {\n unknownKeySink.push({\n filePath: MAJOR_MODES_RELATIVE_PATH,\n path: key,\n message: `${location} has unsupported field`,\n });\n }\n return;\n }\n throw new Error(`${location} has unsupported field(s): ${unsupported.join(', ')}`);\n}\n\nfunction parseLayerPackage(layerName: string, value: unknown, index: number): string | LayerPackage {\n const location = `Layer \"${layerName}\" package[${index}] in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (typeof value === 'string') {\n if (!value.trim()) throw new Error(`${location} must be a non-empty string or mapping`);\n return value.trim();\n }\n if (!isRecord(value)) throw new Error(`${location} must be a non-empty string or mapping`);\n assertKnownKeys(value, LAYER_PACKAGE_KEYS, location);\n if (typeof value.name !== 'string' || !value.name.trim()) {\n throw new Error(`${location}.name must be a non-empty string`);\n }\n if (value.optional !== undefined && typeof value.optional !== 'boolean') {\n throw new Error(`${location}.optional must be a boolean`);\n }\n if (value.config !== undefined && !isRecord(value.config)) {\n throw new Error(`${location}.config must be a mapping`);\n }\n return {\n name: value.name.trim(),\n ...(value.optional === true ? { optional: true } : {}),\n ...(value.config ? { config: { ...value.config } } : {}),\n };\n}\n\nfunction parseLayerExtensions(layerName: string, value: unknown): string[] | undefined {\n if (value === undefined) return undefined;\n const location = `Layer \"${layerName}\" extensions in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((entry, index) => {\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return entry.trim();\n });\n}\n\nfunction parseLayerPackages(layerName: string, value: unknown): Array<string | LayerPackage> | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`Layer \"${layerName}\" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);\n }\n return value.map((entry, index) => parseLayerPackage(layerName, entry, index));\n}\n\nfunction parseDefaultMajorMode(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction parseMajorModeLayers(modeName: string, value: unknown): string[] {\n const location = `Major mode \"${modeName}\" layers in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((layerName, index) => {\n if (typeof layerName !== 'string' || !layerName.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return layerName.trim();\n });\n}\n\nfunction legacyMajorModeDescription(layers: readonly string[]): string {\n return layers.length > 0 ? `Uses layers: ${layers.join(', ')}.` : 'Uses Doom Pi core extensions only.';\n}\n\nfunction parseMajorMode(name: string, value: unknown): MajorModeDefinition {\n if (Array.isArray(value)) {\n const layers = parseMajorModeLayers(name, value);\n return { description: legacyMajorModeDescription(layers), layers };\n }\n\n const location = `Major mode \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping with description and layers`);\n assertKnownKeys(value, MAJOR_MODE_KEYS, location);\n if (typeof value.description !== 'string' || !value.description.trim()) {\n throw new Error(`${location}.description must be a non-empty string`);\n }\n return {\n description: value.description.trim(),\n layers: parseMajorModeLayers(name, value.layers),\n };\n}\n\nfunction parseMajorModes(value: unknown): Record<string, MajorModeDefinition | null> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`majorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n return Object.fromEntries(\n Object.entries(value).map(([name, definition]) => [\n name,\n definition === null ? null : parseMajorMode(name, definition),\n ]),\n );\n}\n\nfunction parseLayer(name: string, definition: unknown): LayerDefinition {\n if (!isRecord(definition)) throw new Error(`Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n if ('targets' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field \"targets\"; select availability through major modes`,\n );\n }\n if ('config' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses unsupported field \"config\"; move it under the package entry that owns it`,\n );\n }\n const extensions = parseLayerExtensions(name, definition.extensions);\n const packages = parseLayerPackages(name, definition.packages);\n return {\n ...definition,\n ...(extensions === undefined ? {} : { extensions }),\n ...(packages === undefined ? {} : { packages }),\n } as LayerDefinition;\n}\n\nfunction parseLayers(value: unknown): Record<string, LayerDefinition | null> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`layers in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n return Object.fromEntries(\n Object.entries(value).map(([name, definition]) => [\n name,\n definition === null ? null : parseLayer(name, definition),\n ]),\n );\n}\n\nfunction parseDefault(value: unknown): LayerDefinition {\n const location = `default in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping with packages`);\n assertKnownKeys(value, DEFAULT_KEYS, location);\n if (!Object.hasOwn(value, 'packages')) {\n throw new Error(`Layer \"default\" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);\n }\n const packages = parseLayerPackages('default', value.packages);\n return { packages };\n}\n\n/**\n * Reads layers and major modes from the global and repository configs.\n *\n * The repository is read last, so it replaces a global layer or major mode of\n * the same name. Layers keep the root they were declared under so that a\n * global layer naming `./extensions/x` still points beside the global config\n * once it is loaded from inside some other repository.\n */\nexport function loadMajorModesConfig(\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): MajorModesConfig {\n const sources = readDoomConfigSources<ModesDocument>(MODES_FILE, repoRoot, homeDirectory);\n let defaultDefinition: ResolvedLayerDefinition | undefined;\n const layers: Record<string, ResolvedLayerDefinition> = {};\n const majorMode: Record<string, MajorModeDefinition> = {};\n const majorModeSources: Record<string, DoomConfigProvenance> = {};\n let defaultMajorMode = FALLBACK_MAJOR_MODE;\n let defaultMajorModeSource: DoomConfigProvenance | undefined;\n let hasConfiguredDefault = false;\n for (const source of sources) {\n if (Object.hasOwn(source.document, 'default')) {\n defaultDefinition = {\n ...parseDefault(source.document.default),\n baseDirectory: source.baseDirectory,\n filePath: source.filePath,\n };\n }\n for (const [name, definition] of Object.entries(parseLayers(source.document.layers))) {\n if (definition === null) {\n delete layers[name];\n continue;\n }\n layers[name] = {\n ...definition,\n baseDirectory: source.baseDirectory,\n filePath: source.filePath,\n };\n }\n if (Object.hasOwn(source.document, 'defaultMajorMode')) {\n defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);\n defaultMajorModeSource = { filePath: source.filePath, baseDirectory: source.baseDirectory };\n hasConfiguredDefault = true;\n }\n for (const [name, definition] of Object.entries(parseMajorModes(source.document.majorMode))) {\n if (definition === null) {\n delete majorMode[name];\n delete majorModeSources[name];\n continue;\n }\n majorMode[name] = definition;\n majorModeSources[name] = { filePath: source.filePath, baseDirectory: source.baseDirectory };\n }\n }\n\n for (const [modeName, definition] of Object.entries(majorMode)) {\n for (const name of definition.layers) {\n if (!layers[name]) {\n throw new Error(`Unknown layer \"${name}\" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n }\n }\n if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) {\n throw new Error(`Unknown default major mode \"${defaultMajorMode}\" in ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n if (environment.PO_DISTRIBUTION === 'desktop') {\n const computerUsePackage = '@agimon-ai/po-computer-use';\n const packages = defaultDefinition?.packages ?? [];\n if (!packages.some((entry) => (typeof entry === 'string' ? entry : entry.name) === computerUsePackage)) {\n defaultDefinition = {\n ...(defaultDefinition ?? { baseDirectory: repoRoot }),\n packages: [...packages, computerUsePackage],\n };\n }\n }\n return {\n ...(defaultDefinition ? { default: defaultDefinition } : {}),\n layers,\n defaultMajorMode,\n ...(defaultMajorModeSource ? { defaultMajorModeSource } : {}),\n majorMode,\n majorModeSources,\n };\n}\n\n/** Finds configuration owned by one package while preserving layer and package order. */\nexport function resolvePackageConfigurations(\n config: MajorModesConfig,\n names: string[],\n packageName: string,\n): ResolvedPackageConfiguration[] {\n const normalizedPackageName = packageName.trim();\n if (!normalizedPackageName) throw new Error('Package name must be a non-empty string');\n const configurations: ResolvedPackageConfiguration[] = [];\n const definitions: Array<{ name: string; definition: ResolvedLayerDefinition }> = [];\n if (config.default) definitions.push({ name: 'default', definition: config.default });\n for (const name of names) {\n const definition = config.layers[name];\n if (!definition) throw new Error(`Unknown layer: ${name}`);\n definitions.push({ name, definition });\n }\n for (const { name, definition } of definitions) {\n for (const entry of definition.packages ?? []) {\n if (typeof entry === 'string' || entry.config === undefined) continue;\n if (entry.name !== normalizedPackageName && !entry.name.startsWith(`${normalizedPackageName}/`)) continue;\n configurations.push({\n layer: name,\n specifier: entry.name,\n config: { ...entry.config },\n baseDirectory: definition.baseDirectory,\n ...(definition.filePath ? { filePath: definition.filePath } : {}),\n });\n }\n }\n return configurations;\n}\n\n/** Resolves one named major mode into its configured layer components. */\nexport function resolveLayers(config: MajorModesConfig, majorMode: string): string[] {\n if (!Object.hasOwn(config.majorMode, majorMode)) {\n throw new Error(\n `Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(', ')}`,\n );\n }\n return [...config.majorMode[majorMode]!.layers];\n}\n\nfunction resolveLocalEntries(\n resolvers: LayerResolvers,\n specifier: string,\n baseDirectory: string,\n): string[] | undefined {\n const resolved = resolvers.localEntries?.(specifier, baseDirectory);\n if (resolved !== undefined) return resolved;\n const single = resolvers.localEntry(specifier, baseDirectory);\n return single ? [single] : undefined;\n}\n\n/** Resolves one layer's extension and package entries to absolute paths. */\nexport function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[] {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const entries: string[] = [];\n for (const entry of layer.extensions ?? []) {\n if (!isLocalPackageSpecifier(entry)) {\n entries.push(resolvers.ownEntry(entry));\n continue;\n }\n const resolved = resolveLocalEntries(resolvers, entry, layer.baseDirectory);\n if (!resolved?.length) {\n throw new Error(\n `Layer \"${name}\" extension \"${entry}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at a Pi extension file or directory.',\n );\n }\n entries.push(...resolved);\n }\n for (const entry of layer.packages ?? []) {\n const specifier = typeof entry === 'string' ? entry : entry.name;\n const optional = typeof entry === 'string' ? false : entry.optional === true;\n if (isLocalPackageSpecifier(specifier)) {\n const resolved = resolveLocalEntries(resolvers, specifier, layer.baseDirectory);\n if (resolved?.length) entries.push(...resolved);\n else if (!optional) {\n throw new Error(\n `Layer \"${name}\" package \"${specifier}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at an extension file, or a directory whose package.json declares pi.extensions.',\n );\n }\n continue;\n }\n if (optional) {\n let resolved = resolvers.optionalPackageEntries?.(specifier);\n if (resolved === undefined) {\n const single = resolvers.optionalPackageEntry(specifier);\n resolved = single ? [single] : undefined;\n }\n if (resolved) entries.push(...resolved);\n continue;\n }\n const resolved = resolvers.packageEntries?.(specifier) ?? [resolvers.packageEntry(specifier)];\n if (resolved.length === 0) {\n throw new Error(`Layer \"${name}\" package \"${specifier}\" declares no Pi extensions.`);\n }\n entries.push(...resolved);\n }\n return entries;\n}\n\n/** Hook group ids contributed by the selected layers, deduped. */\nexport function layerHookGroups(config: MajorModesConfig, names: string[]): string[] {\n const groups = new Set<string>();\n for (const name of names) {\n for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);\n }\n return [...groups];\n}\n\n/**\n * Suppress layers that exist to contribute hook groups when hooks are disabled.\n *\n * Lives beside layerHookGroups because it is the inverse question about the same\n * field, and because every caller that resolves layers has to ask it.\n */\nexport function filterHookDisabledLayers(\n config: MajorModesConfig,\n layers: readonly string[],\n hooks: boolean,\n): string[] {\n if (hooks) return [...layers];\n return layers.filter((layer) => (config.layers[layer]?.hookGroups?.length ?? 0) === 0);\n}\n\n/**\n * Reads layers and major modes, tolerating unknown keys.\n *\n * `po sync` uses this so a modes.yaml written against a different set of\n * layer packages cannot break a build. Every other caller keeps the strict\n * `loadMajorModesConfig`, and `po doctor` still reports what was tolerated.\n */\nexport function loadMajorModesConfigLenient(\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): { config: MajorModesConfig; diagnostics: ConfigDiagnostic[] } {\n const diagnostics: ConfigDiagnostic[] = [];\n const previous = unknownKeySink;\n unknownKeySink = diagnostics;\n try {\n return { config: loadMajorModesConfig(repoRoot, homeDirectory, environment), diagnostics };\n } finally {\n unknownKeySink = previous;\n }\n}\n"],"mappings":";;;;AA2FA,MAAM,aAAa;AACnB,MAAM,sBAAsB;AAC5B,MAAM,4BAA4B,KAAK,KAAA,OAAe,UAAU;AAChE,MAAM,oBAAoB,CAAC,MAAM,KAAK;AACtC,MAAM,eAAe,CAAC,UAAU;;;;;;;AAQhC,SAAgB,wBAAwB,WAA4B;CAClE,OAAO,KAAK,WAAW,SAAS,KAAK,kBAAkB,MAAM,WAAW,UAAU,WAAW,MAAM,CAAC;AACtG;AACA,MAAM,qBAAqB;CAAC;CAAQ;CAAY;AAAQ;AACxD,MAAM,kBAAkB,CAAC,eAAe,QAAQ;AAEhD,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;;;;;AAQA,IAAI;AAEJ,SAAS,gBAAgB,OAAgC,MAAyB,UAAwB;CACxG,MAAM,cAAc,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,QAAQ,CAAC,KAAK,SAAS,GAAG,CAAC;CAC1E,IAAI,YAAY,WAAW,GAAG;CAC9B,IAAI,mBAAmB,KAAA,GAAW;EAChC,KAAK,MAAM,OAAO,aAChB,eAAe,KAAK;GAClB,UAAU;GACV,MAAM;GACN,SAAS,GAAG,SAAS;EACvB,CAAC;EAEH;CACF;CACA,MAAM,IAAI,MAAM,GAAG,SAAS,6BAA6B,YAAY,KAAK,IAAI,GAAG;AACnF;AAEA,SAAS,kBAAkB,WAAmB,OAAgB,OAAsC;CAClG,MAAM,WAAW,UAAU,UAAU,YAAY,MAAM,OAAO;CAC9D,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,CAAC,MAAM,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,uCAAuC;EACtF,OAAO,MAAM,KAAK;CACpB;CACA,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,uCAAuC;CACzF,gBAAgB,OAAO,oBAAoB,QAAQ;CACnD,IAAI,OAAO,MAAM,SAAS,YAAY,CAAC,MAAM,KAAK,KAAK,GACrD,MAAM,IAAI,MAAM,GAAG,SAAS,iCAAiC;CAE/D,IAAI,MAAM,aAAa,KAAA,KAAa,OAAO,MAAM,aAAa,WAC5D,MAAM,IAAI,MAAM,GAAG,SAAS,4BAA4B;CAE1D,IAAI,MAAM,WAAW,KAAA,KAAa,CAAC,SAAS,MAAM,MAAM,GACtD,MAAM,IAAI,MAAM,GAAG,SAAS,0BAA0B;CAExD,OAAO;EACL,MAAM,MAAM,KAAK,KAAK;EACtB,GAAI,MAAM,aAAa,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;EACpD,GAAI,MAAM,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE,IAAI,CAAC;CACxD;AACF;AAEA,SAAS,qBAAqB,WAAmB,OAAsC;CACrF,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,MAAM,WAAW,UAAU,UAAU,kBAAkB;CACvD,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,kBAAkB;CACzE,OAAO,MAAM,KAAK,OAAO,UAAU;EACjC,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,KAAK,GAC3C,MAAM,IAAI,MAAM,GAAG,SAAS,GAAG,MAAM,6BAA6B;EAEpE,OAAO,MAAM,KAAK;CACpB,CAAC;AACH;AAEA,SAAS,mBAAmB,WAAmB,OAA0D;CACvG,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,MAAM,IAAI,MAAM,UAAU,UAAU,gBAAgB,0BAA0B,kBAAkB;CAElG,OAAO,MAAM,KAAK,OAAO,UAAU,kBAAkB,WAAW,OAAO,KAAK,CAAC;AAC/E;AAEA,SAAS,sBAAsB,OAAwB;CACrD,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,KAAK,GAC3C,MAAM,IAAI,MAAM,uBAAuB,0BAA0B,4BAA4B;CAE/F,OAAO,MAAM,KAAK;AACpB;AAEA,SAAS,qBAAqB,UAAkB,OAA0B;CACxE,MAAM,WAAW,eAAe,SAAS,cAAc;CACvD,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,kBAAkB;CACzE,OAAO,MAAM,KAAK,WAAW,UAAU;EACrC,IAAI,OAAO,cAAc,YAAY,CAAC,UAAU,KAAK,GACnD,MAAM,IAAI,MAAM,GAAG,SAAS,GAAG,MAAM,6BAA6B;EAEpE,OAAO,UAAU,KAAK;CACxB,CAAC;AACH;AAEA,SAAS,2BAA2B,QAAmC;CACrE,OAAO,OAAO,SAAS,IAAI,gBAAgB,OAAO,KAAK,IAAI,EAAE,KAAK;AACpE;AAEA,SAAS,eAAe,MAAc,OAAqC;CACzE,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,MAAM,SAAS,qBAAqB,MAAM,KAAK;EAC/C,OAAO;GAAE,aAAa,2BAA2B,MAAM;GAAG;EAAO;CACnE;CAEA,MAAM,WAAW,eAAe,KAAK,OAAO;CAC5C,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,+CAA+C;CACjG,gBAAgB,OAAO,iBAAiB,QAAQ;CAChD,IAAI,OAAO,MAAM,gBAAgB,YAAY,CAAC,MAAM,YAAY,KAAK,GACnE,MAAM,IAAI,MAAM,GAAG,SAAS,wCAAwC;CAEtE,OAAO;EACL,aAAa,MAAM,YAAY,KAAK;EACpC,QAAQ,qBAAqB,MAAM,MAAM,MAAM;CACjD;AACF;AAEA,SAAS,gBAAgB,OAA4D;CACnF,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,gBAAgB,0BAA0B,mBAAmB;CACnG,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAChD,MACA,eAAe,OAAO,OAAO,eAAe,MAAM,UAAU,CAC9D,CAAC,CACH;AACF;AAEA,SAAS,WAAW,MAAc,YAAsC;CACtE,IAAI,CAAC,SAAS,UAAU,GAAG,MAAM,IAAI,MAAM,UAAU,KAAK,OAAO,0BAA0B,mBAAmB;CAC9G,IAAI,aAAa,YACf,MAAM,IAAI,MACR,UAAU,KAAK,OAAO,0BAA0B,uEAClD;CAEF,IAAI,YAAY,YACd,MAAM,IAAI,MACR,UAAU,KAAK,OAAO,0BAA0B,+EAClD;CAEF,MAAM,aAAa,qBAAqB,MAAM,WAAW,UAAU;CACnE,MAAM,WAAW,mBAAmB,MAAM,WAAW,QAAQ;CAC7D,OAAO;EACL,GAAG;EACH,GAAI,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW;EACjD,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;CAC/C;AACF;AAEA,SAAS,YAAY,OAAwD;CAC3E,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,aAAa,0BAA0B,mBAAmB;CAChG,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAChD,MACA,eAAe,OAAO,OAAO,WAAW,MAAM,UAAU,CAC1D,CAAC,CACH;AACF;AAEA,SAAS,aAAa,OAAiC;CACrD,MAAM,WAAW,cAAc;CAC/B,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,iCAAiC;CACnF,gBAAgB,OAAO,cAAc,QAAQ;CAC7C,IAAI,CAAC,OAAO,OAAO,OAAO,UAAU,GAClC,MAAM,IAAI,MAAM,+BAA+B,0BAA0B,kBAAkB;CAG7F,OAAO,EAAE,UADQ,mBAAmB,WAAW,MAAM,QACrC,EAAE;AACpB;;;;;;;;;AAUA,SAAgB,qBACd,UACA,gBAAwB,GAAG,QAAQ,GACnC,cAAiC,QAAQ,KACvB;CAClB,MAAM,UAAU,sBAAqC,YAAY,UAAU,aAAa;CACxF,IAAI;CACJ,MAAM,SAAkD,CAAC;CACzD,MAAM,YAAiD,CAAC;CACxD,MAAM,mBAAyD,CAAC;CAChE,IAAI,mBAAmB;CACvB,IAAI;CACJ,IAAI,uBAAuB;CAC3B,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,OAAO,OAAO,OAAO,UAAU,SAAS,GAC1C,oBAAoB;GAClB,GAAG,aAAa,OAAO,SAAS,OAAO;GACvC,eAAe,OAAO;GACtB,UAAU,OAAO;EACnB;EAEF,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,YAAY,OAAO,SAAS,MAAM,CAAC,GAAG;GACpF,IAAI,eAAe,MAAM;IACvB,OAAO,OAAO;IACd;GACF;GACA,OAAO,QAAQ;IACb,GAAG;IACH,eAAe,OAAO;IACtB,UAAU,OAAO;GACnB;EACF;EACA,IAAI,OAAO,OAAO,OAAO,UAAU,kBAAkB,GAAG;GACtD,mBAAmB,sBAAsB,OAAO,SAAS,gBAAgB;GACzE,yBAAyB;IAAE,UAAU,OAAO;IAAU,eAAe,OAAO;GAAc;GAC1F,uBAAuB;EACzB;EACA,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,gBAAgB,OAAO,SAAS,SAAS,CAAC,GAAG;GAC3F,IAAI,eAAe,MAAM;IACvB,OAAO,UAAU;IACjB,OAAO,iBAAiB;IACxB;GACF;GACA,UAAU,QAAQ;GAClB,iBAAiB,QAAQ;IAAE,UAAU,OAAO;IAAU,eAAe,OAAO;GAAc;EAC5F;CACF;CAEA,KAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,SAAS,GAC3D,KAAK,MAAM,QAAQ,WAAW,QAC5B,IAAI,CAAC,OAAO,OACV,MAAM,IAAI,MAAM,kBAAkB,KAAK,iBAAiB,SAAS,MAAM,2BAA2B;CAIxG,IAAI,wBAAwB,CAAC,OAAO,OAAO,WAAW,gBAAgB,GACpE,MAAM,IAAI,MAAM,+BAA+B,iBAAiB,OAAO,2BAA2B;CAEpG,IAAI,YAAY,oBAAoB,WAAW;EAC7C,MAAM,qBAAqB;EAC3B,MAAM,WAAW,mBAAmB,YAAY,CAAC;EACjD,IAAI,CAAC,SAAS,MAAM,WAAW,OAAO,UAAU,WAAW,QAAQ,MAAM,UAAU,kBAAkB,GACnG,oBAAoB;GAClB,GAAI,qBAAqB,EAAE,eAAe,SAAS;GACnD,UAAU,CAAC,GAAG,UAAU,kBAAkB;EAC5C;CAEJ;CACA,OAAO;EACL,GAAI,oBAAoB,EAAE,SAAS,kBAAkB,IAAI,CAAC;EAC1D;EACA;EACA,GAAI,yBAAyB,EAAE,uBAAuB,IAAI,CAAC;EAC3D;EACA;CACF;AACF;;AAGA,SAAgB,6BACd,QACA,OACA,aACgC;CAChC,MAAM,wBAAwB,YAAY,KAAK;CAC/C,IAAI,CAAC,uBAAuB,MAAM,IAAI,MAAM,yCAAyC;CACrF,MAAM,iBAAiD,CAAC;CACxD,MAAM,cAA4E,CAAC;CACnF,IAAI,OAAO,SAAS,YAAY,KAAK;EAAE,MAAM;EAAW,YAAY,OAAO;CAAQ,CAAC;CACpF,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAa,OAAO,OAAO;EACjC,IAAI,CAAC,YAAY,MAAM,IAAI,MAAM,kBAAkB,MAAM;EACzD,YAAY,KAAK;GAAE;GAAM;EAAW,CAAC;CACvC;CACA,KAAK,MAAM,EAAE,MAAM,gBAAgB,aACjC,KAAK,MAAM,SAAS,WAAW,YAAY,CAAC,GAAG;EAC7C,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAA,GAAW;EAC7D,IAAI,MAAM,SAAS,yBAAyB,CAAC,MAAM,KAAK,WAAW,GAAG,sBAAsB,EAAE,GAAG;EACjG,eAAe,KAAK;GAClB,OAAO;GACP,WAAW,MAAM;GACjB,QAAQ,EAAE,GAAG,MAAM,OAAO;GAC1B,eAAe,WAAW;GAC1B,GAAI,WAAW,WAAW,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;EACjE,CAAC;CACH;CAEF,OAAO;AACT;;AAGA,SAAgB,cAAc,QAA0B,WAA6B;CACnF,IAAI,CAAC,OAAO,OAAO,OAAO,WAAW,SAAS,GAC5C,MAAM,IAAI,MACR,uBAAuB,UAAU,uBAAuB,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,GACxG;CAEF,OAAO,CAAC,GAAG,OAAO,UAAU,UAAU,CAAE,MAAM;AAChD;AAEA,SAAS,oBACP,WACA,WACA,eACsB;CACtB,MAAM,WAAW,UAAU,eAAe,WAAW,aAAa;CAClE,IAAI,aAAa,KAAA,GAAW,OAAO;CACnC,MAAM,SAAS,UAAU,WAAW,WAAW,aAAa;CAC5D,OAAO,SAAS,CAAC,MAAM,IAAI,KAAA;AAC7B;;AAGA,SAAgB,aAAa,QAA0B,MAAc,WAAqC;CACxG,MAAM,QAAQ,OAAO,OAAO;CAC5B,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,kBAAkB,MAAM;CACpD,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,SAAS,MAAM,cAAc,CAAC,GAAG;EAC1C,IAAI,CAAC,wBAAwB,KAAK,GAAG;GACnC,QAAQ,KAAK,UAAU,SAAS,KAAK,CAAC;GACtC;EACF;EACA,MAAM,WAAW,oBAAoB,WAAW,OAAO,MAAM,aAAa;EAC1E,IAAI,CAAC,UAAU,QACb,MAAM,IAAI,MACR,UAAU,KAAK,eAAe,MAAM,2BAA2B,MAAM,cAAc,gDAErF;EAEF,QAAQ,KAAK,GAAG,QAAQ;CAC1B;CACA,KAAK,MAAM,SAAS,MAAM,YAAY,CAAC,GAAG;EACxC,MAAM,YAAY,OAAO,UAAU,WAAW,QAAQ,MAAM;EAC5D,MAAM,WAAW,OAAO,UAAU,WAAW,QAAQ,MAAM,aAAa;EACxE,IAAI,wBAAwB,SAAS,GAAG;GACtC,MAAM,WAAW,oBAAoB,WAAW,WAAW,MAAM,aAAa;GAC9E,IAAI,UAAU,QAAQ,QAAQ,KAAK,GAAG,QAAQ;QACzC,IAAI,CAAC,UACR,MAAM,IAAI,MACR,UAAU,KAAK,aAAa,UAAU,2BAA2B,MAAM,cAAc,2FAEvF;GAEF;EACF;EACA,IAAI,UAAU;GACZ,IAAI,WAAW,UAAU,yBAAyB,SAAS;GAC3D,IAAI,aAAa,KAAA,GAAW;IAC1B,MAAM,SAAS,UAAU,qBAAqB,SAAS;IACvD,WAAW,SAAS,CAAC,MAAM,IAAI,KAAA;GACjC;GACA,IAAI,UAAU,QAAQ,KAAK,GAAG,QAAQ;GACtC;EACF;EACA,MAAM,WAAW,UAAU,iBAAiB,SAAS,KAAK,CAAC,UAAU,aAAa,SAAS,CAAC;EAC5F,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,UAAU,KAAK,aAAa,UAAU,6BAA6B;EAErF,QAAQ,KAAK,GAAG,QAAQ;CAC1B;CACA,OAAO;AACT;;AAGA,SAAgB,gBAAgB,QAA0B,OAA2B;CACnF,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,SAAS,OAAO,OAAO,KAAK,EAAE,cAAc,CAAC,GAAG,OAAO,IAAI,KAAK;CAE7E,OAAO,CAAC,GAAG,MAAM;AACnB;;;;;;;AAQA,SAAgB,yBACd,QACA,QACA,OACU;CACV,IAAI,OAAO,OAAO,CAAC,GAAG,MAAM;CAC5B,OAAO,OAAO,QAAQ,WAAW,OAAO,OAAO,MAAM,EAAE,YAAY,UAAU,OAAO,CAAC;AACvF;;;;;;;;AASA,SAAgB,4BACd,UACA,gBAAwB,GAAG,QAAQ,GACnC,cAAiC,QAAQ,KACsB;CAC/D,MAAM,cAAkC,CAAC;CACzC,MAAM,WAAW;CACjB,iBAAiB;CACjB,IAAI;EACF,OAAO;GAAE,QAAQ,qBAAqB,UAAU,eAAe,WAAW;GAAG;EAAY;CAC3F,UAAU;EACR,iBAAiB;CACnB;AACF"}
|