agents-inc 0.175.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 +67 -0
- package/dist/{chunk-EGC7PNDI.js → chunk-3F5LT433.js} +138 -41
- 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-MFCZARV2.js → chunk-B7AVWSK2.js} +18 -8
- package/dist/chunk-B7AVWSK2.js.map +1 -0
- package/dist/{chunk-6HJVH27C.js → chunk-C2BSCEDN.js} +2 -2
- package/dist/{chunk-SNXEYAFP.js → chunk-CKBWEWHZ.js} +60 -30
- package/dist/chunk-CKBWEWHZ.js.map +1 -0
- package/dist/{chunk-SI2LLEIR.js → chunk-EC3JXT23.js} +4 -4
- package/dist/{chunk-YM3VEDAP.js → chunk-ENET4IF6.js} +440 -192
- package/dist/chunk-ENET4IF6.js.map +1 -0
- package/dist/{chunk-ICHWAFAC.js → chunk-FACDJH6O.js} +11 -104
- package/dist/chunk-FACDJH6O.js.map +1 -0
- package/dist/{chunk-P5XEK7HC.js → chunk-H6WUOW5F.js} +2 -2
- package/dist/{chunk-DQB3E2SX.js → chunk-JNRACLNS.js} +3 -3
- package/dist/{chunk-37QFHJUW.js → chunk-JTMSFBCA.js} +106 -28
- package/dist/chunk-JTMSFBCA.js.map +1 -0
- package/dist/{chunk-GNMRXXRY.js → chunk-MQZNDK5F.js} +3 -3
- package/dist/chunk-MQZNDK5F.js.map +1 -0
- package/dist/{chunk-SRII2GMF.js → chunk-SN64WNWE.js} +2 -2
- package/dist/{chunk-EHEBN4NB.js → chunk-U672FZVC.js} +2 -2
- package/dist/{chunk-TG3SPPZY.js → chunk-UE4Z3YMB.js} +1 -1
- package/dist/chunk-UE4Z3YMB.js.map +1 -0
- package/dist/{chunk-Q4NWATGH.js → chunk-XMQIWPIR.js} +58 -10
- package/dist/chunk-XMQIWPIR.js.map +1 -0
- package/dist/{chunk-YLFKFVQP.js → chunk-ZBI6GFJD.js} +2 -2
- package/dist/commands/build/marketplace.js +4 -3
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -5
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/compile.js +15 -11
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +38 -14
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +46 -25
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +12 -8
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +15 -14
- package/dist/commands/list.js +8 -6
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -3
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +13 -8
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +14 -16
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/uninstall.js +18 -14
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +97 -17
- package/dist/commands/update.js.map +1 -1
- package/dist/components/common/skill-agent-summary.js +3 -2
- package/dist/components/common/summary-panel.js +4 -3
- package/dist/hooks/init.js +15 -14
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-5BSECHE6.js +14 -0
- package/dist/{recompile-project-agents-2QTFMYDC.js → recompile-project-agents-U3UGHPWG.js} +7 -7
- package/dist/{source-loader-I6SWWDUF.js → source-loader-E2Y5MMN5.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-37QFHJUW.js.map +0 -1
- package/dist/chunk-EGC7PNDI.js.map +0 -1
- package/dist/chunk-GNMRXXRY.js.map +0 -1
- package/dist/chunk-ICHWAFAC.js.map +0 -1
- package/dist/chunk-MFCZARV2.js.map +0 -1
- package/dist/chunk-Q4NWATGH.js.map +0 -1
- package/dist/chunk-SNXEYAFP.js.map +0 -1
- package/dist/chunk-TG3SPPZY.js.map +0 -1
- package/dist/chunk-YM3VEDAP.js.map +0 -1
- package/dist/load-agent-defs-BJ4KBKBA.js +0 -14
- /package/dist/{chunk-6HJVH27C.js.map → chunk-C2BSCEDN.js.map} +0 -0
- /package/dist/{chunk-SI2LLEIR.js.map → chunk-EC3JXT23.js.map} +0 -0
- /package/dist/{chunk-P5XEK7HC.js.map → chunk-H6WUOW5F.js.map} +0 -0
- /package/dist/{chunk-DQB3E2SX.js.map → chunk-JNRACLNS.js.map} +0 -0
- /package/dist/{chunk-SRII2GMF.js.map → chunk-SN64WNWE.js.map} +0 -0
- /package/dist/{chunk-EHEBN4NB.js.map → chunk-U672FZVC.js.map} +0 -0
- /package/dist/{chunk-YLFKFVQP.js.map → chunk-ZBI6GFJD.js.map} +0 -0
- /package/dist/{load-agent-defs-BJ4KBKBA.js.map → load-agent-defs-5BSECHE6.js.map} +0 -0
- /package/dist/{recompile-project-agents-2QTFMYDC.js.map → recompile-project-agents-U3UGHPWG.js.map} +0 -0
- /package/dist/{source-loader-I6SWWDUF.js.map → source-loader-E2Y5MMN5.js.map} +0 -0
|
@@ -1,20 +1,12 @@
|
|
|
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
8
|
} from "./chunk-U46LYYRA.js";
|
|
13
9
|
|
|
14
|
-
// src/cli/components/common/skill-agent-summary.tsx
|
|
15
|
-
import { Box, Text } from "ink";
|
|
16
|
-
import "react";
|
|
17
|
-
|
|
18
10
|
// src/cli/lib/configuration/scope-diff.ts
|
|
19
11
|
import { difference, indexBy, partition, unique } from "remeda";
|
|
20
12
|
var NOTHING = /* @__PURE__ */ new Set();
|
|
@@ -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,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
namedByActiveEntries
|
|
4
|
+
} from "./chunk-FACDJH6O.js";
|
|
5
|
+
import {
|
|
6
|
+
ConfigLoadError,
|
|
7
|
+
FailedLeavingPluginsSwitchedOnError,
|
|
3
8
|
INFO_MESSAGES,
|
|
9
|
+
PluginsLeftSwitchedOnError,
|
|
4
10
|
STATUS_MESSAGES,
|
|
5
11
|
addedToGlobalSubAgents,
|
|
6
12
|
buildMarketplacePluginRef,
|
|
7
13
|
chooseProviderForThisRun,
|
|
8
14
|
claimSlug,
|
|
15
|
+
codexPluginLeftSwitchedOn,
|
|
9
16
|
completedWithFailures,
|
|
17
|
+
configDeclaresNothing,
|
|
10
18
|
copy,
|
|
11
19
|
defaultUsageGuidance,
|
|
12
20
|
detectInstallations,
|
|
@@ -28,6 +36,7 @@ import {
|
|
|
28
36
|
loadStackById,
|
|
29
37
|
parseFrontmatter,
|
|
30
38
|
pluginsInstalled,
|
|
39
|
+
pluginsLeftSwitchedOn,
|
|
31
40
|
propagatedRecompileSummary,
|
|
32
41
|
providerInUse,
|
|
33
42
|
providerToNameAt,
|
|
@@ -54,7 +63,7 @@ import {
|
|
|
54
63
|
verbose,
|
|
55
64
|
warn,
|
|
56
65
|
writeFile
|
|
57
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-ENET4IF6.js";
|
|
58
67
|
import {
|
|
59
68
|
BUILT_IN_MATRIX,
|
|
60
69
|
getCategoryDomain,
|
|
@@ -64,7 +73,7 @@ import {
|
|
|
64
73
|
typedEntries,
|
|
65
74
|
typedKeys,
|
|
66
75
|
typedValues
|
|
67
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-UE4Z3YMB.js";
|
|
68
77
|
import {
|
|
69
78
|
CLI_COLORS,
|
|
70
79
|
CLI_INVOKE_COMMAND,
|
|
@@ -161,14 +170,24 @@ async function refuseAnAmbiguousInstallation(cwd, subject, named, onAmbiguous) {
|
|
|
161
170
|
if (providers.length <= 1) return;
|
|
162
171
|
onAmbiguous(ambiguousInstallation(subject, providers, scopeRoot));
|
|
163
172
|
}
|
|
164
|
-
async function
|
|
173
|
+
async function holdsOnlyAConfigDeclaringNothing(cwd) {
|
|
165
174
|
if (!await holdsAConfigDeclaringNothing(cwd)) return false;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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(
|
|
169
179
|
(provider) => named === void 0 || provider === named
|
|
170
180
|
);
|
|
171
|
-
|
|
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
|
+
}
|
|
172
191
|
}
|
|
173
192
|
async function providersInPlay(cwd) {
|
|
174
193
|
return (await installationsInPlay(cwd)).providers;
|
|
@@ -428,11 +447,24 @@ function tooLongForADirectoryError(ids) {
|
|
|
428
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.`
|
|
429
448
|
].join("\n");
|
|
430
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
|
+
}
|
|
431
461
|
function registerExternalSkills(payload, matrix2, projectDir) {
|
|
432
462
|
const notDirectoryNames = externalIdsNamingNoDirectory(payload);
|
|
433
463
|
if (notDirectoryNames.length > 0) throw new Error(notADirectoryNameError(notDirectoryNames));
|
|
434
464
|
const tooLong = externalIdsTooLongForADirectory(payload);
|
|
435
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));
|
|
436
468
|
const externals = selectedExternals(payload);
|
|
437
469
|
const asPlugin = askedForAsPlugin(externals);
|
|
438
470
|
const colliding = claimingACatalogueId(externals, matrix2);
|
|
@@ -600,7 +632,7 @@ async function readCarriedSkills(owned) {
|
|
|
600
632
|
|
|
601
633
|
// src/cli/lib/seed/seed-apply.ts
|
|
602
634
|
import os3 from "os";
|
|
603
|
-
import {
|
|
635
|
+
import { isDeepEqual, omit, partition, pick } from "remeda";
|
|
604
636
|
var NOTHING_KEPT = {
|
|
605
637
|
authoredSkillIds: [],
|
|
606
638
|
unplaceableSkillIds: []
|
|
@@ -855,8 +887,7 @@ function entriesActiveAt(skills, agents, scope) {
|
|
|
855
887
|
};
|
|
856
888
|
}
|
|
857
889
|
function panelRowEntries(held) {
|
|
858
|
-
|
|
859
|
-
return indexBy(active, (skill) => skill.id);
|
|
890
|
+
return namedByActiveEntries(held.result.skills);
|
|
860
891
|
}
|
|
861
892
|
function joinedStatement(held) {
|
|
862
893
|
if (held.joined.length === 0) return [];
|
|
@@ -878,19 +909,37 @@ import { unique } from "remeda";
|
|
|
878
909
|
// src/cli/lib/operations/source/ensure-marketplace.ts
|
|
879
910
|
async function ensureMarketplace(sourceResult, host) {
|
|
880
911
|
const marketplace = await resolveMarketplaceName(sourceResult);
|
|
881
|
-
if (marketplace === null) return { marketplace: null, registered: false };
|
|
912
|
+
if (marketplace === null) return { marketplace: null, registered: false, leftOn: [] };
|
|
882
913
|
const exists = await host.marketplaceExists(marketplace);
|
|
883
914
|
if (!exists) {
|
|
884
915
|
const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, "");
|
|
885
916
|
await host.addMarketplace(marketplaceSource);
|
|
886
|
-
return { marketplace, registered: true };
|
|
917
|
+
return { marketplace, registered: true, leftOn: [] };
|
|
887
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) {
|
|
888
924
|
try {
|
|
889
925
|
await host.refreshMarketplace(marketplace);
|
|
890
|
-
|
|
891
|
-
|
|
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));
|
|
892
942
|
}
|
|
893
|
-
return { marketplace, registered: false };
|
|
894
943
|
}
|
|
895
944
|
async function resolveMarketplaceName(sourceResult) {
|
|
896
945
|
if (sourceResult.marketplace) return sourceResult.marketplace;
|
|
@@ -914,7 +963,12 @@ async function requireMarketplace(sourceResult, purpose, host) {
|
|
|
914
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.`
|
|
915
964
|
};
|
|
916
965
|
}
|
|
917
|
-
return {
|
|
966
|
+
return {
|
|
967
|
+
ok: true,
|
|
968
|
+
marketplace: mpResult.marketplace,
|
|
969
|
+
registered: mpResult.registered,
|
|
970
|
+
leftOn: mpResult.leftOn
|
|
971
|
+
};
|
|
918
972
|
}
|
|
919
973
|
|
|
920
974
|
// src/cli/lib/operations/skills/install-plugin-skills.ts
|
|
@@ -948,6 +1002,10 @@ async function installPluginSkills(skills, marketplace, projectDir) {
|
|
|
948
1002
|
var TERMINAL_RESIZE_POLL_MS = 500;
|
|
949
1003
|
var terminalColumns = () => process.stdout.columns ?? MIN_TERMINAL_SIZE.COLS;
|
|
950
1004
|
var terminalRows = () => process.stdout.rows ?? MIN_TERMINAL_SIZE.ROWS;
|
|
1005
|
+
function sayFirst(line) {
|
|
1006
|
+
process.stderr.write(`${line}
|
|
1007
|
+
`);
|
|
1008
|
+
}
|
|
951
1009
|
function isTerminalBigEnough() {
|
|
952
1010
|
return isTerminalLargeEnough(terminalColumns(), terminalRows());
|
|
953
1011
|
}
|
|
@@ -981,19 +1039,26 @@ function hasActiveProjectEntry(skills, skillId) {
|
|
|
981
1039
|
var BaseCommand = class extends Command {
|
|
982
1040
|
/** Non-empty decides the exit code; see {@link exitIfWorkIncomplete}. */
|
|
983
1041
|
incompleteWork = [];
|
|
1042
|
+
/** Warned of by the refresh that left them; non-empty fails the run, as in `update`. */
|
|
1043
|
+
switchesLeftOn = [];
|
|
984
1044
|
async init() {
|
|
985
1045
|
await super.init();
|
|
986
1046
|
await this.ensureTerminalSize();
|
|
987
1047
|
}
|
|
988
1048
|
/**
|
|
989
1049
|
* Called first where a command starts work on the installation in play, which for a project whose
|
|
990
|
-
* config declares nothing is the global one
|
|
991
|
-
* so piped output is unchanged.
|
|
1050
|
+
* config declares nothing is the global one, or none where HOME holds none the run could work on.
|
|
992
1051
|
*/
|
|
993
1052
|
async sayWhenTheGlobalInstallationStandsIn(named) {
|
|
994
|
-
if (!await
|
|
995
|
-
process.
|
|
996
|
-
|
|
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);
|
|
997
1062
|
}
|
|
998
1063
|
async ensureTerminalSize() {
|
|
999
1064
|
if (isTerminalBigEnough()) return;
|
|
@@ -1027,6 +1092,7 @@ var BaseCommand = class extends Command {
|
|
|
1027
1092
|
if (!required.ok) {
|
|
1028
1093
|
this.error(required.error, { exit: EXIT_CODES.ERROR });
|
|
1029
1094
|
}
|
|
1095
|
+
this.switchesLeftOn.push(...required.leftOn);
|
|
1030
1096
|
if (required.registered) {
|
|
1031
1097
|
onRegistered?.(required.marketplace);
|
|
1032
1098
|
}
|
|
@@ -1090,10 +1156,11 @@ var BaseCommand = class extends Command {
|
|
|
1090
1156
|
this.log(propagatedRecompileSummary(rewrittenCount + unchangedCount, failedCount));
|
|
1091
1157
|
}
|
|
1092
1158
|
reportUnassignedSkills(config, selected) {
|
|
1159
|
+
const namedBy = namedByActiveEntries(selected);
|
|
1093
1160
|
for (const { skillId, blockedBy } of findUnassignedSkills(config, selected)) {
|
|
1094
|
-
this.warn(skillAssignedToNoAgent(skillId));
|
|
1161
|
+
this.warn(skillAssignedToNoAgent(skillId, namedBy));
|
|
1095
1162
|
if (blockedBy.length > 0) {
|
|
1096
|
-
this.warn(scopeBlockedStackAssignment(blockedBy, skillId));
|
|
1163
|
+
this.warn(scopeBlockedStackAssignment(blockedBy, skillId, namedBy));
|
|
1097
1164
|
}
|
|
1098
1165
|
}
|
|
1099
1166
|
}
|
|
@@ -1133,9 +1200,11 @@ var BaseCommand = class extends Command {
|
|
|
1133
1200
|
if (!isHomeDirectory(projectDir) || installsAtHome(result)) return;
|
|
1134
1201
|
const { skillIds, agentNames } = projectScopedContent(result);
|
|
1135
1202
|
const provider = providerToNameAt(projectDir, providerInUse(projectDir));
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1203
|
+
const namedBy = namedByActiveEntries(result.skills);
|
|
1204
|
+
this.error(
|
|
1205
|
+
sharedConfigProjectScopeAtHome(skillIds, agentNames, installedHere, provider, namedBy),
|
|
1206
|
+
{ exit: EXIT_CODES.ERROR }
|
|
1207
|
+
);
|
|
1139
1208
|
}
|
|
1140
1209
|
/** `unloadedSkillIds`: skills the marketplace ships and could not load, never unknown ones. */
|
|
1141
1210
|
warnOfSkippedEntries(mapping, unloadedSkillIds) {
|
|
@@ -1188,11 +1257,20 @@ var BaseCommand = class extends Command {
|
|
|
1188
1257
|
}
|
|
1189
1258
|
/** Every command that records must call this; `this.exit` skips the `Error:` framing. */
|
|
1190
1259
|
exitIfWorkIncomplete() {
|
|
1260
|
+
this.listIncompleteWork();
|
|
1261
|
+
this.failIfPluginsLeftSwitchedOn();
|
|
1262
|
+
if (this.hasIncompleteWork) this.exit(EXIT_CODES.COMPLETED_WITH_FAILURES);
|
|
1263
|
+
}
|
|
1264
|
+
listIncompleteWork() {
|
|
1191
1265
|
if (!this.hasIncompleteWork) return;
|
|
1192
1266
|
this.log(`
|
|
1193
1267
|
${chalk.hex(CLI_COLORS.WARNING)(completedWithFailures(this.incompleteWork))}
|
|
1194
1268
|
`);
|
|
1195
|
-
|
|
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 });
|
|
1196
1274
|
}
|
|
1197
1275
|
};
|
|
1198
1276
|
|
|
@@ -1222,4 +1300,4 @@ export {
|
|
|
1222
1300
|
installsAtHome,
|
|
1223
1301
|
BaseCommand
|
|
1224
1302
|
};
|
|
1225
|
-
//# sourceMappingURL=chunk-
|
|
1303
|
+
//# sourceMappingURL=chunk-JTMSFBCA.js.map
|