agents-inc 0.174.0 → 0.176.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 +115 -0
- package/dist/{chunk-APWMMZOK.js → chunk-3F5LT433.js} +157 -53
- package/dist/chunk-3F5LT433.js.map +1 -0
- package/dist/chunk-5CFHP6Z5.js +109 -0
- package/dist/chunk-5CFHP6Z5.js.map +1 -0
- package/dist/{chunk-3PJZ4QNJ.js → chunk-B7AVWSK2.js} +21 -11
- package/dist/chunk-B7AVWSK2.js.map +1 -0
- package/dist/{chunk-H5E6IO2L.js → chunk-C2BSCEDN.js} +9 -11
- package/dist/chunk-C2BSCEDN.js.map +1 -0
- package/dist/{chunk-R7GKQBZJ.js → chunk-CKBWEWHZ.js} +96 -52
- package/dist/chunk-CKBWEWHZ.js.map +1 -0
- package/dist/{chunk-IXVGBUWI.js → chunk-EC3JXT23.js} +5 -5
- package/dist/{chunk-E45IT3HC.js → chunk-ENET4IF6.js} +998 -472
- package/dist/chunk-ENET4IF6.js.map +1 -0
- package/dist/{chunk-FQF6VHO3.js → chunk-FACDJH6O.js} +12 -105
- package/dist/chunk-FACDJH6O.js.map +1 -0
- package/dist/{chunk-TVEDNGVP.js → chunk-H6WUOW5F.js} +2 -2
- package/dist/{chunk-7BHDKEGK.js → chunk-JNRACLNS.js} +3 -3
- package/dist/{chunk-IAQFZFWD.js → chunk-JTMSFBCA.js} +231 -24
- package/dist/chunk-JTMSFBCA.js.map +1 -0
- package/dist/{chunk-EFXVYQGT.js → chunk-MQZNDK5F.js} +39 -40
- package/dist/chunk-MQZNDK5F.js.map +1 -0
- package/dist/{chunk-QCX66KBM.js → chunk-SN64WNWE.js} +3 -3
- package/dist/{chunk-WUSEZFER.js → chunk-U46LYYRA.js} +3 -2
- package/dist/{chunk-WUSEZFER.js.map → chunk-U46LYYRA.js.map} +1 -1
- package/dist/{chunk-6PGXTLA4.js → chunk-U672FZVC.js} +2 -2
- package/dist/{chunk-AIBVAYHS.js → chunk-UE4Z3YMB.js} +2 -2
- package/dist/chunk-UE4Z3YMB.js.map +1 -0
- package/dist/{chunk-REHVGFJE.js → chunk-XMQIWPIR.js} +84 -32
- package/dist/chunk-XMQIWPIR.js.map +1 -0
- package/dist/{chunk-I3WF6L43.js → chunk-XYBHH3M5.js} +2 -2
- package/dist/{chunk-ECPFYHDX.js → chunk-ZBI6GFJD.js} +11 -11
- package/dist/chunk-ZBI6GFJD.js.map +1 -0
- package/dist/commands/build/marketplace.js +5 -4
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +7 -6
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +20 -16
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +106 -87
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +76 -48
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +31 -18
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +17 -17
- package/dist/commands/list.js +10 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +5 -4
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +14 -9
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +20 -22
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +24 -19
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +110 -31
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +4 -3
- package/dist/components/common/summary-panel.js +5 -4
- package/dist/hooks/init.js +24 -25
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-5BSECHE6.js +14 -0
- package/dist/{recompile-project-agents-KYK44C24.js → recompile-project-agents-U3UGHPWG.js} +8 -8
- package/dist/{source-loader-G5I4RNUP.js → source-loader-E2Y5MMN5.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-3PJZ4QNJ.js.map +0 -1
- package/dist/chunk-AIBVAYHS.js.map +0 -1
- package/dist/chunk-APWMMZOK.js.map +0 -1
- package/dist/chunk-E45IT3HC.js.map +0 -1
- package/dist/chunk-ECPFYHDX.js.map +0 -1
- package/dist/chunk-EFXVYQGT.js.map +0 -1
- package/dist/chunk-FQF6VHO3.js.map +0 -1
- package/dist/chunk-H5E6IO2L.js.map +0 -1
- package/dist/chunk-IAQFZFWD.js.map +0 -1
- package/dist/chunk-ORO2T4K2.js +0 -96
- package/dist/chunk-ORO2T4K2.js.map +0 -1
- package/dist/chunk-R7GKQBZJ.js.map +0 -1
- package/dist/chunk-REHVGFJE.js.map +0 -1
- package/dist/load-agent-defs-5U5KAURA.js +0 -14
- /package/dist/{chunk-IXVGBUWI.js.map → chunk-EC3JXT23.js.map} +0 -0
- /package/dist/{chunk-TVEDNGVP.js.map → chunk-H6WUOW5F.js.map} +0 -0
- /package/dist/{chunk-7BHDKEGK.js.map → chunk-JNRACLNS.js.map} +0 -0
- /package/dist/{chunk-QCX66KBM.js.map → chunk-SN64WNWE.js.map} +0 -0
- /package/dist/{chunk-6PGXTLA4.js.map → chunk-U672FZVC.js.map} +0 -0
- /package/dist/{chunk-I3WF6L43.js.map → chunk-XYBHH3M5.js.map} +0 -0
- /package/dist/{load-agent-defs-5U5KAURA.js.map → load-agent-defs-5BSECHE6.js.map} +0 -0
- /package/dist/{recompile-project-agents-KYK44C24.js.map → recompile-project-agents-U3UGHPWG.js.map} +0 -0
- /package/dist/{source-loader-G5I4RNUP.js.map → source-loader-E2Y5MMN5.js.map} +0 -0
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
getSkillEntryDisplayName,
|
|
4
3
|
typedValues
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UE4Z3YMB.js";
|
|
6
5
|
import {
|
|
7
|
-
CLI_COLORS,
|
|
8
|
-
EJECT_SOURCE,
|
|
9
|
-
UI_SYMBOLS,
|
|
10
6
|
isActiveAt,
|
|
11
7
|
isGlobalTombstone
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
|
|
14
|
-
// src/cli/components/common/skill-agent-summary.tsx
|
|
15
|
-
import { Box, Text } from "ink";
|
|
16
|
-
import "react";
|
|
8
|
+
} from "./chunk-U46LYYRA.js";
|
|
17
9
|
|
|
18
10
|
// src/cli/lib/configuration/scope-diff.ts
|
|
19
11
|
import { difference, indexBy, partition, unique } from "remeda";
|
|
@@ -116,6 +108,12 @@ function toRemovedSkillRow(skill) {
|
|
|
116
108
|
function toRemovedAgentRow(agent) {
|
|
117
109
|
return { name: agent.name, status: "removed" };
|
|
118
110
|
}
|
|
111
|
+
function namedByActiveEntries(entries) {
|
|
112
|
+
return indexBy(
|
|
113
|
+
entries.filter((entry) => !entry.excluded),
|
|
114
|
+
({ id }) => id
|
|
115
|
+
);
|
|
116
|
+
}
|
|
119
117
|
var AGENT_SETTINGS = [
|
|
120
118
|
["model", (agent) => agent.model],
|
|
121
119
|
["codex model", (agent) => agent.codexModel],
|
|
@@ -137,8 +135,7 @@ function namedByEntries(change, before, after) {
|
|
|
137
135
|
return { ...change, namedBy };
|
|
138
136
|
}
|
|
139
137
|
function activeEntriesOf(skillIds, skills) {
|
|
140
|
-
|
|
141
|
-
return indexBy(active, ({ id }) => id);
|
|
138
|
+
return namedByActiveEntries(skills.filter((entry) => skillIds.includes(entry.id)));
|
|
142
139
|
}
|
|
143
140
|
function agentStateIn(config, name) {
|
|
144
141
|
const agent = config.agents.find((entry) => entry.name === name && !entry.excluded);
|
|
@@ -164,100 +161,10 @@ function assignedSkillIds(rows) {
|
|
|
164
161
|
return unique(typedValues(rows ?? {}).flatMap((assignments) => assignments.map(({ id }) => id)));
|
|
165
162
|
}
|
|
166
163
|
|
|
167
|
-
// src/cli/components/common/skill-agent-summary.tsx
|
|
168
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
169
|
-
var TableHeader = ({ children }) => /* @__PURE__ */ jsx(Text, { bold: true, color: CLI_COLORS.WARNING, children });
|
|
170
|
-
var ScopeLabel = ({ children }) => /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WHITE, backgroundColor: CLI_COLORS.LABEL_BG, children: ` ${children} ` });
|
|
171
|
-
var EjectIcon = () => /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.WARNING, children: [
|
|
172
|
-
" ",
|
|
173
|
-
UI_SYMBOLS.EJECT
|
|
174
|
-
] });
|
|
175
|
-
var DIFF_PREFIX = {
|
|
176
|
-
added: `${UI_SYMBOLS.ADDED} `,
|
|
177
|
-
"mode-changed": `${UI_SYMBOLS.CHANGED} `,
|
|
178
|
-
overwritten: `${UI_SYMBOLS.OVERWRITTEN} `,
|
|
179
|
-
changed: `${UI_SYMBOLS.CHANGED} `,
|
|
180
|
-
removed: `${UI_SYMBOLS.REMOVED} `,
|
|
181
|
-
unchanged: `${UI_SYMBOLS.BULLET} `
|
|
182
|
-
};
|
|
183
|
-
var DIFF_COLOR = {
|
|
184
|
-
added: CLI_COLORS.SUCCESS,
|
|
185
|
-
"mode-changed": CLI_COLORS.WARNING,
|
|
186
|
-
overwritten: CLI_COLORS.WARNING,
|
|
187
|
-
changed: CLI_COLORS.WARNING,
|
|
188
|
-
removed: CLI_COLORS.ERROR,
|
|
189
|
-
unchanged: CLI_COLORS.NEUTRAL
|
|
190
|
-
};
|
|
191
|
-
var NAME_GUTTER_COLUMNS = 3;
|
|
192
|
-
var SkillRow = ({ row }) => /* @__PURE__ */ jsxs(Box, { width: "50%", paddingRight: NAME_GUTTER_COLUMNS, children: [
|
|
193
|
-
/* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { color: DIFF_COLOR[row.status], children: DIFF_PREFIX[row.status] }) }),
|
|
194
|
-
/* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
|
|
195
|
-
getSkillEntryDisplayName(row),
|
|
196
|
-
row.source === EJECT_SOURCE && /* @__PURE__ */ jsx(EjectIcon, {})
|
|
197
|
-
] })
|
|
198
|
-
] });
|
|
199
|
-
var AgentRow = ({ row }) => /* @__PURE__ */ jsxs(Text, { color: DIFF_COLOR[row.status], children: [
|
|
200
|
-
DIFF_PREFIX[row.status],
|
|
201
|
-
row.name
|
|
202
|
-
] });
|
|
203
|
-
var skillRowKey = (row) => row.status === "removed" ? `removed-${row.id}` : row.id;
|
|
204
|
-
var agentRowKey = (row) => row.status === "removed" ? `removed-${row.name}` : row.name;
|
|
205
|
-
var SkillAgentSummary = ({
|
|
206
|
-
skillConfigs,
|
|
207
|
-
agentConfigs,
|
|
208
|
-
...baseline
|
|
209
|
-
}) => {
|
|
210
|
-
const diff = computeScopeDiff({
|
|
211
|
-
currentSkills: skillConfigs,
|
|
212
|
-
currentAgents: agentConfigs,
|
|
213
|
-
...baseline
|
|
214
|
-
});
|
|
215
|
-
if (!diff.hasContent) return null;
|
|
216
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", width: "100%", children: [
|
|
217
|
-
/* @__PURE__ */ jsxs(
|
|
218
|
-
Box,
|
|
219
|
-
{
|
|
220
|
-
flexDirection: "column",
|
|
221
|
-
borderStyle: "single",
|
|
222
|
-
flexGrow: 2,
|
|
223
|
-
flexBasis: 0,
|
|
224
|
-
borderRight: true,
|
|
225
|
-
borderTop: false,
|
|
226
|
-
borderBottom: false,
|
|
227
|
-
borderLeft: false,
|
|
228
|
-
borderColor: CLI_COLORS.NEUTRAL,
|
|
229
|
-
borderRightDimColor: true,
|
|
230
|
-
children: [
|
|
231
|
-
/* @__PURE__ */ jsx(TableHeader, { children: "Skills" }),
|
|
232
|
-
diff.projectSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
233
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
|
|
234
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.projectSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
235
|
-
] }),
|
|
236
|
-
diff.globalSkillRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
237
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
|
|
238
|
-
/* @__PURE__ */ jsx(Box, { flexWrap: "wrap", children: diff.globalSkillRows.map((row) => /* @__PURE__ */ jsx(SkillRow, { row }, skillRowKey(row))) })
|
|
239
|
-
] })
|
|
240
|
-
]
|
|
241
|
-
}
|
|
242
|
-
),
|
|
243
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, flexBasis: 0, marginLeft: 1, paddingLeft: 1, children: [
|
|
244
|
-
/* @__PURE__ */ jsx(TableHeader, { children: "Agents" }),
|
|
245
|
-
diff.projectAgentRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
246
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Project" }),
|
|
247
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: diff.projectAgentRows.map((row) => /* @__PURE__ */ jsx(AgentRow, { row }, agentRowKey(row))) })
|
|
248
|
-
] }),
|
|
249
|
-
diff.globalAgentRows.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
250
|
-
/* @__PURE__ */ jsx(ScopeLabel, { children: "Global" }),
|
|
251
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: diff.globalAgentRows.map((row) => /* @__PURE__ */ jsx(AgentRow, { row }, agentRowKey(row))) })
|
|
252
|
-
] })
|
|
253
|
-
] })
|
|
254
|
-
] });
|
|
255
|
-
};
|
|
256
|
-
|
|
257
164
|
export {
|
|
258
165
|
computeScopeDiff,
|
|
259
166
|
formatScopeTag,
|
|
260
|
-
|
|
261
|
-
|
|
167
|
+
namedByActiveEntries,
|
|
168
|
+
agentChangesAmong
|
|
262
169
|
};
|
|
263
|
-
//# sourceMappingURL=chunk-
|
|
170
|
+
//# sourceMappingURL=chunk-FACDJH6O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/configuration/scope-diff.ts"],"sourcesContent":["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/** The entry each skill is named by, as a panel row drawn from that entry names it. */\nexport type NamedBy = Partial<Record<SkillId, Pick<SkillConfig, \"id\" | \"displayName\">>>;\n\nexport function namedByActiveEntries(\n entries: readonly Pick<SkillConfig, \"id\" | \"displayName\" | \"excluded\">[],\n): NamedBy {\n return indexBy(\n entries.filter((entry) => !entry.excluded),\n ({ id }) => id,\n );\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 run's entry for a skill it gains, the install's for one it loses. */\n namedBy?: NamedBy;\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[]): NamedBy {\n return namedByActiveEntries(skills.filter((entry) => skillIds.includes(entry.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":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
execCommand,
|
|
4
4
|
getErrorMessage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ENET4IF6.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/utils/open-url.ts
|
|
8
8
|
function browserOpenerCommand(platform, url) {
|
|
@@ -32,4 +32,4 @@ async function openUrl(url) {
|
|
|
32
32
|
export {
|
|
33
33
|
openUrl
|
|
34
34
|
};
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
35
|
+
//# sourceMappingURL=chunk-H6WUOW5F.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getLocalAgentDefinitions
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EC3JXT23.js";
|
|
5
5
|
import {
|
|
6
6
|
loadMergedAgents
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ENET4IF6.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/lib/operations/project/load-agent-defs.ts
|
|
10
10
|
async function loadAgentDefs() {
|
|
@@ -20,4 +20,4 @@ async function loadAgentDefs() {
|
|
|
20
20
|
export {
|
|
21
21
|
loadAgentDefs
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-JNRACLNS.js.map
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
namedByActiveEntries
|
|
4
|
+
} from "./chunk-FACDJH6O.js";
|
|
5
|
+
import {
|
|
6
|
+
ConfigLoadError,
|
|
7
|
+
FailedLeavingPluginsSwitchedOnError,
|
|
8
|
+
INFO_MESSAGES,
|
|
9
|
+
PluginsLeftSwitchedOnError,
|
|
3
10
|
STATUS_MESSAGES,
|
|
4
11
|
addedToGlobalSubAgents,
|
|
5
12
|
buildMarketplacePluginRef,
|
|
13
|
+
chooseProviderForThisRun,
|
|
6
14
|
claimSlug,
|
|
15
|
+
codexPluginLeftSwitchedOn,
|
|
7
16
|
completedWithFailures,
|
|
17
|
+
configDeclaresNothing,
|
|
8
18
|
copy,
|
|
9
19
|
defaultUsageGuidance,
|
|
20
|
+
detectInstallations,
|
|
10
21
|
directoryExists,
|
|
11
22
|
fetchMarketplace,
|
|
12
23
|
fileExists,
|
|
@@ -16,6 +27,7 @@ import {
|
|
|
16
27
|
getErrorMessage,
|
|
17
28
|
getStackSkillIds,
|
|
18
29
|
glob,
|
|
30
|
+
holdsAConfigDeclaringNothing,
|
|
19
31
|
hostAt,
|
|
20
32
|
installationConfigsUnreadable,
|
|
21
33
|
isHomeDirectory,
|
|
@@ -24,6 +36,7 @@ import {
|
|
|
24
36
|
loadStackById,
|
|
25
37
|
parseFrontmatter,
|
|
26
38
|
pluginsInstalled,
|
|
39
|
+
pluginsLeftSwitchedOn,
|
|
27
40
|
propagatedRecompileSummary,
|
|
28
41
|
providerInUse,
|
|
29
42
|
providerToNameAt,
|
|
@@ -44,13 +57,13 @@ import {
|
|
|
44
57
|
sharedConfigProjectScopeAtHome,
|
|
45
58
|
skillAssignedToNoAgent,
|
|
46
59
|
skillMetadataUnusableDetail,
|
|
60
|
+
skippedSkills,
|
|
47
61
|
skippedUnknownAgents,
|
|
48
|
-
skippedUnknownSkills,
|
|
49
62
|
validateSkillPath,
|
|
50
63
|
verbose,
|
|
51
64
|
warn,
|
|
52
65
|
writeFile
|
|
53
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-ENET4IF6.js";
|
|
54
67
|
import {
|
|
55
68
|
BUILT_IN_MATRIX,
|
|
56
69
|
getCategoryDomain,
|
|
@@ -60,22 +73,24 @@ import {
|
|
|
60
73
|
typedEntries,
|
|
61
74
|
typedKeys,
|
|
62
75
|
typedValues
|
|
63
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-UE4Z3YMB.js";
|
|
64
77
|
import {
|
|
65
78
|
CLI_COLORS,
|
|
66
79
|
CLI_INVOKE_COMMAND,
|
|
67
80
|
DEFAULT_BRANDING,
|
|
81
|
+
EDITOR_URL,
|
|
68
82
|
EJECT_SOURCE,
|
|
69
83
|
GITHUB_PREFIX,
|
|
70
84
|
GITHUB_SOURCE,
|
|
71
85
|
LOCAL_SKILLS_PATH,
|
|
72
86
|
MIN_TERMINAL_SIZE,
|
|
87
|
+
PROVIDERS,
|
|
73
88
|
STANDARD_FILES,
|
|
74
89
|
externalIdsNamingNoDirectory,
|
|
75
90
|
isActiveAt,
|
|
76
91
|
orderDomains,
|
|
77
92
|
seedExternalSkillSchema
|
|
78
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-U46LYYRA.js";
|
|
79
94
|
|
|
80
95
|
// src/cli/utils/terminal.ts
|
|
81
96
|
function clearTerminalScreen() {
|
|
@@ -103,8 +118,100 @@ var EXIT_CODES = {
|
|
|
103
118
|
COMPLETED_WITH_FAILURES: 5
|
|
104
119
|
};
|
|
105
120
|
|
|
106
|
-
// src/cli/lib/
|
|
121
|
+
// src/cli/lib/installation/provider-flag.ts
|
|
107
122
|
import os from "os";
|
|
123
|
+
import { Flags } from "@oclif/core";
|
|
124
|
+
function providerFlag() {
|
|
125
|
+
return Flags.string({
|
|
126
|
+
description: "Which provider's installation this run is about",
|
|
127
|
+
helpValue: `<${PROVIDERS.join("|")}>`,
|
|
128
|
+
options: [...PROVIDERS]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function providerNamedBy(flagValue) {
|
|
132
|
+
if (flagValue === void 0) return void 0;
|
|
133
|
+
return PROVIDERS.find((provider) => provider === flagValue);
|
|
134
|
+
}
|
|
135
|
+
var PROVIDER_FLAG = "--provider";
|
|
136
|
+
var PROVIDER_FLAG_WITH_ITS_VALUE = `${PROVIDER_FLAG}=`;
|
|
137
|
+
var END_OF_FLAGS = "--";
|
|
138
|
+
function providerNamedIn(argv) {
|
|
139
|
+
const end = argv.indexOf(END_OF_FLAGS);
|
|
140
|
+
const flags = end === -1 ? argv : argv.slice(0, end);
|
|
141
|
+
const spaced = flags.indexOf(PROVIDER_FLAG);
|
|
142
|
+
if (spaced !== -1) return providerNamedBy(flags[spaced + 1]);
|
|
143
|
+
const joined = flags.find((token) => token.startsWith(PROVIDER_FLAG_WITH_ITS_VALUE));
|
|
144
|
+
return providerNamedBy(joined?.slice(PROVIDER_FLAG_WITH_ITS_VALUE.length));
|
|
145
|
+
}
|
|
146
|
+
function providerNeedsAConfigurationToInstall() {
|
|
147
|
+
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>'.`;
|
|
148
|
+
}
|
|
149
|
+
function ambiguousInstallation(subject, providers, scopeRoot) {
|
|
150
|
+
return `${scopeRoot} holds ${providers.length} installations \u2014 ${providers.join(" and ")} \u2014 so ${subject} cannot tell which one you mean. Name it with --provider <${providers.join("|")}>. Nothing has been changed.`;
|
|
151
|
+
}
|
|
152
|
+
async function installationsInPlay(cwd) {
|
|
153
|
+
const found = await detectInstallations(cwd);
|
|
154
|
+
const inTheProject = atScope(found, "project");
|
|
155
|
+
if (inTheProject.length > 0) return { scopeRoot: cwd, providers: providersOf(inTheProject) };
|
|
156
|
+
return { scopeRoot: os.homedir(), providers: providersOf(atScope(found, "global")) };
|
|
157
|
+
}
|
|
158
|
+
function atScope(found, scope) {
|
|
159
|
+
return found.filter((installation) => installation.scope === scope);
|
|
160
|
+
}
|
|
161
|
+
function providersOf(installations) {
|
|
162
|
+
return installations.map((installation) => installation.provider);
|
|
163
|
+
}
|
|
164
|
+
async function refuseAnAmbiguousInstallation(cwd, subject, named, onAmbiguous) {
|
|
165
|
+
if (named !== void 0) {
|
|
166
|
+
chooseProviderForThisRun(named);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const { scopeRoot, providers } = await installationsInPlay(cwd);
|
|
170
|
+
if (providers.length <= 1) return;
|
|
171
|
+
onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));
|
|
172
|
+
}
|
|
173
|
+
async function holdsOnlyAConfigDeclaringNothing(cwd) {
|
|
174
|
+
if (!await holdsAConfigDeclaringNothing(cwd)) return false;
|
|
175
|
+
return atScope(await detectInstallations(cwd), "project").length === 0;
|
|
176
|
+
}
|
|
177
|
+
async function homeHoldsAnInstallationFor(cwd, named) {
|
|
178
|
+
const atHome = providersOf(atScope(await detectInstallations(cwd), "global")).filter(
|
|
179
|
+
(provider) => named === void 0 || provider === named
|
|
180
|
+
);
|
|
181
|
+
const declaringContent = await Promise.all(atHome.map(homeConfigDeclaresContent));
|
|
182
|
+
return declaringContent.includes(true);
|
|
183
|
+
}
|
|
184
|
+
async function homeConfigDeclaresContent(provider) {
|
|
185
|
+
try {
|
|
186
|
+
return !await configDeclaresNothing(os.homedir(), provider);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
if (error instanceof ConfigLoadError) return true;
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function providersInPlay(cwd) {
|
|
193
|
+
return (await installationsInPlay(cwd)).providers;
|
|
194
|
+
}
|
|
195
|
+
async function installationToName(cwd, named) {
|
|
196
|
+
if (named !== void 0) return named;
|
|
197
|
+
const providers = await providersInPlay(cwd);
|
|
198
|
+
return providers.length > 1 ? providers : void 0;
|
|
199
|
+
}
|
|
200
|
+
async function ambiguityFinding(cwd) {
|
|
201
|
+
const { scopeRoot, providers } = await installationsInPlay(cwd);
|
|
202
|
+
if (providers.length <= 1) return null;
|
|
203
|
+
return ambiguousInstallation("every command that acts on one", providers, scopeRoot);
|
|
204
|
+
}
|
|
205
|
+
async function otherInstallationsInThisScope(cwd) {
|
|
206
|
+
const { scopeRoot, providers } = await installationsInPlay(cwd);
|
|
207
|
+
const showing = providerInUse(scopeRoot);
|
|
208
|
+
const others = providers.filter((provider) => provider !== showing);
|
|
209
|
+
if (others.length === 0) return null;
|
|
210
|
+
return `${scopeRoot} holds ${providers.length} installations \u2014 ${providers.join(" and ")} \u2014 and this is the ${showing} one. Show another with --provider <${providers.join("|")}>.`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/cli/lib/seed/external-skills.ts
|
|
214
|
+
import os2 from "os";
|
|
108
215
|
import path from "path";
|
|
109
216
|
import { mkdtemp } from "fs/promises";
|
|
110
217
|
|
|
@@ -326,9 +433,38 @@ function notADirectoryNameError(ids) {
|
|
|
326
433
|
"A skill id is the directory the skill is written into, so an id holding a path separator, or naming '.' or '..', would be written somewhere other than a directory of its own, and one holding a control character would hand it to the terminal wherever that directory is named. Re-share it with each skill above added again, which mints an id \u2014 'external-<category>-<name>' \u2014 that names one directory."
|
|
327
434
|
].join("\n");
|
|
328
435
|
}
|
|
436
|
+
var DIRECTORY_NAME_MAX_BYTES = 255;
|
|
437
|
+
function overrunsADirectoryName(id) {
|
|
438
|
+
return Buffer.byteLength(id, "utf8") > DIRECTORY_NAME_MAX_BYTES;
|
|
439
|
+
}
|
|
440
|
+
function externalIdsTooLongForADirectory(payload) {
|
|
441
|
+
return Object.keys(payload.external ?? {}).filter(overrunsADirectoryName);
|
|
442
|
+
}
|
|
443
|
+
function tooLongForADirectoryError(ids) {
|
|
444
|
+
return [
|
|
445
|
+
"This configuration cannot be installed: these skills travel inside it under ids longer than a directory name may be:",
|
|
446
|
+
...ids.map((id) => ` ${JSON.stringify(id)}`),
|
|
447
|
+
`A skill id is the directory the skill is written into, and a directory name may hold at most ${String(DIRECTORY_NAME_MAX_BYTES)} bytes, so none of these could be written. Re-share it without each skill above.`
|
|
448
|
+
].join("\n");
|
|
449
|
+
}
|
|
450
|
+
var CARRIED_ID_PREFIX = "external-";
|
|
451
|
+
function externalIdsLackingThePrefix(payload) {
|
|
452
|
+
return Object.keys(payload.external ?? {}).filter((id) => !id.startsWith(CARRIED_ID_PREFIX));
|
|
453
|
+
}
|
|
454
|
+
function lacksThePrefixError(ids) {
|
|
455
|
+
return [
|
|
456
|
+
"This configuration cannot be installed: these skills travel inside it under ids that do not start with 'external-':",
|
|
457
|
+
...ids.map((id) => ` ${id}`),
|
|
458
|
+
"A skill id is the directory the skill installs into, and no marketplace may publish under the name 'external', so an id starting 'external-' is the only kind that can never take the place of a marketplace's skill. Re-share it with each skill above added again, which mints such an id \u2014 'external-<category>-<name>'."
|
|
459
|
+
].join("\n");
|
|
460
|
+
}
|
|
329
461
|
function registerExternalSkills(payload, matrix2, projectDir) {
|
|
330
462
|
const notDirectoryNames = externalIdsNamingNoDirectory(payload);
|
|
331
463
|
if (notDirectoryNames.length > 0) throw new Error(notADirectoryNameError(notDirectoryNames));
|
|
464
|
+
const tooLong = externalIdsTooLongForADirectory(payload);
|
|
465
|
+
if (tooLong.length > 0) throw new Error(tooLongForADirectoryError(tooLong));
|
|
466
|
+
const unprefixed = externalIdsLackingThePrefix(payload);
|
|
467
|
+
if (unprefixed.length > 0) throw new Error(lacksThePrefixError(unprefixed));
|
|
332
468
|
const externals = selectedExternals(payload);
|
|
333
469
|
const asPlugin = askedForAsPlugin(externals);
|
|
334
470
|
const colliding = claimingACatalogueId(externals, matrix2);
|
|
@@ -344,7 +480,7 @@ async function writeExternalSkills(installs) {
|
|
|
344
480
|
var SCRATCH_DIR_PREFIX = "agents-inc-carried-";
|
|
345
481
|
async function carriedSkillsThatDiffer(installs) {
|
|
346
482
|
if (installs.length === 0) return [];
|
|
347
|
-
const scratch = await mkdtemp(path.join(
|
|
483
|
+
const scratch = await mkdtemp(path.join(os2.tmpdir(), SCRATCH_DIR_PREFIX));
|
|
348
484
|
try {
|
|
349
485
|
const written = await Promise.all(
|
|
350
486
|
installs.map(async (install) => writeExternalSkill(await scratchCopyOf(install, scratch)))
|
|
@@ -495,7 +631,7 @@ async function readCarriedSkills(owned) {
|
|
|
495
631
|
}
|
|
496
632
|
|
|
497
633
|
// src/cli/lib/seed/seed-apply.ts
|
|
498
|
-
import
|
|
634
|
+
import os3 from "os";
|
|
499
635
|
import { isDeepEqual, omit, partition, pick } from "remeda";
|
|
500
636
|
var NOTHING_KEPT = {
|
|
501
637
|
authoredSkillIds: [],
|
|
@@ -572,7 +708,7 @@ function withAgentKeptRows(carried, agent, keptRows, payloadRows) {
|
|
|
572
708
|
};
|
|
573
709
|
}
|
|
574
710
|
async function readInstalledGlobal(projectDir) {
|
|
575
|
-
const loaded = await loadProjectConfigFromDir(
|
|
711
|
+
const loaded = await loadProjectConfigFromDir(os3.homedir(), providerInUse(projectDir));
|
|
576
712
|
return loaded?.config ?? null;
|
|
577
713
|
}
|
|
578
714
|
var NO_GLOBAL_ENTRIES = { skillIds: [], agentNames: [] };
|
|
@@ -750,8 +886,12 @@ function entriesActiveAt(skills, agents, scope) {
|
|
|
750
886
|
agentNames: agents.filter((agent) => isActiveAt(agent, scope)).map((agent) => agent.name)
|
|
751
887
|
};
|
|
752
888
|
}
|
|
889
|
+
function panelRowEntries(held) {
|
|
890
|
+
return namedByActiveEntries(held.result.skills);
|
|
891
|
+
}
|
|
753
892
|
function joinedStatement(held) {
|
|
754
|
-
|
|
893
|
+
if (held.joined.length === 0) return [];
|
|
894
|
+
return [addedToGlobalSubAgents(held.joined, panelRowEntries(held))];
|
|
755
895
|
}
|
|
756
896
|
function projectScopedContent(result) {
|
|
757
897
|
return entriesActiveAt(result.skills, result.agentConfigs, "project");
|
|
@@ -769,19 +909,37 @@ import { unique } from "remeda";
|
|
|
769
909
|
// src/cli/lib/operations/source/ensure-marketplace.ts
|
|
770
910
|
async function ensureMarketplace(sourceResult, host) {
|
|
771
911
|
const marketplace = await resolveMarketplaceName(sourceResult);
|
|
772
|
-
if (marketplace === null) return { marketplace: null, registered: false };
|
|
912
|
+
if (marketplace === null) return { marketplace: null, registered: false, leftOn: [] };
|
|
773
913
|
const exists = await host.marketplaceExists(marketplace);
|
|
774
914
|
if (!exists) {
|
|
775
915
|
const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, "");
|
|
776
916
|
await host.addMarketplace(marketplaceSource);
|
|
777
|
-
return { marketplace, registered: true };
|
|
917
|
+
return { marketplace, registered: true, leftOn: [] };
|
|
778
918
|
}
|
|
919
|
+
const outcome = await refreshOutcome(marketplace, host);
|
|
920
|
+
warnOfShortfalls(outcome);
|
|
921
|
+
return { marketplace, registered: false, leftOn: outcome.leftOn };
|
|
922
|
+
}
|
|
923
|
+
async function refreshOutcome(marketplace, host) {
|
|
779
924
|
try {
|
|
780
925
|
await host.refreshMarketplace(marketplace);
|
|
781
|
-
|
|
782
|
-
|
|
926
|
+
return { refreshed: true, leftOn: [] };
|
|
927
|
+
} catch (error) {
|
|
928
|
+
return outcomeOfRefusal(error);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
function outcomeOfRefusal(error) {
|
|
932
|
+
if (error instanceof PluginsLeftSwitchedOnError) return { refreshed: true, leftOn: error.leftOn };
|
|
933
|
+
if (error instanceof FailedLeavingPluginsSwitchedOnError) {
|
|
934
|
+
return { refreshed: false, leftOn: error.leftOn };
|
|
935
|
+
}
|
|
936
|
+
return { refreshed: false, leftOn: [] };
|
|
937
|
+
}
|
|
938
|
+
function warnOfShortfalls({ refreshed, leftOn }) {
|
|
939
|
+
if (!refreshed) warn("Could not update marketplace \u2014 continuing with cached version");
|
|
940
|
+
for (const { pluginKey, configFile, reason } of leftOn) {
|
|
941
|
+
warn(codexPluginLeftSwitchedOn(pluginKey, configFile, reason));
|
|
783
942
|
}
|
|
784
|
-
return { marketplace, registered: false };
|
|
785
943
|
}
|
|
786
944
|
async function resolveMarketplaceName(sourceResult) {
|
|
787
945
|
if (sourceResult.marketplace) return sourceResult.marketplace;
|
|
@@ -805,7 +963,12 @@ async function requireMarketplace(sourceResult, purpose, host) {
|
|
|
805
963
|
error: `Cannot ${purpose}: marketplace could not be resolved from '${sourceResult.sourceConfig.source}'. Plugin install mode requires a marketplace \u2014 fix the marketplace or switch the affected skills to eject mode.`
|
|
806
964
|
};
|
|
807
965
|
}
|
|
808
|
-
return {
|
|
966
|
+
return {
|
|
967
|
+
ok: true,
|
|
968
|
+
marketplace: mpResult.marketplace,
|
|
969
|
+
registered: mpResult.registered,
|
|
970
|
+
leftOn: mpResult.leftOn
|
|
971
|
+
};
|
|
809
972
|
}
|
|
810
973
|
|
|
811
974
|
// src/cli/lib/operations/skills/install-plugin-skills.ts
|
|
@@ -839,6 +1002,10 @@ async function installPluginSkills(skills, marketplace, projectDir) {
|
|
|
839
1002
|
var TERMINAL_RESIZE_POLL_MS = 500;
|
|
840
1003
|
var terminalColumns = () => process.stdout.columns ?? MIN_TERMINAL_SIZE.COLS;
|
|
841
1004
|
var terminalRows = () => process.stdout.rows ?? MIN_TERMINAL_SIZE.ROWS;
|
|
1005
|
+
function sayFirst(line) {
|
|
1006
|
+
process.stderr.write(`${line}
|
|
1007
|
+
`);
|
|
1008
|
+
}
|
|
842
1009
|
function isTerminalBigEnough() {
|
|
843
1010
|
return isTerminalLargeEnough(terminalColumns(), terminalRows());
|
|
844
1011
|
}
|
|
@@ -872,10 +1039,27 @@ function hasActiveProjectEntry(skills, skillId) {
|
|
|
872
1039
|
var BaseCommand = class extends Command {
|
|
873
1040
|
/** Non-empty decides the exit code; see {@link exitIfWorkIncomplete}. */
|
|
874
1041
|
incompleteWork = [];
|
|
1042
|
+
/** Warned of by the refresh that left them; non-empty fails the run, as in `update`. */
|
|
1043
|
+
switchesLeftOn = [];
|
|
875
1044
|
async init() {
|
|
876
1045
|
await super.init();
|
|
877
1046
|
await this.ensureTerminalSize();
|
|
878
1047
|
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Called first where a command starts work on the installation in play, which for a project whose
|
|
1050
|
+
* config declares nothing is the global one, or none where HOME holds none the run could work on.
|
|
1051
|
+
*/
|
|
1052
|
+
async sayWhenTheGlobalInstallationStandsIn(named) {
|
|
1053
|
+
if (!await holdsOnlyAConfigDeclaringNothing(process.cwd())) return;
|
|
1054
|
+
const standsIn = await homeHoldsAnInstallationFor(process.cwd(), named);
|
|
1055
|
+
sayFirst(
|
|
1056
|
+
standsIn ? INFO_MESSAGES.GLOBAL_INSTALLATION_STANDS_IN : INFO_MESSAGES.NO_GLOBAL_INSTALLATION_STANDS_IN
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
/** For a command that never works on the global installation: `line` says what it does instead. */
|
|
1060
|
+
async sayWhenTheProjectsConfigDeclaresNothing(line) {
|
|
1061
|
+
if (await holdsOnlyAConfigDeclaringNothing(process.cwd())) sayFirst(line);
|
|
1062
|
+
}
|
|
879
1063
|
async ensureTerminalSize() {
|
|
880
1064
|
if (isTerminalBigEnough()) return;
|
|
881
1065
|
clearTerminalScreen();
|
|
@@ -908,6 +1092,7 @@ var BaseCommand = class extends Command {
|
|
|
908
1092
|
if (!required.ok) {
|
|
909
1093
|
this.error(required.error, { exit: EXIT_CODES.ERROR });
|
|
910
1094
|
}
|
|
1095
|
+
this.switchesLeftOn.push(...required.leftOn);
|
|
911
1096
|
if (required.registered) {
|
|
912
1097
|
onRegistered?.(required.marketplace);
|
|
913
1098
|
}
|
|
@@ -971,10 +1156,11 @@ var BaseCommand = class extends Command {
|
|
|
971
1156
|
this.log(propagatedRecompileSummary(rewrittenCount + unchangedCount, failedCount));
|
|
972
1157
|
}
|
|
973
1158
|
reportUnassignedSkills(config, selected) {
|
|
1159
|
+
const namedBy = namedByActiveEntries(selected);
|
|
974
1160
|
for (const { skillId, blockedBy } of findUnassignedSkills(config, selected)) {
|
|
975
|
-
this.warn(skillAssignedToNoAgent(skillId));
|
|
1161
|
+
this.warn(skillAssignedToNoAgent(skillId, namedBy));
|
|
976
1162
|
if (blockedBy.length > 0) {
|
|
977
|
-
this.warn(scopeBlockedStackAssignment(blockedBy, skillId));
|
|
1163
|
+
this.warn(scopeBlockedStackAssignment(blockedBy, skillId, namedBy));
|
|
978
1164
|
}
|
|
979
1165
|
}
|
|
980
1166
|
}
|
|
@@ -1014,14 +1200,17 @@ var BaseCommand = class extends Command {
|
|
|
1014
1200
|
if (!isHomeDirectory(projectDir) || installsAtHome(result)) return;
|
|
1015
1201
|
const { skillIds, agentNames } = projectScopedContent(result);
|
|
1016
1202
|
const provider = providerToNameAt(projectDir, providerInUse(projectDir));
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1203
|
+
const namedBy = namedByActiveEntries(result.skills);
|
|
1204
|
+
this.error(
|
|
1205
|
+
sharedConfigProjectScopeAtHome(skillIds, agentNames, installedHere, provider, namedBy),
|
|
1206
|
+
{ exit: EXIT_CODES.ERROR }
|
|
1207
|
+
);
|
|
1020
1208
|
}
|
|
1021
|
-
|
|
1209
|
+
/** `unloadedSkillIds`: skills the marketplace ships and could not load, never unknown ones. */
|
|
1210
|
+
warnOfSkippedEntries(mapping, unloadedSkillIds) {
|
|
1022
1211
|
const { skippedSkillIds, skippedAgentNames, agentsOnlySkippedSkillsCarried } = mapping;
|
|
1023
1212
|
if (skippedSkillIds.length > 0) {
|
|
1024
|
-
this.warn(
|
|
1213
|
+
this.warn(skippedSkills(skippedSkillIds, agentsOnlySkippedSkillsCarried, unloadedSkillIds));
|
|
1025
1214
|
}
|
|
1026
1215
|
if (skippedAgentNames.length > 0) this.warn(skippedUnknownAgents(skippedAgentNames));
|
|
1027
1216
|
}
|
|
@@ -1068,17 +1257,34 @@ var BaseCommand = class extends Command {
|
|
|
1068
1257
|
}
|
|
1069
1258
|
/** Every command that records must call this; `this.exit` skips the `Error:` framing. */
|
|
1070
1259
|
exitIfWorkIncomplete() {
|
|
1260
|
+
this.listIncompleteWork();
|
|
1261
|
+
this.failIfPluginsLeftSwitchedOn();
|
|
1262
|
+
if (this.hasIncompleteWork) this.exit(EXIT_CODES.COMPLETED_WITH_FAILURES);
|
|
1263
|
+
}
|
|
1264
|
+
listIncompleteWork() {
|
|
1071
1265
|
if (!this.hasIncompleteWork) return;
|
|
1072
1266
|
this.log(`
|
|
1073
1267
|
${chalk.hex(CLI_COLORS.WARNING)(completedWithFailures(this.incompleteWork))}
|
|
1074
1268
|
`);
|
|
1075
|
-
|
|
1269
|
+
}
|
|
1270
|
+
failIfPluginsLeftSwitchedOn() {
|
|
1271
|
+
if (this.switchesLeftOn.length === 0) return;
|
|
1272
|
+
const pluginKeys = this.switchesLeftOn.map(({ pluginKey }) => pluginKey);
|
|
1273
|
+
this.error(pluginsLeftSwitchedOn(pluginKeys), { exit: EXIT_CODES.ERROR });
|
|
1076
1274
|
}
|
|
1077
1275
|
};
|
|
1078
1276
|
|
|
1079
1277
|
export {
|
|
1080
1278
|
clearTerminalScreen,
|
|
1081
1279
|
EXIT_CODES,
|
|
1280
|
+
providerFlag,
|
|
1281
|
+
providerNamedBy,
|
|
1282
|
+
providerNamedIn,
|
|
1283
|
+
providerNeedsAConfigurationToInstall,
|
|
1284
|
+
refuseAnAmbiguousInstallation,
|
|
1285
|
+
installationToName,
|
|
1286
|
+
ambiguityFinding,
|
|
1287
|
+
otherInstallationsInThisScope,
|
|
1082
1288
|
registerExternalSkills,
|
|
1083
1289
|
writeExternalSkills,
|
|
1084
1290
|
carriedSkillsThatDiffer,
|
|
@@ -1089,8 +1295,9 @@ export {
|
|
|
1089
1295
|
restoreInstalledGlobal,
|
|
1090
1296
|
sameAssignments,
|
|
1091
1297
|
notInstalledGlobally,
|
|
1298
|
+
panelRowEntries,
|
|
1092
1299
|
joinedStatement,
|
|
1093
1300
|
installsAtHome,
|
|
1094
1301
|
BaseCommand
|
|
1095
1302
|
};
|
|
1096
|
-
//# sourceMappingURL=chunk-
|
|
1303
|
+
//# sourceMappingURL=chunk-JTMSFBCA.js.map
|