agents-inc 0.171.0 → 0.173.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/CHANGELOG.md +31 -0
- package/dist/{chunk-W4KAY26P.js → chunk-2RTBSLSR.js} +12 -3
- package/dist/{chunk-W4KAY26P.js.map → chunk-2RTBSLSR.js.map} +1 -1
- package/dist/{chunk-WM2N2D6Q.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-WM2N2D6Q.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-ZC6GC66J.js → chunk-3R3LHA4Q.js} +2 -2
- package/dist/{chunk-24OD7IP4.js → chunk-7OG635DK.js} +26 -4
- package/dist/chunk-7OG635DK.js.map +1 -0
- package/dist/{chunk-WDH6HHA3.js → chunk-A3ZAXL5T.js} +4 -5
- package/dist/{chunk-WDH6HHA3.js.map → chunk-A3ZAXL5T.js.map} +1 -1
- package/dist/{chunk-KMOCMVK5.js → chunk-AARQBW5L.js} +106 -60
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-WII6GOPM.js → chunk-BRZA7ZCX.js} +52 -31
- package/dist/chunk-BRZA7ZCX.js.map +1 -0
- package/dist/{chunk-AWWCRL5A.js → chunk-EHJIQDXR.js} +8 -6
- package/dist/{chunk-AWWCRL5A.js.map → chunk-EHJIQDXR.js.map} +1 -1
- package/dist/{chunk-RDXY4GRO.js → chunk-F437ICEG.js} +2 -2
- package/dist/chunk-G7NUK3BF.js +253 -0
- package/dist/chunk-G7NUK3BF.js.map +1 -0
- package/dist/{chunk-7IVLVEHX.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-QIR56IDM.js → chunk-LJQXQTFC.js} +29 -102
- package/dist/chunk-LJQXQTFC.js.map +1 -0
- package/dist/{chunk-A6OWEJGC.js → chunk-MHAQWMNJ.js} +35 -5
- package/dist/{chunk-A6OWEJGC.js.map → chunk-MHAQWMNJ.js.map} +1 -1
- package/dist/{chunk-YLUOGAW7.js → chunk-N33AKFLR.js} +2 -2
- package/dist/{chunk-TNFYBKVD.js → chunk-Q4UNHVPX.js} +25 -14
- package/dist/chunk-Q4UNHVPX.js.map +1 -0
- package/dist/chunk-Q6WRR4BN.js +195 -0
- package/dist/chunk-Q6WRR4BN.js.map +1 -0
- package/dist/{chunk-JGPE4RRE.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-EOKNEGRD.js → chunk-VR6QTK5Z.js} +8 -8
- package/dist/{chunk-S2SKVJT2.js → chunk-VSPC74SS.js} +48 -26
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-3YYHL76L.js → chunk-WVFBBZEP.js} +648 -394
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +16 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +87 -86
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +150 -152
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +25 -30
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +19 -16
- package/dist/commands/list.js +14 -17
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +15 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +11 -11
- package/dist/commands/uninstall.js +145 -130
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/components/common/scroll-affordance.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +3 -4
- package/dist/components/common/summary-panel.js +11 -146
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/hooks/init.js +39 -27
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-IQANWGOP.js → recompile-project-agents-6G6M2RS6.js} +8 -8
- package/dist/{source-loader-YGG7DY2W.js → source-loader-W7XCNKNA.js} +4 -4
- package/dist/src/agents/tester/web-tester/playbook.md +1 -1
- package/package.json +1 -1
- package/src/agents/tester/web-tester/playbook.md +1 -1
- package/dist/chunk-24OD7IP4.js.map +0 -1
- package/dist/chunk-3YYHL76L.js.map +0 -1
- package/dist/chunk-4RQKCV6I.js +0 -103
- package/dist/chunk-4RQKCV6I.js.map +0 -1
- package/dist/chunk-5FM77WKW.js +0 -69
- package/dist/chunk-5FM77WKW.js.map +0 -1
- package/dist/chunk-KMOCMVK5.js.map +0 -1
- package/dist/chunk-QIR56IDM.js.map +0 -1
- package/dist/chunk-R572RLTI.js +0 -108
- package/dist/chunk-R572RLTI.js.map +0 -1
- package/dist/chunk-S2SKVJT2.js.map +0 -1
- package/dist/chunk-TNFYBKVD.js.map +0 -1
- package/dist/chunk-WII6GOPM.js.map +0 -1
- package/dist/components/common/removal-plan-confirm.js +0 -10
- package/dist/load-agent-defs-UBWITIEI.js +0 -14
- package/dist/source-loader-YGG7DY2W.js.map +0 -1
- /package/dist/{chunk-ZC6GC66J.js.map → chunk-3R3LHA4Q.js.map} +0 -0
- /package/dist/{chunk-RDXY4GRO.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-7IVLVEHX.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-YLUOGAW7.js.map → chunk-N33AKFLR.js.map} +0 -0
- /package/dist/{chunk-JGPE4RRE.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-EOKNEGRD.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-IQANWGOP.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{load-agent-defs-UBWITIEI.js.map → source-loader-W7XCNKNA.js.map} +0 -0
package/dist/chunk-R572RLTI.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
computeScopeDiff
|
|
4
|
-
} from "./chunk-4RQKCV6I.js";
|
|
5
|
-
import {
|
|
6
|
-
getSkillDisplayName
|
|
7
|
-
} from "./chunk-24OD7IP4.js";
|
|
8
|
-
import {
|
|
9
|
-
CLI_COLORS,
|
|
10
|
-
EJECT_SOURCE,
|
|
11
|
-
UI_SYMBOLS
|
|
12
|
-
} from "./chunk-A6OWEJGC.js";
|
|
13
|
-
|
|
14
|
-
// src/cli/components/common/skill-agent-summary.tsx
|
|
15
|
-
import { Box, Text } from "ink";
|
|
16
|
-
import "react";
|
|
17
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
-
var TableHeader = ({ children }) => /* @__PURE__ */ jsx(Text, { bold: true, color: CLI_COLORS.WARNING, children });
|
|
19
|
-
var ScopeLabel = ({ children }) => /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WHITE, backgroundColor: CLI_COLORS.LABEL_BG, children: ` ${children} ` });
|
|
20
|
-
var EjectIcon = () => /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.WARNING, children: [
|
|
21
|
-
" ",
|
|
22
|
-
UI_SYMBOLS.EJECT
|
|
23
|
-
] });
|
|
24
|
-
var DIFF_PREFIX = {
|
|
25
|
-
added: `${UI_SYMBOLS.ADDED} `,
|
|
26
|
-
"mode-changed": "~ ",
|
|
27
|
-
removed: `${UI_SYMBOLS.REMOVED} `,
|
|
28
|
-
unchanged: `${UI_SYMBOLS.BULLET} `
|
|
29
|
-
};
|
|
30
|
-
var DIFF_COLOR = {
|
|
31
|
-
added: CLI_COLORS.SUCCESS,
|
|
32
|
-
"mode-changed": CLI_COLORS.WARNING,
|
|
33
|
-
removed: CLI_COLORS.ERROR,
|
|
34
|
-
unchanged: CLI_COLORS.NEUTRAL
|
|
35
|
-
};
|
|
36
|
-
var SkillRow = ({ row }) => /* @__PURE__ */ jsxs(Box, { width: "50%", flexDirection: "row", children: [
|
|
37
|
-
/* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
|
|
38
|
-
DIFF_PREFIX[row.status],
|
|
39
|
-
getSkillDisplayName(row.id)
|
|
40
|
-
] }),
|
|
41
|
-
row.source === EJECT_SOURCE && /* @__PURE__ */ jsx(EjectIcon, {})
|
|
42
|
-
] });
|
|
43
|
-
var AgentRow = ({ row }) => /* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
|
|
44
|
-
DIFF_PREFIX[row.status],
|
|
45
|
-
row.name
|
|
46
|
-
] });
|
|
47
|
-
var skillRowKey = (row) => row.status === "removed" ? `removed-${row.id}` : row.id;
|
|
48
|
-
var agentRowKey = (row) => row.status === "removed" ? `removed-${row.name}` : row.name;
|
|
49
|
-
var SkillAgentSummary = ({
|
|
50
|
-
skillConfigs,
|
|
51
|
-
agentConfigs,
|
|
52
|
-
installedSkillConfigs,
|
|
53
|
-
installedAgentConfigs,
|
|
54
|
-
isInitMode
|
|
55
|
-
}) => {
|
|
56
|
-
const diff = computeScopeDiff({
|
|
57
|
-
currentSkills: skillConfigs,
|
|
58
|
-
currentAgents: agentConfigs,
|
|
59
|
-
installedSkillConfigs,
|
|
60
|
-
installedAgentConfigs,
|
|
61
|
-
isInitMode
|
|
62
|
-
});
|
|
63
|
-
if (!diff.hasContent) return null;
|
|
64
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", width: "100%", children: [
|
|
65
|
-
/* @__PURE__ */ jsxs(
|
|
66
|
-
Box,
|
|
67
|
-
{
|
|
68
|
-
flexDirection: "column",
|
|
69
|
-
borderStyle: "single",
|
|
70
|
-
flexGrow: 2,
|
|
71
|
-
flexBasis: 0,
|
|
72
|
-
borderRight: true,
|
|
73
|
-
borderTop: false,
|
|
74
|
-
borderBottom: false,
|
|
75
|
-
borderLeft: false,
|
|
76
|
-
borderColor: CLI_COLORS.NEUTRAL,
|
|
77
|
-
borderRightDimColor: true,
|
|
78
|
-
children: [
|
|
79
|
-
/* @__PURE__ */ jsx(TableHeader, { children: "Skills" }),
|
|
80
|
-
diff.projectSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
81
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
|
|
82
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
83
|
-
] }),
|
|
84
|
-
diff.globalSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
85
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
|
|
86
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
87
|
-
] })
|
|
88
|
-
]
|
|
89
|
-
}
|
|
90
|
-
),
|
|
91
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, flexBasis: 0, marginLeft: 1, paddingLeft: 1, children: [
|
|
92
|
-
/* @__PURE__ */ jsx(TableHeader, { children: "Agents" }),
|
|
93
|
-
diff.projectAgentRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
94
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
|
|
95
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: diff.projectAgentRows.map((row) => /* @__PURE__ */ jsx(AgentRow, { row }, agentRowKey(row))) })
|
|
96
|
-
] }),
|
|
97
|
-
diff.globalAgentRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
98
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
|
|
99
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: diff.globalAgentRows.map((row) => /* @__PURE__ */ jsx(AgentRow, { row }, agentRowKey(row))) })
|
|
100
|
-
] })
|
|
101
|
-
] })
|
|
102
|
-
] });
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export {
|
|
106
|
-
SkillAgentSummary
|
|
107
|
-
};
|
|
108
|
-
//# sourceMappingURL=chunk-R572RLTI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/components/common/skill-agent-summary.tsx"],"sourcesContent":["import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport { CLI_COLORS, EJECT_SOURCE, UI_SYMBOLS } from \"../../consts.js\";\nimport { computeScopeDiff } from \"../../lib/configuration/scope-diff.js\";\nimport type {\n AgentDiffRow,\n DiffRowStatus,\n ScopeDiffInput,\n SkillDiffRow,\n} from \"../../lib/configuration/scope-diff.js\";\nimport { getSkillDisplayName } from \"../../lib/matrix/matrix-provider.js\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config.js\";\n\nexport type SkillAgentSummaryProps = Pick<\n ScopeDiffInput,\n \"installedSkillConfigs\" | \"installedAgentConfigs\" | \"isInitMode\"\n> & {\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n};\n\nconst TableHeader: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <Text bold color={CLI_COLORS.WARNING}>\n {children}\n </Text>\n);\n\nconst ScopeLabel: React.FC<{ children: string }> = ({ children }) => (\n <Text color={CLI_COLORS.WHITE} backgroundColor={CLI_COLORS.LABEL_BG}>\n {` ${children} `}\n </Text>\n);\n\nconst EjectIcon: React.FC = () => <Text color={CLI_COLORS.WARNING}> {UI_SYMBOLS.EJECT}</Text>;\n\nconst DIFF_PREFIX: Record<DiffRowStatus, string> = {\n added: `${UI_SYMBOLS.ADDED} `,\n \"mode-changed\": \"~ \",\n removed: `${UI_SYMBOLS.REMOVED} `,\n unchanged: `${UI_SYMBOLS.BULLET} `,\n};\n\nconst DIFF_COLOR: Record<DiffRowStatus, string> = {\n added: CLI_COLORS.SUCCESS,\n \"mode-changed\": CLI_COLORS.WARNING,\n removed: CLI_COLORS.ERROR,\n unchanged: CLI_COLORS.NEUTRAL,\n};\n\nconst SkillRow: React.FC<{ row: SkillDiffRow }> = ({ row }) => (\n <Box width=\"50%\" flexDirection=\"row\">\n <Text color={DIFF_COLOR[row.status]}>\n {DIFF_PREFIX[row.status]}\n {getSkillDisplayName(row.id)}\n </Text>\n {row.source === EJECT_SOURCE && <EjectIcon />}\n </Box>\n);\n\nconst AgentRow: React.FC<{ row: AgentDiffRow }> = ({ row }) => (\n <Text color={DIFF_COLOR[row.status]}>\n {DIFF_PREFIX[row.status]}\n {row.name}\n </Text>\n);\n\nconst skillRowKey = (row: SkillDiffRow): string =>\n row.status === \"removed\" ? `removed-${row.id}` : row.id;\n\nconst agentRowKey = (row: AgentDiffRow): string =>\n row.status === \"removed\" ? `removed-${row.name}` : row.name;\n\nexport const SkillAgentSummary: React.FC<SkillAgentSummaryProps> = ({\n skillConfigs,\n agentConfigs,\n installedSkillConfigs,\n installedAgentConfigs,\n isInitMode,\n}) => {\n const diff = computeScopeDiff({\n currentSkills: skillConfigs,\n currentAgents: agentConfigs,\n installedSkillConfigs,\n installedAgentConfigs,\n isInitMode,\n });\n\n if (!diff.hasContent) return null;\n\n return (\n <Box flexDirection=\"row\" width=\"100%\">\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n flexGrow={2}\n flexBasis={0}\n borderRight={true}\n borderTop={false}\n borderBottom={false}\n borderLeft={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderRightDimColor\n >\n <TableHeader>Skills</TableHeader>\n {diff.projectSkillRows.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <ScopeLabel>Project</ScopeLabel>\n <Box flexWrap=\"wrap\">\n {diff.projectSkillRows.map((row) => (\n <SkillRow key={skillRowKey(row)} row={row} />\n ))}\n </Box>\n </Box>\n )}\n {diff.globalSkillRows.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <ScopeLabel>Global</ScopeLabel>\n <Box flexWrap=\"wrap\">\n {diff.globalSkillRows.map((row) => (\n <SkillRow key={skillRowKey(row)} row={row} />\n ))}\n </Box>\n </Box>\n )}\n </Box>\n <Box flexDirection=\"column\" flexGrow={1} flexBasis={0} marginLeft={1} paddingLeft={1}>\n <TableHeader>Agents</TableHeader>\n {diff.projectAgentRows.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <ScopeLabel>Project</ScopeLabel>\n <Box flexDirection=\"column\">\n {diff.projectAgentRows.map((row) => (\n <AgentRow key={agentRowKey(row)} row={row} />\n ))}\n </Box>\n </Box>\n )}\n {diff.globalAgentRows.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <ScopeLabel>Global</ScopeLabel>\n <Box flexDirection=\"column\">\n {diff.globalAgentRows.map((row) => (\n <AgentRow key={agentRowKey(row)} row={row} />\n ))}\n </Box>\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/operations/source/load-source.ts","../src/cli/lib/operations/project/detect-project.ts","../src/cli/lib/operations/project/detect-both-installations.ts","../src/cli/lib/config-gate/propagate.ts","../../compile/src/config-types-source.ts","../src/cli/lib/configuration/config-types-io.ts","../../compile/src/global-config.ts","../src/cli/lib/config-gate/index.ts","../src/cli/lib/config-gate/classify.ts","../src/cli/lib/config-gate/deps.ts","../src/cli/lib/config-gate/pair-writer.ts","../src/cli/lib/config-gate/recompile.ts","../src/cli/lib/config-gate/pair-snapshot.ts","../src/cli/lib/operations/project/write-project-config.ts","../src/cli/lib/operations/project/compile-agents-all-scopes.ts"],"sourcesContent":["import { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../../loading/index.js\";\nimport type { SourceCaller } from \"../../configuration/index.js\";\nimport {\n enableBuffering,\n drainBuffer,\n disableBuffering,\n warn,\n type StartupMessage,\n} from \"../../../utils/logger.js\";\n\nexport type LoadSourceOptions = {\n caller?: SourceCaller;\n sourceFlag?: string;\n projectDir: string;\n /** Captures warn() output during the load instead of writing it to stderr. */\n captureStartupMessages?: boolean;\n};\n\nexport type LoadedSource = {\n sourceResult: SourceLoadResult;\n startupMessages: StartupMessage[];\n};\n\nexport async function loadSource(options: LoadSourceOptions): Promise<LoadedSource> {\n const { caller, sourceFlag, projectDir, captureStartupMessages } = options;\n const load = () =>\n loadSkillsMatrixFromSource({\n ...(caller !== undefined && { caller }),\n ...(sourceFlag !== undefined && { sourceFlag }),\n projectDir,\n });\n\n if (!captureStartupMessages) return { sourceResult: await load(), startupMessages: [] };\n return capturingStartupMessages(load);\n}\n\n/** Buffering ends with the load, whether it lands or throws. */\nasync function capturingStartupMessages(\n load: () => Promise<SourceLoadResult>,\n): Promise<LoadedSource> {\n enableBuffering();\n try {\n const sourceResult = await load();\n return { sourceResult, startupMessages: drainBuffer() };\n } finally {\n disableBuffering();\n }\n}\n\nexport function sayCapturedWarnings(messages: readonly StartupMessage[]): void {\n for (const { text } of messages) warn(text);\n}\n","import { detectInstallation, type Installation } from \"../../installation/index.js\";\nimport { ConfigLoadError, loadProjectConfig } from \"../../configuration/index.js\";\nimport type { ProjectConfig } from \"../../../types/index.js\";\n\nexport type DetectedProject = {\n installation: Installation;\n config: ProjectConfig | null;\n configPath: string | null;\n};\n\n/** Degrades: a corrupt config answers null, as a missing installation does. */\nexport async function detectProject(projectDir?: string): Promise<DetectedProject | null> {\n const resolvedDir = projectDir ?? process.cwd();\n\n let installation: Installation | null;\n try {\n installation = await detectInstallation(resolvedDir);\n } catch (error) {\n if (error instanceof ConfigLoadError) return null;\n throw error;\n }\n\n if (!installation) {\n return null;\n }\n\n const loaded = await loadProjectConfig(installation.projectDir);\n\n return {\n installation,\n config: loaded?.config ?? null,\n configPath: loaded?.configPath ?? null,\n };\n}\n","import {\n detectGlobalInstallation,\n detectProjectInstallation,\n isHomeDirectory,\n type Installation,\n} from \"../../installation/index.js\";\n\nexport type BothInstallations = {\n global: Installation | null;\n project: Installation | null;\n hasBoth: boolean;\n};\n\n/** Skips project detection in the home directory, where it would double-compile the global. */\nexport async function detectBothInstallations(projectDir: string): Promise<BothInstallations> {\n const global = await detectGlobalInstallation();\n\n const project = isHomeDirectory(projectDir) ? null : await detectProjectInstallation(projectDir);\n return { global, project, hasBoth: !!global && !!project };\n}\n","import fs from \"fs\";\nimport { isDeepEqual, unique } from \"remeda\";\nimport type {\n AgentDefinition,\n AgentName,\n Category,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillAssignment,\n SkillId,\n StackAgentConfig,\n} from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport { PROVIDERS, type Provider } from \"../../consts\";\nimport { getInstalledConfigPath, getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { providerInUse, sourceFolderInUse } from \"../installation/install-layout\";\nimport { ConfigLoadError, loadInstalledConfig } from \"../configuration/project-config\";\nimport { mergeConfigs, type AuthoritativeScope } from \"../configuration/config-merger\";\nimport {\n activeProjectAgentNames,\n isActiveAt,\n isGlobalTombstone,\n} from \"../configuration/scope-predicates\";\nimport { generateConfigSource, type ConfigSourceOptions } from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n type ConfigTypesExtras,\n deriveCategories,\n deriveDomains,\n regenerateConfigTypes,\n} from \"../configuration/config-types-writer\";\n// Inside the fan-out this is the seat `withCatalogueSeatedFor` gave the current project.\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { withCatalogueSeatedFor } from \"../loading/catalogue-seat.js\";\nimport { fileExists, writeFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\nimport { addSessionToGlobal, type ResolvedGlobalConfig } from \"@workspace/compile/global-config\";\n\nexport { mergeGlobalConfigs } from \"@workspace/compile/global-config\";\n\nexport async function writeConfigFile(\n config: ProjectConfig,\n configPath: string,\n options?: ConfigSourceOptions,\n): Promise<void> {\n const source = generateConfigSource(config, activeMatrix, options);\n await writeFile(configPath, source);\n}\n\n/** The one normalization for `projects` comparisons; resolves symlinks, throws if missing. */\nexport function normalizeProjectPath(projectDir: string): string {\n return fs.realpathSync(projectDir);\n}\n\n/** Filters stale entries whose config.ts no longer exists. */\nasync function registerProjectPath(\n globalConfig: ProjectConfig,\n projectDir: string,\n): Promise<{ config: ProjectConfig; changed: boolean }> {\n const normalizedPath = normalizeProjectPath(projectDir);\n const existing = globalConfig.projects ?? [];\n const valid = await projectsStillInstalled(existing);\n\n if (valid.includes(normalizedPath)) {\n const changed = valid.length !== existing.length;\n return { config: changed ? { ...globalConfig, projects: valid } : globalConfig, changed };\n }\n\n return { config: { ...globalConfig, projects: [...valid, normalizedPath] }, changed: true };\n}\n\nasync function projectsStillInstalled(projects: string[]): Promise<string[]> {\n const installed = await Promise.all(\n projects.map((project) => fileExists(getInstalledConfigPath(project))),\n );\n return projects.filter((_, index) => installed[index] === true);\n}\n\nfunction globalHasActiveSkill(globalConfig: ProjectConfig, id: SkillId): boolean {\n return globalConfig.skills.some((s) => s.id === id && isActiveAt(s, \"global\"));\n}\n\nfunction globalHasActiveAgent(globalConfig: ProjectConfig, name: AgentName): boolean {\n return globalConfig.agents.some((a) => a.name === name && isActiveAt(a, \"global\"));\n}\n\n/** Keeps project-scoped entries and drops tombstones whose global entry is gone. */\nfunction retainProjectOwnedSkills(\n skills: SkillConfig[],\n globalConfig: ProjectConfig,\n): SkillConfig[] {\n return skills.filter(\n (entry) =>\n entry.scope === \"project\" ||\n (isGlobalTombstone(entry) && globalHasActiveSkill(globalConfig, entry.id)),\n );\n}\n\nfunction retainProjectOwnedAgents(\n agents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n return agents.filter(\n (entry) =>\n entry.scope === \"project\" ||\n (isGlobalTombstone(entry) && globalHasActiveAgent(globalConfig, entry.name)),\n );\n}\n\n/**\n * Undefined for an id the matrix lacks or a `local` skill; neither participates in category rules.\n */\nfunction categoryOfSkill(id: SkillId, matrix: MergedSkillsMatrix): Category | undefined {\n const category = matrix.skills[id]?.category;\n if (category === undefined || category === LOCAL_PSEUDO_CATEGORY) return undefined;\n return category;\n}\n\n/** From the merged matrix, so source overrides count; an undeclared category is not exclusive. */\nfunction isExclusiveCategory(category: Category, matrix: MergedSkillsMatrix): boolean {\n return matrix.categories[category]?.exclusive === true;\n}\n\n/** Categories occupied by an active project-scoped skill, per the merged matrix. */\nfunction activeProjectCategories(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): Set<Category> {\n return new Set(\n projectOwnedSkills\n .filter((s) => isActiveAt(s, \"project\"))\n .map((s) => categoryOfSkill(s.id, matrix))\n .filter((category): category is Category => category !== undefined),\n );\n}\n\n/** IDENTITY (same id at project scope) or CATEGORY (exclusive category); shared with self-heal. */\nfunction buildProjectCollisionTest(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): (id: SkillId) => boolean {\n const ownedIds = new Set(\n projectOwnedSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n const occupiedExclusiveCategories = new Set(\n [...activeProjectCategories(projectOwnedSkills, matrix)].filter((category) =>\n isExclusiveCategory(category, matrix),\n ),\n );\n\n return (id) => {\n if (ownedIds.has(id)) return true;\n const category = categoryOfSkill(id, matrix);\n return category !== undefined && occupiedExclusiveCategories.has(category);\n };\n}\n\n/** A derived mask is byte-identical to a user tombstone, so it stays while its collision does. */\nfunction dropOrphanedDerivedMasks(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n return projectOwnedSkills.filter(\n (entry) => !isGlobalTombstone(entry) || collidesWithProjectOwnership(entry.id),\n );\n}\n\n/** Agents have no categories, so only an identity collision justifies a mask. */\nfunction dropOrphanedDerivedAgentMasks(projectOwnedAgents: AgentScopeConfig[]): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n return projectOwnedAgents.filter(\n (entry) => !isGlobalTombstone(entry) || ownedNames.has(entry.name),\n );\n}\n\n/**\n * Tombstones masking live global skills that collide with what the project owns; the project's own\n * skill wins. Spread from the global entry so they carry its `origin`. Idempotent.\n */\nfunction maskCollidingGlobalSkills(\n projectOwnedSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n const alreadyTombstoned = new Set(projectOwnedSkills.filter(isGlobalTombstone).map((s) => s.id));\n\n return globalConfig.skills\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n collidesWithProjectOwnership(globalEntry.id) &&\n !alreadyTombstoned.has(globalEntry.id),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/** Identity collisions only: agents have no categories. */\nfunction maskCollidingGlobalAgents(\n projectOwnedAgents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n const alreadyTombstoned = new Set(\n projectOwnedAgents.filter(isGlobalTombstone).map((a) => a.name),\n );\n\n return globalConfig.agents\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n ownedNames.has(globalEntry.name) &&\n !alreadyTombstoned.has(globalEntry.name),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/**\n * Run at both sites that inline `globalConfig` into a project config. Self-heal precedes masking,\n * and masking is project-local: the global config is never rewritten.\n */\nexport function reconcileProjectSplitAgainstGlobal(\n projectSplit: ProjectConfig,\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): ProjectConfig {\n const healedSkills = dropOrphanedDerivedMasks(projectSplit.skills, matrix);\n const healedAgents = dropOrphanedDerivedAgentMasks(projectSplit.agents);\n return {\n ...projectSplit,\n skills: [...healedSkills, ...maskCollidingGlobalSkills(healedSkills, globalConfig, matrix)],\n agents: [...healedAgents, ...maskCollidingGlobalAgents(healedAgents, globalConfig)],\n };\n}\n\n/**\n * Global skills the project inherited that are no longer active globally and that it does not own.\n */\nfunction computeRemovedGlobalSkillIds(\n priorProjectSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n): Set<SkillId> {\n const activeGlobalIds = new Set(\n globalConfig.skills.filter((s) => isActiveAt(s, \"global\")).map((s) => s.id),\n );\n const projectOwnedIds = new Set(\n priorProjectSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n return new Set(\n priorProjectSkills\n .filter(\n (s) => isActiveAt(s, \"global\") && !activeGlobalIds.has(s.id) && !projectOwnedIds.has(s.id),\n )\n .map((s) => s.id),\n );\n}\n\n/** Drops only the removed ids and any category or agent left empty; unchanged when none were. */\nfunction retainReconciledStack(\n stack: Record<string, StackAgentConfig> | undefined,\n removedGlobalSkillIds: Set<SkillId>,\n): Record<string, StackAgentConfig> | undefined {\n if (!stack || removedGlobalSkillIds.size === 0) return stack;\n\n const reconciled: Record<string, StackAgentConfig> = {};\n for (const [agent, agentStack] of Object.entries(stack)) {\n const reconciledAgentStack = withoutRemovedAssignments(agentStack, removedGlobalSkillIds);\n if (typedKeys<Category>(reconciledAgentStack).length > 0) {\n reconciled[agent] = reconciledAgentStack;\n }\n }\n return reconciled;\n}\n\n/** A category the pruning empties is left out. */\nfunction withoutRemovedAssignments(\n agentStack: StackAgentConfig,\n removedGlobalSkillIds: Set<SkillId>,\n): StackAgentConfig {\n const reconciledAgentStack: StackAgentConfig = {};\n for (const [category, assignments] of typedEntries<Category, SkillAssignment[]>(agentStack)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Object.entries drops the `| undefined` a Partial<Record> admits\n if (!assignments) continue;\n const kept = assignments.filter((assignment) => !removedGlobalSkillIds.has(assignment.id));\n if (kept.length > 0) reconciledAgentStack[category] = kept;\n }\n return reconciledAgentStack;\n}\n\n/** Each registered project lands in exactly one list. */\nexport type PropagationResult = {\n updated: string[];\n /** Its `config.ts` is there and cannot be loaded. */\n unreadable: string[];\n /** Nothing is installed at the registered path any more. */\n gone: string[];\n /** It holds another provider's installation, not this one's. */\n notOurs: string[];\n /** Its rewrite threw: its catalogue would not load, or its pair could not be written. */\n failed: string[];\n};\n\nexport type PropagationOptions = {\n /** False for a change that moves no type union. */\n regenerateTypes?: boolean;\n};\n\n/** The one project pair writer; extras come from the effective config so the pair agrees. */\nexport async function writeProjectConfigPair(\n projectDir: string,\n provider: Provider,\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n options: PropagationOptions = {},\n): Promise<void> {\n const configPath = refuseAWriteOutsideTheInstallation(projectDir, provider);\n\n // Both halves from the same reconciled data, so neither describes a config the other does not.\n await writeConfigFile(reconciledSplit, configPath, {\n isProjectConfig: true,\n globalConfig: effectiveGlobal,\n });\n\n if (options.regenerateTypes === false) return;\n\n // The global-aware path, so a global-scope install keeps the project's import-form types.\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(matrix, agents)),\n buildProjectTypesExtras(inlinedProjectView(reconciledSplit, effectiveGlobal), matrix),\n );\n}\n\n/** The project's own reconciled entries plus everything the global config contributes. */\nfunction inlinedProjectView(\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n): ProjectConfig {\n return {\n ...reconciledSplit,\n skills: [...effectiveGlobal.skills, ...reconciledSplit.skills],\n agents: [...effectiveGlobal.agents, ...reconciledSplit.agents],\n selectedDomains: unique([\n ...(effectiveGlobal.selectedDomains ?? []),\n ...(reconciledSplit.selectedDomains ?? []),\n ]),\n stack: { ...(effectiveGlobal.stack ?? {}), ...(reconciledSplit.stack ?? {}) },\n };\n}\n\n/** Project-scoped entries and live tombstones; `onDisk.skills` reveals just-removed globals. */\nfunction reconcileAgainstGlobal(\n onDisk: ProjectConfig,\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): ProjectConfig {\n const removedGlobalSkillIds = computeRemovedGlobalSkillIds(onDisk.skills, globalConfig);\n const reconciledStack = retainReconciledStack(onDisk.stack, removedGlobalSkillIds);\n\n return reconcileProjectSplitAgainstGlobal(\n {\n ...onDisk,\n skills: retainProjectOwnedSkills(onDisk.skills, globalConfig),\n agents: retainProjectOwnedAgents(onDisk.agents, globalConfig),\n ...(reconciledStack !== undefined && { stack: reconciledStack }),\n },\n globalConfig,\n matrix,\n );\n}\n\n/**\n * The caller's believed provider checked against the installation on disk: two independent reads.\n */\nfunction refuseAWriteOutsideTheInstallation(projectDir: string, provider: Provider): string {\n const installed = providerInUse(projectDir);\n const configPath = getProjectConfigPath(projectDir, provider);\n\n if (installed !== provider) {\n throw new Error(\n `Refusing to write ${configPath}: ${projectDir} holds the ${installed} installation at ` +\n `${sourceFolderInUse(projectDir, installed).dir}, not a ${provider} one.`,\n );\n }\n return configPath;\n}\n\n/** Looks everything up in this project's own seated catalogue. False for an empty config. */\nasync function propagateToProject(\n projectPath: string,\n provider: Provider,\n globalConfig: ProjectConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n options: PropagationOptions,\n): Promise<boolean> {\n // Before the catalogue load, whose refusal of this config is indistinguishable from others.\n const existingProject = await loadInstalledConfig(projectPath);\n if (!existingProject?.config) return false;\n\n return withCatalogueSeatedFor(projectPath, async (catalogue) => {\n const projectSplit = reconcileAgainstGlobal(existingProject.config, globalConfig, catalogue);\n\n await writeProjectConfigPair(\n projectPath,\n provider,\n projectSplit,\n globalConfig,\n catalogue,\n agents,\n { regenerateTypes: options.regenerateTypes ?? true },\n );\n return true;\n });\n}\n\n/** No catalogue parameter: each project's own is loaded; a failed load lands in `failed`. */\nexport async function propagateGlobalChangesToProjects(\n globalConfig: ProjectConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n provider: Provider,\n currentProjectDir?: string,\n options: PropagationOptions = {},\n): Promise<PropagationResult> {\n const projects = globalConfig.projects ?? [];\n const result: PropagationResult = {\n updated: [],\n unreadable: [],\n gone: [],\n notOurs: [],\n failed: [],\n };\n if (projects.length === 0) return result;\n\n const currentNormalized = currentProjectDir ? normalizeProjectPath(currentProjectDir) : null;\n\n // Sequential: each propagation seats its project's catalogue in the module-wide singleton.\n for (const projectPath of projects) {\n if (currentNormalized && projectPath === currentNormalized) continue;\n\n const outcome = await propagateToRegisteredProject(\n projectPath,\n provider,\n globalConfig,\n agents,\n options,\n );\n result[outcome].push(projectPath);\n }\n\n return result;\n}\n\n/** No skip reason stops the fan-out. Installation presence is asked first, of every provider. */\nasync function propagateToRegisteredProject(\n projectPath: string,\n provider: Provider,\n globalConfig: ProjectConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n options: PropagationOptions,\n): Promise<keyof PropagationResult> {\n if (!(await holdsAnInstallation(projectPath))) {\n verbose(`Skipped propagation to ${projectPath} (nothing installed there)`);\n return \"gone\";\n }\n\n const notOurs = await whyThisProjectIsNotOurs(projectPath, provider);\n if (notOurs !== null) {\n verbose(`Skipped propagation to ${projectPath} (${notOurs})`);\n return \"notOurs\";\n }\n\n try {\n if (!(await propagateToProject(projectPath, provider, globalConfig, agents, options))) {\n return \"gone\";\n }\n verbose(`Propagated global changes to ${projectPath}`);\n return \"updated\";\n } catch (error) {\n verbose(`Failed to propagate to ${projectPath}: ${getErrorMessage(error)}`);\n return error instanceof ConfigLoadError ? \"unreadable\" : \"failed\";\n }\n}\n\n/**\n * The registered projects a fan-out would rewrite, asked before one runs: the same skips it makes,\n * so a project it would pass over is not promised a rewrite.\n */\nexport async function projectsAFanOutReaches(\n projects: readonly string[],\n provider: Provider,\n): Promise<string[]> {\n const reached = await Promise.all(\n projects.map(async (projectPath) =>\n (await wouldBeRewritten(projectPath, provider)) ? [projectPath] : [],\n ),\n );\n return reached.flat();\n}\n\nasync function wouldBeRewritten(projectPath: string, provider: Provider): Promise<boolean> {\n if (!(await holdsAnInstallation(projectPath))) return false;\n if ((await whyThisProjectIsNotOurs(projectPath, provider)) !== null) return false;\n try {\n return (await loadInstalledConfig(projectPath)) !== null;\n } catch {\n // DEGRADE: the fan-out skips any project it cannot load, and says why once it has run.\n return false;\n }\n}\n\n/** Whether any provider's installation is at `projectPath`, this fan-out's or another's. */\nasync function holdsAnInstallation(projectPath: string): Promise<boolean> {\n const configs = await Promise.all(\n PROVIDERS.map((installed) => fileExists(getProjectConfigPath(projectPath, installed))),\n );\n return configs.includes(true);\n}\n\n/** `null` when ours to rewrite. A `providerInUse` refusal skips the project, never aborts. */\nasync function whyThisProjectIsNotOurs(\n projectPath: string,\n provider: Provider,\n): Promise<string | null> {\n const notOurs = `not a ${provider} installation`;\n try {\n if (providerInUse(projectPath) !== provider) return notOurs;\n } catch (error) {\n return getErrorMessage(error);\n }\n return (await fileExists(getProjectConfigPath(projectPath, provider))) ? null : notOurs;\n}\n\n/**\n * Reuses the fan-out with an emptied global config. Call it after the global manifest is removed;\n * unreachable dirs are reported, never thrown.\n */\nexport async function pruneGlobalEntriesFromRegisteredProjects(\n globalConfig: ProjectConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n provider: Provider,\n): Promise<PropagationResult> {\n const emptiedGlobal: ProjectConfig = {\n ...globalConfig,\n skills: [],\n agents: [],\n };\n return propagateGlobalChangesToProjects(emptiedGlobal, agents, provider);\n}\n\n/** `globalDataChanged` gates propagation and `changed` the write; `\"all\"` matches the session. */\nexport async function resolveEffectiveGlobalConfig(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n projectDir: string,\n authority?: AuthoritativeScope,\n): Promise<{ config: ProjectConfig; globalDataChanged: boolean; changed: boolean }> {\n const merged =\n authority === \"all\"\n ? matchGlobalToSession(globalSplit, existingGlobalConfig)\n : addSessionToGlobal(globalSplit, existingGlobalConfig, activeMatrix);\n\n const registration = await registerProjectPath(merged.config, projectDir);\n return {\n config: registration.config,\n globalDataChanged: merged.changed,\n changed: merged.changed || registration.changed,\n };\n}\n\n/** Makes the global config MATCH a confirmed `edit --from` session, even an empty one. */\nfunction matchGlobalToSession(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n): ResolvedGlobalConfig {\n if (!existingGlobalConfig) return { config: globalSplit, changed: true };\n\n const config = mergeConfigs(globalSplit, existingGlobalConfig, { authoritativeScope: \"all\" });\n return { config, changed: !isDeepEqual(config, existingGlobalConfig) };\n}\n\n/** Category keys the emitted stack holds, across every agent it configures. */\nfunction stackCategories(stack: ProjectConfig[\"stack\"]): Category[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Object.entries drops the `| undefined` a Partial<Record> admits\n return Object.values(stack ?? {}).flatMap((agentStack) => typedKeys<Category>(agentStack ?? {}));\n}\n\n/** Extras from ALL active entries: the project's config.ts inlines the active global rows. */\nexport function buildProjectTypesExtras(\n finalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): Required<ConfigTypesExtras> {\n const activeSkills = finalConfig.skills.filter((s) => !s.excluded);\n const activeAgents = finalConfig.agents.filter((a) => !a.excluded);\n\n const extraSkillIds = unique(activeSkills.map((s) => s.id));\n const extraAgentNames = unique(activeAgents.map((a) => a.name));\n\n const extraCategories = unique([\n ...deriveCategories(extraSkillIds, matrix),\n ...stackCategories(finalConfig.stack),\n ]);\n const extraDomains = unique([\n ...deriveDomains(extraCategories, matrix),\n ...(finalConfig.selectedDomains ?? []),\n ]);\n\n return { extraSkillIds, extraAgentNames, extraDomains, extraCategories };\n}\n","import { CODEX_MODEL_NAMES, EFFORT_NAMES, MODEL_NAMES } from \"@workspace/matrix\"\nimport { groupBy, unique } from \"remeda\"\n\nimport { isExclusiveCategory, type CompileCatalog } from \"./catalog.js\"\nimport {\n INDENT_STEP,\n brokenUnionLayout,\n flatUnion,\n quoteText,\n renderKey,\n renderTypeImportLine,\n renderUnionBody,\n spaces,\n unionLayout,\n} from \"./installed-format.js\"\nimport { LOCAL_PSEUDO_CATEGORY } from \"./paths.js\"\nimport {\n activeAgentNames,\n activeProjectAgentNames,\n} from \"./scope-predicates.js\"\nimport { bytewise } from \"./string.js\"\nimport { typedEntries, typedKeys } from \"./typed-object.js\"\nimport type {\n AgentName,\n Category,\n CategoryPath,\n ProjectConfig,\n SkillId,\n} from \"./types.js\"\n\n/** Renders `config-types.ts`; writes nothing. Probing for a global types file stays in the CLI. */\n\n/**\n * `never` is the union identity, so a project extending an empty global union still narrows.\n * `string` would absorb every literal and disable type checking of config.ts.\n */\nconst EMPTY_UNION_TYPE = \"never\"\n\nexport type ConfigTypesExtras = {\n extraSkillIds?: string[]\n extraAgentNames?: string[]\n extraDomains?: string[]\n extraCategories?: string[]\n}\n\n/**\n * Width is the lists' concern; `contract/emission-scenarios.test.ts` reddens if one outgrows it.\n */\nfunction formatLiteralUnion(members: readonly string[]): string {\n return flatUnion(members.map(quoteText))\n}\n\nexport const PROJECT_CONFIG_TYPES_BEFORE = `export type InstallMode = 'eject' | 'plugin' | 'mixed'\n\nexport type SkillConfig = {\n id: SkillId\n scope: 'project' | 'global'\n origin: string\n excluded?: boolean\n}\n\nexport type AgentScopeConfig = {\n name: AgentName\n scope: 'project' | 'global'\n model?: ${formatLiteralUnion(MODEL_NAMES)}\n codexModel?: ${formatLiteralUnion(CODEX_MODEL_NAMES)}\n effort?: ${formatLiteralUnion(EFFORT_NAMES)}\n excluded?: boolean\n}\n\nexport type SkillAssignment<S extends SkillId = SkillId> = S | { id: S; preloaded: boolean }\n`\n\nexport const PROJECT_CONFIG_INTERFACE_AFTER = `export interface ProjectConfig {\n /** Project/plugin name (kebab-case) */\n name: string\n\n /** Project description */\n description?: string\n\n /** Per-agent configuration with scope */\n agents: AgentScopeConfig[]\n\n /** Per-skill configuration with scope and provenance */\n skills: SkillConfig[]\n\n /** Author handle (e.g., \"@vince\") */\n author?: string\n\n /** Stack configuration: agent -> category -> skill assignment */\n stack?: Partial<Record<ProjectAgentName, StackAgentConfig>>\n\n /** The marketplace this install reads skills from, as a path or URL */\n marketplace?: string\n\n /** The name that marketplace's manifest gives it, which plugins are registered under */\n marketplaceName?: string\n\n /** Selected domains */\n selectedDomains?: Domain[]\n\n /** Branding overrides for white-labeling the CLI */\n branding?: { name?: string }\n\n /** Custom skills directory override (default: \"src/skills\") */\n skillsDir?: string\n\n /** Custom stacks file path override (default: \"config/stacks.ts\") */\n stacksFile?: string\n\n /** Custom categories file path override (default: \"config/skill-categories.ts\") */\n categoriesFile?: string\n\n /** Custom rules file path override (default: \"config/skill-rules.ts\") */\n rulesFile?: string\n\n /** Tracked project installation paths (global config only) */\n projects?: string[]\n}\n`\n\n/** Admits a single assignment too: project configs carry the bare form for exclusive categories. */\nexport const STACK_AGENT_CONFIG_LOOSE_LINE =\n \"export type StackAgentConfig = Partial<Record<Category, SkillAssignment | SkillAssignment[]>>\"\n\n/**\n * The one template for every config-types.ts. Its ProjectConfig deliberately diverges from\n * types/config.ts, using the narrowed generated aliases so config.ts is checked against only what\n * is installed.\n */\nexport function assembleConfigTypesSource(parts: {\n importBlock?: string\n skillId: AliasRhs\n agentName: AliasRhs\n selectedAgentName: AliasRhs\n projectAgentName: AliasRhs\n domain: AliasRhs\n category: AliasRhs\n stackAgentConfig: string\n}): string {\n const importSection = parts.importBlock ? `${parts.importBlock}\\n\\n` : \"\"\n return `// AUTO-GENERATED by agents-inc — DO NOT EDIT\n\n${importSection}${renderAlias(\"SkillId\", parts.skillId)}\n\n${renderAlias(\"AgentName\", parts.agentName)}\n\n${renderAlias(\"SelectedAgentName\", parts.selectedAgentName)}\n\n${renderAlias(\"ProjectAgentName\", parts.projectAgentName)}\n\n${renderAlias(\"Domain\", parts.domain)}\n\n${renderAlias(\"Category\", parts.category)}\n\n${PROJECT_CONFIG_TYPES_BEFORE}\n${parts.stackAgentConfig}\n\n${PROJECT_CONFIG_INTERFACE_AFTER}`\n}\n\n/** Members rather than text: the layout depends on their width after the alias name. */\nexport type AliasRhs =\n | { kind: \"plain\"; members: readonly string[] }\n | {\n kind: \"sectioned\"\n custom: readonly string[]\n marketplace: readonly string[]\n }\n\nfunction literalUnion(members: readonly string[]): AliasRhs {\n return members.length === 0\n ? typeReference(EMPTY_UNION_TYPE)\n : { kind: \"plain\", members: members.map(quoteText) }\n}\n\nfunction typeReference(name: string): AliasRhs {\n return { kind: \"plain\", members: [name] }\n}\n\n/** Laid out the way prettier lays a union out. */\nfunction renderAlias(name: string, rhs: AliasRhs): string {\n const head = `export type ${name} =`\n if (rhs.kind === \"sectioned\") {\n return `${head}\\n${renderSectionedUnion(rhs.custom, rhs.marketplace)}`\n }\n\n const layout = unionLayout(rhs.members, {\n headWidth: head.length + \" \".length,\n tailWidth: 0,\n bodyIndent: INDENT_STEP,\n })\n\n return layout === \"inline\"\n ? `${head} ${flatUnion(rhs.members)}`\n : `${head}\\n${renderUnionBody(rhs.members, layout, INDENT_STEP)}`\n}\n\n/**\n * `custom` is non-empty by construction. Two headings put a comment between members, which\n * prettier cannot fold, so that union stays one member per line.\n */\nfunction renderSectionedUnion(\n custom: readonly string[],\n marketplace: readonly string[]\n): string {\n if (marketplace.length > 0) {\n return [\n sectionHeading(\"Custom\"),\n renderUnionBody(custom, \"stacked\", INDENT_STEP),\n sectionHeading(\"Marketplace\"),\n renderUnionBody(marketplace, \"stacked\", INDENT_STEP),\n ].join(\"\\n\")\n }\n\n return [\n sectionHeading(\"Custom\"),\n renderUnionBody(\n custom,\n brokenUnionLayout(custom, INDENT_STEP),\n INDENT_STEP\n ),\n ].join(\"\\n\")\n}\n\nfunction sectionHeading(text: string): string {\n return `${spaces(INDENT_STEP)}// ${text}`\n}\n\n/**\n * The union says WHICH skill; exclusivity says HOW MANY, so an exclusive category emits a bare\n * `SkillAssignment<...>`. An undeclared category is not exclusive: a constraint fires only on a\n * flag the data carries.\n */\nfunction generateStackAgentConfig(\n skillsByCategory: Map<Category, SkillId[]>,\n catalog: CompileCatalog\n): string {\n if (skillsByCategory.size === 0) {\n return STACK_AGENT_CONFIG_LOOSE_LINE\n }\n\n const properties = [...skillsByCategory.entries()]\n // Committed bytes: comparator order, not the machine's collation.\n .sort(([a], [b]) => bytewise(a, b))\n .map(([category, skills]) => renderStackProperty(category, skills, catalog))\n\n return [\"export type StackAgentConfig = {\", ...properties, \"}\"].join(\"\\n\")\n}\n\n/** The union sits in a type argument, so its multi-line forms carry the closing `>` down. */\nfunction renderStackProperty(\n category: Category,\n skills: SkillId[],\n catalog: CompileCatalog\n): string {\n const members = [...skills].sort().map(quoteText)\n const tail = `>${isExclusiveCategory(catalog, category) ? \"\" : \"[]\"}`\n const head = `${spaces(INDENT_STEP)}${renderKey(category)}?: SkillAssignment<`\n const bodyIndent = INDENT_STEP * 2\n\n const layout = unionLayout(members, {\n headWidth: head.length,\n tailWidth: tail.length,\n bodyIndent,\n })\n if (layout === \"inline\") return `${head}${flatUnion(members)}${tail}`\n\n return [\n head,\n renderUnionBody(members, layout, bodyIndent),\n `${spaces(INDENT_STEP)}${tail}`,\n ].join(\"\\n\")\n}\n\nfunction buildSkillsByCategory(\n skillIds: SkillId[],\n categories: Category[],\n catalog: CompileCatalog\n): Map<Category, SkillId[]> {\n const categorySet = new Set(categories)\n const eligible = [...new Set(skillIds)]\n .map((id) => ({ id, category: catalog.skills[id]?.category }))\n .filter(\n (entry): entry is { id: SkillId; category: Category } =>\n entry.category !== undefined &&\n entry.category !== LOCAL_PSEUDO_CATEGORY &&\n // Boundary cast: `string` on the narrow catalogue shape; `has` is the runtime check.\n categorySet.has(entry.category as Category)\n )\n\n return new Map(\n typedEntries(groupBy(eligible, (entry) => entry.category)).map(\n ([category, entries]) => [category, entries.map((entry) => entry.id)]\n )\n )\n}\n\n/**\n * A category no loaded catalogue declares. Not \"a category a custom skill is in\": custom skills\n * are placed in existing categories.\n */\nfunction isUndeclaredCategory(\n category: Category,\n catalog: CompileCatalog\n): boolean {\n return catalog.categories[category] === undefined\n}\n\n/**\n * Undeclared, or declared with `custom: true`. `local: true` is not a signal: an ejected catalogue\n * skill is rediscovered as local.\n */\nfunction isCustomSkill(skillId: SkillId, catalog: CompileCatalog): boolean {\n const declared = catalog.skills[skillId]\n return declared === undefined || declared.custom === true\n}\n\nfunction isCustomAgent(\n agentName: AgentName,\n declared: ReadonlySet<AgentName>,\n flaggedCustom: ReadonlySet<AgentName>\n): boolean {\n return !declared.has(agentName) || flaggedCustom.has(agentName)\n}\n\nfunction isCustomDomain(\n domain: string,\n declared: ReadonlySet<string>\n): boolean {\n return !declared.has(domain)\n}\n\n/**\n * @param config Narrows SkillId/AgentName/Category/Domain to the config's skills and agents\n * rather than the full catalogue.\n */\nexport function generateConfigTypesSource(\n catalog: CompileCatalog,\n agentNames: AgentName[],\n customAgentNames: AgentName[] = [],\n extras?: ConfigTypesExtras,\n config?: ProjectConfig\n): string {\n const extra = extraMembers(extras)\n const { skillIds, agents, domains, categories } = config\n ? configMembers(config, extra, catalog)\n : catalogueMembers(agentNames, extra, catalog)\n\n const declaredAgents = new Set<AgentName>(agentNames)\n const flaggedCustomAgents = new Set<AgentName>(customAgentNames)\n const declaredDomains = new Set<string>(extractDomains(catalog))\n\n const skillIdLine = formatMaybeSectionedUnion(skillIds, (id) =>\n isCustomSkill(id, catalog)\n )\n const agentNameLine = formatMaybeSectionedUnion(agents, (name) =>\n isCustomAgent(name, declaredAgents, flaggedCustomAgents)\n )\n const domainLine = formatMaybeSectionedUnion(domains, (domain) =>\n isCustomDomain(domain, declaredDomains)\n )\n const categoryLine = formatMaybeSectionedUnion(categories, (category) =>\n isUndeclaredCategory(category, catalog)\n )\n\n const configAgents = config?.agents ?? []\n const selectedAgentNameLine = narrowedUnion(\n activeAgentNames(configAgents),\n \"AgentName\"\n )\n const projectAgentNameLine = narrowedUnion(\n activeProjectAgentNames(configAgents),\n \"SelectedAgentName\"\n )\n\n const skillsByCategory = buildSkillsByCategory(skillIds, categories, catalog)\n const stackAgentConfigType = generateStackAgentConfig(\n skillsByCategory,\n catalog\n )\n\n return assembleConfigTypesSource({\n skillId: skillIdLine,\n agentName: agentNameLine,\n selectedAgentName: selectedAgentNameLine,\n projectAgentName: projectAgentNameLine,\n domain: domainLine,\n category: categoryLine,\n stackAgentConfig: stackAgentConfigType,\n })\n}\n\ntype UnionMembers = {\n skillIds: SkillId[]\n agents: AgentName[]\n domains: string[]\n categories: Category[]\n}\n\nfunction extraMembers(extras: ConfigTypesExtras | undefined): UnionMembers {\n // Boundary cast: extra ids from CLI args may not match the strict unions.\n return {\n skillIds: (extras?.extraSkillIds ?? []) as SkillId[],\n agents: (extras?.extraAgentNames ?? []) as AgentName[],\n domains: extras?.extraDomains ?? [],\n categories: (extras?.extraCategories ?? []) as Category[],\n }\n}\n\nfunction configMembers(\n config: ProjectConfig,\n extra: UnionMembers,\n catalog: CompileCatalog\n): UnionMembers {\n const configSkillIds = config.skills.map((s) => s.id)\n const categories = sortedUnion(\n deriveCategories(configSkillIds, catalog),\n extra.categories\n )\n\n return {\n skillIds: sortedUnion(configSkillIds, extra.skillIds),\n agents: sortedUnion(\n config.agents.map((a) => a.name),\n extra.agents\n ),\n // selectedDomains may carry domains with no skills in this scope.\n domains: sortedUnion(\n deriveDomains(categories, catalog),\n config.selectedDomains ?? [],\n extra.domains\n ),\n categories,\n }\n}\n\n/** No config: the full catalogue (e.g., a blank global config). */\nfunction catalogueMembers(\n agentNames: AgentName[],\n extra: UnionMembers,\n catalog: CompileCatalog\n): UnionMembers {\n return {\n skillIds: sortedUnion(typedKeys<SkillId>(catalog.skills), extra.skillIds),\n agents: sortedUnion(agentNames, extra.agents),\n domains: sortedUnion(extractDomains(catalog), extra.domains),\n categories: sortedUnion(\n typedKeys<Category>(catalog.categories),\n extra.categories\n ),\n }\n}\n\nfunction sortedUnion<T extends string>(...lists: (readonly T[])[]): T[] {\n return unique(lists.flat()).sort()\n}\n\nfunction narrowedUnion(members: readonly string[], fallback: string): AliasRhs {\n return members.length > 0 ? literalUnion(members) : typeReference(fallback)\n}\n\n// The full-catalogue domain union for the standalone types file.\nfunction extractDomains(catalog: CompileCatalog): string[] {\n return deriveDomains(typedKeys<Category>(catalog.categories), catalog).sort()\n}\n\nconst isNonLocalCategory = (\n category: CategoryPath | undefined\n): category is Category =>\n Boolean(category) && category !== LOCAL_PSEUDO_CATEGORY\n\nexport function deriveCategories(\n skillIds: SkillId[],\n catalog: CompileCatalog\n): Category[] {\n return unique(\n skillIds\n // Boundary cast: CategoryPath to Category for the catalogue lookup.\n .map((id) => catalog.skills[id]?.category as CategoryPath | undefined)\n .filter(isNonLocalCategory)\n )\n}\n\nexport function deriveDomains(\n categories: Category[],\n catalog: CompileCatalog\n): string[] {\n return unique(\n categories\n .map((cat) => catalog.categories[cat]?.domain)\n .filter((domain): domain is string => domain !== undefined)\n )\n}\n\nfunction formatMaybeSectionedUnion<T extends string>(\n members: T[],\n isCustom: (member: T) => boolean\n): AliasRhs {\n if (members.length === 0) {\n return typeReference(EMPTY_UNION_TYPE)\n }\n\n const custom = members.filter(isCustom)\n const marketplace = members.filter((m) => !isCustom(m))\n\n if (custom.length === 0) {\n return literalUnion(members)\n }\n\n return {\n kind: \"sectioned\",\n custom: custom.map(quoteText),\n marketplace: marketplace.map(quoteText),\n }\n}\n\nexport type ProjectConfigTypesOptions = {\n /** The global scope's source folder; extends its types. */\n globalTypesImportPath: string\n projectSkillIds: string[]\n projectAgentNames: string[]\n projectDomains: string[]\n projectCategories?: string[]\n /** Narrows SelectedAgentName */\n selectedAgentNames?: string[]\n /** Narrows ProjectAgentName for stack keys */\n projectScopedAgentNames?: string[]\n}\n\n/** Each union is `GlobalType | \"project-item\"`; Category extends GlobalCategory when given. */\nexport function generateProjectConfigTypesSource(\n options: ProjectConfigTypesOptions\n): string {\n const importPath = `${options.globalTypesImportPath}/config-types`\n\n const skillIdUnion = formatExtendedUnion(\n \"GlobalSkillId\",\n options.projectSkillIds\n )\n const agentNameUnion = formatExtendedUnion(\n \"GlobalAgentName\",\n options.projectAgentNames\n )\n const domainUnion = formatExtendedUnion(\n \"GlobalDomain\",\n options.projectDomains\n )\n\n const categoryUnion = formatExtendedUnion(\n \"GlobalCategory\",\n options.projectCategories ?? []\n )\n\n const selectedAgentNameUnion = narrowedUnion(\n options.selectedAgentNames ?? [],\n \"AgentName\"\n )\n\n const projectAgentNameUnion = narrowedUnion(\n options.projectScopedAgentNames ?? [],\n \"SelectedAgentName\"\n )\n\n // Category is re-exported either way, so it is always imported.\n const importBlock = renderTypeImportLine(\n [\n \"SkillId as GlobalSkillId\",\n \"AgentName as GlobalAgentName\",\n \"Domain as GlobalDomain\",\n \"Category as GlobalCategory\",\n ],\n importPath\n )\n\n return assembleConfigTypesSource({\n importBlock,\n skillId: skillIdUnion,\n agentName: agentNameUnion,\n selectedAgentName: selectedAgentNameUnion,\n projectAgentName: projectAgentNameUnion,\n domain: domainUnion,\n category: categoryUnion,\n stackAgentConfig: STACK_AGENT_CONFIG_LOOSE_LINE,\n })\n}\n\nexport function generateBlankGlobalConfigTypesSource(): string {\n return assembleConfigTypesSource({\n skillId: typeReference(EMPTY_UNION_TYPE),\n agentName: typeReference(EMPTY_UNION_TYPE),\n selectedAgentName: typeReference(EMPTY_UNION_TYPE),\n projectAgentName: typeReference(\"SelectedAgentName\"),\n domain: typeReference(EMPTY_UNION_TYPE),\n category: typeReference(EMPTY_UNION_TYPE),\n stackAgentConfig: STACK_AGENT_CONFIG_LOOSE_LINE,\n })\n}\n\nfunction formatExtendedUnion(\n globalTypeName: string,\n projectMembers: readonly string[]\n): AliasRhs {\n if (projectMembers.length === 0) {\n return typeReference(globalTypeName)\n }\n\n return {\n kind: \"plain\",\n members: [globalTypeName, ...[...projectMembers].sort().map(quoteText)],\n }\n}\n","import path from \"path\";\n\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../../types\";\nimport type { Provider } from \"../../consts\";\nimport { globalInstallRoot, STANDARD_FILES } from \"../../consts\";\n// Imported by exception (eslint records it): `gate-token.ts` is a dependency-free leaf.\nimport { GlobalPairWriteViolation } from \"../config-gate/gate-token.js\";\nimport { providerInUse, sourceFolderInUse } from \"../installation/install-layout\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { fileExists, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedKeys } from \"../../utils/typed-object\";\nimport {\n generateConfigTypesSource,\n generateProjectConfigTypesSource,\n type ConfigTypesExtras,\n} from \"@workspace/compile/config-types-source\";\n\nimport { loadProjectConfigFromDir } from \"./project-config\";\nimport { activeAgentNames, activeProjectAgentNames } from \"./scope-predicates\";\n\n/** The provider is the asking project's: a project inherits only from its own provider's global. */\nasync function getGlobalConfigTypesPath(provider: Provider): Promise<string | null> {\n const globalConfigTypesPath = path.join(\n sourceFolderInUse(globalInstallRoot(), provider).dir,\n STANDARD_FILES.CONFIG_TYPES_TS,\n );\n if (await fileExists(globalConfigTypesPath)) {\n return globalConfigTypesPath;\n }\n return null;\n}\n\n/** POSIX specifier to the provider's global types; machine-specific, so not shared. */\nfunction computeGlobalTypesImportPath(projectDir: string, provider: Provider): string {\n const projectSourceDir = sourceFolderInUse(projectDir, provider).dir;\n const globalSourceDir = sourceFolderInUse(globalInstallRoot(), provider).dir;\n const relativePath = path.relative(projectSourceDir, globalSourceDir);\n return relativePath.split(path.sep).join(\"/\");\n}\n\nexport type ConfigTypesBackgroundData = {\n matrix: MergedSkillsMatrix;\n agentNames: AgentName[];\n customAgentNames: AgentName[];\n};\n\n/** The one constructor, so every emitted `AgentName` union agrees on which agents are custom. */\nexport function buildConfigTypesBackgroundData(\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): ConfigTypesBackgroundData {\n const agentNames = typedKeys<AgentName>(agents);\n return {\n matrix,\n agentNames,\n customAgentNames: agentNames.filter((name) => agents[name]?.custom === true),\n };\n}\n\n/** Adds `extras` (just-created skills or agents) to the regenerated unions. Errors propagate. */\nexport async function regenerateConfigTypes(\n projectDir: string,\n backgroundData: Promise<ConfigTypesBackgroundData>,\n extras?: ConfigTypesExtras,\n): Promise<void> {\n // One provider for every path built below: they must all name one installation.\n const provider = providerInUse(projectDir);\n const configTypesPath = path.join(\n sourceFolderInUse(projectDir, provider).dir,\n STANDARD_FILES.CONFIG_TYPES_TS,\n );\n\n // The gate token every caller holds lifts the `utils/fs` refusal, so this is the one they meet.\n if (isHomeDirectory(projectDir)) throw new GlobalPairWriteViolation(configTypesPath);\n\n const [data, globalConfigTypes, loadedConfig] = await Promise.all([\n backgroundData,\n getGlobalConfigTypesPath(provider),\n loadProjectConfigFromDir(projectDir, provider),\n ]);\n\n // Otherwise standalone, narrowed to the config: full unions would stop `satisfies` biting.\n const source = globalConfigTypes\n ? renderTypesExtendingGlobal(projectDir, provider, loadedConfig?.config.agents, extras)\n : generateConfigTypesSource(\n data.matrix,\n data.agentNames,\n data.customAgentNames,\n extras,\n loadedConfig?.config,\n );\n\n await writeFile(configTypesPath, source);\n verbose(`Regenerated ${STANDARD_FILES.CONFIG_TYPES_TS}`);\n}\n\nfunction renderTypesExtendingGlobal(\n projectDir: string,\n provider: Provider,\n agents: ProjectConfig[\"agents\"] | undefined,\n extras: ConfigTypesExtras | undefined,\n): string {\n const selectedAgentNames = agents ? activeAgentNames(agents) : undefined;\n const projectScopedAgentNames = agents ? activeProjectAgentNames(agents) : undefined;\n const source = generateProjectConfigTypesSource({\n globalTypesImportPath: computeGlobalTypesImportPath(projectDir, provider),\n projectSkillIds: extras?.extraSkillIds ?? [],\n projectAgentNames: extras?.extraAgentNames ?? [],\n projectDomains: extras?.extraDomains ?? [],\n projectCategories: extras?.extraCategories ?? [],\n ...(selectedAgentNames?.length ? { selectedAgentNames } : {}),\n ...(projectScopedAgentNames?.length ? { projectScopedAgentNames } : {}),\n });\n verbose(\"Using project config-types.ts that imports from global\");\n return source;\n}\n","import { isDeepEqual } from \"remeda\"\n\nimport { skillDomain, type CompileCatalog } from \"./catalog.js\"\nimport { GLOBAL_CONFIG_NAME } from \"./paths.js\"\nimport { typedEntries } from \"./typed-object.js\"\nimport type {\n AgentName,\n Category,\n ProjectConfig,\n SkillAssignment,\n StackAgentConfig,\n} from \"./types.js\"\n\n// The global config a project install writes: the session's global half merged into what is on\n// disk. The CLI and the editor preview both resolve it through {@link addSessionToGlobal}.\n\n/** The CLI's blank global `config.ts` template as a loader reads it back. */\nexport function blankGlobalConfig(): ProjectConfig {\n return {\n name: GLOBAL_CONFIG_NAME,\n skills: [],\n agents: [],\n selectedDomains: [],\n }\n}\n\n/** Deep-additive: appends missing (agent, category, skill) triples; never overwrites or mutates. */\nfunction additiveMergeStack(\n existing: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n incoming: Partial<Record<AgentName, StackAgentConfig>> | undefined\n): { stack: Partial<Record<AgentName, StackAgentConfig>>; changed: boolean } {\n const merged: Partial<Record<AgentName, StackAgentConfig>> = existing\n ? structuredClone(existing)\n : {}\n if (!incoming) return { stack: merged, changed: false }\n\n let changed = false\n for (const [agentName, incomingAgentStack] of typedEntries<\n AgentName,\n StackAgentConfig\n >(incoming)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries drops Partial's `| undefined`; this guards an explicitly-undefined slot\n if (!incomingAgentStack) continue\n\n const existingAgentStack = merged[agentName]\n if (!existingAgentStack) {\n merged[agentName] = structuredClone(incomingAgentStack)\n changed = true\n continue\n }\n\n if (mergeAgentCategories(existingAgentStack, incomingAgentStack)) {\n changed = true\n }\n }\n\n return { stack: merged, changed }\n}\n\n/** Mutates the cloned `existingAgentStack`; true if anything was appended. */\nfunction mergeAgentCategories(\n existingAgentStack: StackAgentConfig,\n incomingAgentStack: StackAgentConfig\n): boolean {\n let changed = false\n for (const [category, incomingAssignments] of typedEntries<\n Category,\n SkillAssignment[]\n >(incomingAgentStack)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries drops Partial's `| undefined`; this guards an explicitly-undefined slot\n if (!incomingAssignments) continue\n\n const existingAssignments = existingAgentStack[category]\n if (!existingAssignments) {\n existingAgentStack[category] = incomingAssignments.map((a) => ({ ...a }))\n changed = true\n continue\n }\n\n if (appendMissingAssignments(existingAssignments, incomingAssignments)) {\n changed = true\n }\n }\n return changed\n}\n\n/** Mutates the cloned `existingAssignments`; an id repeated in `incomingAssignments` lands once. */\nfunction appendMissingAssignments(\n existingAssignments: SkillAssignment[],\n incomingAssignments: SkillAssignment[]\n): boolean {\n const existingIds = new Set(existingAssignments.map((a) => a.id))\n let changed = false\n for (const assignment of incomingAssignments) {\n if (existingIds.has(assignment.id)) continue\n existingAssignments.push({ ...assignment })\n existingIds.add(assignment.id)\n changed = true\n }\n return changed\n}\n\n/** Adds global items that don't exist yet; never removes. */\nexport function mergeGlobalConfigs(\n existing: ProjectConfig,\n incoming: ProjectConfig\n): { config: ProjectConfig; changed: boolean } {\n const newSkills = activeEntriesNotIn(\n incoming.skills,\n existing.skills,\n (s) => s.id\n )\n const newAgents = activeEntriesNotIn(\n incoming.agents,\n existing.agents,\n (a) => a.name\n )\n\n const mergedSkills = [...existing.skills, ...newSkills]\n const mergedAgents = [...existing.agents, ...newAgents]\n\n // Project-context edits never remove or overwrite global state, including `preloaded` flags.\n const { stack: mergedStack, changed: stackChanged } = additiveMergeStack(\n existing.stack,\n incoming.stack\n )\n\n const mergedSelectedDomains = [\n ...new Set([\n ...(existing.selectedDomains ?? []),\n ...(incoming.selectedDomains ?? []),\n ]),\n ]\n\n // Marketplace identity is fill-only: the merged config may hold plugins from several\n // marketplaces, so repointing it from a project would orphan another's registry key.\n const addsEntries = newSkills.length > 0 || newAgents.length > 0\n\n // The identity fill only happens alongside an added entry, which `addsEntries` already counts.\n const changed =\n addsEntries ||\n stackChanged ||\n !isDeepEqual(existing.selectedDomains ?? [], mergedSelectedDomains)\n\n return {\n config: {\n ...existing,\n skills: mergedSkills,\n agents: mergedAgents,\n stack: mergedStack,\n selectedDomains: mergedSelectedDomains,\n ...marketplaceIdentityFilledFrom(existing, addsEntries ? incoming : null),\n },\n changed,\n }\n}\n\nfunction activeEntriesNotIn<Entry extends { excluded?: boolean }>(\n incoming: Entry[],\n existing: Entry[],\n keyOf: (entry: Entry) => string\n): Entry[] {\n const held = new Set(existing.map(keyOf))\n return incoming.filter((entry) => !entry.excluded && !held.has(keyOf(entry)))\n}\n\n/**\n * Fills only when the merge adds an entry: a project session inlines global entries it did not\n * bring, so its marketplace may not be theirs.\n */\nfunction marketplaceIdentityFilledFrom(\n existing: ProjectConfig,\n arriving: ProjectConfig | null\n): Pick<ProjectConfig, \"marketplace\" | \"marketplaceName\"> {\n const marketplaceName = existing.marketplaceName ?? arriving?.marketplaceName\n const marketplace = existing.marketplace ?? arriving?.marketplace\n return {\n ...(marketplaceName !== undefined && { marketplaceName }),\n ...(marketplace !== undefined && { marketplace }),\n }\n}\n\nexport type ResolvedGlobalConfig = { config: ProjectConfig; changed: boolean }\n\n/**\n * The resolution every caller but `edit --from` gets: global items are added, never removed. A\n * session with nothing global does not empty the global install.\n */\nexport function addSessionToGlobal(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n catalog: CompileCatalog\n): ResolvedGlobalConfig {\n const hasGlobalItems =\n globalSplit.skills.length > 0 || globalSplit.agents.length > 0\n if (!hasGlobalItems) {\n return {\n config: existingGlobalConfig ?? {\n name: GLOBAL_CONFIG_NAME,\n skills: [],\n agents: [],\n },\n changed: false,\n }\n }\n\n const arriving = withTheDomainsItAdds(\n globalSplit,\n existingGlobalConfig,\n catalog\n )\n if (!existingGlobalConfig) return { config: arriving, changed: true }\n return mergeGlobalConfigs(existingGlobalConfig, arriving)\n}\n\n/**\n * Narrows the domains to those a newly added global skill comes from, so a project's own picks do\n * not widen what every project inherits.\n */\nfunction withTheDomainsItAdds(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n catalog: CompileCatalog\n): ProjectConfig {\n const installed = new Set(\n existingGlobalConfig?.skills.map((skill) => skill.id)\n )\n const arrivingDomains = new Set(\n globalSplit.skills\n .filter((skill) => !skill.excluded && !installed.has(skill.id))\n .map((skill) => skillDomain(catalog, skill.id))\n )\n return {\n ...globalSplit,\n selectedDomains: (globalSplit.selectedDomains ?? []).filter((domain) =>\n arrivingDomains.has(domain)\n ),\n }\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { ProjectConfig } from \"../../types\";\nimport type { AuthoritativeScope } from \"../configuration/config-merger\";\nimport { CLI_INVOKE_COMMAND } from \"../../consts\";\nimport { ensureDir, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport type { Provider } from \"../../consts\";\nimport { getInstalledConfigPath, getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { providerInUse } from \"../installation/install-layout\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport { normalizeStackRecord } from \"../stacks/stacks-loader\";\nimport { splitConfigByScope } from \"../configuration/config-generator\";\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { generateConfigSource } from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n regenerateConfigTypes,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\nimport {\n classifyGlobalChange,\n consequenceTier,\n tierPropagates,\n tierRegeneratesTypes,\n NO_CHANGES,\n type GlobalChangeSet,\n} from \"./classify.js\";\nimport { resolveGateDeps, type GateDeps, type LoadedGateDeps } from \"./deps.js\";\nimport { GlobalPairWriteViolation, withGateToken } from \"./gate-token.js\";\nimport {\n ensureBlankPair as ensureBlankPairInternal,\n writeGlobalConfigHalf,\n writeGlobalPair,\n writeGlobalTypesHalf,\n} from \"./pair-writer.js\";\nimport {\n buildProjectTypesExtras,\n mergeGlobalConfigs,\n normalizeProjectPath,\n propagateGlobalChangesToProjects,\n pruneGlobalEntriesFromRegisteredProjects,\n reconcileProjectSplitAgainstGlobal,\n resolveEffectiveGlobalConfig,\n writeProjectConfigPair,\n type PropagationResult,\n} from \"./propagate.js\";\nimport { NOTHING_RECOMPILED, pairRewriteSummary, recompilePropagated } from \"./recompile.js\";\nimport { pairsRewrittenSince, snapshotProjectPairs } from \"./pair-snapshot.js\";\nimport type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\nexport type { GateDeps } from \"./deps.js\";\nexport type { ConsequenceTier, GlobalChangeSet } from \"./classify.js\";\nexport { GlobalPairWriteViolation } from \"./gate-token.js\";\n\n/** A propagating write recompiles the propagated projects itself, so no caller can forget to. */\nexport type GateReport = {\n /** True when either half of the global pair was actually rewritten. */\n globalWritten: boolean;\n changes: GlobalChangeSet;\n propagated: PropagationResult;\n recompile: PropagatedRecompileSummary;\n};\n\n/**\n * Only these entry points mint the pair-write privilege, held across each whole consequence flow;\n * the private writers require it. `writeProjectPartial` is the exception: it refuses the home\n * directory and writes only a project's own config.\n */\n\nconst NOTHING_PROPAGATED: PropagationResult = {\n updated: [],\n unreadable: [],\n gone: [],\n notOurs: [],\n failed: [],\n};\n\n/** Whether a gated write moved anything the global install's compiled sub-agents are built from. */\nexport function movedGlobalAgentInputs(written: GateReport): boolean {\n return tierRegeneratesTypes(consequenceTier(written.changes));\n}\n\nfunction report(\n globalWritten: boolean,\n changes: GlobalChangeSet,\n propagated: PropagationResult = NOTHING_PROPAGATED,\n recompile: PropagatedRecompileSummary = NOTHING_RECOMPILED,\n): GateReport {\n return { globalWritten, changes, propagated, recompile };\n}\n\ntype FanOut = { propagated: PropagationResult; recompile: PropagatedRecompileSummary };\n\n/**\n * Runs `propagate` over the registered projects, then recompiles what it updated where `recompiles`.\n * A project whose config pair changed counts as rewritten whether or not its sub-agents did.\n */\nasync function fanOut(\n projects: readonly string[],\n provider: Provider,\n propagate: () => Promise<PropagationResult>,\n recompiles: boolean,\n): Promise<FanOut> {\n const pairsBefore = await snapshotProjectPairs(projects, provider);\n const propagated = await propagate();\n const pairsRewritten = await pairsRewrittenSince(pairsBefore, propagated.updated, provider);\n\n const recompile = recompiles\n ? await recompilePropagated(propagated.updated, pairsRewritten)\n : pairRewriteSummary(propagated.updated, pairsRewritten);\n return { propagated, recompile };\n}\n\nfunction sayPropagated(propagated: PropagationResult): void {\n if (propagated.updated.length > 0) {\n verbose(`Propagated global changes to ${propagated.updated.length} project(s)`);\n }\n}\n\n/** `currentProjectDir` is left out of the fan-out: its pair and agents are the caller's. */\nasync function applyConsequences(\n globalConfig: ProjectConfig,\n changes: GlobalChangeSet,\n deps: LoadedGateDeps,\n provider: Provider,\n currentProjectDir?: string,\n): Promise<FanOut> {\n const tier = consequenceTier(changes);\n const projects = globalConfig.projects ?? [];\n if (!tierPropagates(tier) || projects.length === 0) {\n return { propagated: NOTHING_PROPAGATED, recompile: NOTHING_RECOMPILED };\n }\n\n const regenerateTypes = tierRegeneratesTypes(tier);\n const reached = await fanOut(\n projects,\n provider,\n () =>\n propagateGlobalChangesToProjects(globalConfig, deps.agents, provider, currentProjectDir, {\n regenerateTypes,\n }),\n regenerateTypes,\n );\n sayPropagated(reached.propagated);\n return reached;\n}\n\n/**\n * Nothing is fetched unless classification needs it, so a registration-only mutation stays offline.\n */\nexport function lazyGateDeps(projectDir: string): GateDeps {\n return {\n loadMatrix: async () => {\n const { loadSkillsMatrixFromSource } = await import(\"../loading/source-loader.js\");\n const { matrix } = await loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n return matrix;\n },\n loadAgents: async () => {\n const { loadAgentDefs } = await import(\"../operations/project/load-agent-defs.js\");\n return (await loadAgentDefs()).agents;\n },\n };\n}\n\nexport type WriteConfigByScopeArgs = {\n finalConfig: ProjectConfig;\n matrix: LoadedGateDeps[\"matrix\"];\n agents: LoadedGateDeps[\"agents\"];\n projectDir: string;\n projectConfigPath: string;\n projectInstallationExists: boolean;\n /**\n * Read by the project branch only: whether the global config matches this session or absorbs it.\n */\n authoritativeScope?: AuthoritativeScope;\n};\n\n/** From a project, splits config and types by scope; from home, writes one standalone config. */\nexport async function writeConfigByScope(args: WriteConfigByScopeArgs): Promise<GateReport> {\n return withGateToken(async () => {\n const { matrix, agents, projectDir } = args;\n // os.homedir() at call time, matching getGlobalConfigImportPath().\n const homeDir = os.homedir();\n const deps: LoadedGateDeps = { matrix, agents };\n\n return isHomeDirectory(projectDir)\n ? writeFromHome(args, homeDir, deps)\n : writeFromProjectContext(args, homeDir, deps);\n });\n}\n\n/** At home the project IS the global installation, so the provider is home's own. */\nasync function writeFromHome(\n args: WriteConfigByScopeArgs,\n homeDir: string,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n const { finalConfig, projectConfigPath } = args;\n const provider = providerInUse(homeDir);\n const priorGlobal = await loadProjectConfigFromDir(homeDir, provider);\n const changes = classifyGlobalChange(priorGlobal?.config, finalConfig);\n const globalWritten = await writeGlobalPair(\n finalConfig,\n projectConfigPath,\n deps.matrix,\n deps.agents,\n );\n\n const { propagated, recompile } = await applyConsequences(finalConfig, changes, deps, provider);\n return report(globalWritten, changes, propagated, recompile);\n}\n\nasync function writeFromProjectContext(\n args: WriteConfigByScopeArgs,\n homeDir: string,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n const { finalConfig, projectDir } = args;\n\n const { global: globalConfig, project: projectSplitConfig } = splitConfigByScope(finalConfig);\n // The project's provider: each provider family inherits and propagates only within itself.\n const provider = providerInUse(projectDir);\n const globalConfigPath = getProjectConfigPath(homeDir, provider);\n\n // Merged into the existing global config: project init adds, never removes.\n const existingGlobal = await loadProjectConfigFromDir(homeDir, provider);\n const effective = await resolveEffectiveGlobalConfig(\n globalConfig,\n existingGlobal?.config,\n projectDir,\n args.authoritativeScope,\n );\n const effectiveGlobalConfig = effective.config;\n\n const changes = classifyGlobalChange(existingGlobal?.config, effectiveGlobalConfig);\n const globalWritten = await writeGlobalPairWhenChanged(effective, globalConfigPath, deps);\n\n const { propagated, recompile } = await applyConsequences(\n effectiveGlobalConfig,\n changes,\n deps,\n provider,\n projectDir,\n );\n\n // Reconcile with the inlined global, or a colliding global entry lands active beside ours.\n const reconciledProjectConfig = reconcileProjectSplitAgainstGlobal(\n projectSplitConfig,\n effectiveGlobalConfig,\n deps.matrix,\n );\n await writeProjectPairWhenOwed(\n args,\n provider,\n reconciledProjectConfig,\n effectiveGlobalConfig,\n deps,\n );\n\n return report(globalWritten, changes, propagated, recompile);\n}\n\nasync function writeGlobalPairWhenChanged(\n effective: { config: ProjectConfig; changed: boolean },\n globalConfigPath: string,\n deps: LoadedGateDeps,\n): Promise<boolean> {\n if (!effective.changed) {\n verbose(\"Global config unchanged, skipping write\");\n return false;\n }\n\n await ensureDir(path.dirname(globalConfigPath));\n const written = await writeGlobalPair(\n effective.config,\n globalConfigPath,\n deps.matrix,\n deps.agents,\n );\n verbose(`Updated global config at ${globalConfigPath}`);\n return written;\n}\n\n/** Skips only when no project installation exists and nothing is the project's own. */\nasync function writeProjectPairWhenOwed(\n project: Pick<\n WriteConfigByScopeArgs,\n \"projectDir\" | \"projectConfigPath\" | \"projectInstallationExists\"\n >,\n provider: Provider,\n reconciledProjectConfig: ProjectConfig,\n effectiveGlobalConfig: ProjectConfig,\n deps: LoadedGateDeps,\n): Promise<void> {\n if (!project.projectInstallationExists && !holdsAnythingOfItsOwn(reconciledProjectConfig)) {\n verbose(\n \"Skipped project config — no existing project installation and no project-scoped items\",\n );\n return;\n }\n\n await ensureDir(path.dirname(project.projectConfigPath));\n await writeProjectConfigPair(\n project.projectDir,\n provider,\n reconciledProjectConfig,\n effectiveGlobalConfig,\n deps.matrix,\n deps.agents,\n );\n verbose(`Updated project config at ${project.projectConfigPath}`);\n}\n\nfunction holdsAnythingOfItsOwn(projectConfig: ProjectConfig): boolean {\n return projectConfig.skills.length > 0 || projectConfig.agents.length > 0;\n}\n\n/** Matches `writeConfigByScope`'s writer choice; writes no config half; false at project scope. */\nexport async function writeScopeConfigTypes(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return withGateToken(async () => {\n if (isHomeDirectory(projectDir)) {\n return writeGlobalTypesHalf(\n config,\n getInstalledConfigPath(projectDir),\n deps.matrix,\n deps.agents,\n extras,\n );\n }\n\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(deps.matrix, deps.agents)),\n extras ?? buildProjectTypesExtras(config, deps.matrix),\n );\n return false;\n });\n}\n\n/**\n * The config on disk is the truth and survives. At home the fan-out is unconditional, since a hand\n * edit leaves nothing to diff; elsewhere nothing propagates.\n */\nexport async function reconcileTypesFromDisk(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n options?: { extras?: ConfigTypesExtras; currentProjectDir?: string },\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(undefined, config);\n const globalWritten = await writeScopeConfigTypes(projectDir, config, deps, options?.extras);\n\n if (!isHomeDirectory(projectDir)) return report(false, changes);\n if (!config.projects?.length) return report(globalWritten, changes);\n\n const provider = providerInUse(projectDir);\n const { propagated, recompile } = await fanOut(\n config.projects,\n provider,\n () =>\n propagateGlobalChangesToProjects(config, deps.agents, provider, options?.currentProjectDir),\n true,\n );\n sayPropagated(propagated);\n\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/** Closed, so no caller-authored transform runs inside the only code allowed to write the pair. */\nexport type GlobalMutation =\n | { kind: \"deregister-project\"; projectDir: string }\n | { kind: \"set-source\"; source: string; fallbackName: string };\n\n/** The config on disk with required fields filled, so a scalar mutation cannot empty an install. */\nfunction fillRequiredFields(\n partial: Partial<ProjectConfig>,\n fallbackName: string | undefined,\n): ProjectConfig {\n const name = partial.name ?? fallbackName;\n if (!name) {\n throw new Error(\n `Cannot write config: no project config found. Run \\`${CLI_INVOKE_COMMAND} init\\` first.`,\n );\n }\n return { ...partial, name, skills: partial.skills ?? [], agents: partial.agents ?? [] };\n}\n\n/** Applies a mutation to the config on disk, or null when it is a no-op. */\nfunction applyMutation(\n mutation: GlobalMutation,\n current: Partial<ProjectConfig>,\n): Partial<ProjectConfig> | null {\n switch (mutation.kind) {\n case \"deregister-project\": {\n const projects = current.projects ?? [];\n if (projects.length === 0) return null;\n const normalized = normalizeProjectPath(mutation.projectDir);\n const filtered = projects.filter((p) => p !== normalized);\n return filtered.length === projects.length ? null : { ...current, projects: filtered };\n }\n case \"set-source\":\n return { ...current, marketplace: mutation.source };\n default: {\n const _exhaustive: never = mutation;\n return _exhaustive;\n }\n }\n}\n\n/** The name a mutation invents when the global config has none yet. */\nfunction fallbackNameFor(mutation: GlobalMutation): string | undefined {\n return mutation.kind === \"set-source\" ? mutation.fallbackName : undefined;\n}\n\n/** Every mutation is classified: a source change propagates, a deregistration does not. */\nexport async function mutateGlobal(mutation: GlobalMutation, deps: GateDeps): Promise<GateReport> {\n return withGateToken(async () => {\n const homeDir = os.homedir();\n // The full loader normalizes the stack; re-emitting bare values drops exclusive categories.\n const provider = providerInUse(homeDir);\n const loadedGlobal = await loadProjectConfigFromDir(homeDir, provider);\n if (!loadedGlobal) return report(false, NO_CHANGES);\n\n const current = loadedGlobal.config;\n const mutated = applyMutation(mutation, current);\n if (!mutated) return report(false, NO_CHANGES);\n\n const prior = fillRequiredFields(current, fallbackNameFor(mutation));\n const next = fillRequiredFields(mutated, fallbackNameFor(mutation));\n const changes = classifyGlobalChange(prior, next);\n\n const globalWritten = await writeGlobalConfigHalf(\n next,\n getProjectConfigPath(homeDir, provider),\n );\n if (!next.projects?.length) return report(globalWritten, changes);\n\n const loaded = await resolveGateDeps(deps, consequenceTier(changes));\n if (!loaded) return report(globalWritten, changes);\n\n const { propagated, recompile } = await applyConsequences(next, changes, loaded, provider);\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/**\n * Prunes CLI-inlined global entries from registered projects after a global uninstall. Call it\n * after the global manifest is removed. `provider` is passed because its folder is already gone.\n */\nexport async function propagateGlobalRemoval(\n preRemovalGlobalConfig: ProjectConfig,\n deps: LoadedGateDeps,\n provider: Provider,\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(preRemovalGlobalConfig, {\n ...preRemovalGlobalConfig,\n skills: [],\n agents: [],\n });\n\n const { propagated, recompile } = await fanOut(\n preRemovalGlobalConfig.projects ?? [],\n provider,\n () => pruneGlobalEntriesFromRegisteredProjects(preRemovalGlobalConfig, deps.agents, provider),\n true,\n );\n\n return report(false, changes, propagated, recompile);\n });\n}\n\n/** No classification or fan-out: a pair created here has no registered projects. */\nexport async function ensureBlankPair(provider: Provider): Promise<boolean> {\n return withGateToken(() => ensureBlankPairInternal(provider));\n}\n\nexport type WriteProjectPartialOptions = {\n /** Name to invent when the partial has none. Absent → a missing name is an error. */\n fallbackName?: string;\n};\n\n/** The lenient loader leaves bare exclusive values that a re-emit would drop; normalized here. */\nfunction withNormalizedStack(partial: Partial<ProjectConfig>): Partial<ProjectConfig> {\n if (!partial.stack) return partial;\n return { ...partial, stack: normalizeStackRecord(partial.stack) };\n}\n\n/** Refuses the home directory: the global config half is written only by the gate. */\nexport async function writeProjectPartial(\n projectDir: string,\n partial: Partial<ProjectConfig>,\n options: WriteProjectPartialOptions = {},\n): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n throw new GlobalPairWriteViolation(getInstalledConfigPath(projectDir));\n }\n\n const configPath = getInstalledConfigPath(projectDir);\n await ensureDir(path.dirname(configPath));\n await writeFile(\n configPath,\n generateConfigSource(\n fillRequiredFields(withNormalizedStack(partial), options.fallbackName),\n activeMatrix,\n ),\n );\n}\n\n/** Exported so readers match registrations by the stored rule; it writes nothing. */\nexport { mergeGlobalConfigs, normalizeProjectPath };\n\n/** Read-only: names what a fan-out would reach, so a run can say so before it writes. */\nexport { projectsAFanOutReaches } from \"./propagate.js\";\n","import { isDeepEqual } from \"remeda\";\nimport { isRecord } from \"../../utils/type-guards.js\";\nimport type { AgentName, ProjectConfig, SkillId } from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\n\n/**\n * T1: the type unions or compiled agents derive from what changed; rewrite both halves, propagate,\n * recompile. T2: an inlined scalar changed; propagate the config half only. T3: only `projects[]`\n * changed; nothing propagates. T4: nothing moved.\n */\nexport type ConsequenceTier = \"T1\" | \"T2\" | \"T3\" | \"T4\";\n\nexport type GlobalChangeSet = {\n skills: {\n added: SkillId[];\n removed: SkillId[];\n /** Apart from `otherChanged`: it decides the reference form a compiled agent emits. */\n sourceChanged: SkillId[];\n otherChanged: SkillId[];\n };\n agents: {\n added: AgentName[];\n removed: AgentName[];\n changed: AgentName[];\n };\n stackChanged: boolean;\n selectedDomainsChanged: boolean;\n /** Names of the inlined scalar fields that moved, in config key order. */\n scalarsChanged: string[];\n projectsChanged: boolean;\n};\n\nexport const NO_CHANGES: GlobalChangeSet = {\n skills: { added: [], removed: [], sourceChanged: [], otherChanged: [] },\n agents: { added: [], removed: [], changed: [] },\n stackChanged: false,\n selectedDomainsChanged: false,\n scalarsChanged: [],\n projectsChanged: false,\n};\n\n/** The four fields the config writer extracts into typed named variables. */\nconst EXTRACTED_FIELDS = new Set([\"skills\", \"agents\", \"stack\", \"selectedDomains\"]);\n\n/** The registration list — bookkeeping, never emitted into a project config. */\nconst REGISTRATION_FIELD = \"projects\";\n\n/**\n * Fields an empty value leaves meaning nothing: the writer omits an empty `stack` and writes an\n * empty `selectedDomains`, and the global merge spells both out, so either reading occurs.\n */\nconst EMPTY_MEANS_ABSENT = new Set([\"stack\", \"selectedDomains\"]);\n\nfunction isEmptyCollection(value: unknown): boolean {\n return Array.isArray(value)\n ? value.length === 0\n : isRecord(value) && Object.keys(value).length === 0;\n}\n\n/**\n * A JSON round-trip, as the writer does, so an explicitly-`undefined` field equals an absent one;\n * an empty stack or domain list equals an absent one too.\n */\nfunction normalize(config: ProjectConfig): Record<string, unknown> {\n // Boundary cast: `JSON.parse` returns `any`; the round-trip yields the same record.\n const record = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n return Object.fromEntries(\n Object.entries(record).filter(\n ([key, value]) => !(EMPTY_MEANS_ABSENT.has(key) && isEmptyCollection(value)),\n ),\n );\n}\n\nfunction skillsById(config: Record<string, unknown>): Map<SkillId, SkillConfig> {\n // Boundary cast: `normalize`'s round-trip of a `ProjectConfig`, or `{}` where none came before.\n const skills = (config.skills ?? []) as SkillConfig[];\n return new Map(skills.map((skill) => [skill.id, skill]));\n}\n\nfunction agentsByName(config: Record<string, unknown>): Map<AgentName, AgentScopeConfig> {\n // Boundary cast: as in `skillsById`.\n const agents = (config.agents ?? []) as AgentScopeConfig[];\n return new Map(agents.map((agent) => [agent.name, agent]));\n}\n\n/** The scalar keys either side carries, in `next`-first order with `prev` extras appended. */\nfunction scalarKeys(prev: Record<string, unknown>, next: Record<string, unknown>): string[] {\n const isScalarKey = (key: string): boolean =>\n !EXTRACTED_FIELDS.has(key) && key !== REGISTRATION_FIELD;\n const nextKeys = Object.keys(next).filter(isScalarKey);\n const extraPrevKeys = Object.keys(prev).filter(\n (key) => isScalarKey(key) && !nextKeys.includes(key),\n );\n return [...nextKeys, ...extraPrevKeys];\n}\n\nfunction diffSkills(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"skills\"] {\n const before = skillsById(prev);\n const after = skillsById(next);\n\n const added = [...after.keys()].filter((id) => !before.has(id));\n const removed = [...before.keys()].filter((id) => !after.has(id));\n\n const sourceChanged: SkillId[] = [];\n const otherChanged: SkillId[] = [];\n for (const [id, afterEntry] of after) {\n const beforeEntry = before.get(id);\n if (!beforeEntry || isDeepEqual(beforeEntry, afterEntry)) continue;\n if (beforeEntry.origin !== afterEntry.origin) sourceChanged.push(id);\n else otherChanged.push(id);\n }\n\n return { added, removed, sourceChanged, otherChanged };\n}\n\nfunction diffAgents(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"agents\"] {\n const before = agentsByName(prev);\n const after = agentsByName(next);\n\n return {\n added: [...after.keys()].filter((name) => !before.has(name)),\n removed: [...before.keys()].filter((name) => !after.has(name)),\n changed: [...after.keys()].filter((name) => {\n const beforeEntry = before.get(name);\n return beforeEntry !== undefined && !isDeepEqual(beforeEntry, after.get(name));\n }),\n };\n}\n\n/** `prev` is undefined when no global config exists yet; every field then reads as changed. */\nexport function classifyGlobalChange(\n prev: ProjectConfig | undefined,\n next: ProjectConfig,\n): GlobalChangeSet {\n const before = prev ? normalize(prev) : {};\n const after = normalize(next);\n const moved = (key: string): boolean => !isDeepEqual(before[key], after[key]);\n\n return {\n skills: diffSkills(before, after),\n agents: diffAgents(before, after),\n stackChanged: moved(\"stack\"),\n selectedDomainsChanged: moved(\"selectedDomains\"),\n scalarsChanged: scalarKeys(before, after).filter(moved),\n projectsChanged: moved(REGISTRATION_FIELD),\n };\n}\n\nfunction movesTypesOrCompiledAgents(changes: GlobalChangeSet): boolean {\n const { skills, agents } = changes;\n return (\n skills.added.length > 0 ||\n skills.removed.length > 0 ||\n skills.sourceChanged.length > 0 ||\n skills.otherChanged.length > 0 ||\n agents.added.length > 0 ||\n agents.removed.length > 0 ||\n agents.changed.length > 0 ||\n changes.stackChanged ||\n changes.selectedDomainsChanged\n );\n}\n\nexport function consequenceTier(changes: GlobalChangeSet): ConsequenceTier {\n if (movesTypesOrCompiledAgents(changes)) return \"T1\";\n if (changes.scalarsChanged.length > 0) return \"T2\";\n if (changes.projectsChanged) return \"T3\";\n return \"T4\";\n}\n\nexport function tierNeedsDeps(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n\nexport function tierRegeneratesTypes(tier: ConsequenceTier): boolean {\n return tier === \"T1\";\n}\n\nexport function tierPropagates(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n","import type { AgentDefinition, AgentName, MergedSkillsMatrix } from \"../../types\";\nimport { tierNeedsDeps, tierRegeneratesTypes, type ConsequenceTier } from \"./classify.js\";\n\nexport type LoadedGateDeps = {\n matrix: MergedSkillsMatrix;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n};\n\n/** Lazy, so a caller that cannot cheaply load the matrix stays offline when nothing reads it. */\nexport type GateDeps =\n | LoadedGateDeps\n | {\n loadMatrix: () => Promise<MergedSkillsMatrix>;\n loadAgents: () => Promise<Partial<Record<AgentName, AgentDefinition>>>;\n };\n\nfunction isLoaded(deps: GateDeps): deps is LoadedGateDeps {\n return \"matrix\" in deps;\n}\n\n/** Null when `tier` has no consequences that read `deps`; the lazy loaders then never run. */\nexport async function resolveGateDeps(\n deps: GateDeps,\n tier: ConsequenceTier,\n): Promise<LoadedGateDeps | null> {\n if (!tierNeedsDeps(tier)) return null;\n if (isLoaded(deps)) return deps;\n\n // Agent definitions are read only where the types half is regenerated.\n const [matrix, agents] = await Promise.all([\n deps.loadMatrix(),\n tierRegeneratesTypes(tier) ? deps.loadAgents() : NO_AGENTS,\n ]);\n return { matrix, agents };\n}\n\nconst NO_AGENTS: Promise<Partial<Record<AgentName, AgentDefinition>>> = Promise.resolve({});\n","import os from \"os\";\nimport path from \"path\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../../types\";\nimport type { Provider } from \"../../consts\";\nimport { STANDARD_FILES } from \"../../consts\";\nimport { sourceFolderInUse } from \"../installation/install-layout\";\nimport { ensureDir, fileExists, readFile, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport {\n generateBlankGlobalConfigSource,\n generateConfigSource,\n} from \"../configuration/config-writer\";\nimport {\n buildConfigTypesBackgroundData,\n generateBlankGlobalConfigTypesSource,\n generateConfigTypesSource,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\nimport { matrix as activeMatrix } from \"../matrix/matrix-provider\";\nimport { assertGateToken } from \"./gate-token.js\";\n\n/**\n * Nothing here mints the write privilege: every writer requires it (asserted in `writeIfChanged`)\n * and only the gate's entry points in `index.ts` open it.\n */\n\nexport type GlobalPairPaths = {\n configPath: string;\n typesPath: string;\n};\n\n/** `os.homedir()` at call time, so the paths agree with test home mocks. */\nexport function globalPairPaths(provider: Provider): GlobalPairPaths {\n const dir = sourceFolderInUse(os.homedir(), provider).dir;\n return {\n configPath: path.join(dir, STANDARD_FILES.CONFIG_TS),\n typesPath: path.join(dir, STANDARD_FILES.CONFIG_TYPES_TS),\n };\n}\n\n/** The types sibling of a config path — the two always share a directory. */\nexport function typesPathFor(configPath: string): string {\n return path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);\n}\n\n/** Skips identical bytes to spare watchers mtime churn; true when written. */\nasync function writeIfChanged(filePath: string, source: string): Promise<boolean> {\n assertGateToken(filePath);\n if ((await fileExists(filePath)) && (await readFile(filePath)) === source) return false;\n await writeFile(filePath, source);\n return true;\n}\n\n/** Unions narrowed to `config`'s entries, widened by `extras` for a just-created skill or agent. */\nfunction renderStandaloneTypes(\n config: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): string {\n const data = buildConfigTypesBackgroundData(matrix, agents);\n return generateConfigTypesSource(\n data.matrix,\n data.agentNames,\n data.customAgentNames,\n extras,\n config,\n );\n}\n\n/** Reads the singleton catalogue: its caller writes this half before any catalogue is loaded. */\nexport async function writeGlobalConfigHalf(\n config: ProjectConfig,\n configPath: string,\n): Promise<boolean> {\n return writeIfChanged(configPath, generateConfigSource(config, activeMatrix));\n}\n\nexport async function writeGlobalTypesHalf(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents, extras),\n );\n}\n\n/** Both halves from one config and one catalogue, so they cannot disagree. */\nexport async function writeGlobalPair(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Promise<boolean> {\n const configWritten = await writeIfChanged(configPath, generateConfigSource(config, matrix));\n const typesWritten = await writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents),\n );\n return configWritten || typesWritten;\n}\n\n/** Creates a blank pair (empty arrays, `never` unions) when none exists; true when created. */\nexport async function ensureBlankPair(provider: Provider): Promise<boolean> {\n const { configPath, typesPath } = globalPairPaths(provider);\n\n if (await fileExists(configPath)) {\n verbose(\"Global config already exists, skipping blank creation\");\n return false;\n }\n\n await ensureDir(path.dirname(configPath));\n\n await writeIfChanged(configPath, generateBlankGlobalConfigSource());\n await writeIfChanged(typesPath, generateBlankGlobalConfigTypesSource());\n\n verbose(`Created blank global config at ${path.dirname(configPath)}`);\n return true;\n}\n","import type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\nexport const NOTHING_RECOMPILED: PropagatedRecompileSummary = {\n rewrittenCount: 0,\n unchangedCount: 0,\n failedCount: 0,\n warnings: [],\n};\n\n/** Imported lazily: a static import of the operations layer would form a load-time cycle. */\nexport async function recompilePropagated(\n projectDirs: string[],\n pairsRewritten: ReadonlySet<string>,\n): Promise<PropagatedRecompileSummary> {\n if (projectDirs.length === 0) return NOTHING_RECOMPILED;\n\n const { recompilePropagatedProjectAgents } =\n await import(\"../operations/project/recompile-project-agents.js\");\n return recompilePropagatedProjectAgents(projectDirs, pairsRewritten);\n}\n\n/** A fan-out that moved no compiled input recompiles nothing, yet may still rewrite a pair. */\nexport function pairRewriteSummary(\n projectDirs: readonly string[],\n pairsRewritten: ReadonlySet<string>,\n): PropagatedRecompileSummary {\n const rewrittenCount = projectDirs.filter((dir) => pairsRewritten.has(dir)).length;\n return {\n rewrittenCount,\n unchangedCount: projectDirs.length - rewrittenCount,\n failedCount: 0,\n warnings: [],\n };\n}\n","import type { Provider } from \"../../consts\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { fileExists, readFile } from \"../../utils/fs\";\nimport { typesPathFor } from \"./pair-writer.js\";\n\n/** What one half of a pair reads as: absent is `null`; unreadable is a symbol equal to nothing. */\ntype HalfContents = string | null | symbol;\n\n/** Both halves of a project's config pair as they read now. */\ntype PairContents = readonly [HalfContents, HalfContents];\n\nexport type PairSnapshot = ReadonlyMap<string, PairContents>;\n\n/**\n * DEGRADE: one project's unreadable file must not stop the fan-out from visiting the rest, which\n * skips that project and says why. A fresh symbol never equals a later read, not even another\n * unreadable one, so a pair the fan-out did update still counts as rewritten.\n */\nasync function readHalf(filePath: string): Promise<HalfContents> {\n try {\n return (await fileExists(filePath)) ? await readFile(filePath) : null;\n } catch {\n return Symbol(filePath);\n }\n}\n\nasync function readPair(projectDir: string, provider: Provider): Promise<PairContents> {\n const configPath = getProjectConfigPath(projectDir, provider);\n return Promise.all([readHalf(configPath), readHalf(typesPathFor(configPath))]);\n}\n\n/** Taken before a fan-out, so what it writes can be told from a re-emit of the same bytes. */\nexport async function snapshotProjectPairs(\n projectDirs: readonly string[],\n provider: Provider,\n): Promise<PairSnapshot> {\n const pairs = await Promise.all(\n projectDirs.map(async (dir) => [dir, await readPair(dir, provider)] as const),\n );\n return new Map(pairs);\n}\n\n/** `projectDirs` must each have been snapshotted: a fan-out only reaches projects it was handed. */\nexport async function pairsRewrittenSince(\n before: PairSnapshot,\n projectDirs: readonly string[],\n provider: Provider,\n): Promise<Set<string>> {\n const judged = await Promise.all(\n projectDirs.map(async (dir) => ({\n dir,\n rewritten: !samePair(snapshotOf(before, dir), await readPair(dir, provider)),\n })),\n );\n return new Set(judged.filter(({ rewritten }) => rewritten).map(({ dir }) => dir));\n}\n\nfunction snapshotOf(before: PairSnapshot, dir: string): PairContents {\n const pair = before.get(dir);\n if (pair === undefined) throw new Error(`No snapshot of ${dir} was taken before the fan-out`);\n return pair;\n}\n\nfunction samePair([config, types]: PairContents, [configNow, typesNow]: PairContents): boolean {\n return config === configNow && types === typesNow;\n}\n","import path from \"path\";\nimport {\n buildAndMergeConfig,\n resolveInstallPaths,\n isHomeDirectory,\n} from \"../../installation/index.js\";\nimport type { SourceLoadResult } from \"../../loading/index.js\";\nimport type { AuthoritativeScope } from \"../../configuration/index.js\";\nimport { ensureBlankPair, writeConfigByScope, type GateReport } from \"../../config-gate/index.js\";\nimport { providerInUse } from \"../../installation/install-layout.js\";\nimport { loadAgentDefs, type AgentDefs } from \"./load-agent-defs.js\";\nimport { ensureDir } from \"../../../utils/fs.js\";\nimport type { ProjectConfig } from \"../../../types/index.js\";\nimport type { InstallSelection } from \"@workspace/compile/seed-to-config\";\n\nexport type ConfigWriteOptions = {\n selection: InstallSelection;\n sourceResult: SourceLoadResult;\n projectDir: string;\n sourceFlag?: string;\n /** What {@link loadAgentDefs} answered, for a caller that already asked; loaded when omitted. */\n agentDefs?: AgentDefs;\n /** `\"all\"` drops any deselected entry, `\"owned\"` only project-owned ones, absent keeps all. */\n authoritativeScope?: AuthoritativeScope;\n};\n\nexport type ConfigWriteResult = {\n config: ProjectConfig;\n configPath: string;\n wasMerged: boolean;\n existingConfigPath?: string;\n propagation: GateReport;\n};\n\nexport async function writeProjectConfig(options: ConfigWriteOptions): Promise<ConfigWriteResult> {\n const { selection, sourceResult, projectDir, sourceFlag } = options;\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n\n await ensureDir(path.dirname(projectPaths.configPath));\n\n const { agents } = options.agentDefs ?? (await loadAgentDefs());\n\n const mergeResult = await buildAndMergeConfig(\n selection,\n sourceResult,\n projectDir,\n sourceFlag,\n options.authoritativeScope,\n );\n const finalConfig = mergeResult.config;\n\n const isProjectContext = !isHomeDirectory(projectDir);\n\n if (isProjectContext) {\n // A project inherits only from its own provider's global.\n await ensureBlankPair(providerInUse(projectDir));\n }\n\n const propagation = await writeConfigByScope({\n finalConfig,\n matrix: sourceResult.matrix,\n agents,\n projectDir,\n projectConfigPath: projectPaths.configPath,\n projectInstallationExists: isProjectContext,\n // Must match the merger's, or the global config and the project rows disagree.\n ...(options.authoritativeScope !== undefined && {\n authoritativeScope: options.authoritativeScope,\n }),\n });\n\n return {\n config: finalConfig,\n configPath: projectPaths.configPath,\n wasMerged: mergeResult.merged,\n ...(mergeResult.existingConfigPath !== undefined && {\n existingConfigPath: mergeResult.existingConfigPath,\n }),\n propagation,\n };\n}\n","import os from \"os\";\nimport { compileAgents, type CompilationResult } from \"./compile-agents.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"../../installation/index.js\";\nimport type { AgentName, SkillDefinitionMap, SkillScope } from \"../../../types/index.js\";\n\nexport type CompileAllScopesOptions = {\n projectDir: string;\n sourcePath: string;\n skills: SkillDefinitionMap;\n agentScopeMap: Map<AgentName, SkillScope>;\n};\n\n/**\n * Each pass is filtered to its own scope so the project pass cannot overwrite global agents with\n * zero-skill versions.\n */\nexport async function compileAgentsAllScopes(\n options: CompileAllScopesOptions,\n): Promise<CompilationResult> {\n const { projectDir, sourcePath, skills, agentScopeMap } = options;\n const base = { sourcePath, skills, agentScopeMap };\n\n if (isHomeDirectory(projectDir)) {\n return compileAgents({\n ...base,\n projectDir,\n outputDir: resolveInstallPaths(projectDir, \"project\").agentsDir,\n });\n }\n\n const globalResult = await compileAgents({\n ...base,\n projectDir: os.homedir(),\n outputDir: resolveInstallPaths(os.homedir(), \"global\").agentsDir,\n scopeFilter: \"global\",\n });\n const projectResult = await compileProjectScope(options);\n return mergeCompilationResults(globalResult, projectResult);\n}\n\nexport async function compileProjectScope(\n options: CompileAllScopesOptions,\n): Promise<CompilationResult> {\n const { projectDir, sourcePath, skills, agentScopeMap } = options;\n return compileAgents({\n sourcePath,\n skills,\n agentScopeMap,\n projectDir,\n outputDir: resolveInstallPaths(projectDir, \"project\").agentsDir,\n scopeFilter: \"project\",\n });\n}\n\nfunction mergeCompilationResults(...results: CompilationResult[]): CompilationResult {\n return {\n compiled: results.flatMap((r) => r.compiled),\n rewritten: results.flatMap((r) => r.rewritten),\n failed: results.flatMap((r) => r.failed),\n warnings: results.flatMap((r) => r.warnings),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,WAAW,SAAmD;AAClF,QAAM,EAAE,QAAQ,YAAY,YAAY,uBAAuB,IAAI;AACnE,QAAM,OAAO,MACX,2BAA2B;AAAA,IACzB,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACrC,GAAI,eAAe,UAAa,EAAE,WAAW;AAAA,IAC7C;AAAA,EACF,CAAC;AAEH,MAAI,CAAC,uBAAwB,QAAO,EAAE,cAAc,MAAM,KAAK,GAAG,iBAAiB,CAAC,EAAE;AACtF,SAAO,yBAAyB,IAAI;AACtC;AAGA,eAAe,yBACb,MACuB;AACvB,kBAAgB;AAChB,MAAI;AACF,UAAM,eAAe,MAAM,KAAK;AAChC,WAAO,EAAE,cAAc,iBAAiB,YAAY,EAAE;AAAA,EACxD,UAAE;AACA,qBAAiB;AAAA,EACnB;AACF;AAEO,SAAS,oBAAoB,UAA2C;AAC7E,aAAW,EAAE,KAAK,KAAK,SAAU,MAAK,IAAI;AAC5C;;;ACxCA,eAAsB,cAAc,YAAsD;AACxF,QAAM,cAAc,cAAc,QAAQ,IAAI;AAE9C,MAAI;AACJ,MAAI;AACF,mBAAe,MAAM,mBAAmB,WAAW;AAAA,EACrD,SAAS,OAAO;AACd,QAAI,iBAAiB,gBAAiB,QAAO;AAC7C,UAAM;AAAA,EACR;AAEA,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,kBAAkB,aAAa,UAAU;AAE9D,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,QAAQ,UAAU;AAAA,IAC1B,YAAY,QAAQ,cAAc;AAAA,EACpC;AACF;;;ACnBA,eAAsB,wBAAwB,YAAgD;AAC5F,QAAM,SAAS,MAAM,yBAAyB;AAE9C,QAAM,UAAU,gBAAgB,UAAU,IAAI,OAAO,MAAM,0BAA0B,UAAU;AAC/F,SAAO,EAAE,QAAQ,SAAS,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ;AAC3D;;;ACnBA,OAAO,QAAQ;AACf,SAAS,eAAAA,cAAa,UAAAC,eAAc;;;ACApC,SAAS,SAAS,cAAc;AAmChC,IAAM,mBAAmB;AAYzB,SAAS,mBAAmB,SAAoC;AAC9D,SAAO,UAAU,QAAQ,IAAI,SAAS,CAAC;AACzC;AAEO,IAAM,8BAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAY/B,mBAAmB,WAAW,CAAC;AAAA,iBAC1B,mBAAmB,iBAAiB,CAAC;AAAA,aACzC,mBAAmB,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,IAAM,iCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDvC,IAAM,gCACX;AAOK,SAAS,0BAA0B,OAS/B;AACT,QAAM,gBAAgB,MAAM,cAAc,GAAG,MAAM,WAAW;AAAA;AAAA,IAAS;AACvE,SAAO;AAAA;AAAA,EAEP,aAAa,GAAG,YAAY,WAAW,MAAM,OAAO,CAAC;AAAA;AAAA,EAErD,YAAY,aAAa,MAAM,SAAS,CAAC;AAAA;AAAA,EAEzC,YAAY,qBAAqB,MAAM,iBAAiB,CAAC;AAAA;AAAA,EAEzD,YAAY,oBAAoB,MAAM,gBAAgB,CAAC;AAAA;AAAA,EAEvD,YAAY,UAAU,MAAM,MAAM,CAAC;AAAA;AAAA,EAEnC,YAAY,YAAY,MAAM,QAAQ,CAAC;AAAA;AAAA,EAEvC,2BAA2B;AAAA,EAC3B,MAAM,gBAAgB;AAAA;AAAA,EAEtB,8BAA8B;AAChC;AAWA,SAAS,aAAa,SAAsC;AAC1D,SAAO,QAAQ,WAAW,IACtB,cAAc,gBAAgB,IAC9B,EAAE,MAAM,SAAS,SAAS,QAAQ,IAAI,SAAS,EAAE;AACvD;AAEA,SAAS,cAAc,MAAwB;AAC7C,SAAO,EAAE,MAAM,SAAS,SAAS,CAAC,IAAI,EAAE;AAC1C;AAGA,SAAS,YAAY,MAAc,KAAuB;AACxD,QAAM,OAAO,eAAe,IAAI;AAChC,MAAI,IAAI,SAAS,aAAa;AAC5B,WAAO,GAAG,IAAI;AAAA,EAAK,qBAAqB,IAAI,QAAQ,IAAI,WAAW,CAAC;AAAA,EACtE;AAEA,QAAM,SAAS,YAAY,IAAI,SAAS;AAAA,IACtC,WAAW,KAAK,SAAS,IAAI;AAAA,IAC7B,WAAW;AAAA,IACX,YAAY;AAAA,EACd,CAAC;AAED,SAAO,WAAW,WACd,GAAG,IAAI,IAAI,UAAU,IAAI,OAAO,CAAC,KACjC,GAAG,IAAI;AAAA,EAAK,gBAAgB,IAAI,SAAS,QAAQ,WAAW,CAAC;AACnE;AAMA,SAAS,qBACP,QACA,aACQ;AACR,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,MACL,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ,WAAW,WAAW;AAAA,MAC9C,eAAe,aAAa;AAAA,MAC5B,gBAAgB,aAAa,WAAW,WAAW;AAAA,IACrD,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,SAAO;AAAA,IACL,eAAe,QAAQ;AAAA,IACvB;AAAA,MACE;AAAA,MACA,kBAAkB,QAAQ,WAAW;AAAA,MACrC;AAAA,IACF;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,eAAe,MAAsB;AAC5C,SAAO,GAAG,OAAO,WAAW,CAAC,MAAM,IAAI;AACzC;AAOA,SAAS,yBACP,kBACA,SACQ;AACR,MAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,CAAC,GAAG,iBAAiB,QAAQ,CAAC,EAE9C,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,EACjC,IAAI,CAAC,CAAC,UAAU,MAAM,MAAM,oBAAoB,UAAU,QAAQ,OAAO,CAAC;AAE7E,SAAO,CAAC,oCAAoC,GAAG,YAAY,GAAG,EAAE,KAAK,IAAI;AAC3E;AAGA,SAAS,oBACP,UACA,QACA,SACQ;AACR,QAAM,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,SAAS;AAChD,QAAM,OAAO,IAAI,oBAAoB,SAAS,QAAQ,IAAI,KAAK,IAAI;AACnE,QAAM,OAAO,GAAG,OAAO,WAAW,CAAC,GAAG,UAAU,QAAQ,CAAC;AACzD,QAAM,aAAa,cAAc;AAEjC,QAAM,SAAS,YAAY,SAAS;AAAA,IAClC,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK;AAAA,IAChB;AAAA,EACF,CAAC;AACD,MAAI,WAAW,SAAU,QAAO,GAAG,IAAI,GAAG,UAAU,OAAO,CAAC,GAAG,IAAI;AAEnE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,SAAS,QAAQ,UAAU;AAAA,IAC3C,GAAG,OAAO,WAAW,CAAC,GAAG,IAAI;AAAA,EAC/B,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,sBACP,UACA,YACA,SAC0B;AAC1B,QAAM,cAAc,IAAI,IAAI,UAAU;AACtC,QAAM,WAAW,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,EACnC,IAAI,CAAC,QAAQ,EAAE,IAAI,UAAU,QAAQ,OAAO,EAAE,GAAG,SAAS,EAAE,EAC5D;AAAA,IACC,CAAC,UACC,MAAM,aAAa,UACnB,MAAM,aAAa;AAAA,IAEnB,YAAY,IAAI,MAAM,QAAoB;AAAA,EAC9C;AAEF,SAAO,IAAI;AAAA,IACTC,cAAa,QAAQ,UAAU,CAAC,UAAU,MAAM,QAAQ,CAAC,EAAE;AAAA,MACzD,CAAC,CAAC,UAAU,OAAO,MAAM,CAAC,UAAU,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAAA,IACtE;AAAA,EACF;AACF;AAMA,SAAS,qBACP,UACA,SACS;AACT,SAAO,QAAQ,WAAW,QAAQ,MAAM;AAC1C;AAMA,SAAS,cAAc,SAAkB,SAAkC;AACzE,QAAM,WAAW,QAAQ,OAAO,OAAO;AACvC,SAAO,aAAa,UAAa,SAAS,WAAW;AACvD;AAEA,SAAS,cACP,WACA,UACA,eACS;AACT,SAAO,CAAC,SAAS,IAAI,SAAS,KAAK,cAAc,IAAI,SAAS;AAChE;AAEA,SAAS,eACP,QACA,UACS;AACT,SAAO,CAAC,SAAS,IAAI,MAAM;AAC7B;AAMO,SAAS,0BACd,SACA,YACA,mBAAgC,CAAC,GACjC,QACA,QACQ;AACR,QAAM,QAAQ,aAAa,MAAM;AACjC,QAAM,EAAE,UAAU,QAAQ,SAAS,WAAW,IAAI,SAC9C,cAAc,QAAQ,OAAO,OAAO,IACpC,iBAAiB,YAAY,OAAO,OAAO;AAE/C,QAAM,iBAAiB,IAAI,IAAe,UAAU;AACpD,QAAM,sBAAsB,IAAI,IAAe,gBAAgB;AAC/D,QAAM,kBAAkB,IAAI,IAAY,eAAe,OAAO,CAAC;AAE/D,QAAM,cAAc;AAAA,IAA0B;AAAA,IAAU,CAAC,OACvD,cAAc,IAAI,OAAO;AAAA,EAC3B;AACA,QAAM,gBAAgB;AAAA,IAA0B;AAAA,IAAQ,CAAC,SACvD,cAAc,MAAM,gBAAgB,mBAAmB;AAAA,EACzD;AACA,QAAM,aAAa;AAAA,IAA0B;AAAA,IAAS,CAAC,WACrD,eAAe,QAAQ,eAAe;AAAA,EACxC;AACA,QAAM,eAAe;AAAA,IAA0B;AAAA,IAAY,CAAC,aAC1D,qBAAqB,UAAU,OAAO;AAAA,EACxC;AAEA,QAAM,eAAe,QAAQ,UAAU,CAAC;AACxC,QAAM,wBAAwB;AAAA,IAC5B,iBAAiB,YAAY;AAAA,IAC7B;AAAA,EACF;AACA,QAAM,uBAAuB;AAAA,IAC3B,wBAAwB,YAAY;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,mBAAmB,sBAAsB,UAAU,YAAY,OAAO;AAC5E,QAAM,uBAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AAEA,SAAO,0BAA0B;AAAA,IAC/B,SAAS;AAAA,IACT,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,kBAAkB;AAAA,EACpB,CAAC;AACH;AASA,SAAS,aAAa,QAAqD;AAEzE,SAAO;AAAA,IACL,UAAW,QAAQ,iBAAiB,CAAC;AAAA,IACrC,QAAS,QAAQ,mBAAmB,CAAC;AAAA,IACrC,SAAS,QAAQ,gBAAgB,CAAC;AAAA,IAClC,YAAa,QAAQ,mBAAmB,CAAC;AAAA,EAC3C;AACF;AAEA,SAAS,cACP,QACA,OACA,SACc;AACd,QAAM,iBAAiB,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AACpD,QAAM,aAAa;AAAA,IACjB,iBAAiB,gBAAgB,OAAO;AAAA,IACxC,MAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL,UAAU,YAAY,gBAAgB,MAAM,QAAQ;AAAA,IACpD,QAAQ;AAAA,MACN,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MAC/B,MAAM;AAAA,IACR;AAAA;AAAA,IAEA,SAAS;AAAA,MACP,cAAc,YAAY,OAAO;AAAA,MACjC,OAAO,mBAAmB,CAAC;AAAA,MAC3B,MAAM;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAGA,SAAS,iBACP,YACA,OACA,SACc;AACd,SAAO;AAAA,IACL,UAAU,YAAYC,WAAmB,QAAQ,MAAM,GAAG,MAAM,QAAQ;AAAA,IACxE,QAAQ,YAAY,YAAY,MAAM,MAAM;AAAA,IAC5C,SAAS,YAAY,eAAe,OAAO,GAAG,MAAM,OAAO;AAAA,IAC3D,YAAY;AAAA,MACVA,WAAoB,QAAQ,UAAU;AAAA,MACtC,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAiC,OAA8B;AACtE,SAAO,OAAO,MAAM,KAAK,CAAC,EAAE,KAAK;AACnC;AAEA,SAAS,cAAc,SAA4B,UAA4B;AAC7E,SAAO,QAAQ,SAAS,IAAI,aAAa,OAAO,IAAI,cAAc,QAAQ;AAC5E;AAGA,SAAS,eAAe,SAAmC;AACzD,SAAO,cAAcA,WAAoB,QAAQ,UAAU,GAAG,OAAO,EAAE,KAAK;AAC9E;AAEA,IAAM,qBAAqB,CACzB,aAEA,QAAQ,QAAQ,KAAK,aAAa;AAE7B,SAAS,iBACd,UACA,SACY;AACZ,SAAO;AAAA,IACL,SAEG,IAAI,CAAC,OAAO,QAAQ,OAAO,EAAE,GAAG,QAAoC,EACpE,OAAO,kBAAkB;AAAA,EAC9B;AACF;AAEO,SAAS,cACd,YACA,SACU;AACV,SAAO;AAAA,IACL,WACG,IAAI,CAAC,QAAQ,QAAQ,WAAW,GAAG,GAAG,MAAM,EAC5C,OAAO,CAAC,WAA6B,WAAW,MAAS;AAAA,EAC9D;AACF;AAEA,SAAS,0BACP,SACA,UACU;AACV,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,cAAc,gBAAgB;AAAA,EACvC;AAEA,QAAM,SAAS,QAAQ,OAAO,QAAQ;AACtC,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAEtD,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,aAAa,OAAO;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,OAAO,IAAI,SAAS;AAAA,IAC5B,aAAa,YAAY,IAAI,SAAS;AAAA,EACxC;AACF;AAgBO,SAAS,iCACd,SACQ;AACR,QAAM,aAAa,GAAG,QAAQ,qBAAqB;AAEnD,QAAM,eAAe;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,EACV;AACA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,QAAQ;AAAA,EACV;AACA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,QAAQ;AAAA,EACV;AAEA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,QAAQ,qBAAqB,CAAC;AAAA,EAChC;AAEA,QAAM,yBAAyB;AAAA,IAC7B,QAAQ,sBAAsB,CAAC;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,wBAAwB;AAAA,IAC5B,QAAQ,2BAA2B,CAAC;AAAA,IACpC;AAAA,EACF;AAGA,QAAM,cAAc;AAAA,IAClB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,SAAO,0BAA0B;AAAA,IAC/B;AAAA,IACA,SAAS;AAAA,IACT,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,kBAAkB;AAAA,EACpB,CAAC;AACH;AAEO,SAAS,uCAA+C;AAC7D,SAAO,0BAA0B;AAAA,IAC/B,SAAS,cAAc,gBAAgB;AAAA,IACvC,WAAW,cAAc,gBAAgB;AAAA,IACzC,mBAAmB,cAAc,gBAAgB;AAAA,IACjD,kBAAkB,cAAc,mBAAmB;AAAA,IACnD,QAAQ,cAAc,gBAAgB;AAAA,IACtC,UAAU,cAAc,gBAAgB;AAAA,IACxC,kBAAkB;AAAA,EACpB,CAAC;AACH;AAEA,SAAS,oBACP,gBACA,gBACU;AACV,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO,cAAc,cAAc;AAAA,EACrC;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,gBAAgB,GAAG,CAAC,GAAG,cAAc,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC;AAAA,EACxE;AACF;;;ACnmBA,OAAO,UAAU;AAsBjB,eAAe,yBAAyB,UAA4C;AAClF,QAAM,wBAAwB,KAAK;AAAA,IACjC,kBAAkB,kBAAkB,GAAG,QAAQ,EAAE;AAAA,IACjD,eAAe;AAAA,EACjB;AACA,MAAI,MAAM,WAAW,qBAAqB,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGA,SAAS,6BAA6B,YAAoB,UAA4B;AACpF,QAAM,mBAAmB,kBAAkB,YAAY,QAAQ,EAAE;AACjE,QAAM,kBAAkB,kBAAkB,kBAAkB,GAAG,QAAQ,EAAE;AACzE,QAAM,eAAe,KAAK,SAAS,kBAAkB,eAAe;AACpE,SAAO,aAAa,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAC9C;AASO,SAAS,+BACdC,SACA,QAC2B;AAC3B,QAAM,aAAa,UAAqB,MAAM;AAC9C,SAAO;AAAA,IACL,QAAAA;AAAA,IACA;AAAA,IACA,kBAAkB,WAAW,OAAO,CAAC,SAAS,OAAO,IAAI,GAAG,WAAW,IAAI;AAAA,EAC7E;AACF;AAGA,eAAsB,sBACpB,YACA,gBACA,QACe;AAEf,QAAM,WAAW,cAAc,UAAU;AACzC,QAAM,kBAAkB,KAAK;AAAA,IAC3B,kBAAkB,YAAY,QAAQ,EAAE;AAAA,IACxC,eAAe;AAAA,EACjB;AAGA,MAAI,gBAAgB,UAAU,EAAG,OAAM,IAAI,yBAAyB,eAAe;AAEnF,QAAM,CAAC,MAAM,mBAAmB,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,IAChE;AAAA,IACA,yBAAyB,QAAQ;AAAA,IACjC,yBAAyB,YAAY,QAAQ;AAAA,EAC/C,CAAC;AAGD,QAAM,SAAS,oBACX,2BAA2B,YAAY,UAAU,cAAc,OAAO,QAAQ,MAAM,IACpF;AAAA,IACE,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA,cAAc;AAAA,EAChB;AAEJ,QAAM,UAAU,iBAAiB,MAAM;AACvC,UAAQ,eAAe,eAAe,eAAe,EAAE;AACzD;AAEA,SAAS,2BACP,YACA,UACA,QACA,QACQ;AACR,QAAM,qBAAqB,SAAS,iBAAiB,MAAM,IAAI;AAC/D,QAAM,0BAA0B,SAAS,wBAAwB,MAAM,IAAI;AAC3E,QAAM,SAAS,iCAAiC;AAAA,IAC9C,uBAAuB,6BAA6B,YAAY,QAAQ;AAAA,IACxE,iBAAiB,QAAQ,iBAAiB,CAAC;AAAA,IAC3C,mBAAmB,QAAQ,mBAAmB,CAAC;AAAA,IAC/C,gBAAgB,QAAQ,gBAAgB,CAAC;AAAA,IACzC,mBAAmB,QAAQ,mBAAmB,CAAC;AAAA,IAC/C,GAAI,oBAAoB,SAAS,EAAE,mBAAmB,IAAI,CAAC;AAAA,IAC3D,GAAI,yBAAyB,SAAS,EAAE,wBAAwB,IAAI,CAAC;AAAA,EACvE,CAAC;AACD,UAAQ,wDAAwD;AAChE,SAAO;AACT;;;ACpHA,SAAS,mBAAmB;AA2B5B,SAAS,mBACP,UACA,UAC2E;AAC3E,QAAM,SAAuD,WACzD,gBAAgB,QAAQ,IACxB,CAAC;AACL,MAAI,CAAC,SAAU,QAAO,EAAE,OAAO,QAAQ,SAAS,MAAM;AAEtD,MAAI,UAAU;AACd,aAAW,CAAC,WAAW,kBAAkB,KAAKC,cAG5C,QAAQ,GAAG;AAEX,QAAI,CAAC,mBAAoB;AAEzB,UAAM,qBAAqB,OAAO,SAAS;AAC3C,QAAI,CAAC,oBAAoB;AACvB,aAAO,SAAS,IAAI,gBAAgB,kBAAkB;AACtD,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,qBAAqB,oBAAoB,kBAAkB,GAAG;AAChE,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,QAAQ,QAAQ;AAClC;AAGA,SAAS,qBACP,oBACA,oBACS;AACT,MAAI,UAAU;AACd,aAAW,CAAC,UAAU,mBAAmB,KAAKA,cAG5C,kBAAkB,GAAG;AAErB,QAAI,CAAC,oBAAqB;AAE1B,UAAM,sBAAsB,mBAAmB,QAAQ;AACvD,QAAI,CAAC,qBAAqB;AACxB,yBAAmB,QAAQ,IAAI,oBAAoB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AACxE,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,yBAAyB,qBAAqB,mBAAmB,GAAG;AACtE,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,yBACP,qBACA,qBACS;AACT,QAAM,cAAc,IAAI,IAAI,oBAAoB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAChE,MAAI,UAAU;AACd,aAAW,cAAc,qBAAqB;AAC5C,QAAI,YAAY,IAAI,WAAW,EAAE,EAAG;AACpC,wBAAoB,KAAK,EAAE,GAAG,WAAW,CAAC;AAC1C,gBAAY,IAAI,WAAW,EAAE;AAC7B,cAAU;AAAA,EACZ;AACA,SAAO;AACT;AAGO,SAAS,mBACd,UACA,UAC6C;AAC7C,QAAM,YAAY;AAAA,IAChB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,CAAC,MAAM,EAAE;AAAA,EACX;AACA,QAAM,YAAY;AAAA,IAChB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,CAAC,MAAM,EAAE;AAAA,EACX;AAEA,QAAM,eAAe,CAAC,GAAG,SAAS,QAAQ,GAAG,SAAS;AACtD,QAAM,eAAe,CAAC,GAAG,SAAS,QAAQ,GAAG,SAAS;AAGtD,QAAM,EAAE,OAAO,aAAa,SAAS,aAAa,IAAI;AAAA,IACpD,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAEA,QAAM,wBAAwB;AAAA,IAC5B,GAAG,oBAAI,IAAI;AAAA,MACT,GAAI,SAAS,mBAAmB,CAAC;AAAA,MACjC,GAAI,SAAS,mBAAmB,CAAC;AAAA,IACnC,CAAC;AAAA,EACH;AAIA,QAAM,cAAc,UAAU,SAAS,KAAK,UAAU,SAAS;AAG/D,QAAM,UACJ,eACA,gBACA,CAAC,YAAY,SAAS,mBAAmB,CAAC,GAAG,qBAAqB;AAEpE,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,GAAG,8BAA8B,UAAU,cAAc,WAAW,IAAI;AAAA,IAC1E;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBACP,UACA,UACA,OACS;AACT,QAAM,OAAO,IAAI,IAAI,SAAS,IAAI,KAAK,CAAC;AACxC,SAAO,SAAS,OAAO,CAAC,UAAU,CAAC,MAAM,YAAY,CAAC,KAAK,IAAI,MAAM,KAAK,CAAC,CAAC;AAC9E;AAMA,SAAS,8BACP,UACA,UACwD;AACxD,QAAM,kBAAkB,SAAS,mBAAmB,UAAU;AAC9D,QAAM,cAAc,SAAS,eAAe,UAAU;AACtD,SAAO;AAAA,IACL,GAAI,oBAAoB,UAAa,EAAE,gBAAgB;AAAA,IACvD,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,EACjD;AACF;AAQO,SAAS,mBACd,aACA,sBACA,SACsB;AACtB,QAAM,iBACJ,YAAY,OAAO,SAAS,KAAK,YAAY,OAAO,SAAS;AAC/D,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,MACL,QAAQ,wBAAwB;AAAA,QAC9B,MAAM;AAAA,QACN,QAAQ,CAAC;AAAA,QACT,QAAQ,CAAC;AAAA,MACX;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,CAAC,qBAAsB,QAAO,EAAE,QAAQ,UAAU,SAAS,KAAK;AACpE,SAAO,mBAAmB,sBAAsB,QAAQ;AAC1D;AAMA,SAAS,qBACP,aACA,sBACA,SACe;AACf,QAAM,YAAY,IAAI;AAAA,IACpB,sBAAsB,OAAO,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,EACtD;AACA,QAAM,kBAAkB,IAAI;AAAA,IAC1B,YAAY,OACT,OAAO,CAAC,UAAU,CAAC,MAAM,YAAY,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC,EAC7D,IAAI,CAAC,UAAU,YAAY,SAAS,MAAM,EAAE,CAAC;AAAA,EAClD;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,kBAAkB,YAAY,mBAAmB,CAAC,GAAG;AAAA,MAAO,CAAC,WAC3D,gBAAgB,IAAI,MAAM;AAAA,IAC5B;AAAA,EACF;AACF;;;AHnMA,eAAsB,gBACpB,QACA,YACA,SACe;AACf,QAAM,SAAS,qBAAqB,QAAQ,QAAc,OAAO;AACjE,QAAM,UAAU,YAAY,MAAM;AACpC;AAGO,SAAS,qBAAqB,YAA4B;AAC/D,SAAO,GAAG,aAAa,UAAU;AACnC;AAGA,eAAe,oBACb,cACA,YACsD;AACtD,QAAM,iBAAiB,qBAAqB,UAAU;AACtD,QAAM,WAAW,aAAa,YAAY,CAAC;AAC3C,QAAM,QAAQ,MAAM,uBAAuB,QAAQ;AAEnD,MAAI,MAAM,SAAS,cAAc,GAAG;AAClC,UAAM,UAAU,MAAM,WAAW,SAAS;AAC1C,WAAO,EAAE,QAAQ,UAAU,EAAE,GAAG,cAAc,UAAU,MAAM,IAAI,cAAc,QAAQ;AAAA,EAC1F;AAEA,SAAO,EAAE,QAAQ,EAAE,GAAG,cAAc,UAAU,CAAC,GAAG,OAAO,cAAc,EAAE,GAAG,SAAS,KAAK;AAC5F;AAEA,eAAe,uBAAuB,UAAuC;AAC3E,QAAM,YAAY,MAAM,QAAQ;AAAA,IAC9B,SAAS,IAAI,CAAC,YAAY,WAAW,uBAAuB,OAAO,CAAC,CAAC;AAAA,EACvE;AACA,SAAO,SAAS,OAAO,CAAC,GAAG,UAAU,UAAU,KAAK,MAAM,IAAI;AAChE;AAEA,SAAS,qBAAqB,cAA6B,IAAsB;AAC/E,SAAO,aAAa,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC/E;AAEA,SAAS,qBAAqB,cAA6B,MAA0B;AACnF,SAAO,aAAa,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,WAAW,GAAG,QAAQ,CAAC;AACnF;AAGA,SAAS,yBACP,QACA,cACe;AACf,SAAO,OAAO;AAAA,IACZ,CAAC,UACC,MAAM,UAAU,aACf,kBAAkB,KAAK,KAAK,qBAAqB,cAAc,MAAM,EAAE;AAAA,EAC5E;AACF;AAEA,SAAS,yBACP,QACA,cACoB;AACpB,SAAO,OAAO;AAAA,IACZ,CAAC,UACC,MAAM,UAAU,aACf,kBAAkB,KAAK,KAAK,qBAAqB,cAAc,MAAM,IAAI;AAAA,EAC9E;AACF;AAKA,SAAS,gBAAgB,IAAaC,SAAkD;AACtF,QAAM,WAAWA,QAAO,OAAO,EAAE,GAAG;AACpC,MAAI,aAAa,UAAa,aAAa,sBAAuB,QAAO;AACzE,SAAO;AACT;AAGA,SAASC,qBAAoB,UAAoBD,SAAqC;AACpF,SAAOA,QAAO,WAAW,QAAQ,GAAG,cAAc;AACpD;AAGA,SAAS,wBACP,oBACAA,SACe;AACf,SAAO,IAAI;AAAA,IACT,mBACG,OAAO,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,EACtC,IAAI,CAAC,MAAM,gBAAgB,EAAE,IAAIA,OAAM,CAAC,EACxC,OAAO,CAAC,aAAmC,aAAa,MAAS;AAAA,EACtE;AACF;AAGA,SAAS,0BACP,oBACAA,SAC0B;AAC1B,QAAM,WAAW,IAAI;AAAA,IACnB,mBAAmB,OAAO,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAC5E;AACA,QAAM,8BAA8B,IAAI;AAAA,IACtC,CAAC,GAAG,wBAAwB,oBAAoBA,OAAM,CAAC,EAAE;AAAA,MAAO,CAAC,aAC/DC,qBAAoB,UAAUD,OAAM;AAAA,IACtC;AAAA,EACF;AAEA,SAAO,CAAC,OAAO;AACb,QAAI,SAAS,IAAI,EAAE,EAAG,QAAO;AAC7B,UAAM,WAAW,gBAAgB,IAAIA,OAAM;AAC3C,WAAO,aAAa,UAAa,4BAA4B,IAAI,QAAQ;AAAA,EAC3E;AACF;AAGA,SAAS,yBACP,oBACAA,SACe;AACf,QAAM,+BAA+B,0BAA0B,oBAAoBA,OAAM;AACzF,SAAO,mBAAmB;AAAA,IACxB,CAAC,UAAU,CAAC,kBAAkB,KAAK,KAAK,6BAA6B,MAAM,EAAE;AAAA,EAC/E;AACF;AAGA,SAAS,8BAA8B,oBAA4D;AACjG,QAAM,aAAa,IAAI,IAAI,wBAAwB,kBAAkB,CAAC;AACtE,SAAO,mBAAmB;AAAA,IACxB,CAAC,UAAU,CAAC,kBAAkB,KAAK,KAAK,WAAW,IAAI,MAAM,IAAI;AAAA,EACnE;AACF;AAMA,SAAS,0BACP,oBACA,cACAA,SACe;AACf,QAAM,+BAA+B,0BAA0B,oBAAoBA,OAAM;AACzF,QAAM,oBAAoB,IAAI,IAAI,mBAAmB,OAAO,iBAAiB,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAE/F,SAAO,aAAa,OACjB;AAAA,IACC,CAAC,gBACC,WAAW,aAAa,QAAQ,KAChC,6BAA6B,YAAY,EAAE,KAC3C,CAAC,kBAAkB,IAAI,YAAY,EAAE;AAAA,EACzC,EACC,IAAI,CAAC,iBAAiB,EAAE,GAAG,aAAa,UAAU,KAAK,EAAE;AAC9D;AAGA,SAAS,0BACP,oBACA,cACoB;AACpB,QAAM,aAAa,IAAI,IAAI,wBAAwB,kBAAkB,CAAC;AACtE,QAAM,oBAAoB,IAAI;AAAA,IAC5B,mBAAmB,OAAO,iBAAiB,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAChE;AAEA,SAAO,aAAa,OACjB;AAAA,IACC,CAAC,gBACC,WAAW,aAAa,QAAQ,KAChC,WAAW,IAAI,YAAY,IAAI,KAC/B,CAAC,kBAAkB,IAAI,YAAY,IAAI;AAAA,EAC3C,EACC,IAAI,CAAC,iBAAiB,EAAE,GAAG,aAAa,UAAU,KAAK,EAAE;AAC9D;AAMO,SAAS,mCACd,cACA,cACAA,SACe;AACf,QAAM,eAAe,yBAAyB,aAAa,QAAQA,OAAM;AACzE,QAAM,eAAe,8BAA8B,aAAa,MAAM;AACtE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,CAAC,GAAG,cAAc,GAAG,0BAA0B,cAAc,cAAcA,OAAM,CAAC;AAAA,IAC1F,QAAQ,CAAC,GAAG,cAAc,GAAG,0BAA0B,cAAc,YAAY,CAAC;AAAA,EACpF;AACF;AAKA,SAAS,6BACP,oBACA,cACc;AACd,QAAM,kBAAkB,IAAI;AAAA,IAC1B,aAAa,OAAO,OAAO,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAC5E;AACA,QAAM,kBAAkB,IAAI;AAAA,IAC1B,mBAAmB,OAAO,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EAC5E;AACA,SAAO,IAAI;AAAA,IACT,mBACG;AAAA,MACC,CAAC,MAAM,WAAW,GAAG,QAAQ,KAAK,CAAC,gBAAgB,IAAI,EAAE,EAAE,KAAK,CAAC,gBAAgB,IAAI,EAAE,EAAE;AAAA,IAC3F,EACC,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EACpB;AACF;AAGA,SAAS,sBACP,OACA,uBAC8C;AAC9C,MAAI,CAAC,SAAS,sBAAsB,SAAS,EAAG,QAAO;AAEvD,QAAM,aAA+C,CAAC;AACtD,aAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,KAAK,GAAG;AACvD,UAAM,uBAAuB,0BAA0B,YAAY,qBAAqB;AACxF,QAAI,UAAoB,oBAAoB,EAAE,SAAS,GAAG;AACxD,iBAAW,KAAK,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,0BACP,YACA,uBACkB;AAClB,QAAM,uBAAyC,CAAC;AAChD,aAAW,CAAC,UAAU,WAAW,KAAK,aAA0C,UAAU,GAAG;AAE3F,QAAI,CAAC,YAAa;AAClB,UAAM,OAAO,YAAY,OAAO,CAAC,eAAe,CAAC,sBAAsB,IAAI,WAAW,EAAE,CAAC;AACzF,QAAI,KAAK,SAAS,EAAG,sBAAqB,QAAQ,IAAI;AAAA,EACxD;AACA,SAAO;AACT;AAqBA,eAAsB,uBACpB,YACA,UACA,iBACA,iBACAA,SACA,QACA,UAA8B,CAAC,GAChB;AACf,QAAM,aAAa,mCAAmC,YAAY,QAAQ;AAG1E,QAAM,gBAAgB,iBAAiB,YAAY;AAAA,IACjD,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAChB,CAAC;AAED,MAAI,QAAQ,oBAAoB,MAAO;AAGvC,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ,QAAQ,+BAA+BA,SAAQ,MAAM,CAAC;AAAA,IAC9D,wBAAwB,mBAAmB,iBAAiB,eAAe,GAAGA,OAAM;AAAA,EACtF;AACF;AAGA,SAAS,mBACP,iBACA,iBACe;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,CAAC,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,MAAM;AAAA,IAC7D,QAAQ,CAAC,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,MAAM;AAAA,IAC7D,iBAAiBE,QAAO;AAAA,MACtB,GAAI,gBAAgB,mBAAmB,CAAC;AAAA,MACxC,GAAI,gBAAgB,mBAAmB,CAAC;AAAA,IAC1C,CAAC;AAAA,IACD,OAAO,EAAE,GAAI,gBAAgB,SAAS,CAAC,GAAI,GAAI,gBAAgB,SAAS,CAAC,EAAG;AAAA,EAC9E;AACF;AAGA,SAAS,uBACP,QACA,cACAF,SACe;AACf,QAAM,wBAAwB,6BAA6B,OAAO,QAAQ,YAAY;AACtF,QAAM,kBAAkB,sBAAsB,OAAO,OAAO,qBAAqB;AAEjF,SAAO;AAAA,IACL;AAAA,MACE,GAAG;AAAA,MACH,QAAQ,yBAAyB,OAAO,QAAQ,YAAY;AAAA,MAC5D,QAAQ,yBAAyB,OAAO,QAAQ,YAAY;AAAA,MAC5D,GAAI,oBAAoB,UAAa,EAAE,OAAO,gBAAgB;AAAA,IAChE;AAAA,IACA;AAAA,IACAA;AAAA,EACF;AACF;AAKA,SAAS,mCAAmC,YAAoB,UAA4B;AAC1F,QAAM,YAAY,cAAc,UAAU;AAC1C,QAAM,aAAa,qBAAqB,YAAY,QAAQ;AAE5D,MAAI,cAAc,UAAU;AAC1B,UAAM,IAAI;AAAA,MACR,qBAAqB,UAAU,KAAK,UAAU,cAAc,SAAS,oBAChE,kBAAkB,YAAY,SAAS,EAAE,GAAG,WAAW,QAAQ;AAAA,IACtE;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAe,mBACb,aACA,UACA,cACA,QACA,SACkB;AAElB,QAAM,kBAAkB,MAAM,oBAAoB,WAAW;AAC7D,MAAI,CAAC,iBAAiB,OAAQ,QAAO;AAErC,SAAO,uBAAuB,aAAa,OAAO,cAAc;AAC9D,UAAM,eAAe,uBAAuB,gBAAgB,QAAQ,cAAc,SAAS;AAE3F,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,iBAAiB,QAAQ,mBAAmB,KAAK;AAAA,IACrD;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,eAAsB,iCACpB,cACA,QACA,UACA,mBACA,UAA8B,CAAC,GACH;AAC5B,QAAM,WAAW,aAAa,YAAY,CAAC;AAC3C,QAAM,SAA4B;AAAA,IAChC,SAAS,CAAC;AAAA,IACV,YAAY,CAAC;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,CAAC;AAAA,IACV,QAAQ,CAAC;AAAA,EACX;AACA,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,oBAAoB,oBAAoB,qBAAqB,iBAAiB,IAAI;AAGxF,aAAW,eAAe,UAAU;AAClC,QAAI,qBAAqB,gBAAgB,kBAAmB;AAE5D,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,OAAO,EAAE,KAAK,WAAW;AAAA,EAClC;AAEA,SAAO;AACT;AAGA,eAAe,6BACb,aACA,UACA,cACA,QACA,SACkC;AAClC,MAAI,CAAE,MAAM,oBAAoB,WAAW,GAAI;AAC7C,YAAQ,0BAA0B,WAAW,4BAA4B;AACzE,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,wBAAwB,aAAa,QAAQ;AACnE,MAAI,YAAY,MAAM;AACpB,YAAQ,0BAA0B,WAAW,KAAK,OAAO,GAAG;AAC5D,WAAO;AAAA,EACT;AAEA,MAAI;AACF,QAAI,CAAE,MAAM,mBAAmB,aAAa,UAAU,cAAc,QAAQ,OAAO,GAAI;AACrF,aAAO;AAAA,IACT;AACA,YAAQ,gCAAgC,WAAW,EAAE;AACrD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,0BAA0B,WAAW,KAAK,gBAAgB,KAAK,CAAC,EAAE;AAC1E,WAAO,iBAAiB,kBAAkB,eAAe;AAAA,EAC3D;AACF;AAMA,eAAsB,uBACpB,UACA,UACmB;AACnB,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,SAAS;AAAA,MAAI,OAAO,gBACjB,MAAM,iBAAiB,aAAa,QAAQ,IAAK,CAAC,WAAW,IAAI,CAAC;AAAA,IACrE;AAAA,EACF;AACA,SAAO,QAAQ,KAAK;AACtB;AAEA,eAAe,iBAAiB,aAAqB,UAAsC;AACzF,MAAI,CAAE,MAAM,oBAAoB,WAAW,EAAI,QAAO;AACtD,MAAK,MAAM,wBAAwB,aAAa,QAAQ,MAAO,KAAM,QAAO;AAC5E,MAAI;AACF,WAAQ,MAAM,oBAAoB,WAAW,MAAO;AAAA,EACtD,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAGA,eAAe,oBAAoB,aAAuC;AACxE,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,UAAU,IAAI,CAAC,cAAc,WAAW,qBAAqB,aAAa,SAAS,CAAC,CAAC;AAAA,EACvF;AACA,SAAO,QAAQ,SAAS,IAAI;AAC9B;AAGA,eAAe,wBACb,aACA,UACwB;AACxB,QAAM,UAAU,SAAS,QAAQ;AACjC,MAAI;AACF,QAAI,cAAc,WAAW,MAAM,SAAU,QAAO;AAAA,EACtD,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACA,SAAQ,MAAM,WAAW,qBAAqB,aAAa,QAAQ,CAAC,IAAK,OAAO;AAClF;AAMA,eAAsB,yCACpB,cACA,QACA,UAC4B;AAC5B,QAAM,gBAA+B;AAAA,IACnC,GAAG;AAAA,IACH,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX;AACA,SAAO,iCAAiC,eAAe,QAAQ,QAAQ;AACzE;AAGA,eAAsB,6BACpB,aACA,sBACA,YACA,WACkF;AAClF,QAAM,SACJ,cAAc,QACV,qBAAqB,aAAa,oBAAoB,IACtD,mBAAmB,aAAa,sBAAsB,MAAY;AAExE,QAAM,eAAe,MAAM,oBAAoB,OAAO,QAAQ,UAAU;AACxE,SAAO;AAAA,IACL,QAAQ,aAAa;AAAA,IACrB,mBAAmB,OAAO;AAAA,IAC1B,SAAS,OAAO,WAAW,aAAa;AAAA,EAC1C;AACF;AAGA,SAAS,qBACP,aACA,sBACsB;AACtB,MAAI,CAAC,qBAAsB,QAAO,EAAE,QAAQ,aAAa,SAAS,KAAK;AAEvE,QAAM,SAAS,aAAa,aAAa,sBAAsB,EAAE,oBAAoB,MAAM,CAAC;AAC5F,SAAO,EAAE,QAAQ,SAAS,CAACG,aAAY,QAAQ,oBAAoB,EAAE;AACvE;AAGA,SAAS,gBAAgB,OAA2C;AAElE,SAAO,OAAO,OAAO,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,eAAe,UAAoB,cAAc,CAAC,CAAC,CAAC;AACjG;AAGO,SAAS,wBACd,aACAH,SAC6B;AAC7B,QAAM,eAAe,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AACjE,QAAM,eAAe,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ;AAEjE,QAAM,gBAAgBE,QAAO,aAAa,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC1D,QAAM,kBAAkBA,QAAO,aAAa,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAE9D,QAAM,kBAAkBA,QAAO;AAAA,IAC7B,GAAG,iBAAiB,eAAeF,OAAM;AAAA,IACzC,GAAG,gBAAgB,YAAY,KAAK;AAAA,EACtC,CAAC;AACD,QAAM,eAAeE,QAAO;AAAA,IAC1B,GAAG,cAAc,iBAAiBF,OAAM;AAAA,IACxC,GAAI,YAAY,mBAAmB,CAAC;AAAA,EACtC,CAAC;AAED,SAAO,EAAE,eAAe,iBAAiB,cAAc,gBAAgB;AACzE;;;AIrmBA,OAAOI,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,SAAS,eAAAC,oBAAmB;AAgCrB,IAAM,aAA8B;AAAA,EACzC,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,eAAe,CAAC,GAAG,cAAc,CAAC,EAAE;AAAA,EACtE,QAAQ,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,EAC9C,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,gBAAgB,CAAC;AAAA,EACjB,iBAAiB;AACnB;AAGA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,UAAU,UAAU,SAAS,iBAAiB,CAAC;AAGjF,IAAM,qBAAqB;AAM3B,IAAM,qBAAqB,oBAAI,IAAI,CAAC,SAAS,iBAAiB,CAAC;AAE/D,SAAS,kBAAkB,OAAyB;AAClD,SAAO,MAAM,QAAQ,KAAK,IACtB,MAAM,WAAW,IACjB,SAAS,KAAK,KAAK,OAAO,KAAK,KAAK,EAAE,WAAW;AACvD;AAMA,SAAS,UAAU,QAAgD;AAEjE,QAAM,SAAS,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC;AAChD,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,MAAM,EAAE;AAAA,MACrB,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,mBAAmB,IAAI,GAAG,KAAK,kBAAkB,KAAK;AAAA,IAC5E;AAAA,EACF;AACF;AAEA,SAAS,WAAW,QAA4D;AAE9E,QAAM,SAAU,OAAO,UAAU,CAAC;AAClC,SAAO,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACzD;AAEA,SAAS,aAAa,QAAmE;AAEvF,QAAM,SAAU,OAAO,UAAU,CAAC;AAClC,SAAO,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAC3D;AAGA,SAAS,WAAW,MAA+B,MAAyC;AAC1F,QAAM,cAAc,CAAC,QACnB,CAAC,iBAAiB,IAAI,GAAG,KAAK,QAAQ;AACxC,QAAM,WAAW,OAAO,KAAK,IAAI,EAAE,OAAO,WAAW;AACrD,QAAM,gBAAgB,OAAO,KAAK,IAAI,EAAE;AAAA,IACtC,CAAC,QAAQ,YAAY,GAAG,KAAK,CAAC,SAAS,SAAS,GAAG;AAAA,EACrD;AACA,SAAO,CAAC,GAAG,UAAU,GAAG,aAAa;AACvC;AAEA,SAAS,WACP,MACA,MAC2B;AAC3B,QAAM,SAAS,WAAW,IAAI;AAC9B,QAAM,QAAQ,WAAW,IAAI;AAE7B,QAAM,QAAQ,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;AAC9D,QAAM,UAAU,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;AAEhE,QAAM,gBAA2B,CAAC;AAClC,QAAM,eAA0B,CAAC;AACjC,aAAW,CAAC,IAAI,UAAU,KAAK,OAAO;AACpC,UAAM,cAAc,OAAO,IAAI,EAAE;AACjC,QAAI,CAAC,eAAeC,aAAY,aAAa,UAAU,EAAG;AAC1D,QAAI,YAAY,WAAW,WAAW,OAAQ,eAAc,KAAK,EAAE;AAAA,QAC9D,cAAa,KAAK,EAAE;AAAA,EAC3B;AAEA,SAAO,EAAE,OAAO,SAAS,eAAe,aAAa;AACvD;AAEA,SAAS,WACP,MACA,MAC2B;AAC3B,QAAM,SAAS,aAAa,IAAI;AAChC,QAAM,QAAQ,aAAa,IAAI;AAE/B,SAAO;AAAA,IACL,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI,CAAC;AAAA,IAC3D,SAAS,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC;AAAA,IAC7D,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS;AAC1C,YAAM,cAAc,OAAO,IAAI,IAAI;AACnC,aAAO,gBAAgB,UAAa,CAACA,aAAY,aAAa,MAAM,IAAI,IAAI,CAAC;AAAA,IAC/E,CAAC;AAAA,EACH;AACF;AAGO,SAAS,qBACd,MACA,MACiB;AACjB,QAAM,SAAS,OAAO,UAAU,IAAI,IAAI,CAAC;AACzC,QAAM,QAAQ,UAAU,IAAI;AAC5B,QAAM,QAAQ,CAAC,QAAyB,CAACA,aAAY,OAAO,GAAG,GAAG,MAAM,GAAG,CAAC;AAE5E,SAAO;AAAA,IACL,QAAQ,WAAW,QAAQ,KAAK;AAAA,IAChC,QAAQ,WAAW,QAAQ,KAAK;AAAA,IAChC,cAAc,MAAM,OAAO;AAAA,IAC3B,wBAAwB,MAAM,iBAAiB;AAAA,IAC/C,gBAAgB,WAAW,QAAQ,KAAK,EAAE,OAAO,KAAK;AAAA,IACtD,iBAAiB,MAAM,kBAAkB;AAAA,EAC3C;AACF;AAEA,SAAS,2BAA2B,SAAmC;AACrE,QAAM,EAAE,QAAQ,OAAO,IAAI;AAC3B,SACE,OAAO,MAAM,SAAS,KACtB,OAAO,QAAQ,SAAS,KACxB,OAAO,cAAc,SAAS,KAC9B,OAAO,aAAa,SAAS,KAC7B,OAAO,MAAM,SAAS,KACtB,OAAO,QAAQ,SAAS,KACxB,OAAO,QAAQ,SAAS,KACxB,QAAQ,gBACR,QAAQ;AAEZ;AAEO,SAAS,gBAAgB,SAA2C;AACzE,MAAI,2BAA2B,OAAO,EAAG,QAAO;AAChD,MAAI,QAAQ,eAAe,SAAS,EAAG,QAAO;AAC9C,MAAI,QAAQ,gBAAiB,QAAO;AACpC,SAAO;AACT;AAEO,SAAS,cAAc,MAAgC;AAC5D,SAAO,SAAS,QAAQ,SAAS;AACnC;AAEO,SAAS,qBAAqB,MAAgC;AACnE,SAAO,SAAS;AAClB;AAEO,SAAS,eAAe,MAAgC;AAC7D,SAAO,SAAS,QAAQ,SAAS;AACnC;;;AC1KA,SAAS,SAAS,MAAwC;AACxD,SAAO,YAAY;AACrB;AAGA,eAAsB,gBACpB,MACA,MACgC;AAChC,MAAI,CAAC,cAAc,IAAI,EAAG,QAAO;AACjC,MAAI,SAAS,IAAI,EAAG,QAAO;AAG3B,QAAM,CAACC,SAAQ,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,KAAK,WAAW;AAAA,IAChB,qBAAqB,IAAI,IAAI,KAAK,WAAW,IAAI;AAAA,EACnD,CAAC;AACD,SAAO,EAAE,QAAAA,SAAQ,OAAO;AAC1B;AAEA,IAAM,YAAkE,QAAQ,QAAQ,CAAC,CAAC;;;ACpC1F,OAAO,QAAQ;AACf,OAAOC,WAAU;AA+BV,SAAS,gBAAgB,UAAqC;AACnE,QAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,EAAE;AACtD,SAAO;AAAA,IACL,YAAYC,MAAK,KAAK,KAAK,eAAe,SAAS;AAAA,IACnD,WAAWA,MAAK,KAAK,KAAK,eAAe,eAAe;AAAA,EAC1D;AACF;AAGO,SAAS,aAAa,YAA4B;AACvD,SAAOA,MAAK,KAAKA,MAAK,QAAQ,UAAU,GAAG,eAAe,eAAe;AAC3E;AAGA,eAAe,eAAe,UAAkB,QAAkC;AAChF,kBAAgB,QAAQ;AACxB,MAAK,MAAM,WAAW,QAAQ,KAAO,MAAM,SAAS,QAAQ,MAAO,OAAQ,QAAO;AAClF,QAAM,UAAU,UAAU,MAAM;AAChC,SAAO;AACT;AAGA,SAAS,sBACP,QACAC,SACA,QACA,QACQ;AACR,QAAM,OAAO,+BAA+BA,SAAQ,MAAM;AAC1D,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,sBACpB,QACA,YACkB;AAClB,SAAO,eAAe,YAAY,qBAAqB,QAAQ,MAAY,CAAC;AAC9E;AAEA,eAAsB,qBACpB,QACA,YACAA,SACA,QACA,QACkB;AAClB,SAAO;AAAA,IACL,aAAa,UAAU;AAAA,IACvB,sBAAsB,QAAQA,SAAQ,QAAQ,MAAM;AAAA,EACtD;AACF;AAGA,eAAsB,gBACpB,QACA,YACAA,SACA,QACkB;AAClB,QAAM,gBAAgB,MAAM,eAAe,YAAY,qBAAqB,QAAQA,OAAM,CAAC;AAC3F,QAAM,eAAe,MAAM;AAAA,IACzB,aAAa,UAAU;AAAA,IACvB,sBAAsB,QAAQA,SAAQ,MAAM;AAAA,EAC9C;AACA,SAAO,iBAAiB;AAC1B;AAGA,eAAsB,gBAAgB,UAAsC;AAC1E,QAAM,EAAE,YAAY,UAAU,IAAI,gBAAgB,QAAQ;AAE1D,MAAI,MAAM,WAAW,UAAU,GAAG;AAChC,YAAQ,uDAAuD;AAC/D,WAAO;AAAA,EACT;AAEA,QAAM,UAAUD,MAAK,QAAQ,UAAU,CAAC;AAExC,QAAM,eAAe,YAAY,gCAAgC,CAAC;AAClE,QAAM,eAAe,WAAW,qCAAqC,CAAC;AAEtE,UAAQ,kCAAkCA,MAAK,QAAQ,UAAU,CAAC,EAAE;AACpE,SAAO;AACT;;;ACxHO,IAAM,qBAAiD;AAAA,EAC5D,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,UAAU,CAAC;AACb;AAGA,eAAsB,oBACpB,aACA,gBACqC;AACrC,MAAI,YAAY,WAAW,EAAG,QAAO;AAErC,QAAM,EAAE,iCAAiC,IACvC,MAAM,OAAO,wCAAmD;AAClE,SAAO,iCAAiC,aAAa,cAAc;AACrE;AAGO,SAAS,mBACd,aACA,gBAC4B;AAC5B,QAAM,iBAAiB,YAAY,OAAO,CAAC,QAAQ,eAAe,IAAI,GAAG,CAAC,EAAE;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,YAAY,SAAS;AAAA,IACrC,aAAa;AAAA,IACb,UAAU,CAAC;AAAA,EACb;AACF;;;ACfA,eAAe,SAAS,UAAyC;AAC/D,MAAI;AACF,WAAQ,MAAM,WAAW,QAAQ,IAAK,MAAM,SAAS,QAAQ,IAAI;AAAA,EACnE,QAAQ;AACN,WAAO,OAAO,QAAQ;AAAA,EACxB;AACF;AAEA,eAAe,SAAS,YAAoB,UAA2C;AACrF,QAAM,aAAa,qBAAqB,YAAY,QAAQ;AAC5D,SAAO,QAAQ,IAAI,CAAC,SAAS,UAAU,GAAG,SAAS,aAAa,UAAU,CAAC,CAAC,CAAC;AAC/E;AAGA,eAAsB,qBACpB,aACA,UACuB;AACvB,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,YAAY,IAAI,OAAO,QAAQ,CAAC,KAAK,MAAM,SAAS,KAAK,QAAQ,CAAC,CAAU;AAAA,EAC9E;AACA,SAAO,IAAI,IAAI,KAAK;AACtB;AAGA,eAAsB,oBACpB,QACA,aACA,UACsB;AACtB,QAAM,SAAS,MAAM,QAAQ;AAAA,IAC3B,YAAY,IAAI,OAAO,SAAS;AAAA,MAC9B;AAAA,MACA,WAAW,CAAC,SAAS,WAAW,QAAQ,GAAG,GAAG,MAAM,SAAS,KAAK,QAAQ,CAAC;AAAA,IAC7E,EAAE;AAAA,EACJ;AACA,SAAO,IAAI,IAAI,OAAO,OAAO,CAAC,EAAE,UAAU,MAAM,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,MAAM,GAAG,CAAC;AAClF;AAEA,SAAS,WAAW,QAAsB,KAA2B;AACnE,QAAM,OAAO,OAAO,IAAI,GAAG;AAC3B,MAAI,SAAS,OAAW,OAAM,IAAI,MAAM,kBAAkB,GAAG,+BAA+B;AAC5F,SAAO;AACT;AAEA,SAAS,SAAS,CAAC,QAAQ,KAAK,GAAiB,CAAC,WAAW,QAAQ,GAA0B;AAC7F,SAAO,WAAW,aAAa,UAAU;AAC3C;;;ALMA,IAAM,qBAAwC;AAAA,EAC5C,SAAS,CAAC;AAAA,EACV,YAAY,CAAC;AAAA,EACb,MAAM,CAAC;AAAA,EACP,SAAS,CAAC;AAAA,EACV,QAAQ,CAAC;AACX;AAGO,SAAS,uBAAuB,SAA8B;AACnE,SAAO,qBAAqB,gBAAgB,QAAQ,OAAO,CAAC;AAC9D;AAEA,SAAS,OACP,eACA,SACA,aAAgC,oBAChC,YAAwC,oBAC5B;AACZ,SAAO,EAAE,eAAe,SAAS,YAAY,UAAU;AACzD;AAQA,eAAe,OACb,UACA,UACA,WACA,YACiB;AACjB,QAAM,cAAc,MAAM,qBAAqB,UAAU,QAAQ;AACjE,QAAM,aAAa,MAAM,UAAU;AACnC,QAAM,iBAAiB,MAAM,oBAAoB,aAAa,WAAW,SAAS,QAAQ;AAE1F,QAAM,YAAY,aACd,MAAM,oBAAoB,WAAW,SAAS,cAAc,IAC5D,mBAAmB,WAAW,SAAS,cAAc;AACzD,SAAO,EAAE,YAAY,UAAU;AACjC;AAEA,SAAS,cAAc,YAAqC;AAC1D,MAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,YAAQ,gCAAgC,WAAW,QAAQ,MAAM,aAAa;AAAA,EAChF;AACF;AAGA,eAAe,kBACb,cACA,SACA,MACA,UACA,mBACiB;AACjB,QAAM,OAAO,gBAAgB,OAAO;AACpC,QAAM,WAAW,aAAa,YAAY,CAAC;AAC3C,MAAI,CAAC,eAAe,IAAI,KAAK,SAAS,WAAW,GAAG;AAClD,WAAO,EAAE,YAAY,oBAAoB,WAAW,mBAAmB;AAAA,EACzE;AAEA,QAAM,kBAAkB,qBAAqB,IAAI;AACjD,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,MACE,iCAAiC,cAAc,KAAK,QAAQ,UAAU,mBAAmB;AAAA,MACvF;AAAA,IACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,gBAAc,QAAQ,UAAU;AAChC,SAAO;AACT;AAKO,SAAS,aAAa,YAA8B;AACzD,SAAO;AAAA,IACL,YAAY,YAAY;AACtB,YAAM,EAAE,4BAAAE,4BAA2B,IAAI,MAAM,OAAO,6BAA6B;AACjF,YAAM,EAAE,QAAAC,QAAO,IAAI,MAAMD,4BAA2B;AAAA,QAClD;AAAA,QACA,kBAAkB;AAAA,QAClB,YAAY;AAAA,MACd,CAAC;AACD,aAAOC;AAAA,IACT;AAAA,IACA,YAAY,YAAY;AACtB,YAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,+BAA0C;AACjF,cAAQ,MAAMA,eAAc,GAAG;AAAA,IACjC;AAAA,EACF;AACF;AAgBA,eAAsB,mBAAmB,MAAmD;AAC1F,SAAO,cAAc,YAAY;AAC/B,UAAM,EAAE,QAAAD,SAAQ,QAAQ,WAAW,IAAI;AAEvC,UAAM,UAAUE,IAAG,QAAQ;AAC3B,UAAM,OAAuB,EAAE,QAAAF,SAAQ,OAAO;AAE9C,WAAO,gBAAgB,UAAU,IAC7B,cAAc,MAAM,SAAS,IAAI,IACjC,wBAAwB,MAAM,SAAS,IAAI;AAAA,EACjD,CAAC;AACH;AAGA,eAAe,cACb,MACA,SACA,MACqB;AACrB,QAAM,EAAE,aAAa,kBAAkB,IAAI;AAC3C,QAAM,WAAW,cAAc,OAAO;AACtC,QAAM,cAAc,MAAM,yBAAyB,SAAS,QAAQ;AACpE,QAAM,UAAU,qBAAqB,aAAa,QAAQ,WAAW;AACrE,QAAM,gBAAgB,MAAM;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEA,QAAM,EAAE,YAAY,UAAU,IAAI,MAAM,kBAAkB,aAAa,SAAS,MAAM,QAAQ;AAC9F,SAAO,OAAO,eAAe,SAAS,YAAY,SAAS;AAC7D;AAEA,eAAe,wBACb,MACA,SACA,MACqB;AACrB,QAAM,EAAE,aAAa,WAAW,IAAI;AAEpC,QAAM,EAAE,QAAQ,cAAc,SAAS,mBAAmB,IAAI,mBAAmB,WAAW;AAE5F,QAAM,WAAW,cAAc,UAAU;AACzC,QAAM,mBAAmB,qBAAqB,SAAS,QAAQ;AAG/D,QAAM,iBAAiB,MAAM,yBAAyB,SAAS,QAAQ;AACvE,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA,KAAK;AAAA,EACP;AACA,QAAM,wBAAwB,UAAU;AAExC,QAAM,UAAU,qBAAqB,gBAAgB,QAAQ,qBAAqB;AAClF,QAAM,gBAAgB,MAAM,2BAA2B,WAAW,kBAAkB,IAAI;AAExF,QAAM,EAAE,YAAY,UAAU,IAAI,MAAM;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,0BAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,OAAO,eAAe,SAAS,YAAY,SAAS;AAC7D;AAEA,eAAe,2BACb,WACA,kBACA,MACkB;AAClB,MAAI,CAAC,UAAU,SAAS;AACtB,YAAQ,yCAAyC;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,UAAUG,MAAK,QAAQ,gBAAgB,CAAC;AAC9C,QAAM,UAAU,MAAM;AAAA,IACpB,UAAU;AAAA,IACV;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,UAAQ,4BAA4B,gBAAgB,EAAE;AACtD,SAAO;AACT;AAGA,eAAe,yBACb,SAIA,UACA,yBACA,uBACA,MACe;AACf,MAAI,CAAC,QAAQ,6BAA6B,CAAC,sBAAsB,uBAAuB,GAAG;AACzF;AAAA,MACE;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,UAAUA,MAAK,QAAQ,QAAQ,iBAAiB,CAAC;AACvD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,UAAQ,6BAA6B,QAAQ,iBAAiB,EAAE;AAClE;AAEA,SAAS,sBAAsB,eAAuC;AACpE,SAAO,cAAc,OAAO,SAAS,KAAK,cAAc,OAAO,SAAS;AAC1E;AAGA,eAAsB,sBACpB,YACA,QACA,MACA,QACkB;AAClB,SAAO,cAAc,YAAY;AAC/B,QAAI,gBAAgB,UAAU,GAAG;AAC/B,aAAO;AAAA,QACL;AAAA,QACA,uBAAuB,UAAU;AAAA,QACjC,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,MACJ;AAAA,MACA,QAAQ,QAAQ,+BAA+B,KAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,MACxE,UAAU,wBAAwB,QAAQ,KAAK,MAAM;AAAA,IACvD;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAMA,eAAsB,uBACpB,YACA,QACA,MACA,SACqB;AACrB,SAAO,cAAc,YAAY;AAC/B,UAAM,UAAU,qBAAqB,QAAW,MAAM;AACtD,UAAM,gBAAgB,MAAM,sBAAsB,YAAY,QAAQ,MAAM,SAAS,MAAM;AAE3F,QAAI,CAAC,gBAAgB,UAAU,EAAG,QAAO,OAAO,OAAO,OAAO;AAC9D,QAAI,CAAC,OAAO,UAAU,OAAQ,QAAO,OAAO,eAAe,OAAO;AAElE,UAAM,WAAW,cAAc,UAAU;AACzC,UAAM,EAAE,YAAY,UAAU,IAAI,MAAM;AAAA,MACtC,OAAO;AAAA,MACP;AAAA,MACA,MACE,iCAAiC,QAAQ,KAAK,QAAQ,UAAU,SAAS,iBAAiB;AAAA,MAC5F;AAAA,IACF;AACA,kBAAc,UAAU;AAExB,WAAO,OAAO,eAAe,SAAS,YAAY,SAAS;AAAA,EAC7D,CAAC;AACH;AAQA,SAAS,mBACP,SACA,cACe;AACf,QAAM,OAAO,QAAQ,QAAQ;AAC7B,MAAI,CAAC,MAAM;AACT,UAAM,IAAI;AAAA,MACR,uDAAuD,kBAAkB;AAAA,IAC3E;AAAA,EACF;AACA,SAAO,EAAE,GAAG,SAAS,MAAM,QAAQ,QAAQ,UAAU,CAAC,GAAG,QAAQ,QAAQ,UAAU,CAAC,EAAE;AACxF;AAGA,SAAS,cACP,UACA,SAC+B;AAC/B,UAAQ,SAAS,MAAM;AAAA,IACrB,KAAK,sBAAsB;AACzB,YAAM,WAAW,QAAQ,YAAY,CAAC;AACtC,UAAI,SAAS,WAAW,EAAG,QAAO;AAClC,YAAM,aAAa,qBAAqB,SAAS,UAAU;AAC3D,YAAM,WAAW,SAAS,OAAO,CAAC,MAAM,MAAM,UAAU;AACxD,aAAO,SAAS,WAAW,SAAS,SAAS,OAAO,EAAE,GAAG,SAAS,UAAU,SAAS;AAAA,IACvF;AAAA,IACA,KAAK;AACH,aAAO,EAAE,GAAG,SAAS,aAAa,SAAS,OAAO;AAAA,IACpD,SAAS;AACP,YAAM,cAAqB;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGA,SAAS,gBAAgB,UAA8C;AACrE,SAAO,SAAS,SAAS,eAAe,SAAS,eAAe;AAClE;AAGA,eAAsB,aAAa,UAA0B,MAAqC;AAChG,SAAO,cAAc,YAAY;AAC/B,UAAM,UAAUD,IAAG,QAAQ;AAE3B,UAAM,WAAW,cAAc,OAAO;AACtC,UAAM,eAAe,MAAM,yBAAyB,SAAS,QAAQ;AACrE,QAAI,CAAC,aAAc,QAAO,OAAO,OAAO,UAAU;AAElD,UAAM,UAAU,aAAa;AAC7B,UAAM,UAAU,cAAc,UAAU,OAAO;AAC/C,QAAI,CAAC,QAAS,QAAO,OAAO,OAAO,UAAU;AAE7C,UAAM,QAAQ,mBAAmB,SAAS,gBAAgB,QAAQ,CAAC;AACnE,UAAM,OAAO,mBAAmB,SAAS,gBAAgB,QAAQ,CAAC;AAClE,UAAM,UAAU,qBAAqB,OAAO,IAAI;AAEhD,UAAM,gBAAgB,MAAM;AAAA,MAC1B;AAAA,MACA,qBAAqB,SAAS,QAAQ;AAAA,IACxC;AACA,QAAI,CAAC,KAAK,UAAU,OAAQ,QAAO,OAAO,eAAe,OAAO;AAEhE,UAAM,SAAS,MAAM,gBAAgB,MAAM,gBAAgB,OAAO,CAAC;AACnE,QAAI,CAAC,OAAQ,QAAO,OAAO,eAAe,OAAO;AAEjD,UAAM,EAAE,YAAY,UAAU,IAAI,MAAM,kBAAkB,MAAM,SAAS,QAAQ,QAAQ;AACzF,WAAO,OAAO,eAAe,SAAS,YAAY,SAAS;AAAA,EAC7D,CAAC;AACH;AAMA,eAAsB,uBACpB,wBACA,MACA,UACqB;AACrB,SAAO,cAAc,YAAY;AAC/B,UAAM,UAAU,qBAAqB,wBAAwB;AAAA,MAC3D,GAAG;AAAA,MACH,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,UAAM,EAAE,YAAY,UAAU,IAAI,MAAM;AAAA,MACtC,uBAAuB,YAAY,CAAC;AAAA,MACpC;AAAA,MACA,MAAM,yCAAyC,wBAAwB,KAAK,QAAQ,QAAQ;AAAA,MAC5F;AAAA,IACF;AAEA,WAAO,OAAO,OAAO,SAAS,YAAY,SAAS;AAAA,EACrD,CAAC;AACH;AAGA,eAAsBE,iBAAgB,UAAsC;AAC1E,SAAO,cAAc,MAAM,gBAAwB,QAAQ,CAAC;AAC9D;AAQA,SAAS,oBAAoB,SAAyD;AACpF,MAAI,CAAC,QAAQ,MAAO,QAAO;AAC3B,SAAO,EAAE,GAAG,SAAS,OAAO,qBAAqB,QAAQ,KAAK,EAAE;AAClE;AAGA,eAAsB,oBACpB,YACA,SACA,UAAsC,CAAC,GACxB;AACf,MAAI,gBAAgB,UAAU,GAAG;AAC/B,UAAM,IAAI,yBAAyB,uBAAuB,UAAU,CAAC;AAAA,EACvE;AAEA,QAAM,aAAa,uBAAuB,UAAU;AACpD,QAAM,UAAUD,MAAK,QAAQ,UAAU,CAAC;AACxC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,MACE,mBAAmB,oBAAoB,OAAO,GAAG,QAAQ,YAAY;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AACF;;;AMxgBA,OAAOE,WAAU;AAkCjB,eAAsB,mBAAmB,SAAyD;AAChG,QAAM,EAAE,WAAW,cAAc,YAAY,WAAW,IAAI;AAC5D,QAAM,eAAe,oBAAoB,YAAY,SAAS;AAE9D,QAAM,UAAUC,MAAK,QAAQ,aAAa,UAAU,CAAC;AAErD,QAAM,EAAE,OAAO,IAAI,QAAQ,aAAc,MAAM,cAAc;AAE7D,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AACA,QAAM,cAAc,YAAY;AAEhC,QAAM,mBAAmB,CAAC,gBAAgB,UAAU;AAEpD,MAAI,kBAAkB;AAEpB,UAAMC,iBAAgB,cAAc,UAAU,CAAC;AAAA,EACjD;AAEA,QAAM,cAAc,MAAM,mBAAmB;AAAA,IAC3C;AAAA,IACA,QAAQ,aAAa;AAAA,IACrB;AAAA,IACA;AAAA,IACA,mBAAmB,aAAa;AAAA,IAChC,2BAA2B;AAAA;AAAA,IAE3B,GAAI,QAAQ,uBAAuB,UAAa;AAAA,MAC9C,oBAAoB,QAAQ;AAAA,IAC9B;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,YAAY,aAAa;AAAA,IACzB,WAAW,YAAY;AAAA,IACvB,GAAI,YAAY,uBAAuB,UAAa;AAAA,MAClD,oBAAoB,YAAY;AAAA,IAClC;AAAA,IACA;AAAA,EACF;AACF;;;AChFA,OAAOC,SAAQ;AAgBf,eAAsB,uBACpB,SAC4B;AAC5B,QAAM,EAAE,YAAY,YAAY,QAAQ,cAAc,IAAI;AAC1D,QAAM,OAAO,EAAE,YAAY,QAAQ,cAAc;AAEjD,MAAI,gBAAgB,UAAU,GAAG;AAC/B,WAAO,cAAc;AAAA,MACnB,GAAG;AAAA,MACH;AAAA,MACA,WAAW,oBAAoB,YAAY,SAAS,EAAE;AAAA,IACxD,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,MAAM,cAAc;AAAA,IACvC,GAAG;AAAA,IACH,YAAYC,IAAG,QAAQ;AAAA,IACvB,WAAW,oBAAoBA,IAAG,QAAQ,GAAG,QAAQ,EAAE;AAAA,IACvD,aAAa;AAAA,EACf,CAAC;AACD,QAAM,gBAAgB,MAAM,oBAAoB,OAAO;AACvD,SAAO,wBAAwB,cAAc,aAAa;AAC5D;AAEA,eAAsB,oBACpB,SAC4B;AAC5B,QAAM,EAAE,YAAY,YAAY,QAAQ,cAAc,IAAI;AAC1D,SAAO,cAAc;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,oBAAoB,YAAY,SAAS,EAAE;AAAA,IACtD,aAAa;AAAA,EACf,CAAC;AACH;AAEA,SAAS,2BAA2B,SAAiD;AACnF,SAAO;AAAA,IACL,UAAU,QAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ;AAAA,IAC3C,WAAW,QAAQ,QAAQ,CAAC,MAAM,EAAE,SAAS;AAAA,IAC7C,QAAQ,QAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,IACvC,UAAU,QAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ;AAAA,EAC7C;AACF;","names":["isDeepEqual","unique","typedEntries","typedKeys","matrix","typedEntries","matrix","isExclusiveCategory","unique","isDeepEqual","os","path","isDeepEqual","isDeepEqual","matrix","path","path","matrix","loadSkillsMatrixFromSource","matrix","loadAgentDefs","os","path","ensureBlankPair","path","path","ensureBlankPair","os","os"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/seed/installation-payload.ts","../src/cli/lib/seed/config-to-seed.ts","../src/cli/lib/seed/publish-seed.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\n\nimport {\n configToSeedPayload,\n isInstalled,\n skillsItsMarketplaceLeavesBehind,\n} from \"./config-to-seed.js\";\nimport { readCarriedSkills } from \"./external-skills.js\";\nimport { EJECT_SOURCE } from \"../../consts.js\";\nimport { withoutExcludedAssignments } from \"../agents/agent-recompiler.js\";\nimport { loadProjectConfig, loadProjectConfigFromDir } from \"../configuration/project-config.js\";\nimport { activeAgentScopeMap, activeSkillScopeMap } from \"../configuration/scope-predicates.js\";\nimport { getProjectConfigPath, resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { readForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { ERROR_MESSAGES } from \"../../utils/messages.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading, OwnedSkillDir } from \"./external-skills.js\";\nimport type { LoadedProjectConfig } from \"../configuration/project-config.js\";\nimport type { AgentScopeConfig, ProjectConfig, SkillConfig, SkillId } from \"../../types/index.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * Counts come off the payload, not the config, so what is announced matches what is posted.\n * `leftBehind`: carried skills the payload's one marketplace does not serve.\n */\nexport type InstallationPayload =\n | { ok: true; payload: SeedPayload; skills: number; agents: number; leftBehind: SkillId[] }\n | { ok: false; error: string };\n\n/** `inheritedFrom` is absent when the config read is the global one already. */\ntype InstalledConfig =\n | { ok: true; config: ProjectConfig; inheritedFrom: ProjectConfig | undefined }\n | { ok: false; error: string };\n\ntype MappedPayload = { ok: true; payload: SeedPayload } | { ok: false; error: string };\n\ntype RoundTrip = { config: ProjectConfig; content: ContentReading };\n\ntype SkillJudgement = { skill: SkillConfig; owned: boolean; carried: OwnedSkillDir | null };\n\n/** Shared by `share` and `edit --ui` so both mint the same id; fails as a message, never a throw. */\nexport async function seedPayloadForInstallation(projectDir: string): Promise<InstallationPayload> {\n const installed = await readInstalledConfig(projectDir);\n if (!installed.ok) return installed;\n\n const roundTrip = await readRoundTrip(installed.config, projectDir);\n const mapped = mapOrRefuse(roundTrip, installed.inheritedFrom);\n if (!mapped.ok) return mapped;\n\n const { payload } = mapped;\n const skills = Object.keys(payload.skills).length;\n const agents = Object.keys(payload.agents).length;\n\n // A sub-agent is installable without skills, so only neither-skills-nor-agents is empty.\n if (skills === 0 && agents === 0) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n\n const leftBehind = skillsItsMarketplaceLeavesBehind(roundTrip.config, payload);\n return { ok: true, payload, skills, agents, leftBehind };\n}\n\n/** An unloadable config, HOME's included, is reported as its own error, not \"not installed\". */\nasync function readInstalledConfig(projectDir: string): Promise<InstalledConfig> {\n try {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n const inheritedFrom = await readInheritedConfig(loaded);\n return { ok: true, config: withInheritedCuration(loaded.config, inheritedFrom), inheritedFrom };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n\nasync function readInheritedConfig(\n loaded: LoadedProjectConfig,\n): Promise<ProjectConfig | undefined> {\n if (isGlobalConfig(loaded)) return undefined;\n\n // Aborts: a throw reaches readInstalledConfig and refuses the share.\n const home = await loadProjectConfigFromDir(os.homedir(), loaded.provider);\n return home?.config;\n}\n\nfunction isGlobalConfig(loaded: LoadedProjectConfig): boolean {\n return loaded.configPath === getProjectConfigPath(os.homedir(), loaded.provider);\n}\n\n/**\n * A project file keeps stack rows for its own sub-agents only, so inherited sub-agents take their\n * rows from the global config (which wins, since it compiles them).\n */\nfunction withInheritedCuration(\n config: ProjectConfig,\n inheritedFrom: ProjectConfig | undefined,\n): ProjectConfig {\n if (inheritedFrom?.stack === undefined) return config;\n\n return { ...config, stack: { ...config.stack, ...inheritedRows(config, inheritedFrom.stack) } };\n}\n\n/** Narrowed to inherited sub-agents and skills, so no global row lands on a project-scoped entry. */\nfunction inheritedRows(\n config: ProjectConfig,\n globalStack: NonNullable<ProjectConfig[\"stack\"]>,\n): NonNullable<ProjectConfig[\"stack\"]> {\n const agents = inheritedAgents(config.agents);\n const rows = Object.fromEntries(typedEntries(globalStack).filter(([agent]) => agents.has(agent)));\n return withoutExcludedAssignments(rows, skillsNotInherited(config.skills));\n}\n\nfunction inheritedAgents(agents: AgentScopeConfig[]): Set<string> {\n const scopes = activeAgentScopeMap(agents);\n return new Set(agents.map((agent) => agent.name).filter((name) => scopes.get(name) === \"global\"));\n}\n\nfunction skillsNotInherited(skills: SkillConfig[]): Set<SkillId> {\n const scopes = activeSkillScopeMap(skills);\n return new Set(skills.map((skill) => skill.id).filter((id) => scopes.get(id) !== \"global\"));\n}\n\n/**\n * Drops skills the CLI did not write (no `forkedFrom`): a user-authored skill is outside the round\n * trip, neither carried nor refused.\n */\nasync function readRoundTrip(config: ProjectConfig, projectDir: string): Promise<RoundTrip> {\n const owned = (await judgeSkills(config, projectDir)).filter((entry) => entry.owned);\n\n return {\n config: { ...config, skills: owned.map((entry) => entry.skill) },\n content: await readCarriedSkills(owned.flatMap((entry) => entry.carried ?? [])),\n };\n}\n\nfunction judgeSkills(config: ProjectConfig, projectDir: string): Promise<SkillJudgement[]> {\n return Promise.all(config.skills.map((skill) => judgeSkill(skill, projectDir)));\n}\n\n/** User-authored skills, which `edit --from` must not read a payload's silence as deleting. */\nexport async function skillsAuthoredHere(\n config: ProjectConfig,\n projectDir: string,\n): Promise<Set<SkillId>> {\n const judged = await judgeSkills(config, projectDir);\n return new Set(judged.filter((entry) => !entry.owned).map((entry) => entry.skill.id));\n}\n\nfunction travelsAsAnId(skill: SkillConfig): SkillJudgement {\n return { skill, owned: true, carried: null };\n}\n\n/** Only an existing directory with no provenance is the user's own work. */\nasync function judgeSkill(skill: SkillConfig, projectDir: string): Promise<SkillJudgement> {\n if (skill.origin !== EJECT_SOURCE) return travelsAsAnId(skill);\n if (!isInstalled(skill)) return travelsAsAnId(skill);\n\n const skillsDir = resolveInstallPaths(projectDir, skill.scope).skillsDir;\n const skillDir = path.join(skillsDir, skill.id);\n if (!(await directoryExists(skillDir))) return travelsAsAnId(skill);\n\n const provenance = await readForkedFromMetadata(skillDir);\n if (provenance === null) return { skill, owned: false, carried: null };\n\n return { skill, owned: true, carried: { id: skill.id, skillDir, provenance } };\n}\n\nfunction mapOrRefuse(\n { config, content }: RoundTrip,\n inheritedFrom: ProjectConfig | undefined,\n): MappedPayload {\n try {\n return { ok: true, payload: configToSeedPayload(config, content, inheritedFrom) };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n","import { MATRIX_VERSION } from \"@workspace/matrix\";\nimport { SEED_VERSION, seedModelSchema } from \"@workspace/matrix/seed\";\n\nimport { DEFAULT_PUBLIC_SOURCE_NAME, EJECT_SOURCE } from \"../../consts.js\";\nimport { isScopePairCompatible } from \"../configuration/config-generator.js\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading } from \"./external-skills.js\";\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillConfig,\n SkillScope,\n} from \"../../types/config.js\";\nimport type { ModelName } from \"../../types/matrix.js\";\nimport type { SkillId } from \"../../types/skills.js\";\nimport type {\n SeedAgent,\n SeedLoadState,\n SeedModel,\n SeedPayload,\n SeedSkill,\n} from \"@workspace/matrix/seed\";\n\ntype SeedAssignments = Record<string, SeedLoadState>;\n\ntype StackReading = {\n assignments: Map<SkillId, SeedAssignments>;\n unwritable: string[];\n};\n\n/** A tombstone describes something not installed, so it has nothing to say on the wire. */\nexport function isInstalled(entry: { excluded?: boolean }): boolean {\n return !entry.excluded;\n}\n\n/** An ejected copy travels with the project, and the default catalogue is what no ref means. */\nfunction needsMarketplaceNamed(origin: string): boolean {\n return origin !== EJECT_SOURCE && origin !== DEFAULT_PUBLIC_SOURCE_NAME;\n}\n\n/** The contract's own enum, so widening `MODEL_NAMES` alone cannot silently drop a pin. */\nfunction isSeedModel(model: ModelName): model is SeedModel {\n return seedModelSchema.safeParse(model).success;\n}\n\nfunction seedLoadState(preloaded: boolean | undefined): SeedLoadState {\n return preloaded === true ? \"preloaded\" : \"lazy\";\n}\n\nfunction unnameableOriginMessage(skill: SkillConfig): string {\n return `${skill.id} comes from the marketplace '${skill.origin}', and this installation does not record where that marketplace is fetched from`;\n}\n\nfunction unnameableModelMessage(agent: AgentScopeConfig[\"name\"], model: ModelName): string {\n return `${agent} pins model '${model}', which this contract has no word for — leaving it out would say \"keep the sub-agent's own metadata\", which is a different instruction`;\n}\n\nfunction unwritablePairMessage(skillId: SkillId, agent: string): string {\n return `${skillId} -> ${agent}: a project-scoped skill never reaches a sub-agent that rests at global scope`;\n}\n\nfunction unshareableConfigError(unshareable: string[]): string {\n return [\n \"This installation cannot be shared as it stands — a shared configuration has no way to carry:\",\n ...unshareable.map((line) => ` ${line}`),\n \"Sharing it anyway would mint an id that installs something else.\",\n ].join(\"\\n\");\n}\n\ntype MarketplaceReading = {\n ref: string | undefined;\n unnameable: string[];\n};\n\ntype MarketplaceRecord = Pick<ProjectConfig, \"marketplace\" | \"marketplaceName\">;\n\n/** `origin` is a marketplace name, `marketplace` its ref, and `marketplaceName` joins them. */\nfunction isRecordedMarketplace(record: MarketplaceRecord | undefined, skill: SkillConfig): boolean {\n return record?.marketplace !== undefined && skill.origin === record.marketplaceName;\n}\n\n/** A payload names one marketplace; only a skill whose marketplace neither config records is refused. */\nfunction readMarketplace(\n config: ProjectConfig,\n skills: SkillConfig[],\n inheritedFrom: MarketplaceRecord | undefined,\n): MarketplaceReading {\n const served = skills.filter((skill) => needsMarketplaceNamed(skill.origin));\n const unaccounted = served.filter(\n (skill) =>\n !isRecordedMarketplace(config, skill) && !isRecordedMarketplace(inheritedFrom, skill),\n );\n if (unaccounted.length > 0) {\n return { ref: undefined, unnameable: unaccounted.map(unnameableOriginMessage) };\n }\n\n const servesItsOwn = served.some((skill) => isRecordedMarketplace(config, skill));\n return { ref: servesItsOwn ? config.marketplace : undefined, unnameable: [] };\n}\n\n/** Plugins from a marketplace other than the payload's one, which an install will skip. */\nexport function skillsItsMarketplaceLeavesBehind(\n config: ProjectConfig,\n payload: SeedPayload,\n): SkillId[] {\n const namedMarketplace =\n payload.marketplace === undefined ? DEFAULT_PUBLIC_SOURCE_NAME : config.marketplaceName;\n const isPluginFromElsewhere = (skill: SkillConfig): boolean =>\n skill.origin !== EJECT_SOURCE && skill.origin !== namedMarketplace;\n\n return config.skills\n .filter(isInstalled)\n .filter(isPluginFromElsewhere)\n .map((skill) => skill.id);\n}\n\nfunction unnameableModels(agents: AgentScopeConfig[]): string[] {\n return agents.flatMap((agent) =>\n agent.model !== undefined && !isSeedModel(agent.model)\n ? [unnameableModelMessage(agent.name, agent.model)]\n : [],\n );\n}\n\n/** Re-keys rows by skill; rows the decoder would refuse are collected for the refusal. */\nfunction readStack(\n stack: ProjectConfig[\"stack\"],\n skillScopes: Map<SkillId, SkillScope>,\n agentScopes: Map<string, SkillScope>,\n): StackReading {\n const assignments = new Map<SkillId, SeedAssignments>();\n const unwritable: string[] = [];\n\n for (const [agent, agentStack] of typedEntries(stack ?? {})) {\n const agentScope = agentScopes.get(agent);\n if (agentScope === undefined) continue;\n\n for (const { id, preloaded } of typedValues(agentStack).flat()) {\n const skillScope = skillScopes.get(id);\n if (skillScope === undefined) continue;\n\n if (!isScopePairCompatible(skillScope, agentScope)) {\n unwritable.push(unwritablePairMessage(id, agent));\n continue;\n }\n\n const forSkill = assignments.get(id) ?? {};\n forSkill[agent] = seedLoadState(preloaded);\n assignments.set(id, forSkill);\n }\n }\n\n return { assignments, unwritable };\n}\n\nfunction toSeedSkill(skill: SkillConfig, assignments: SeedAssignments | undefined): SeedSkill {\n return {\n // A plugin's marketplace has already been checked against the envelope's ref.\n install: skill.origin === EJECT_SOURCE ? \"eject\" : \"plugin\",\n scope: skill.scope,\n assignments: assignments ?? {},\n };\n}\n\n/** Always `on`: it carries a sub-agent that owns no skill, which assignments cannot. */\nfunction toSeedAgent(agent: AgentScopeConfig): SeedAgent {\n return {\n on: true,\n scope: agent.scope,\n ...(agent.model !== undefined && isSeedModel(agent.model) && { model: agent.model }),\n ...(agent.codexModel !== undefined && { codexModel: agent.codexModel }),\n ...(agent.effort !== undefined && { effort: agent.effort }),\n };\n}\n\n/** Inverse of `seedToInstallSelection`; anything the contract cannot state is refused by name. */\nexport function configToSeedPayload(\n config: ProjectConfig,\n carried: ContentReading,\n inheritedFrom?: MarketplaceRecord,\n): SeedPayload {\n const skills = config.skills.filter(isInstalled);\n const agents = config.agents.filter(isInstalled);\n const skillScopes = new Map(skills.map((skill) => [skill.id, skill.scope]));\n const agentScopes = new Map<string, SkillScope>(agents.map((agent) => [agent.name, agent.scope]));\n\n const { assignments, unwritable } = readStack(config.stack, skillScopes, agentScopes);\n const marketplace = readMarketplace(config, skills, inheritedFrom);\n\n const unshareable = [\n ...marketplace.unnameable,\n ...unnameableModels(agents),\n ...unwritable,\n ...carried.uncarryable,\n ];\n if (unshareable.length > 0) throw new Error(unshareableConfigError(unshareable));\n\n return {\n v: SEED_VERSION,\n matrixVersion: MATRIX_VERSION,\n stackId: null,\n // Absent rather than empty: an id is the hash of its body.\n ...(config.description !== undefined && { description: config.description }),\n ...(marketplace.ref !== undefined && { marketplace: marketplace.ref }),\n skills: Object.fromEntries(\n skills.map((skill) => [skill.id, toSeedSkill(skill, assignments.get(skill.id))]),\n ),\n ...(Object.keys(carried.external).length > 0 && { external: carried.external }),\n agents: Object.fromEntries(agents.map((agent) => [agent.name, toSeedAgent(agent)])),\n };\n}\n","import { STATUS_CODES } from \"node:http\";\n\nimport { retryAfterSeconds } from \"@workspace/api\";\nimport { z } from \"zod\";\n\nimport { arrivedAsText, jsonBodyOrUndefined, SEED_API_URL, SEED_USER_AGENT } from \"./fetch-seed.js\";\nimport { CLI_INVOKE_COMMAND } from \"../../consts.js\";\nimport { plural, truncateText } from \"../../utils/string.js\";\n\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/** Revalidated: the deployed worker may not match the one this CLI was built against. */\nconst mintedSchema = z.object({ id: z.string().min(1) });\n\n/** `@hono/zod-validator` sends the `safeParse` result; its error crosses as `{ name, message }`. */\nconst refusalSchema = z.object({ error: z.object({ message: z.string() }) });\n\n/** Zod renders its issues into `message` as JSON; the readable sentences are inside. */\nconst refusedIssuesSchema = z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string().min(1),\n }),\n )\n .min(1);\n\n/** Holds about two of the store's refusal sentences; a longer body must not paint the terminal. */\nconst EXPLANATION_BUDGET = 300;\n\nconst CONTRACT_MISMATCH = 409;\n\nconst RATE_LIMITED = 429;\n\n/** The editor's `limitReachedNote` wording, so both front doors say it alike. */\nconst LIMIT_REACHED = \"rate limit reached — try again in\";\n\nconst SECONDS_PER_MINUTE = 60;\n\n/**\n * The store's 409 body says \"Reload the page\", which a terminal cannot do. The seed version is\n * bundled into the CLI, so only a newer CLI fixes it.\n */\nconst OUT_OF_DATE_AGAINST_STORE =\n `This CLI is out of date against the configuration store: it writes a version of the sharing ` +\n `contract the store does not serve, and that version travels inside the CLI rather than with ` +\n `the configuration. Re-run this command through '${CLI_INVOKE_COMMAND}@latest'.`;\n\nexport type PublishSeedResult = { ok: true; id: string } | { ok: false; error: string };\n\n/** Every failure is a message rather than a throw. */\nexport async function publishSeedConfig(payload: SeedPayload): Promise<PublishSeedResult> {\n const response = await postToStore(payload);\n if (response === null) {\n return { ok: false, error: `Could not reach ${SEED_API_URL} — check your connection.` };\n }\n\n if (!response.ok) return { ok: false, error: await refusalMessage(response) };\n\n return mintedIdIn(await jsonBodyOrUndefined(response));\n}\n\n/** Null where the store could not be reached at all. */\nasync function postToStore(payload: SeedPayload): Promise<Response | null> {\n try {\n return await fetch(`${SEED_API_URL}/configs`, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n // Tells the store the configuration came from the CLI rather than a browser.\n \"user-agent\": SEED_USER_AGENT,\n },\n body: JSON.stringify(payload),\n });\n } catch {\n return null;\n }\n}\n\nfunction mintedIdIn(body: unknown): PublishSeedResult {\n if (body === undefined) {\n return { ok: false, error: \"The configuration store returned something that is not JSON.\" };\n }\n\n const minted = mintedSchema.safeParse(body);\n if (!minted.success) {\n return { ok: false, error: \"The configuration store did not return an id for this share.\" };\n }\n\n return { ok: true, id: minted.data.id };\n}\n\n/** Always names the status, and quotes the store's own explanation when it gives one. */\nasync function refusalMessage(response: Response): Promise<string> {\n const failed = `Sharing this configuration failed (HTTP ${response.status})`;\n const refused = `${failed}.`;\n\n if (response.status === CONTRACT_MISMATCH) return `${refused} ${OUT_OF_DATE_AGAINST_STORE}`;\n\n const window = rateLimitWindow(response);\n if (window !== null) return `${failed}: ${LIMIT_REACHED} ${waitOf(window)}.`;\n\n const explanation = explanationOf(response, await refusalBody(response));\n\n return explanation === undefined ? refused : `${refused} The store said: ${explanation}`;\n}\n\n/** Seconds to wait out, or `null` where this is no 429 or its window is unreadable. */\nfunction rateLimitWindow(response: Response): number | null {\n return response.status === RATE_LIMITED ? retryAfterSeconds(response) : null;\n}\n\n/** Minutes round up, so nobody is sent back early. */\nfunction waitOf(seconds: number): string {\n return seconds < SECONDS_PER_MINUTE\n ? plural(seconds, \"second\")\n : plural(Math.ceil(seconds / SECONDS_PER_MINUTE), \"minute\");\n}\n\n/** Not gated on content type: this route refuses as JSON and as plain text. */\nasync function refusalBody(response: Response): Promise<string | undefined> {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n}\n\nfunction jsonOf(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction explanationOf(response: Response, body: string | undefined): string | undefined {\n if (body === undefined) return undefined;\n\n const said = schemaIssuesIn(body) ?? quotableProseIn(response, body);\n\n return said === undefined ? undefined : truncateText(said, EXPLANATION_BUDGET);\n}\n\nfunction schemaIssuesIn(body: string): string | undefined {\n const refusal = refusalSchema.safeParse(jsonOf(body));\n if (!refusal.success) return undefined;\n\n const issues = refusedIssuesSchema.safeParse(jsonOf(refusal.data.error.message));\n if (!issues.success) return undefined;\n\n return issues.data.map(sentenceOf).join(\"; \");\n}\n\n/** Quoted only when it adds something to the status printed beside it. */\nfunction quotableProseIn(response: Response, body: string): string | undefined {\n if (!arrivedAsText(response)) return undefined;\n\n const said = body.trim();\n if (said === \"\") return undefined;\n if (restatesItsOwnStatus(said, response.status)) return undefined;\n\n return said;\n}\n\n/** Case-insensitive: the worker writes sentence case where the reason phrase is title case. */\nfunction restatesItsOwnStatus(said: string, status: number): boolean {\n const reason = STATUS_CODES[status];\n\n return reason !== undefined && said.toLowerCase() === reason.toLowerCase();\n}\n\ntype RefusedIssue = z.infer<typeof refusedIssuesSchema>[number];\n\n/** Renders like `formatZodIssue`, which cannot take a plain object read off the wire. */\nfunction sentenceOf(issue: RefusedIssue): string {\n const path = issue.path.join(\".\");\n return path === \"\" ? issue.message : `${path}: ${issue.message}`;\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/lib/agents/agent-fetcher.ts","../src/cli/lib/agents/agent-plugin-compiler.ts"],"sourcesContent":["import path from \"path\";\nimport { directoryExists } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { PROJECT_ROOT, DIRS } from \"../../consts\";\nimport type { AgentSourcePaths } from \"../../types\";\n\nexport async function getLocalAgentDefinitions(): Promise<AgentSourcePaths> {\n const agentsDir = path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(agentsDir))) {\n throw new Error(\n `Agent partials not found at '${agentsDir}'. Ensure the CLI is properly installed.`,\n );\n }\n\n verbose(`Agent partials loaded from CLI: ${agentsDir}`);\n\n return {\n agentsDir,\n sourcePath: PROJECT_ROOT,\n };\n}\n","import path from \"path\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { readFile, ensureDir, copy } from \"../../utils/fs\";\nimport { log, verbose, warn } from \"../../utils/logger\";\nimport {\n agentPluginName,\n generateAgentPluginManifest,\n getPluginAgentsDir,\n writePluginManifest,\n getPluginManifestPath,\n} from \"../plugins\";\nimport { listAgentMdFiles } from \"./list-compiled-agents\";\nimport { agentCodec } from \"../installation/install-layout\";\nimport { computeStringHash, determinePluginVersion, writeContentHash } from \"../versioning\";\nimport { extractFrontmatter } from \"../../utils/frontmatter\";\nimport { plural } from \"../../utils/string\";\nimport type { AgentFrontmatter, PluginManifest } from \"../../types\";\nimport { agentFrontmatterValidationSchema, formatZodIssues } from \"../schemas\";\n\ntype AgentPluginOptions = {\n agentPath: string;\n outputDir: string;\n};\n\ntype CompiledAgentPlugin = {\n pluginPath: string;\n manifest: PluginManifest;\n agentName: string;\n};\n\n/** Carries the reason out, so the throw in `compileAgentPlugin` names what actually went wrong. */\ntype AgentFrontmatterParse =\n | { ok: true; frontmatter: Pick<AgentFrontmatter, \"name\" | \"description\"> }\n | { ok: false; reason: string };\n\nconst NO_FRONTMATTER_REASON = \"no YAML frontmatter block\";\n\nfunction parseAgentFrontmatter(content: string): AgentFrontmatterParse {\n const raw = extractFrontmatter(content);\n if (!raw) {\n return { ok: false, reason: NO_FRONTMATTER_REASON };\n }\n\n const result = agentFrontmatterValidationSchema.safeParse(raw);\n if (!result.success) {\n return { ok: false, reason: formatZodIssues(result.error.issues) };\n }\n\n return {\n ok: true,\n frontmatter: { name: result.data.name, description: result.data.description },\n };\n}\n\nasync function compileAgentPlugin(options: AgentPluginOptions): Promise<CompiledAgentPlugin> {\n const { agentPath, outputDir } = options;\n const fileName = path.basename(agentPath);\n\n const content = await readFile(agentPath);\n const parsed = parseAgentFrontmatter(content);\n\n if (!parsed.ok) {\n throw new Error(\n `Agent '${fileName}' has invalid or missing YAML frontmatter: ${parsed.reason}. ` +\n `File: ${agentPath}`,\n );\n }\n\n const agentName = parsed.frontmatter.name;\n\n verbose(`Compiling agent plugin: ${agentName} from ${agentPath}`);\n\n const pluginDir = path.join(outputDir, agentPluginName(agentName));\n const agentsDir = getPluginAgentsDir(pluginDir);\n\n await ensureDir(pluginDir);\n await ensureDir(agentsDir);\n\n const newHash = computeStringHash(content);\n const { version, contentHash } = await determinePluginVersion(\n newHash,\n pluginDir,\n getPluginManifestPath,\n );\n\n const manifest = generateAgentPluginManifest({\n agentName,\n description: parsed.frontmatter.description,\n version,\n });\n\n await writePluginManifest(pluginDir, manifest);\n\n await writeContentHash(pluginDir, contentHash, getPluginManifestPath);\n\n verbose(` Wrote plugin.json for ${agentName} (v${version})`);\n\n const pluginAgentFile = `${agentName}${agentCodec(\"claude\").extension}`;\n await copy(agentPath, path.join(agentsDir, pluginAgentFile));\n verbose(` Copied agent ${fileName} -> agents/${pluginAgentFile}`);\n\n return {\n pluginPath: pluginDir,\n manifest,\n agentName,\n };\n}\n\nexport async function compileAllAgentPlugins(\n agentsDir: string,\n outputDir: string,\n): Promise<CompiledAgentPlugin[]> {\n const results: CompiledAgentPlugin[] = [];\n\n const agentMdFiles = await listAgentMdFiles(agentsDir);\n\n for (const agentFile of agentMdFiles) {\n const agentPath = path.join(agentsDir, agentFile);\n\n try {\n const result = await compileAgentPlugin({\n agentPath,\n outputDir,\n });\n results.push(result);\n log(` [OK] ${agentPluginName(result.agentName)}`);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n warn(`Failed to compile agent from '${agentFile}': ${errorMessage}`);\n }\n }\n\n return results;\n}\n\nexport function printAgentCompilationSummary(results: CompiledAgentPlugin[]): void {\n log(`\\nCompiled ${plural(results.length, \"agent plugin\")}:`);\n for (const result of results) {\n log(` - ${agentPluginName(result.agentName)} (v${result.manifest.version})`);\n }\n}\n"],"mappings":"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","names":["path","path"]}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
loadAgentDefs
|
|
4
|
-
} from "./chunk-7IVLVEHX.js";
|
|
5
|
-
import "./chunk-WII6GOPM.js";
|
|
6
|
-
import "./chunk-AWWCRL5A.js";
|
|
7
|
-
import "./chunk-3YYHL76L.js";
|
|
8
|
-
import "./chunk-24OD7IP4.js";
|
|
9
|
-
import "./chunk-A6OWEJGC.js";
|
|
10
|
-
import "./chunk-GHHJYNAN.js";
|
|
11
|
-
export {
|
|
12
|
-
loadAgentDefs
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=load-agent-defs-UBWITIEI.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|