agents-inc 0.173.0 → 0.174.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 +54 -0
- package/dist/{chunk-Q4UNHVPX.js → chunk-3PJZ4QNJ.js} +7 -7
- package/dist/{chunk-3N4FSTVX.js → chunk-6PGXTLA4.js} +2 -2
- package/dist/{chunk-ITQF35UQ.js → chunk-7BHDKEGK.js} +3 -3
- package/dist/{chunk-7OG635DK.js → chunk-AIBVAYHS.js} +6 -2
- package/dist/{chunk-7OG635DK.js.map → chunk-AIBVAYHS.js.map} +1 -1
- package/dist/{chunk-AARQBW5L.js → chunk-APWMMZOK.js} +30 -23
- package/dist/chunk-APWMMZOK.js.map +1 -0
- package/dist/{chunk-WVFBBZEP.js → chunk-E45IT3HC.js} +117 -22
- package/dist/chunk-E45IT3HC.js.map +1 -0
- package/dist/{chunk-F437ICEG.js → chunk-ECPFYHDX.js} +2 -2
- package/dist/{chunk-EHJIQDXR.js → chunk-EFXVYQGT.js} +4 -4
- package/dist/{chunk-G7NUK3BF.js → chunk-FQF6VHO3.js} +29 -19
- package/dist/chunk-FQF6VHO3.js.map +1 -0
- package/dist/chunk-H5E6IO2L.js +116 -0
- package/dist/chunk-H5E6IO2L.js.map +1 -0
- package/dist/{chunk-3R3LHA4Q.js → chunk-I3WF6L43.js} +2 -2
- package/dist/{chunk-LJQXQTFC.js → chunk-IAQFZFWD.js} +4 -4
- package/dist/{chunk-BRZA7ZCX.js → chunk-IXVGBUWI.js} +5 -5
- package/dist/{chunk-2RTBSLSR.js → chunk-ORO2T4K2.js} +19 -5
- package/dist/chunk-ORO2T4K2.js.map +1 -0
- package/dist/{chunk-A3ZAXL5T.js → chunk-QCX66KBM.js} +3 -3
- package/dist/{chunk-VSPC74SS.js → chunk-R7GKQBZJ.js} +10 -9
- package/dist/chunk-R7GKQBZJ.js.map +1 -0
- package/dist/{chunk-VR6QTK5Z.js → chunk-REHVGFJE.js} +5 -5
- package/dist/{chunk-SPQSNZMM.js → chunk-TVEDNGVP.js} +2 -2
- package/dist/{chunk-MHAQWMNJ.js → chunk-WUSEZFER.js} +1 -5
- package/dist/{chunk-MHAQWMNJ.js.map → chunk-WUSEZFER.js.map} +1 -1
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +7 -7
- package/dist/commands/edit.js +56 -59
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +10 -10
- package/dist/commands/init.js +17 -18
- package/dist/commands/list.js +41 -16
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +9 -9
- package/dist/commands/share.js +9 -9
- package/dist/commands/uninstall.js +25 -24
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +3 -3
- package/dist/components/common/summary-panel.js +4 -7
- package/dist/hooks/init.js +40 -25
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-5U5KAURA.js +14 -0
- package/dist/{recompile-project-agents-6G6M2RS6.js → recompile-project-agents-KYK44C24.js} +8 -8
- package/dist/{source-loader-W7XCNKNA.js → source-loader-G5I4RNUP.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-2RTBSLSR.js.map +0 -1
- package/dist/chunk-AARQBW5L.js.map +0 -1
- package/dist/chunk-G7NUK3BF.js.map +0 -1
- package/dist/chunk-N33AKFLR.js +0 -24
- package/dist/chunk-N33AKFLR.js.map +0 -1
- package/dist/chunk-Q6WRR4BN.js +0 -195
- package/dist/chunk-Q6WRR4BN.js.map +0 -1
- package/dist/chunk-VSPC74SS.js.map +0 -1
- package/dist/chunk-WVFBBZEP.js.map +0 -1
- package/dist/components/common/scroll-affordance.js +0 -9
- package/dist/load-agent-defs-E67DSYTN.js +0 -14
- package/dist/source-loader-W7XCNKNA.js.map +0 -1
- /package/dist/{chunk-Q4UNHVPX.js.map → chunk-3PJZ4QNJ.js.map} +0 -0
- /package/dist/{chunk-3N4FSTVX.js.map → chunk-6PGXTLA4.js.map} +0 -0
- /package/dist/{chunk-ITQF35UQ.js.map → chunk-7BHDKEGK.js.map} +0 -0
- /package/dist/{chunk-F437ICEG.js.map → chunk-ECPFYHDX.js.map} +0 -0
- /package/dist/{chunk-EHJIQDXR.js.map → chunk-EFXVYQGT.js.map} +0 -0
- /package/dist/{chunk-3R3LHA4Q.js.map → chunk-I3WF6L43.js.map} +0 -0
- /package/dist/{chunk-LJQXQTFC.js.map → chunk-IAQFZFWD.js.map} +0 -0
- /package/dist/{chunk-BRZA7ZCX.js.map → chunk-IXVGBUWI.js.map} +0 -0
- /package/dist/{chunk-A3ZAXL5T.js.map → chunk-QCX66KBM.js.map} +0 -0
- /package/dist/{chunk-VR6QTK5Z.js.map → chunk-REHVGFJE.js.map} +0 -0
- /package/dist/{chunk-SPQSNZMM.js.map → chunk-TVEDNGVP.js.map} +0 -0
- /package/dist/{components/common/scroll-affordance.js.map → load-agent-defs-5U5KAURA.js.map} +0 -0
- /package/dist/{recompile-project-agents-6G6M2RS6.js.map → recompile-project-agents-KYK44C24.js.map} +0 -0
- /package/dist/{load-agent-defs-E67DSYTN.js.map → source-loader-G5I4RNUP.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
hostAt,
|
|
7
7
|
loadInstalledConfig,
|
|
8
8
|
refuseUnofferedPlacements
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-E45IT3HC.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/lib/hosts/configured-placements.ts
|
|
12
12
|
async function unofferablePlacementsFound(cwd) {
|
|
@@ -36,4 +36,4 @@ async function configuredSkillsAt(root) {
|
|
|
36
36
|
export {
|
|
37
37
|
unofferablePlacementsFound
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
//# sourceMappingURL=chunk-ECPFYHDX.js.map
|
|
@@ -29,12 +29,12 @@ import {
|
|
|
29
29
|
sourceFolderName,
|
|
30
30
|
verbose,
|
|
31
31
|
writeFile
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-E45IT3HC.js";
|
|
33
33
|
import {
|
|
34
34
|
typedEntries,
|
|
35
35
|
typedFromEntries,
|
|
36
36
|
typedKeys
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-AIBVAYHS.js";
|
|
38
38
|
import {
|
|
39
39
|
CLAUDE_DIR,
|
|
40
40
|
DIRS,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
STANDARD_DIRS,
|
|
43
43
|
STANDARD_FILES,
|
|
44
44
|
effectivelyExcludedSkillIds
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-WUSEZFER.js";
|
|
46
46
|
|
|
47
47
|
// src/cli/lib/agents/list-compiled-agents.ts
|
|
48
48
|
import path from "path";
|
|
@@ -374,4 +374,4 @@ export {
|
|
|
374
374
|
withoutExcludedAssignments,
|
|
375
375
|
recompileAgents
|
|
376
376
|
};
|
|
377
|
-
//# sourceMappingURL=chunk-
|
|
377
|
+
//# sourceMappingURL=chunk-EFXVYQGT.js.map
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
inertLine,
|
|
3
|
+
getSkillEntryDisplayName,
|
|
5
4
|
typedValues
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AIBVAYHS.js";
|
|
7
6
|
import {
|
|
8
7
|
CLI_COLORS,
|
|
9
8
|
EJECT_SOURCE,
|
|
10
9
|
UI_SYMBOLS,
|
|
11
10
|
isActiveAt,
|
|
12
11
|
isGlobalTombstone
|
|
13
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WUSEZFER.js";
|
|
14
13
|
|
|
15
14
|
// src/cli/components/common/skill-agent-summary.tsx
|
|
16
15
|
import { Box, Text } from "ink";
|
|
17
16
|
import "react";
|
|
18
17
|
|
|
19
18
|
// src/cli/lib/configuration/scope-diff.ts
|
|
20
|
-
import { difference, partition, unique } from "remeda";
|
|
19
|
+
import { difference, indexBy, partition, unique } from "remeda";
|
|
21
20
|
var NOTHING = /* @__PURE__ */ new Set();
|
|
22
21
|
function computeScopeDiff(input) {
|
|
23
22
|
const { currentSkills, currentAgents, installedSkillConfigs, installedAgentConfigs, isInitMode } = input;
|
|
@@ -87,9 +86,13 @@ function skillRowClassifier(installed, overwritten) {
|
|
|
87
86
|
return (skill) => ({
|
|
88
87
|
id: skill.id,
|
|
89
88
|
source: skill.origin,
|
|
90
|
-
status: skillStatus(skill, installedSlots, installedOriginBySlot, overwritten)
|
|
89
|
+
status: skillStatus(skill, installedSlots, installedOriginBySlot, overwritten),
|
|
90
|
+
...recordedNameOf(skill)
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
+
function recordedNameOf(skill) {
|
|
94
|
+
return skill.displayName === void 0 ? {} : { displayName: skill.displayName };
|
|
95
|
+
}
|
|
93
96
|
function agentRowClassifier(installed, changed) {
|
|
94
97
|
const installedSlots = installed ? new Set(installed.map((agent) => slotKey(agent.name, agent.scope))) : null;
|
|
95
98
|
return (agent) => ({ name: agent.name, status: agentStatus(agent, installedSlots, changed) });
|
|
@@ -108,7 +111,7 @@ function agentStatus(agent, installedSlots, changed) {
|
|
|
108
111
|
return !agent.excluded && changed.has(agent.name) ? "changed" : "unchanged";
|
|
109
112
|
}
|
|
110
113
|
function toRemovedSkillRow(skill) {
|
|
111
|
-
return { id: skill.id, source: skill.origin, status: "removed" };
|
|
114
|
+
return { id: skill.id, source: skill.origin, status: "removed", ...recordedNameOf(skill) };
|
|
112
115
|
}
|
|
113
116
|
function toRemovedAgentRow(agent) {
|
|
114
117
|
return { name: agent.name, status: "removed" };
|
|
@@ -122,9 +125,21 @@ function agentChangesAmong(names, before, after) {
|
|
|
122
125
|
return names.flatMap((name) => {
|
|
123
126
|
const was = agentStateIn(before, name);
|
|
124
127
|
const is = agentStateIn(after, name);
|
|
125
|
-
|
|
128
|
+
if (was === void 0 || is === void 0) return [];
|
|
129
|
+
return [namedByEntries(agentChange(was, is), before.skills, after.skills)];
|
|
126
130
|
});
|
|
127
131
|
}
|
|
132
|
+
function namedByEntries(change, before, after) {
|
|
133
|
+
const namedBy = {
|
|
134
|
+
...activeEntriesOf(change.loses, before),
|
|
135
|
+
...activeEntriesOf(change.gains, after)
|
|
136
|
+
};
|
|
137
|
+
return { ...change, namedBy };
|
|
138
|
+
}
|
|
139
|
+
function activeEntriesOf(skillIds, skills) {
|
|
140
|
+
const active = skills.filter((entry) => !entry.excluded && skillIds.includes(entry.id));
|
|
141
|
+
return indexBy(active, ({ id }) => id);
|
|
142
|
+
}
|
|
128
143
|
function agentStateIn(config, name) {
|
|
129
144
|
const agent = config.agents.find((entry) => entry.name === name && !entry.excluded);
|
|
130
145
|
return agent === void 0 ? void 0 : { agent, rows: config.stack?.[name] };
|
|
@@ -151,11 +166,6 @@ function assignedSkillIds(rows) {
|
|
|
151
166
|
|
|
152
167
|
// src/cli/components/common/skill-agent-summary.tsx
|
|
153
168
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
154
|
-
var NO_NAMES = /* @__PURE__ */ new Map();
|
|
155
|
-
function skillNameOf(id, names) {
|
|
156
|
-
const recorded = names.get(id);
|
|
157
|
-
return recorded === void 0 ? getSkillDisplayName(id) : inertLine(recorded);
|
|
158
|
-
}
|
|
159
169
|
var TableHeader = ({ children }) => /* @__PURE__ */ jsx(Text, { bold: true, color: CLI_COLORS.WARNING, children });
|
|
160
170
|
var ScopeLabel = ({ children }) => /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WHITE, backgroundColor: CLI_COLORS.LABEL_BG, children: ` ${children} ` });
|
|
161
171
|
var EjectIcon = () => /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.WARNING, children: [
|
|
@@ -179,10 +189,10 @@ var DIFF_COLOR = {
|
|
|
179
189
|
unchanged: CLI_COLORS.NEUTRAL
|
|
180
190
|
};
|
|
181
191
|
var NAME_GUTTER_COLUMNS = 3;
|
|
182
|
-
var SkillRow = ({ row
|
|
192
|
+
var SkillRow = ({ row }) => /* @__PURE__ */ jsxs(Box, { width: "50%", paddingRight: NAME_GUTTER_COLUMNS, children: [
|
|
183
193
|
/* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { color: DIFF_COLOR[row.status], children: DIFF_PREFIX[row.status] }) }),
|
|
184
194
|
/* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
|
|
185
|
-
|
|
195
|
+
getSkillEntryDisplayName(row),
|
|
186
196
|
row.source === EJECT_SOURCE && /* @__PURE__ */ jsx(EjectIcon, {})
|
|
187
197
|
] })
|
|
188
198
|
] });
|
|
@@ -195,7 +205,6 @@ var agentRowKey = (row) => row.status === "removed" ? `removed-${row.name}` : ro
|
|
|
195
205
|
var SkillAgentSummary = ({
|
|
196
206
|
skillConfigs,
|
|
197
207
|
agentConfigs,
|
|
198
|
-
skillNames = NO_NAMES,
|
|
199
208
|
...baseline
|
|
200
209
|
}) => {
|
|
201
210
|
const diff = computeScopeDiff({
|
|
@@ -222,11 +231,11 @@ var SkillAgentSummary = ({
|
|
|
222
231
|
/* @__PURE__ */ jsx(TableHeader, { children: "Skills" }),
|
|
223
232
|
diff.projectSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
224
233
|
/* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
|
|
225
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row
|
|
234
|
+
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
226
235
|
] }),
|
|
227
236
|
diff.globalSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
228
237
|
/* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
|
|
229
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row
|
|
238
|
+
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
230
239
|
] })
|
|
231
240
|
]
|
|
232
241
|
}
|
|
@@ -246,8 +255,9 @@ var SkillAgentSummary = ({
|
|
|
246
255
|
};
|
|
247
256
|
|
|
248
257
|
export {
|
|
258
|
+
computeScopeDiff,
|
|
249
259
|
formatScopeTag,
|
|
250
260
|
agentChangesAmong,
|
|
251
261
|
SkillAgentSummary
|
|
252
262
|
};
|
|
253
|
-
//# sourceMappingURL=chunk-
|
|
263
|
+
//# sourceMappingURL=chunk-FQF6VHO3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/common/skill-agent-summary.tsx","../src/cli/lib/configuration/scope-diff.ts"],"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 { getSkillEntryDisplayName } from \"../../lib/matrix/matrix-provider.js\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config.js\";\n\nexport type SkillAgentSummaryProps = Pick<\n ScopeDiffInput,\n | \"installedSkillConfigs\"\n | \"installedAgentConfigs\"\n | \"isInitMode\"\n | \"overwrittenSkillIds\"\n | \"changedAgentNames\"\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\": `${UI_SYMBOLS.CHANGED} `,\n overwritten: `${UI_SYMBOLS.OVERWRITTEN} `,\n changed: `${UI_SYMBOLS.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 overwritten: CLI_COLORS.WARNING,\n changed: CLI_COLORS.WARNING,\n removed: CLI_COLORS.ERROR,\n unchanged: CLI_COLORS.NEUTRAL,\n};\n\n/**\n * Yoga widens a text to whole columns on both sides and Ink draws it from its rounded left, so a\n * name in a half that starts or ends mid-column draws up to two columns past the half: over the\n * next name, or over the table's border. The third column stays blank.\n */\nconst NAME_GUTTER_COLUMNS = 3;\n\n/**\n * A long name wraps under itself, beside a prefix that never shrinks, and carries its mark in its\n * own text: drawn beside the name, the mark covered its last letters.\n */\nconst SkillRow: React.FC<{ row: SkillDiffRow }> = ({ row }) => (\n <Box width=\"50%\" paddingRight={NAME_GUTTER_COLUMNS}>\n <Box flexShrink={0}>\n <Text color={DIFF_COLOR[row.status]}>{DIFF_PREFIX[row.status]}</Text>\n </Box>\n <Text color={DIFF_COLOR[row.status]}>\n {getSkillEntryDisplayName(row)}\n {row.source === EJECT_SOURCE && <EjectIcon />}\n </Text>\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 ...baseline\n}) => {\n const diff = computeScopeDiff({\n currentSkills: skillConfigs,\n currentAgents: agentConfigs,\n ...baseline,\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","import { difference, indexBy, partition, unique } from \"remeda\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../../types/config\";\nimport type { AgentName, SkillId, StackAgentConfig } from \"../../types/index\";\nimport { typedValues } from \"../../utils/typed-object\";\nimport { isActiveAt, isGlobalTombstone, type ScopedEntry } from \"./scope-predicates\";\n\nexport type ScopeDiffInput = {\n currentSkills: SkillConfig[];\n currentAgents: AgentScopeConfig[];\n installedSkillConfigs: SkillConfig[] | null;\n installedAgentConfigs: AgentScopeConfig[] | null;\n isInitMode: boolean;\n /** Skills whose files the run writes over where they stand. */\n overwrittenSkillIds?: ReadonlySet<SkillId>;\n /** Sub-agents that keep their slot and still change. */\n changedAgentNames?: ReadonlySet<AgentName>;\n};\n\nexport type DiffRowStatus =\n \"added\" | \"mode-changed\" | \"overwritten\" | \"changed\" | \"removed\" | \"unchanged\";\n\nexport type SkillDiffRow = {\n id: SkillId;\n source: string;\n status: Exclude<DiffRowStatus, \"changed\">;\n /** The name the entry the row was drawn from records; absent where it records none. */\n displayName?: string;\n};\n\nexport type AgentDiffRow = {\n name: AgentName;\n status: Exclude<DiffRowStatus, \"mode-changed\" | \"overwritten\">;\n};\n\nexport type ScopeDiff = {\n projectSkillRows: SkillDiffRow[];\n globalSkillRows: SkillDiffRow[];\n projectAgentRows: AgentDiffRow[];\n globalAgentRows: AgentDiffRow[];\n hasContent: boolean;\n};\n\nconst NOTHING: ReadonlySet<never> = new Set();\n\n/** One scope's share of a roster's diff: the entries listed with a status, then the removals. */\ntype ScopeEntries<Entry> = { listed: Entry[]; removed: Entry[] };\n\ntype RosterDiff<Entry> = Record<SkillScope, ScopeEntries<Entry>>;\n\n/**\n * A tombstone occupies its (id, scope) slot without filling it: it silences a global install at\n * project scope. Slot checks count tombstones; removal and `~` read the active baseline only.\n */\nexport function computeScopeDiff(input: ScopeDiffInput): ScopeDiff {\n const { currentSkills, currentAgents, installedSkillConfigs, installedAgentConfigs, isInitMode } =\n input;\n const overwritten = input.overwrittenSkillIds ?? NOTHING;\n const changed = input.changedAgentNames ?? NOTHING;\n\n const skills = diffRoster(currentSkills, installedSkillConfigs, (skill) => skill.id, isInitMode);\n const agents = diffRoster(\n currentAgents,\n installedAgentConfigs,\n (agent) => agent.name,\n isInitMode,\n );\n const skillRow = skillRowClassifier(installedSkillConfigs, overwritten);\n const agentRow = agentRowClassifier(installedAgentConfigs, changed);\n\n const projectSkillRows = rowsOf(skills.project, skillRow, toRemovedSkillRow);\n const globalSkillRows = rowsOf(skills.global, skillRow, toRemovedSkillRow);\n const projectAgentRows = rowsOf(agents.project, agentRow, toRemovedAgentRow);\n const globalAgentRows = rowsOf(agents.global, agentRow, toRemovedAgentRow);\n\n const hasContent = [projectSkillRows, globalSkillRows, projectAgentRows, globalAgentRows].some(\n (rows) => rows.length > 0,\n );\n\n return { projectSkillRows, globalSkillRows, projectAgentRows, globalAgentRows, hasContent };\n}\n\nfunction diffRoster<Entry extends ScopedEntry>(\n current: Entry[],\n installed: Entry[] | null,\n identityOf: (entry: Entry) => string,\n isInitMode: boolean,\n): RosterDiff<Entry> {\n // The installs the baseline actually records; tombstones are not installs.\n const activeBaseline = (installed ?? []).filter((entry) => !entry.excluded);\n const vacated = vacatedInstalls(activeBaseline, current, identityOf);\n const projectEntries = current.filter((entry) => isActiveAt(entry, \"project\"));\n const claimedByProject = new Set(projectEntries.map(identityOf));\n // A vacated global the project claims is inherited: listed once under Global, never removed.\n const [inheritedGlobals, removedGlobals] = partition(\n vacated.filter((entry) => entry.scope === \"global\"),\n (entry) => claimedByProject.has(identityOf(entry)),\n );\n\n return {\n project: {\n listed: projectEntries,\n removed: vacated.filter((entry) => entry.scope === \"project\"),\n },\n global: {\n listed: [\n ...current.filter((entry) => isActiveAt(entry, \"global\")),\n ...inheritedGlobals,\n ...current.filter(isGlobalTombstone),\n ],\n removed: isInitMode ? [] : removedGlobals,\n },\n };\n}\n\n/** Baseline installs whose slot nothing in current, active or tombstone, occupies. */\nfunction vacatedInstalls<Entry extends ScopedEntry>(\n activeBaseline: Entry[],\n current: Entry[],\n identityOf: (entry: Entry) => string,\n): Entry[] {\n const slotOf = (entry: Entry) => slotKey(identityOf(entry), entry.scope);\n const occupiedSlots = new Set(current.map(slotOf));\n return activeBaseline.filter((install) => !occupiedSlots.has(slotOf(install)));\n}\n\nfunction rowsOf<Entry, Row>(\n entries: ScopeEntries<Entry>,\n toRow: (entry: Entry) => Row,\n toRemovedRow: (entry: Entry) => Row,\n): Row[] {\n return [...entries.listed.map(toRow), ...entries.removed.map(toRemovedRow)];\n}\n\n/** The `(id, scope)` SLOT key this module diffs on, rather than the id alone. */\nfunction slotKey(identity: string, scope: SkillScope | undefined): string {\n return `${identity}:${scope}`;\n}\n\nexport function formatScopeTag(scope: SkillScope): \"[G]\" | \"[P]\" {\n return scope === \"global\" ? \"[G]\" : \"[P]\";\n}\n\nfunction skillRowClassifier(\n installed: SkillConfig[] | null,\n overwritten: ReadonlySet<SkillId>,\n): (skill: SkillConfig) => SkillDiffRow {\n const installedSlots = installed\n ? new Set(installed.map((skill) => slotKey(skill.id, skill.scope)))\n : null;\n const installedOriginBySlot = installed\n ? new Map(\n installed\n .filter((skill) => !skill.excluded)\n .map((skill) => [slotKey(skill.id, skill.scope), skill.origin]),\n )\n : null;\n return (skill) => ({\n id: skill.id,\n source: skill.origin,\n status: skillStatus(skill, installedSlots, installedOriginBySlot, overwritten),\n ...recordedNameOf(skill),\n });\n}\n\nfunction recordedNameOf(skill: SkillConfig): Pick<SkillDiffRow, \"displayName\"> {\n return skill.displayName === undefined ? {} : { displayName: skill.displayName };\n}\n\nfunction agentRowClassifier(\n installed: AgentScopeConfig[] | null,\n changed: ReadonlySet<AgentName>,\n): (agent: AgentScopeConfig) => AgentDiffRow {\n const installedSlots = installed\n ? new Set(installed.map((agent) => slotKey(agent.name, agent.scope)))\n : null;\n return (agent) => ({ name: agent.name, status: agentStatus(agent, installedSlots, changed) });\n}\n\n/**\n * Compares `origin`, which is where a skill's install mode is recorded. An overwrite outranks a\n * mode change: a copy its plugin replaces is deleted, not merely switched. A mask is never written.\n */\nfunction skillStatus(\n skill: SkillConfig,\n installedSlots: Set<string> | null,\n installedOriginBySlot: Map<string, string> | null,\n overwritten: ReadonlySet<SkillId>,\n): SkillDiffRow[\"status\"] {\n const slot = slotKey(skill.id, skill.scope);\n if (installedSlots === null || !installedSlots.has(slot)) return \"added\";\n if (!skill.excluded && overwritten.has(skill.id)) return \"overwritten\";\n\n const installedOrigin = installedOriginBySlot?.get(slot);\n const modeChanged = installedOrigin != null && installedOrigin !== skill.origin;\n return modeChanged ? \"mode-changed\" : \"unchanged\";\n}\n\n/** A mask is never the sub-agent that changes: its active half is. */\nfunction agentStatus(\n agent: AgentScopeConfig,\n installedSlots: Set<string> | null,\n changed: ReadonlySet<AgentName>,\n): AgentDiffRow[\"status\"] {\n const isNew = installedSlots === null || !installedSlots.has(slotKey(agent.name, agent.scope));\n if (isNew) return \"added\";\n return !agent.excluded && changed.has(agent.name) ? \"changed\" : \"unchanged\";\n}\n\nfunction toRemovedSkillRow(skill: SkillConfig): SkillDiffRow {\n return { id: skill.id, source: skill.origin, status: \"removed\", ...recordedNameOf(skill) };\n}\n\nfunction toRemovedAgentRow(agent: AgentScopeConfig): AgentDiffRow {\n return { name: agent.name, status: \"removed\" };\n}\n\n/** A sub-agent that keeps its slot and still changes: the skills its rows gain and lose, and its retunes. */\nexport type AgentChange = {\n name: AgentName;\n scope: SkillScope;\n gains: SkillId[];\n loses: SkillId[];\n settings: SettingChange[];\n /** The entry each is named by: the run's for a skill it gains, the install's for one it loses. */\n namedBy?: Partial<Record<SkillId, Pick<SkillConfig, \"id\" | \"displayName\">>>;\n};\n\n/** `undefined` where the setting is left to its default. */\nexport type SettingChange = {\n setting: AgentSetting;\n from: string | undefined;\n to: string | undefined;\n};\n\ntype AgentSetting = \"model\" | \"codex model\" | \"effort\";\n\nconst AGENT_SETTINGS: ReadonlyArray<\n [AgentSetting, (agent: AgentScopeConfig) => string | undefined]\n> = [\n [\"model\", (agent) => agent.model],\n [\"codex model\", (agent) => agent.codexModel],\n [\"effort\", (agent) => agent.effort],\n];\n\n/** One sub-agent as a config records it: its entry and its skill rows. */\nexport type AgentState = { agent: AgentScopeConfig; rows: StackAgentConfig | undefined };\n\ntype AgentsAndRows = {\n agents: AgentScopeConfig[];\n skills: SkillConfig[];\n stack?: Partial<Record<string, StackAgentConfig>>;\n};\n\n/** How each named sub-agent moves between two configs; one either config lacks is not named. */\nexport function agentChangesAmong(\n names: readonly AgentName[],\n before: AgentsAndRows,\n after: AgentsAndRows,\n): AgentChange[] {\n return names.flatMap((name) => {\n const was = agentStateIn(before, name);\n const is = agentStateIn(after, name);\n if (was === undefined || is === undefined) return [];\n return [namedByEntries(agentChange(was, is), before.skills, after.skills)];\n });\n}\n\nfunction namedByEntries(\n change: AgentChange,\n before: SkillConfig[],\n after: SkillConfig[],\n): AgentChange {\n const namedBy = {\n ...activeEntriesOf(change.loses, before),\n ...activeEntriesOf(change.gains, after),\n };\n return { ...change, namedBy };\n}\n\nfunction activeEntriesOf(skillIds: readonly SkillId[], skills: SkillConfig[]) {\n const active = skills.filter((entry) => !entry.excluded && skillIds.includes(entry.id));\n return indexBy(active, ({ id }) => id);\n}\n\n/** Its active entry, never the mask a project's own copy leaves; `undefined` where none is. */\nfunction agentStateIn(config: AgentsAndRows, name: AgentName): AgentState | undefined {\n const agent = config.agents.find((entry) => entry.name === name && !entry.excluded);\n return agent === undefined ? undefined : { agent, rows: config.stack?.[name] };\n}\n\nexport function agentChange(before: AgentState, after: AgentState): AgentChange {\n const beforeIds = assignedSkillIds(before.rows);\n const afterIds = assignedSkillIds(after.rows);\n\n return {\n name: after.agent.name,\n scope: after.agent.scope,\n gains: difference(afterIds, beforeIds),\n loses: difference(beforeIds, afterIds),\n settings: settingChanges(before.agent, after.agent),\n };\n}\n\nfunction settingChanges(before: AgentScopeConfig, after: AgentScopeConfig): SettingChange[] {\n return AGENT_SETTINGS.filter(([, read]) => read(before) !== read(after)).map(\n ([setting, read]) => ({ setting, from: read(before), to: read(after) }),\n );\n}\n\nfunction assignedSkillIds(rows: StackAgentConfig | undefined): SkillId[] {\n return unique(typedValues(rows ?? {}).flatMap((assignments) => assignments.map(({ id }) => id)));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
SkillAgentSummary
|
|
4
|
+
} from "./chunk-FQF6VHO3.js";
|
|
5
|
+
import {
|
|
6
|
+
ALL_SKILLS_EJECTED_LABEL,
|
|
7
|
+
CLI_COLORS,
|
|
8
|
+
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
9
|
+
EJECT_SOURCE,
|
|
10
|
+
formatSourceDisplayName
|
|
11
|
+
} from "./chunk-WUSEZFER.js";
|
|
12
|
+
|
|
13
|
+
// src/cli/components/common/summary-panel.tsx
|
|
14
|
+
import { Box, Text, renderToString } from "ink";
|
|
15
|
+
import "react";
|
|
16
|
+
import { unique } from "remeda";
|
|
17
|
+
|
|
18
|
+
// src/cli/components/hooks/use-terminal-dimensions.ts
|
|
19
|
+
import { useState, useEffect } from "react";
|
|
20
|
+
import { useStdout } from "ink";
|
|
21
|
+
var DEFAULT_COLUMNS = 80;
|
|
22
|
+
var DEFAULT_ROWS = 24;
|
|
23
|
+
function dimensionsOf(stdout) {
|
|
24
|
+
return {
|
|
25
|
+
columns: stdout.columns || DEFAULT_COLUMNS,
|
|
26
|
+
rows: stdout.rows || DEFAULT_ROWS
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function useTerminalDimensions() {
|
|
30
|
+
const { stdout } = useStdout();
|
|
31
|
+
const [dimensions, setDimensions] = useState(() => dimensionsOf(stdout));
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const handleResize = () => {
|
|
34
|
+
setDimensions(dimensionsOf(stdout));
|
|
35
|
+
};
|
|
36
|
+
stdout.on("resize", handleResize);
|
|
37
|
+
return () => {
|
|
38
|
+
stdout.off("resize", handleResize);
|
|
39
|
+
};
|
|
40
|
+
}, [stdout]);
|
|
41
|
+
return dimensions;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/cli/components/common/summary-panel.tsx
|
|
45
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
46
|
+
function skillsTheHeaderNames({
|
|
47
|
+
skillConfigs,
|
|
48
|
+
installedSkillConfigs
|
|
49
|
+
}) {
|
|
50
|
+
return skillConfigs.length > 0 ? skillConfigs : installedSkillConfigs ?? [];
|
|
51
|
+
}
|
|
52
|
+
function formatSkillMarketplaces(skillConfigs) {
|
|
53
|
+
if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);
|
|
54
|
+
const marketplaceNames = unique(
|
|
55
|
+
skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE)
|
|
56
|
+
);
|
|
57
|
+
if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;
|
|
58
|
+
return marketplaceNames.map((name) => formatSourceDisplayName(name)).sort().join(" \xB7 ");
|
|
59
|
+
}
|
|
60
|
+
var PanelHeader = ({ sourceNames, stackName }) => /* @__PURE__ */ jsxs(
|
|
61
|
+
Box,
|
|
62
|
+
{
|
|
63
|
+
flexDirection: "column",
|
|
64
|
+
borderStyle: "single",
|
|
65
|
+
borderBottom: true,
|
|
66
|
+
borderTop: false,
|
|
67
|
+
borderLeft: false,
|
|
68
|
+
borderRight: false,
|
|
69
|
+
borderColor: CLI_COLORS.NEUTRAL,
|
|
70
|
+
borderBottomDimColor: true,
|
|
71
|
+
paddingBottom: 1,
|
|
72
|
+
marginBottom: 1,
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
|
|
75
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Marketplace" }),
|
|
76
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: sourceNames })
|
|
77
|
+
] }),
|
|
78
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
|
|
79
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Stack" }),
|
|
80
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: stackName ?? "none" })
|
|
81
|
+
] })
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
var SummaryPanel = ({
|
|
86
|
+
stackName,
|
|
87
|
+
headerSkillConfigs,
|
|
88
|
+
...summary
|
|
89
|
+
}) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: CLI_COLORS.NEUTRAL, paddingX: 2, children: [
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
PanelHeader,
|
|
92
|
+
{
|
|
93
|
+
sourceNames: formatSkillMarketplaces(headerSkillConfigs ?? skillsTheHeaderNames(summary)),
|
|
94
|
+
stackName
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
/* @__PURE__ */ jsx(SkillAgentSummary, { ...summary })
|
|
98
|
+
] });
|
|
99
|
+
function summaryPanelText(props, columns = dimensionsOf(process.stdout).columns) {
|
|
100
|
+
return renderToString(/* @__PURE__ */ jsx(SummaryPanel, { ...props }), { columns });
|
|
101
|
+
}
|
|
102
|
+
function summaryPanelBlock(panel, linesUnder, statements) {
|
|
103
|
+
return [
|
|
104
|
+
summaryPanelText(panel),
|
|
105
|
+
...linesUnder,
|
|
106
|
+
...statements.flatMap((statement) => ["", statement]),
|
|
107
|
+
""
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
useTerminalDimensions,
|
|
113
|
+
summaryPanelText,
|
|
114
|
+
summaryPanelBlock
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=chunk-H5E6IO2L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/common/summary-panel.tsx","../src/cli/components/hooks/use-terminal-dimensions.ts"],"sourcesContent":["import { Box, Text, renderToString } from \"ink\";\nimport React from \"react\";\nimport { unique } from \"remeda\";\nimport {\n ALL_SKILLS_EJECTED_LABEL,\n CLI_COLORS,\n DEFAULT_PUBLIC_SOURCE_NAME,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../../consts.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { dimensionsOf } from \"../hooks/use-terminal-dimensions.js\";\nimport { SkillAgentSummary, type SkillAgentSummaryProps } from \"./skill-agent-summary.js\";\n\nexport type SummaryPanelProps = SkillAgentSummaryProps & {\n /** `undefined` when the configuration was built from no stack. */\n stackName: string | undefined;\n /** Where set, the skills the header names in place of those the panel leaves in place. */\n headerSkillConfigs?: SkillConfig[];\n};\n\n/**\n * The skills the panel leaves in place; leaving none, those it removes. The default marketplace is\n * only for a panel with no skill either way.\n */\nfunction skillsTheHeaderNames({\n skillConfigs,\n installedSkillConfigs,\n}: SkillAgentSummaryProps): SkillConfig[] {\n return skillConfigs.length > 0 ? skillConfigs : (installedSkillConfigs ?? []);\n}\n\n/**\n * No skills shows the default marketplace; all-ejected names none. Tombstoned entries count: the\n * summary below renders them as rows.\n */\nfunction formatSkillMarketplaces(skillConfigs: SkillConfig[]): string {\n if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);\n\n const marketplaceNames = unique(\n skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE),\n );\n if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;\n\n return marketplaceNames\n .map((name) => formatSourceDisplayName(name))\n .sort()\n .join(\" · \");\n}\n\ntype PanelHeaderProps = {\n sourceNames: string;\n stackName: string | undefined;\n};\n\nconst PanelHeader: React.FC<PanelHeaderProps> = ({ sourceNames, stackName }) => (\n <Box\n flexDirection=\"column\"\n borderStyle=\"single\"\n borderBottom={true}\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderBottomDimColor\n paddingBottom={1}\n marginBottom={1}\n >\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{sourceNames}</Text>\n </Box>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Stack\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{stackName ?? \"none\"}</Text>\n </Box>\n </Box>\n);\n\nconst SummaryPanel: React.FC<SummaryPanelProps> = ({\n stackName,\n headerSkillConfigs,\n ...summary\n}) => (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor={CLI_COLORS.NEUTRAL} paddingX={2}>\n <PanelHeader\n sourceNames={formatSkillMarketplaces(headerSkillConfigs ?? skillsTheHeaderNames(summary))}\n stackName={stackName}\n />\n <SkillAgentSummary {...summary} />\n </Box>\n);\n\n/**\n * The whole panel as text, drawn once: printed, it scrolls with the terminal like any other line,\n * and a run with no terminal prints the same thing.\n */\nexport function summaryPanelText(\n props: SummaryPanelProps,\n columns: number = dimensionsOf(process.stdout).columns,\n): string {\n return renderToString(<SummaryPanel {...props} />, { columns });\n}\n\n/**\n * What a question shows, or where none is asked, what prints in its place: the panel, the lines\n * under it marking what it cannot show, then each statement after a blank line, and a blank line\n * before what follows.\n */\nexport function summaryPanelBlock(\n panel: SummaryPanelProps,\n linesUnder: readonly string[],\n statements: readonly string[],\n): string[] {\n return [\n summaryPanelText(panel),\n ...linesUnder,\n ...statements.flatMap((statement) => [\"\", statement]),\n \"\",\n ];\n}\n","import { useState, useEffect } from \"react\";\nimport { useStdout } from \"ink\";\n\nconst DEFAULT_COLUMNS = 80;\nconst DEFAULT_ROWS = 24;\n\nexport type TerminalDimensions = {\n columns: number;\n rows: number;\n};\n\n/** A stream that is not a terminal reports no size, so it gets the defaults. */\nexport function dimensionsOf(stdout: NodeJS.WriteStream): TerminalDimensions {\n return {\n columns: stdout.columns || DEFAULT_COLUMNS,\n rows: stdout.rows || DEFAULT_ROWS,\n };\n}\n\nexport function useTerminalDimensions(): TerminalDimensions {\n const { stdout } = useStdout();\n\n const [dimensions, setDimensions] = useState<TerminalDimensions>(() => dimensionsOf(stdout));\n\n useEffect(() => {\n const handleResize = () => {\n setDimensions(dimensionsOf(stdout));\n };\n\n stdout.on(\"resize\", handleResize);\n return () => {\n stdout.off(\"resize\", handleResize);\n };\n }, [stdout]);\n\n return dimensions;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CLI_COLORS,
|
|
4
4
|
UI_SYMBOLS
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WUSEZFER.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/components/common/select-list.tsx
|
|
8
8
|
import { useCallback as useCallback2 } from "react";
|
|
@@ -103,4 +103,4 @@ function SelectList({
|
|
|
103
103
|
export {
|
|
104
104
|
SelectList
|
|
105
105
|
};
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
106
|
+
//# sourceMappingURL=chunk-I3WF6L43.js.map
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
verbose,
|
|
51
51
|
warn,
|
|
52
52
|
writeFile
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-E45IT3HC.js";
|
|
54
54
|
import {
|
|
55
55
|
BUILT_IN_MATRIX,
|
|
56
56
|
getCategoryDomain,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
typedEntries,
|
|
61
61
|
typedKeys,
|
|
62
62
|
typedValues
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-AIBVAYHS.js";
|
|
64
64
|
import {
|
|
65
65
|
CLI_COLORS,
|
|
66
66
|
CLI_INVOKE_COMMAND,
|
|
@@ -75,7 +75,7 @@ import {
|
|
|
75
75
|
isActiveAt,
|
|
76
76
|
orderDomains,
|
|
77
77
|
seedExternalSkillSchema
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-WUSEZFER.js";
|
|
79
79
|
|
|
80
80
|
// src/cli/utils/terminal.ts
|
|
81
81
|
function clearTerminalScreen() {
|
|
@@ -1093,4 +1093,4 @@ export {
|
|
|
1093
1093
|
installsAtHome,
|
|
1094
1094
|
BaseCommand
|
|
1095
1095
|
};
|
|
1096
|
-
//# sourceMappingURL=chunk-
|
|
1096
|
+
//# sourceMappingURL=chunk-IAQFZFWD.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
listAgentMdFiles
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EFXVYQGT.js";
|
|
5
5
|
import {
|
|
6
6
|
agentCodec,
|
|
7
7
|
agentFrontmatterValidationSchema,
|
|
@@ -27,17 +27,17 @@ import {
|
|
|
27
27
|
warn,
|
|
28
28
|
writeContentHash,
|
|
29
29
|
writePluginManifest
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-E45IT3HC.js";
|
|
31
31
|
import {
|
|
32
32
|
plural
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-AIBVAYHS.js";
|
|
34
34
|
import {
|
|
35
35
|
DEFAULT_VERSION,
|
|
36
36
|
DIRS,
|
|
37
37
|
PLUGIN_MANIFEST_DIR,
|
|
38
38
|
PLUGIN_MANIFEST_FILE,
|
|
39
39
|
PROJECT_ROOT
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-WUSEZFER.js";
|
|
41
41
|
|
|
42
42
|
// src/cli/lib/agents/agent-fetcher.ts
|
|
43
43
|
import path from "path";
|
|
@@ -157,4 +157,4 @@ export {
|
|
|
157
157
|
compileAllAgentPlugins,
|
|
158
158
|
printAgentCompilationSummary
|
|
159
159
|
};
|
|
160
|
-
//# sourceMappingURL=chunk-
|
|
160
|
+
//# sourceMappingURL=chunk-IXVGBUWI.js.map
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
chooseProviderForThisRun,
|
|
4
|
-
detectInstallations
|
|
5
|
-
|
|
4
|
+
detectInstallations,
|
|
5
|
+
providerInUse
|
|
6
|
+
} from "./chunk-E45IT3HC.js";
|
|
6
7
|
import {
|
|
7
8
|
CLI_INVOKE_COMMAND,
|
|
8
9
|
EDITOR_URL,
|
|
9
10
|
PROVIDERS
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WUSEZFER.js";
|
|
11
12
|
|
|
12
13
|
// src/cli/lib/installation/provider-flag.ts
|
|
13
14
|
import os from "os";
|
|
@@ -23,6 +24,17 @@ function providerNamedBy(flagValue) {
|
|
|
23
24
|
if (flagValue === void 0) return void 0;
|
|
24
25
|
return PROVIDERS.find((provider) => provider === flagValue);
|
|
25
26
|
}
|
|
27
|
+
var PROVIDER_FLAG = "--provider";
|
|
28
|
+
var PROVIDER_FLAG_WITH_ITS_VALUE = `${PROVIDER_FLAG}=`;
|
|
29
|
+
var END_OF_FLAGS = "--";
|
|
30
|
+
function providerNamedIn(argv) {
|
|
31
|
+
const end = argv.indexOf(END_OF_FLAGS);
|
|
32
|
+
const flags = end === -1 ? argv : argv.slice(0, end);
|
|
33
|
+
const spaced = flags.indexOf(PROVIDER_FLAG);
|
|
34
|
+
if (spaced !== -1) return providerNamedBy(flags[spaced + 1]);
|
|
35
|
+
const joined = flags.find((token) => token.startsWith(PROVIDER_FLAG_WITH_ITS_VALUE));
|
|
36
|
+
return providerNamedBy(joined?.slice(PROVIDER_FLAG_WITH_ITS_VALUE.length));
|
|
37
|
+
}
|
|
26
38
|
function providerNeedsAConfigurationToInstall() {
|
|
27
39
|
return `--provider names which installation to create and needs the configuration to create it from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run '${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`;
|
|
28
40
|
}
|
|
@@ -63,8 +75,9 @@ async function ambiguityFinding(cwd) {
|
|
|
63
75
|
if (providers.length <= 1) return null;
|
|
64
76
|
return ambiguousInstallation("every command that acts on one", providers, scopeRoot);
|
|
65
77
|
}
|
|
66
|
-
async function otherInstallationsInThisScope(cwd
|
|
78
|
+
async function otherInstallationsInThisScope(cwd) {
|
|
67
79
|
const { scopeRoot, providers } = await installationsInPlay(cwd);
|
|
80
|
+
const showing = providerInUse(scopeRoot);
|
|
68
81
|
const others = providers.filter((provider) => provider !== showing);
|
|
69
82
|
if (others.length === 0) return null;
|
|
70
83
|
return `${scopeRoot} holds ${providers.length} installations \u2014 ${providers.join(" and ")} \u2014 and this is the ${showing} one. Show another with --provider <${providers.join("|")}>.`;
|
|
@@ -73,10 +86,11 @@ async function otherInstallationsInThisScope(cwd, showing) {
|
|
|
73
86
|
export {
|
|
74
87
|
providerFlag,
|
|
75
88
|
providerNamedBy,
|
|
89
|
+
providerNamedIn,
|
|
76
90
|
providerNeedsAConfigurationToInstall,
|
|
77
91
|
refuseAnAmbiguousInstallation,
|
|
78
92
|
installationToName,
|
|
79
93
|
ambiguityFinding,
|
|
80
94
|
otherInstallationsInThisScope
|
|
81
95
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
96
|
+
//# sourceMappingURL=chunk-ORO2T4K2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/installation/provider-flag.ts"],"sourcesContent":["/**\n * `--provider`: names the installation where the folder cannot — a greenfield `init --from`, or a\n * scope holding both providers, where acting commands refuse until it is given.\n */\n\nimport os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\n\nimport { PROVIDERS, EDITOR_URL, CLI_INVOKE_COMMAND, type Provider } from \"../../consts.js\";\nimport { detectInstallations, type DetectedInstallation } from \"./detect-installations.js\";\nimport { chooseProviderForThisRun, providerInUse } from \"./install-layout.js\";\n\n/** A factory because oclif mutates flag definitions, so commands must not share one. */\nexport function providerFlag() {\n return Flags.string({\n description: \"Which provider's installation this run is about\",\n helpValue: `<${PROVIDERS.join(\"|\")}>`,\n options: [...PROVIDERS],\n });\n}\n\n/** oclif has already rejected unlisted values; this only narrows. */\nexport function providerNamedBy(flagValue: string | undefined): Provider | undefined {\n if (flagValue === undefined) return undefined;\n return PROVIDERS.find((provider) => provider === flagValue);\n}\n\nconst PROVIDER_FLAG = \"--provider\";\nconst PROVIDER_FLAG_WITH_ITS_VALUE = `${PROVIDER_FLAG}=`;\nconst END_OF_FLAGS = \"--\";\n\n/**\n * For a run oclif has not parsed yet: `--provider <name>` or `--provider=<name>`, ahead of any\n * `--`; a value naming no provider names none.\n */\nexport function providerNamedIn(argv: readonly string[]): Provider | undefined {\n const end = argv.indexOf(END_OF_FLAGS);\n const flags = end === -1 ? argv : argv.slice(0, end);\n\n const spaced = flags.indexOf(PROVIDER_FLAG);\n if (spaced !== -1) return providerNamedBy(flags[spaced + 1]);\n\n const joined = flags.find((token) => token.startsWith(PROVIDER_FLAG_WITH_ITS_VALUE));\n return providerNamedBy(joined?.slice(PROVIDER_FLAG_WITH_ITS_VALUE.length));\n}\n\nexport function providerNeedsAConfigurationToInstall(): string {\n return (\n `--provider names which installation to create and needs the configuration to create it ` +\n `from, so it is only meaningful beside --from. Build one at ${EDITOR_URL}, then run ` +\n `'${CLI_INVOKE_COMMAND} init --from <id> --provider <provider>'.`\n );\n}\n\nfunction ambiguousInstallation(\n subject: string,\n providers: readonly Provider[],\n scopeRoot: string,\n): string {\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — so ` +\n `${subject} cannot tell which one you mean. Name it with --provider <${providers.join(\"|\")}>. ` +\n `Nothing has been changed.`\n );\n}\n\ntype InstallationsInPlay = {\n scopeRoot: string;\n providers: Provider[];\n};\n\n/** The project's installations, or the global ones only when the project has none. */\nasync function installationsInPlay(cwd: string): Promise<InstallationsInPlay> {\n const found = await detectInstallations(cwd);\n const inTheProject = atScope(found, \"project\");\n\n if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };\n return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, \"global\")) };\n}\n\nfunction atScope(\n found: readonly DetectedInstallation[],\n scope: DetectedInstallation[\"scope\"],\n): DetectedInstallation[] {\n return found.filter((installation) => installation.scope === scope);\n}\n\nfunction providersOf(installations: readonly DetectedInstallation[]): Provider[] {\n return installations.map((installation) => installation.provider);\n}\n\n/**\n * A named provider is committed for the run; two installations and no flag call `onAmbiguous`\n * (the command's `this.error`); otherwise nothing happens.\n */\nexport async function refuseAnAmbiguousInstallation(\n cwd: string,\n subject: string,\n named: Provider | undefined,\n onAmbiguous: (message: string) => never,\n): Promise<void> {\n if (named !== undefined) {\n chooseProviderForThisRun(named);\n return;\n }\n\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return;\n\n onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));\n}\n\n/** The non-refusing read the remedies hand a command out from, so they and the refusal agree. */\nexport async function providersInPlay(cwd: string): Promise<Provider[]> {\n return (await installationsInPlay(cwd)).providers;\n}\n\n/**\n * Which installation a handed-out acting command must name: the one the run named, else the choice\n * where two are in play, since a bare one refuses there.\n */\nexport async function installationToName(\n cwd: string,\n named: Provider | undefined,\n): Promise<Provider | Provider[] | undefined> {\n if (named !== undefined) return named;\n\n const providers = await providersInPlay(cwd);\n return providers.length > 1 ? providers : undefined;\n}\n\n/** The non-refusing form, for `doctor`. */\nexport async function ambiguityFinding(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n if (providers.length <= 1) return null;\n\n return ambiguousInstallation(\"every command that acts on one\", providers, scopeRoot);\n}\n\n/**\n * For `list`: names the other installation in the scope, or `null` when there is none. The one\n * shown is read off the scope the roster came from, as `detectInstallation` reads it.\n */\nexport async function otherInstallationsInThisScope(cwd: string): Promise<string | null> {\n const { scopeRoot, providers } = await installationsInPlay(cwd);\n const showing = providerInUse(scopeRoot);\n const others = providers.filter((provider) => provider !== showing);\n if (others.length === 0) return null;\n\n return (\n `${scopeRoot} holds ${providers.length} installations — ${providers.join(\" and \")} — and this ` +\n `is the ${showing} one. Show another with --provider <${providers.join(\"|\")}>.`\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
truncateText
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AIBVAYHS.js";
|
|
5
5
|
import {
|
|
6
6
|
SEED_API_URL,
|
|
7
7
|
seedPayloadSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WUSEZFER.js";
|
|
9
9
|
|
|
10
10
|
// ../../node_modules/hono/dist/utils/cookie.js
|
|
11
11
|
var validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
|
|
@@ -425,4 +425,4 @@ export {
|
|
|
425
425
|
jsonBodyOrUndefined,
|
|
426
426
|
arrivedAsText
|
|
427
427
|
};
|
|
428
|
-
//# sourceMappingURL=chunk-
|
|
428
|
+
//# sourceMappingURL=chunk-QCX66KBM.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAgents,
|
|
4
4
|
withCatalogueSeatedFor
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-REHVGFJE.js";
|
|
6
6
|
import {
|
|
7
7
|
loadAgentDefs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-7BHDKEGK.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigLoadError,
|
|
11
11
|
EXTRACTED_FIELDS,
|
|
@@ -53,12 +53,12 @@ import {
|
|
|
53
53
|
warn,
|
|
54
54
|
withGateToken,
|
|
55
55
|
writeFile
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-E45IT3HC.js";
|
|
57
57
|
import {
|
|
58
58
|
matrix,
|
|
59
59
|
typedEntries,
|
|
60
60
|
typedKeys
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-AIBVAYHS.js";
|
|
62
62
|
import {
|
|
63
63
|
CLI_INVOKE_COMMAND,
|
|
64
64
|
CODEX_MODEL_NAMES,
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
isExclusiveCategory,
|
|
77
77
|
isGlobalTombstone,
|
|
78
78
|
skillDomain
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-WUSEZFER.js";
|
|
80
80
|
|
|
81
81
|
// src/cli/lib/operations/source/load-source.ts
|
|
82
82
|
async function loadSource(options) {
|
|
@@ -146,6 +146,7 @@ export type SkillConfig = {
|
|
|
146
146
|
id: SkillId
|
|
147
147
|
scope: 'project' | 'global'
|
|
148
148
|
origin: string
|
|
149
|
+
displayName?: string
|
|
149
150
|
excluded?: boolean
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -1231,7 +1232,7 @@ var NOTHING_RECOMPILED = {
|
|
|
1231
1232
|
};
|
|
1232
1233
|
async function recompilePropagated(projectDirs, pairsRewritten) {
|
|
1233
1234
|
if (projectDirs.length === 0) return NOTHING_RECOMPILED;
|
|
1234
|
-
const { recompilePropagatedProjectAgents } = await import("./recompile-project-agents-
|
|
1235
|
+
const { recompilePropagatedProjectAgents } = await import("./recompile-project-agents-KYK44C24.js");
|
|
1235
1236
|
return recompilePropagatedProjectAgents(projectDirs, pairsRewritten);
|
|
1236
1237
|
}
|
|
1237
1238
|
function pairRewriteSummary(projectDirs, pairsRewritten) {
|
|
@@ -1327,7 +1328,7 @@ async function applyConsequences(globalConfig, changes, deps, provider, currentP
|
|
|
1327
1328
|
function lazyGateDeps(projectDir) {
|
|
1328
1329
|
return {
|
|
1329
1330
|
loadMatrix: async () => {
|
|
1330
|
-
const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-
|
|
1331
|
+
const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-G5I4RNUP.js");
|
|
1331
1332
|
const { matrix: matrix2 } = await loadSkillsMatrixFromSource2({
|
|
1332
1333
|
projectDir,
|
|
1333
1334
|
skipExtraSources: true,
|
|
@@ -1336,7 +1337,7 @@ function lazyGateDeps(projectDir) {
|
|
|
1336
1337
|
return matrix2;
|
|
1337
1338
|
},
|
|
1338
1339
|
loadAgents: async () => {
|
|
1339
|
-
const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-
|
|
1340
|
+
const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-5U5KAURA.js");
|
|
1340
1341
|
return (await loadAgentDefs2()).agents;
|
|
1341
1342
|
}
|
|
1342
1343
|
};
|
|
@@ -1664,4 +1665,4 @@ export {
|
|
|
1664
1665
|
compileAgentsAllScopes,
|
|
1665
1666
|
compileProjectScope
|
|
1666
1667
|
};
|
|
1667
|
-
//# sourceMappingURL=chunk-
|
|
1668
|
+
//# sourceMappingURL=chunk-R7GKQBZJ.js.map
|