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
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SelectList
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-I3WF6L43.js";
|
|
5
5
|
import {
|
|
6
6
|
openUrl
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TVEDNGVP.js";
|
|
8
8
|
import {
|
|
9
9
|
fetchSeedConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QCX66KBM.js";
|
|
11
11
|
import {
|
|
12
12
|
Confirm
|
|
13
13
|
} from "./chunk-OZXAJNLA.js";
|
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
summaryPanelBlock,
|
|
20
20
|
useTerminalDimensions
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-H5E6IO2L.js";
|
|
22
22
|
import {
|
|
23
23
|
hostCompileNotices
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-6PGXTLA4.js";
|
|
25
25
|
import {
|
|
26
26
|
compileAgentsAllScopes,
|
|
27
27
|
compileProjectScope,
|
|
@@ -29,26 +29,26 @@ import {
|
|
|
29
29
|
movedGlobalAgentInputs,
|
|
30
30
|
sayCapturedWarnings,
|
|
31
31
|
writeProjectConfig
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-R7GKQBZJ.js";
|
|
33
33
|
import {
|
|
34
34
|
copyLocalSkills,
|
|
35
35
|
discoverInstalledSkills
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-REHVGFJE.js";
|
|
37
37
|
import {
|
|
38
38
|
loadAgentDefs
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-7BHDKEGK.js";
|
|
40
40
|
import {
|
|
41
41
|
render
|
|
42
42
|
} from "./chunk-KIK5EZYD.js";
|
|
43
43
|
import {
|
|
44
44
|
agentChangesAmong
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-FQF6VHO3.js";
|
|
46
46
|
import {
|
|
47
47
|
installationToName,
|
|
48
48
|
providerFlag,
|
|
49
49
|
providerNamedBy,
|
|
50
50
|
providerNeedsAConfigurationToInstall
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-ORO2T4K2.js";
|
|
52
52
|
import {
|
|
53
53
|
BaseCommand,
|
|
54
54
|
EXIT_CODES,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
readInstalledGlobal,
|
|
61
61
|
registerExternalSkills,
|
|
62
62
|
writeExternalSkills
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-IAQFZFWD.js";
|
|
64
64
|
import {
|
|
65
65
|
ERROR_MESSAGES,
|
|
66
66
|
INCOMPLETE_WORK_RECOVERY,
|
|
@@ -101,12 +101,13 @@ import {
|
|
|
101
101
|
seedToInstallSelection,
|
|
102
102
|
settingsFileSchema,
|
|
103
103
|
sharedConfigExistingInstall,
|
|
104
|
+
stoppingOnARefusal,
|
|
104
105
|
subAgentChanged,
|
|
105
106
|
warn
|
|
106
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-E45IT3HC.js";
|
|
107
108
|
import {
|
|
108
109
|
plural
|
|
109
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-AIBVAYHS.js";
|
|
110
111
|
import {
|
|
111
112
|
ASCII_LOGO,
|
|
112
113
|
CLI_COLORS,
|
|
@@ -118,7 +119,7 @@ import {
|
|
|
118
119
|
MAX_CONFIG_FILE_SIZE,
|
|
119
120
|
editorConfigUrl,
|
|
120
121
|
isActiveAt
|
|
121
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-WUSEZFER.js";
|
|
122
123
|
|
|
123
124
|
// src/cli/commands/init.tsx
|
|
124
125
|
import os from "os";
|
|
@@ -524,13 +525,15 @@ var Init = class _Init extends BaseCommand {
|
|
|
524
525
|
}
|
|
525
526
|
async loadSourceOrFail(flags, projectDir) {
|
|
526
527
|
try {
|
|
527
|
-
const loaded = await
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
528
|
+
const loaded = await stoppingOnARefusal(
|
|
529
|
+
() => loadSource({
|
|
530
|
+
// The one load that may choose a marketplace rather than read the stored one.
|
|
531
|
+
caller: "init",
|
|
532
|
+
...flags.marketplace !== void 0 && { sourceFlag: flags.marketplace },
|
|
533
|
+
projectDir,
|
|
534
|
+
captureStartupMessages: true
|
|
535
|
+
})
|
|
536
|
+
);
|
|
534
537
|
return { sourceResult: loaded.sourceResult, startupMessages: loaded.startupMessages };
|
|
535
538
|
} catch (error) {
|
|
536
539
|
this.error(getErrorMessage(error), {
|
|
@@ -747,7 +750,11 @@ function joinedGlobalAgents(held, installedGlobal) {
|
|
|
747
750
|
return agentChangesAmong(
|
|
748
751
|
held.joined.map(({ agentName }) => agentName),
|
|
749
752
|
installedGlobal,
|
|
750
|
-
{
|
|
753
|
+
{
|
|
754
|
+
agents: held.result.agentConfigs,
|
|
755
|
+
skills: held.result.skills,
|
|
756
|
+
stack: held.result.assignedStack
|
|
757
|
+
}
|
|
751
758
|
);
|
|
752
759
|
}
|
|
753
760
|
function planInstall(result, installedAlready) {
|
|
@@ -861,4 +868,4 @@ export {
|
|
|
861
868
|
runDashboardFlow,
|
|
862
869
|
Init
|
|
863
870
|
};
|
|
864
|
-
//# sourceMappingURL=chunk-
|
|
871
|
+
//# sourceMappingURL=chunk-APWMMZOK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/init.tsx","../src/cli/lib/permission-checker.tsx"],"sourcesContent":["import os from \"os\";\nimport React from \"react\";\n\nimport { Flags, type Interfaces } from \"@oclif/core\";\nimport { Box, Text, useApp } from \"ink\";\nimport { partition } from \"remeda\";\nimport { render } from \"../components/render.js\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport type { InstallSelection } from \"@workspace/compile/seed-to-config\";\nimport { useTerminalDimensions } from \"../components/hooks/use-terminal-dimensions.js\";\nimport { stoppingOnARefusal, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport {\n loadSource,\n sayCapturedWarnings,\n loadAgentDefs,\n copyLocalSkills,\n writeProjectConfig,\n compileAgentsAllScopes,\n compileProjectScope,\n type CompilationResult,\n type ConfigWriteResult,\n type SkillCopyResult,\n discoverInstalledSkills,\n} from \"../lib/operations/index.js\";\nimport { movedGlobalAgentInputs, type GateReport } from \"../lib/config-gate/index.js\";\nimport { fetchSeedConfig } from \"../lib/seed/fetch-seed.js\";\nimport {\n registerExternalSkills,\n writeExternalSkills,\n type ExternalSkillInstall,\n} from \"../lib/seed/external-skills.js\";\nimport { seedToInstallSelection, type SeedMapping } from \"../lib/seed/seed-to-selection.js\";\nimport {\n holdInstalledGlobal,\n installsAtHome,\n joinedStatement,\n notInstalledGlobally,\n readInstalledGlobal,\n type HeldGlobal,\n type InstalledGlobal,\n} from \"../lib/seed/seed-apply.js\";\nimport { agentChangesAmong, type AgentChange } from \"../lib/configuration/scope-diff.js\";\nimport { isActiveAt } from \"../lib/configuration/scope-predicates.js\";\nimport { summaryPanelBlock, type SummaryPanelProps } from \"../components/common/summary-panel.js\";\nimport {\n getInstallationsByProvider,\n type ProviderInstallation,\n} from \"../lib/plugins/plugin-info.js\";\nimport {\n assertNamedSourceUsable,\n isLocalSource,\n resolveBranding,\n} from \"../lib/configuration/config.js\";\nimport {\n type InstallMode,\n detectInstallation,\n detectProjectInstallation,\n deriveInstallMode,\n holdsItsOwnInstallation,\n installBaseDir,\n resolveInstallPaths,\n buildAgentScopeMap,\n isHomeDirectory,\n INSTALL_MODE_LABELS,\n INSTALL_MODE_DESCRIPTIONS,\n} from \"../lib/installation/index.js\";\nimport { hostAt } from \"../lib/hosts/host-for.js\";\nimport {\n agentCodec,\n chooseProviderForThisRun,\n providerInUse,\n relativeConfigPath,\n} from \"../lib/installation/install-layout.js\";\nimport { providerToNameAt } from \"../lib/installation/provider-to-name.js\";\nimport { hostCompileNotices } from \"../lib/hosts/host-compile-notices.js\";\nimport {\n installationToName,\n providerFlag,\n providerNamedBy,\n providerNeedsAConfigurationToInstall,\n} from \"../lib/installation/provider-flag.js\";\nimport { checkPermissions } from \"../lib/permission-checker.js\";\nimport {\n ASCII_LOGO,\n CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n EDITOR_ADDRESS,\n EDITOR_URL,\n EJECT_SOURCE,\n editorConfigUrl,\n type Provider,\n} from \"../consts.js\";\nimport { clearTerminalScreen } from \"../utils/terminal.js\";\nimport { SelectList, type SelectListItem } from \"../components/common/select-list.js\";\nimport { promptConfirm, promptValue } from \"../components/common/prompt-confirm.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { openUrl } from \"../utils/open-url.js\";\nimport { plural } from \"../utils/string.js\";\nimport type {\n AgentName,\n AgentScopeConfig,\n MergedSkillsMatrix,\n SkillConfig,\n SkillId,\n SkillScope,\n} from \"../types/index.js\";\nimport { type StartupMessage } from \"../utils/logger.js\";\nimport {\n ERROR_MESSAGES,\n INCOMPLETE_WORK_RECOVERY,\n SHARED_CONFIG_ARRIVALS,\n STATUS_MESSAGES,\n addMarketplaceInTheEditor,\n agentsNotCompiled,\n applySharedConfigHere,\n carriedSkillsWritten,\n globalScopedAgentsHint,\n initSucceeded,\n keptAsInstalledGlobally,\n sharedConfigExistingInstall,\n subAgentChanged,\n} from \"../utils/messages.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\nconst DASHBOARD_OPTIONS = [\n { label: \"Edit in the web editor\", value: \"edit\" },\n { label: \"Compile\", value: \"compile\" },\n { label: \"Doctor\", value: \"doctor\" },\n { label: \"List\", value: \"list\" },\n] as const satisfies readonly SelectListItem<string>[];\n\nconst DASHBOARD_OPTIONS_LINE = ` ${DASHBOARD_OPTIONS.map(({ label }) => `[${label}]`).join(\" \")}`;\n\ntype DashboardCommand = (typeof DASHBOARD_OPTIONS)[number][\"value\"];\n\n/** A white-labelled name replaces the logo, because the logo spells the shipped name. */\nconst DashboardTitle: React.FC<{ name: string }> = ({ name }) =>\n name === DEFAULT_BRANDING.NAME ? <Text>{ASCII_LOGO}</Text> : <Text bold>{name}</Text>;\n\ntype DashboardProps = {\n data: DashboardData;\n onSelect: (command: DashboardCommand) => void;\n onCancel: () => void;\n};\n\nexport const Dashboard: React.FC<DashboardProps> = ({ data, onSelect, onCancel }) => {\n const { exit } = useApp();\n const { rows: terminalHeight } = useTerminalDimensions();\n\n return (\n <Box flexDirection=\"column\" height={terminalHeight}>\n <Box marginBottom={1}>\n <DashboardTitle name={data.name} />\n </Box>\n <Box marginBottom={1}>\n <Text>{dashboardCountLines(data).join(\"\\n\")}</Text>\n </Box>\n <SelectList\n items={DASHBOARD_OPTIONS}\n onSelect={(command) => {\n onSelect(command);\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n />\n </Box>\n );\n};\n\n/**\n * Shared by the TTY and piped dashboards so the two cannot drift apart. A scope holding two\n * installations gets a named block for each, a blank line apart.\n */\nfunction dashboardCountLines({ installations }: DashboardData): string[] {\n const named = installations.length > 1;\n const blocks = installations.map((installation) => [\n ...(named ? [` Provider: ${installation.provider}`] : []),\n ...installationCountLines(installation),\n ]);\n return blankLineBetween(blocks);\n}\n\nfunction blankLineBetween(blocks: string[][]): string[] {\n return blocks.flatMap((block, index) => (index === 0 ? block : [\"\", ...block]));\n}\n\nfunction installationCountLines(installation: ProviderInstallation): string[] {\n return [\n ` Skills: ${installation.skillCount} installed`,\n ` Agents: ${installation.agentCount} compiled`,\n ` Mode: ${INSTALL_MODE_LABELS[installation.mode]}`,\n ...(installation.marketplace ? [` Marketplace: ${installation.marketplace}`] : []),\n ];\n}\n\nexport function formatDashboardText(data: DashboardData): string {\n return [data.name, \"\", ...dashboardCountLines(data), \"\", DASHBOARD_OPTIONS_LINE].join(\"\\n\");\n}\n\n/** Ctrl+C cancels the run; Escape (null) only leaves the dashboard. */\nconst DASHBOARD_INTERRUPTED = \"interrupted\";\n\ntype DashboardAnswer = DashboardCommand | typeof DASHBOARD_INTERRUPTED | null;\n\nasync function showDashboard(\n projectDir: string,\n log?: (message: string) => void,\n): Promise<DashboardAnswer> {\n const data = await getDashboardData(projectDir);\n\n if (!process.stdin.isTTY) {\n const output = log ?? console.log;\n output(formatDashboardText(data));\n return null;\n }\n\n // clearOnResolve repaints a clean terminal before unmount: the dashboard fills the height.\n const selectedCommand = await promptValue<DashboardAnswer>(\n (resolve) => (\n <Dashboard\n data={data}\n onSelect={(command) => resolve(command)}\n onCancel={() => resolve(null)}\n />\n ),\n { onExit: DASHBOARD_INTERRUPTED, clearOnResolve: true },\n );\n\n clearTerminalScreen();\n\n return selectedCommand;\n}\n\nfunction dashboardCommandArgv(command: DashboardCommand): string[] {\n return command === \"edit\" ? [\"--ui\"] : [];\n}\n\nexport type DashboardFlow = \"not-installed\" | \"shown\" | \"cancelled\";\n\n/** Never exits the process: callers decide from the {@link DashboardFlow} it answers. */\nexport async function runDashboardFlow(\n projectDir: string,\n config: Interfaces.Config,\n log?: (message: string) => void,\n): Promise<DashboardFlow> {\n const installation = await detectInstallation(projectDir);\n if (!installation) return \"not-installed\";\n\n const selectedCommand = await showDashboard(projectDir, log);\n if (selectedCommand === DASHBOARD_INTERRUPTED) return \"cancelled\";\n if (selectedCommand) {\n await config.runCommand(selectedCommand, dashboardCommandArgv(selectedCommand));\n }\n return \"shown\";\n}\n\n/** A required key, not `?`: oclif writes the key as `undefined` when the flag is not passed. */\ntype SourceFlags = { marketplace: string | undefined };\n\ntype Selection = {\n result: InstallSelection;\n sourceResult: SourceLoadResult;\n /** Where the selection was actually loaded from; a shared id may name a marketplace. */\n sourceFlags: SourceFlags;\n /** A global install's own skills, recorded as they are and never installed over. */\n installedAlready: ReadonlySet<SkillId>;\n};\n\n/** The payload names the marketplace because a skill id never says where its repository lives. */\nfunction sharedConfigSourceFlags(flags: SourceFlags, payload: SeedPayload): SourceFlags {\n return { marketplace: flags.marketplace ?? payload.marketplace };\n}\n\nexport default class Init extends BaseCommand {\n /** Resolved once in {@link install}; the closing line is printed several calls below. */\n private brandingName: string = DEFAULT_BRANDING.NAME;\n\n static summary = `Initialize ${DEFAULT_BRANDING.NAME} in this project`;\n static description = `Build a configuration in ${EDITOR_ADDRESS}, or install one by id with --from. Over an existing installation, shows its dashboard.`;\n\n static examples = [\n {\n description: \"Open the editor to build a configuration\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Install a configuration built in the editor\",\n command: \"<%= config.bin %> <%= command.id %> --from <id>\",\n },\n {\n description: \"Test local marketplace changes against a configuration built in the editor\",\n command: \"<%= config.bin %> <%= command.id %> --from <id> --marketplace ./my-marketplace\",\n },\n ];\n\n static flags = {\n marketplace: Flags.string({\n char: \"m\",\n description:\n \"With --from, install from this marketplace instead of the one the configuration names. Without --from, open the editor and say how to add it there\",\n required: false,\n }),\n from: Flags.string({\n description: \"Install a configuration shared from agentsinc.sh by its id\",\n helpValue: \"<id>\",\n }),\n ui: Flags.boolean({\n description: `Open ${EDITOR_ADDRESS} on the id --from names, or on the catalogue — what a bare init does where nothing is installed`,\n default: false,\n }),\n provider: providerFlag(),\n };\n\n /** The exit code is decided once, after every path through {@link install} has ended. */\n async run(): Promise<void> {\n await this.install();\n this.exitIfWorkIncomplete();\n }\n\n /** The link is printed before it is opened, so it still works where no browser can open. */\n private async openEditor(\n projectDir: string,\n provider: Provider | undefined,\n id?: string,\n marketplace?: string,\n ): Promise<void> {\n const url = id === undefined ? EDITOR_URL : editorConfigUrl(id);\n // Above the first line, so a ref the install route would refuse is refused before any output.\n const marketplaceLine =\n marketplace === undefined ? undefined : this.addMarketplaceLineOrFail(marketplace);\n\n const installedHere = await holdsItsOwnInstallation(projectDir);\n const toName = installedHere ? await installationToName(projectDir, provider) : provider;\n\n this.log(id === undefined ? `Build it at ${url}` : `Open it at ${url}`);\n if (marketplaceLine !== undefined) this.log(marketplaceLine);\n this.log(applySharedConfigHere(id, installedHere, toName));\n\n if (!process.stdin.isTTY) return;\n\n const opened = await openUrl(url);\n if (!opened.ok) this.warn(opened.error);\n }\n\n private async install(): Promise<void> {\n const { flags } = await this.parse(Init);\n const projectDir = process.cwd();\n\n // First, so a refused `--provider` leaves the filesystem untouched at both scopes.\n this.settleTheProviderForThisRun(flags);\n\n // Before `ensureConfigReadable`: a broken config must not block the editor route.\n if (opensTheEditor(flags)) {\n return this.openEditor(\n projectDir,\n providerNamedBy(flags.provider),\n flags.from,\n flags.marketplace,\n );\n }\n\n // ABORT: an unreadable config is refused here, before any route reads it.\n await this.ensureConfigReadable(projectDir);\n\n if (flags.from === undefined) return this.showDashboardOrOpenEditor(projectDir);\n\n // Its degrade arm cannot fire: `ensureConfigReadable` already refused every unreadable config.\n this.brandingName = await this.resolveBrandingName(projectDir);\n\n const selection = await this.selectionFromSharedConfig(flags.from, flags, projectDir);\n if (!selection) this.exit(EXIT_CODES.CANCELLED);\n\n this.reportValidationErrors(selection.result.validation);\n\n await this.handleInstallation(selection, projectDir);\n }\n\n private async showDashboardOrOpenEditor(projectDir: string): Promise<void> {\n const dashboard = await runDashboardFlow(projectDir, this.config, (msg) => this.log(msg));\n switch (dashboard) {\n case \"cancelled\":\n return this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n case \"not-installed\":\n return this.openEditor(projectDir, undefined);\n case \"shown\":\n return;\n default: {\n const _exhaustive: never = dashboard;\n return _exhaustive;\n }\n }\n }\n\n /** Refused as the install route refuses it, since the line echoes the ref it was given. */\n private addMarketplaceLineOrFail(ref: string): string {\n try {\n assertNamedSourceUsable(ref);\n return addMarketplaceInTheEditor(ref, isLocalSource(ref));\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /** `--provider` only picks which folder an install creates, so it needs `--from`. */\n private settleTheProviderForThisRun(flags: Interfaces.InferredFlags<typeof Init.flags>): void {\n const named = providerNamedBy(flags.provider);\n if (named === undefined) return;\n\n if (flags.from === undefined) {\n this.error(providerNeedsAConfigurationToInstall(), { exit: EXIT_CODES.INVALID_ARGS });\n }\n\n chooseProviderForThisRun(named);\n }\n\n /** Every refusal fires before anything is written. */\n private async selectionFromSharedConfig(\n id: string,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<Selection | null> {\n await this.refuseInstalledProject(projectDir, id);\n\n const payload = await this.fetchSharedConfigOrFail(id);\n const sourceFlags = sharedConfigSourceFlags(flags, payload);\n const { sourceResult, startupMessages } = await this.loadSourceOrFail(sourceFlags, projectDir);\n // Before the decode, which would otherwise skip carried skills as unknown ids.\n const carriedSkills = this.registerExternalSkillsOrFail(\n payload,\n sourceResult.matrix,\n projectDir,\n );\n const mapping = this.decodeSeedOrFail(payload, sourceResult.matrix);\n const { result } = mapping;\n\n // Nothing is installed here: `refuseInstalledProject` has already refused a home that holds one.\n this.refuseProjectScopedContentAtHome(result, projectDir, false);\n\n const installedGlobal = await installedGlobalToHold(projectDir);\n const held = holdInstalledGlobal(result, installedGlobal);\n const arrivingCarried = notInstalledGlobally(carriedSkills, held);\n\n // Above the lists: a yes installs what was listed, so nothing listed may then be refused.\n await this.refuseSharedConfigBeforeAsking(\n held.result,\n arrivingCarried,\n projectDir,\n sourceResult,\n );\n\n // Above the skips: an \"unknown\" skill is often one whose file failed to parse.\n sayCapturedWarnings(startupMessages);\n this.warnOfSkippedEntries(mapping);\n this.refuseAnEmptySelection(held.result, id);\n\n const stackName = await this.stackNameOf(result.selectedStackId, sourceResult);\n this.logWhatGoesWhere(held, installedGlobal, stackName, {\n id: installsAtHome(result) ? id : undefined,\n provider: providerToNameAt(os.homedir(), providerInUse(projectDir)),\n });\n if (process.stdin.isTTY && !(await this.confirmInstall())) {\n this.log(\"Setup cancelled\");\n return null;\n }\n\n // After the question, so a refusal or a no leaves nothing written.\n await this.writeCarriedSkills(arrivingCarried);\n this.announceArrivingSkills(held, result.selectedAgents.length);\n\n return {\n result: held.result,\n sourceResult,\n sourceFlags,\n installedAlready: new Set(held.installed.skillIds),\n };\n }\n\n /**\n * The panel where the question is asked, or where it would be: the project against the whole\n * global install it inherits. `runFromHome.id` is the id only where home would take it.\n */\n private logWhatGoesWhere(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n stackName: string | undefined,\n runFromHome: RunFromHome,\n ): void {\n const joined = joinedGlobalAgents(held, installedGlobal);\n const lines = summaryPanelBlock(\n installPanel(held, installedGlobal, joined, stackName),\n joined.map(subAgentChanged),\n [...joinedStatement(held), ...keptAsInstalledStatement(held, runFromHome)],\n );\n for (const line of lines) {\n this.log(line);\n }\n }\n\n private refuseAnEmptySelection(result: InstallSelection, id: string): void {\n if (!selectsNothing(result)) return;\n\n this.error(`Configuration '${id}' contains no skills this catalog can install.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n private announceArrivingSkills(held: HeldGlobal, agentCount: number): void {\n const arriving = notInstalledGlobally(held.result.skills, held);\n if (arriving.length === 0) return;\n\n this.log(`Installing ${arriving.length} skill(s) across ${agentCount} sub-agent(s)\\n`);\n }\n\n private async confirmInstall(): Promise<boolean> {\n const outcome = await promptConfirm(({ onConfirm, onCancel }) => (\n <Confirm\n message={SHARED_CONFIG_ARRIVALS.INSTALL_CONFIRM}\n onConfirm={onConfirm}\n onCancel={onCancel}\n />\n ));\n return outcome === \"confirmed\";\n }\n\n /** Project-scoped: `detectInstallation`'s global fallback would refuse every clean project. */\n private async refuseInstalledProject(projectDir: string, id: string): Promise<void> {\n const installation = await detectProjectInstallation(projectDir);\n if (!installation) return;\n\n const provider = providerToNameAt(projectDir, providerInUse(projectDir));\n this.error(sharedConfigExistingInstall(installation.configPath, id, provider), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n private async fetchSharedConfigOrFail(id: string): Promise<SeedPayload> {\n this.log(`Fetching configuration ${id}...`);\n const fetched = await fetchSeedConfig(id);\n if (!fetched.ok) {\n this.error(fetched.error, { exit: EXIT_CODES.ERROR });\n }\n return fetched.payload;\n }\n\n private decodeSeedOrFail(payload: SeedPayload, matrix: MergedSkillsMatrix): SeedMapping {\n try {\n return seedToInstallSelection(payload, matrix);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private registerExternalSkillsOrFail(\n payload: SeedPayload,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n ): ExternalSkillInstall[] {\n try {\n return registerExternalSkills(payload, matrix, projectDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async writeCarriedSkills(carried: ExternalSkillInstall[]): Promise<void> {\n if (carried.length === 0) return;\n\n await writeExternalSkills(carried);\n this.log(carriedSkillsWritten(carried.map((skill) => skill.id)));\n }\n\n private async loadSourceOrFail(\n flags: SourceFlags,\n projectDir: string,\n ): Promise<{ sourceResult: SourceLoadResult; startupMessages: StartupMessage[] }> {\n try {\n const loaded = await stoppingOnARefusal(() =>\n loadSource({\n // The one load that may choose a marketplace rather than read the stored one.\n caller: \"init\",\n ...(flags.marketplace !== undefined && { sourceFlag: flags.marketplace }),\n projectDir,\n captureStartupMessages: true,\n }),\n );\n return { sourceResult: loaded.sourceResult, startupMessages: loaded.startupMessages };\n } catch (error) {\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n private async handleInstallation(\n { result, sourceResult, sourceFlags, installedAlready }: Selection,\n projectDir: string,\n ): Promise<void> {\n const plan = planInstall(result, installedAlready);\n this.logInstallPlan(plan);\n\n // Before any copy, so a failed resolution cannot leave a half-install with no config.ts.\n const resolvedMarketplace = await this.marketplaceForPluginSkills(\n plan.pluginSkills,\n sourceResult,\n projectDir,\n );\n\n const copyResult = await this.copyEjectedSkills(plan, projectDir, sourceResult);\n\n if (resolvedMarketplace !== null) {\n await this.installPluginSkillsReported(\n plan.pluginSkills,\n resolvedMarketplace,\n projectDir,\n sourceResult.matrix,\n );\n }\n\n try {\n const written = await this.writeConfigAndCompile(\n result,\n sourceResult,\n sourceFlags,\n projectDir,\n );\n this.reportSuccess(written, copyResult, projectDir);\n\n await this.showPermissionNotice(projectDir);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async marketplaceForPluginSkills(\n pluginSkills: InstallSelection[\"skills\"],\n sourceResult: SourceLoadResult,\n projectDir: string,\n ): Promise<string | null> {\n if (pluginSkills.length === 0) return null;\n\n return this.requireMarketplaceOrExit(\n sourceResult,\n \"install plugin skills\",\n hostAt(projectDir),\n (marketplace) => this.log(`Registering marketplace \"${marketplace}\"...`),\n );\n }\n\n /** One frame, then unmount: the notice has no exit of its own and `--from` must run headless. */\n private async showPermissionNotice(projectDir: string): Promise<void> {\n const permissionWarning = await checkPermissions(projectDir);\n if (!permissionWarning) return;\n\n const { unmount } = render(permissionWarning);\n unmount();\n }\n\n private logInstallPlan(plan: InstallPlan): void {\n this.log(\"\\n\");\n this.log(`Selected ${plural(plan.ejectedSkills.length + plan.pluginSkills.length, \"skill\")}`);\n this.log(`Install mode: ${installModeDescription(plan)}`);\n }\n\n private async copyEjectedSkills(\n { ejectedSkills, installMode }: InstallPlan,\n projectDir: string,\n sourceResult: SourceLoadResult,\n ): Promise<SkillCopyResult | null> {\n if (ejectedSkills.length === 0) return null;\n\n this.log(\"Copying skills to local directory...\");\n const copyResult = await copyLocalSkills(ejectedSkills, projectDir, sourceResult);\n this.log(skillsCopiedLine(copyResult, installMode, projectDir));\n return copyResult;\n }\n\n private async writeConfigAndCompile(\n result: InstallSelection,\n sourceResult: SourceLoadResult,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<WrittenInstall> {\n const configResult = await this.writeConfigReported(result, sourceResult, flags, projectDir);\n const agentScopeMap = buildAgentScopeMap(configResult.config);\n const compileResult = await this.compileInstalledAgents(\n configResult.propagation,\n agentScopeMap,\n projectDir,\n );\n this.reportCompilation(compileResult);\n await this.reportWhatThisHostCannotCarry(projectDir);\n\n this.reportFanOut(configResult.propagation);\n\n return { configResult, compileResult, agentScopeMap };\n }\n\n private async writeConfigReported(\n result: InstallSelection,\n sourceResult: SourceLoadResult,\n flags: SourceFlags,\n projectDir: string,\n ): Promise<ConfigWriteResult> {\n this.log(\"Generating configuration...\");\n const configResult = await writeProjectConfig({\n selection: result,\n sourceResult,\n projectDir,\n ...(flags.marketplace !== undefined && { sourceFlag: flags.marketplace }),\n });\n\n if (configResult.wasMerged) {\n this.log(`Merged with existing config at ${configResult.existingConfigPath}`);\n }\n\n this.log(`Configuration saved (${plural(configResult.config.agents.length, \"agent\")})\\n`);\n this.reportUnassignedSkills(configResult.config, result.skills);\n return configResult;\n }\n\n private async compileInstalledAgents(\n written: GateReport,\n agentScopeMap: Map<AgentName, SkillScope>,\n projectDir: string,\n ): Promise<CompilationResult> {\n this.log(STATUS_MESSAGES.COMPILING_AGENTS);\n // Sequential: both can reject and discovery warns, so the order decides what the user reads.\n const agentDefs = await loadAgentDefs();\n const { allSkills } = await discoverInstalledSkills(projectDir);\n const compile = compilesGlobalScope(projectDir, written)\n ? compileAgentsAllScopes\n : compileProjectScope;\n return compile({\n projectDir,\n sourcePath: agentDefs.sourcePath,\n skills: allSkills,\n agentScopeMap,\n });\n }\n\n private async reportWhatThisHostCannotCarry(projectDir: string): Promise<void> {\n for (const notice of await hostCompileNotices(providerInUse(projectDir), projectDir)) {\n this.log(notice);\n }\n }\n\n /**\n * Failures are recorded rather than aborted on: the skills and config are already written, and\n * {@link BaseCommand.exitIfWorkIncomplete} answers for them.\n */\n private reportCompilation(compileResult: CompilationResult): void {\n const { compiled, failed, warnings } = compileResult;\n const summary = `Compiled ${plural(compiled.length, \"agent\")}`;\n\n if (failed.length === 0) {\n this.log(`${summary}\\n`);\n return;\n }\n\n this.log(`${summary} (${failed.length} failed)\\n`);\n for (const warning of warnings) {\n this.warn(warning);\n }\n // Off `failed`, not `warnings`: warnings also carry entries that are not failures.\n this.recordIncompleteWork(agentsNotCompiled(failed), INCOMPLETE_WORK_RECOVERY.RECOMPILE);\n }\n\n private reportSuccess(\n { configResult, compileResult, agentScopeMap }: WrittenInstall,\n copyResult: SkillCopyResult | null,\n projectDir: string,\n ): void {\n // A run with work owed ends on the failure account instead of claiming success.\n if (!this.hasIncompleteWork) this.log(`${initSucceeded(this.brandingName)}\\n`);\n\n if (copyResult !== null && copyResult.totalCopied > 0) {\n this.logDirectoryBlocks(\"Skills copied to:\", skillsCopiedBlocks(projectDir, copyResult));\n }\n this.logDirectoryBlocks(\n \"Agents compiled to:\",\n agentsCompiledBlocks(projectDir, compileResult.compiled, agentScopeMap),\n );\n this.reportConfiguration(configResult, agentScopeMap, projectDir);\n }\n\n private reportConfiguration(\n { configPath, propagation }: ConfigWriteResult,\n agentScopeMap: Map<AgentName, SkillScope>,\n projectDir: string,\n ): void {\n const paths = {\n global: resolveInstallPaths(projectDir, \"global\").configPath,\n project: configPath,\n };\n const split = splitAgentScopes(projectDir, agentScopeMap);\n\n this.log(\"Configuration:\");\n for (const written of configsWritten(projectDir, paths, propagation.globalWritten)) {\n this.log(` ${written}`);\n }\n this.log(\"\");\n\n this.log(\"To customize agent-skill assignments:\");\n for (const [index, step] of customizationSteps(split, paths.global, projectDir).entries()) {\n this.log(` ${index + 1}. ${step}`);\n }\n this.log(\"\");\n }\n\n private logDirectoryBlocks(heading: string, blocks: DirectoryBlock[]): void {\n for (const { dir, entries } of blocks) {\n this.log(heading);\n this.log(` ${dir}`);\n for (const entry of entries) {\n this.log(` ${entry}`);\n }\n this.log(\"\");\n }\n }\n}\n\n/** The editor is where a marketplace is added, so `--marketplace` without `--from` opens it. */\nfunction opensTheEditor(\n flags: Pick<Interfaces.InferredFlags<typeof Init.flags>, \"ui\" | \"from\" | \"marketplace\">,\n): boolean {\n return flags.ui || (flags.from === undefined && flags.marketplace !== undefined);\n}\n\n/** A sub-agent is installable without skills, so only a selection with neither is empty. */\nfunction selectsNothing(result: InstallSelection): boolean {\n return result.skills.length === 0 && result.selectedAgents.length === 0;\n}\n\n/** At the home root the global config is the project's own, so there is no global install apart. */\nasync function installedGlobalToHold(projectDir: string): Promise<InstalledGlobal | null> {\n if (isHomeDirectory(projectDir)) return null;\n return await readInstalledGlobal(projectDir);\n}\n\n/** The run from home that changes what a project run keeps, where home would take it. */\ntype RunFromHome = { id: string | undefined; provider: Provider | undefined };\n\nfunction keptAsInstalledStatement(held: HeldGlobal, runFromHome: RunFromHome): string[] {\n const { skillIds, agentNames } = held.keptAsInstalled;\n if (skillIds.length === 0 && agentNames.length === 0) return [];\n return [keptAsInstalledGlobally(skillIds, agentNames, runFromHome.id, runFromHome.provider)];\n}\n\ntype GlobalEntries = { skills: SkillConfig[]; agents: AgentScopeConfig[] };\n\n/** What the project inherits that the configuration leaves unnamed: a project config copies it all. */\nfunction inheritedGlobal(held: HeldGlobal, installedGlobal: InstalledGlobal | null): GlobalEntries {\n if (installedGlobal === null) return { skills: [], agents: [] };\n\n const namedSkills = new Set(held.result.skills.filter(isGlobal).map(({ id }) => id));\n const namedAgents = new Set(held.result.agentConfigs.filter(isGlobal).map(({ name }) => name));\n return {\n skills: installedGlobal.skills.filter((skill) => isGlobal(skill) && !namedSkills.has(skill.id)),\n agents: installedGlobal.agents.filter(\n (agent) => isGlobal(agent) && !namedAgents.has(agent.name),\n ),\n };\n}\n\nfunction isGlobal(entry: SkillConfig | AgentScopeConfig): boolean {\n return isActiveAt(entry, \"global\");\n}\n\n/** Measured against the global install: the project changes nothing else of it. */\nfunction installPanel(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n joined: AgentChange[],\n stackName: string | undefined,\n): SummaryPanelProps {\n const inherited = inheritedGlobal(held, installedGlobal);\n return {\n skillConfigs: [...held.result.skills, ...inherited.skills],\n agentConfigs: [...held.result.agentConfigs, ...inherited.agents],\n installedSkillConfigs: installedGlobal?.skills ?? null,\n installedAgentConfigs: installedGlobal?.agents ?? null,\n isInitMode: true,\n changedAgentNames: new Set(joined.map(({ name }) => name)),\n stackName,\n };\n}\n\n/** The held global sub-agents an arriving skill's row joins, against their installed rows. */\nfunction joinedGlobalAgents(\n held: HeldGlobal,\n installedGlobal: InstalledGlobal | null,\n): AgentChange[] {\n if (installedGlobal === null) return [];\n\n return agentChangesAmong(\n held.joined.map(({ agentName }) => agentName),\n installedGlobal,\n {\n agents: held.result.agentConfigs,\n skills: held.result.skills,\n stack: held.result.assignedStack,\n },\n );\n}\n\ntype InstallPlan = {\n installMode: InstallMode;\n ejectedSkills: InstallSelection[\"skills\"];\n pluginSkills: InstallSelection[\"skills\"];\n};\n\nfunction planInstall(\n result: InstallSelection,\n installedAlready: ReadonlySet<SkillId>,\n): InstallPlan {\n const toInstall = result.skills.filter(\n (skill) => !skill.excluded && !installedAlready.has(skill.id),\n );\n const [ejectedSkills, pluginSkills] = partition(\n toInstall,\n (skill) => skill.origin === EJECT_SOURCE,\n );\n return { installMode: deriveInstallMode(toInstall), ejectedSkills, pluginSkills };\n}\n\nfunction installModeDescription({ installMode, ejectedSkills, pluginSkills }: InstallPlan): string {\n if (installMode !== \"mixed\") return INSTALL_MODE_DESCRIPTIONS[installMode];\n return `${INSTALL_MODE_LABELS.mixed} (${ejectedSkills.length} eject, ${pluginSkills.length} plugin)`;\n}\n\ntype WrittenInstall = {\n configResult: ConfigWriteResult;\n compileResult: CompilationResult;\n agentScopeMap: Map<AgentName, SkillScope>;\n};\n\n/**\n * From a project, global sub-agents recompile only when the write changed their inputs;\n * otherwise they would be rebuilt from this run's catalogue, not the one they were made from.\n */\nfunction compilesGlobalScope(cwd: string, written: GateReport): boolean {\n return isHomeDirectory(cwd) || movedGlobalAgentInputs(written);\n}\n\n/** Names the directory only when every skill landed at one scope; the block beneath lists both. */\nfunction skillsCopiedLine(\n copyResult: SkillCopyResult,\n installMode: InstallMode,\n projectDir: string,\n): string {\n const isMixed = installMode === \"mixed\";\n const copied = plural(copyResult.totalCopied, isMixed ? \"local skill\" : \"skill\");\n const lineEnd = isMixed ? \"\" : \"\\n\";\n const projectCount = copyResult.projectCopied.length;\n const globalCount = copyResult.globalCopied.length;\n const landedAtBothScopes = projectCount > 0 && globalCount > 0;\n\n if (landedAtBothScopes) {\n return `Copied ${copied} (${projectCount} project, ${globalCount} global)${lineEnd}`;\n }\n const landedAt: SkillScope = globalCount > 0 ? \"global\" : \"project\";\n return `Copied ${copied} to ${resolveInstallPaths(projectDir, landedAt).skillsDir}/${lineEnd}`;\n}\n\n/** Entries are on-disk names, so ids, never display names. */\ntype DirectoryBlock = { dir: string; entries: string[] };\n\nfunction hasEntries(block: DirectoryBlock): boolean {\n return block.entries.length > 0;\n}\n\n/** At home a Claude install's two scopes are one folder, which is named once. */\nfunction oneBlockPerDir(blocks: DirectoryBlock[]): DirectoryBlock[] {\n const dirs = [...new Set(blocks.map((block) => block.dir))];\n return dirs.map((dir) => ({\n dir,\n entries: blocks.filter((block) => block.dir === dir).flatMap((block) => block.entries),\n }));\n}\n\nfunction skillsCopiedBlocks(projectDir: string, copyResult: SkillCopyResult): DirectoryBlock[] {\n return oneBlockPerDir(\n [\n copiedSkillsBlock(projectDir, \"global\", copyResult.globalCopied),\n copiedSkillsBlock(projectDir, \"project\", copyResult.projectCopied),\n ].filter(hasEntries),\n );\n}\n\nfunction copiedSkillsBlock(\n projectDir: string,\n scope: SkillScope,\n copied: SkillCopyResult[\"projectCopied\"],\n): DirectoryBlock {\n return {\n dir: resolveInstallPaths(projectDir, scope).skillsDir,\n entries: copied.map(({ skillId }) => `${skillId}/`),\n };\n}\n\n/** Mirrors `writeCompiledAgentsByScope`' routing. */\nfunction agentsCompiledBlocks(\n projectDir: string,\n compiled: AgentName[],\n agentScopeMap: Map<AgentName, SkillScope>,\n): DirectoryBlock[] {\n const [globalAgents, projectAgents] = partition(\n compiled,\n (name) => agentScopeMap.get(name) === \"global\",\n );\n return oneBlockPerDir(\n [\n compiledAgentsBlock(projectDir, \"global\", globalAgents),\n compiledAgentsBlock(projectDir, \"project\", projectAgents),\n ].filter(hasEntries),\n );\n}\n\n/** Per scope, because the project and global installs can be on different hosts. */\nfunction compiledAgentsBlock(\n projectDir: string,\n scope: SkillScope,\n agents: AgentName[],\n): DirectoryBlock {\n const { extension } = agentCodec(providerInUse(installBaseDir(projectDir, scope)));\n return {\n dir: resolveInstallPaths(projectDir, scope).agentsDir,\n entries: agents.map((name) => `${name}${extension}`),\n };\n}\n\ntype ConfigPaths = { global: string; project: string };\n\ntype AgentScopeSplit = { globalAgentCount: number; isGlobalOnly: boolean };\n\n/** At the home root both scopes are one config and one pass, so there is no split. */\nfunction splitAgentScopes(cwd: string, agentScopeMap: Map<AgentName, SkillScope>): AgentScopeSplit {\n if (isHomeDirectory(cwd)) return { globalAgentCount: 0, isGlobalOnly: false };\n\n const scopes = [...agentScopeMap.values()];\n const globalAgentCount = scopes.filter((scope) => scope === \"global\").length;\n return {\n globalAgentCount,\n isGlobalOnly: globalAgentCount > 0 && globalAgentCount === scopes.length,\n };\n}\n\n/**\n * From a project its own config is always written, and the global one whenever the run changed it,\n * if only to register the project. At home the two are one file.\n */\nfunction configsWritten(projectDir: string, paths: ConfigPaths, globalWritten: boolean): string[] {\n if (isHomeDirectory(projectDir)) return [paths.project];\n return globalWritten ? [paths.global, paths.project] : [paths.project];\n}\n\n/** `compile` in a project recompiles no global agent, hence the global hint. */\nfunction customizationSteps(\n split: AgentScopeSplit,\n globalConfigPath: string,\n projectDir: string,\n): string[] {\n if (split.isGlobalOnly) {\n return [`Edit ${globalConfigPath}`, globalScopedAgentsHint(split.globalAgentCount)];\n }\n\n return [\n `Edit ${relativeConfigPath(projectDir, providerInUse(projectDir))}`,\n `Run '${CLI_INVOKE_COMMAND} compile' to regenerate agents`,\n ...(split.globalAgentCount > 0 ? [globalScopedAgentsHint(split.globalAgentCount)] : []),\n ];\n}\n\nexport type DashboardData = {\n name: string;\n installations: ProviderInstallation[];\n};\n\n/** Each installation's counts come from its own scope-aware read, so project and global never mix. */\nasync function getDashboardData(projectDir: string): Promise<DashboardData> {\n // ABORT: an unloadable config throws here, as the installation check before it already would.\n const [installations, branding] = await Promise.all([\n getInstallationsByProvider(projectDir),\n resolveBranding(projectDir),\n ]);\n // Every caller found an installation before drawing the dashboard.\n if (installations.length === 0) throw new Error(ERROR_MESSAGES.NO_INSTALLATION);\n\n return { name: branding.name, installations };\n}\n","import React from \"react\";\nimport { z } from \"zod\";\n\nimport { Text, Box } from \"ink\";\nimport path from \"path\";\n\nimport { CLI_COLORS, MAX_CONFIG_FILE_SIZE } from \"../consts\";\nimport {\n advisesOnPermissions,\n permissionFiles,\n providerInUse,\n} from \"./installation/install-layout.js\";\nimport { fileExists, readFileSafe } from \"../utils/fs\";\nimport { warn } from \"../utils/logger\";\nimport { settingsFileSchema } from \"./schemas\";\n\ntype SettingsFile = z.infer<typeof settingsFileSchema>;\ntype PermissionConfig = NonNullable<SettingsFile[\"permissions\"]>;\n\n/** Undefined when absent, malformed or empty; silent about every other field (Claude Code's). */\nasync function readSettingsPermissions(filePath: string): Promise<PermissionConfig | undefined> {\n if (!(await fileExists(filePath))) return undefined;\n try {\n const content = await readFileSafe(filePath, MAX_CONFIG_FILE_SIZE);\n const raw: unknown = JSON.parse(content);\n const result = settingsFileSchema.safeParse(raw);\n const parsed: SettingsFile = result.success ? result.data : {};\n return parsed.permissions;\n } catch {\n warn(`Malformed settings file at '${filePath}' — skipping`);\n return undefined;\n }\n}\n\nfunction settingsFilesFor(projectRoot: string): string[] {\n return permissionFiles(providerInUse(projectRoot), \"project\", projectRoot);\n}\n\n/** Permissions from the highest-precedence settings file that defines them — the overlay wins. */\nasync function loadPermissions(files: readonly string[]): Promise<PermissionConfig | undefined> {\n for (const filePath of [...files].reverse()) {\n const permissions = await readSettingsPermissions(filePath);\n if (permissions) return permissions;\n }\n return undefined;\n}\n\n/** Relative to the project and POSIX-separated: a name shown to a person, not a path to open. */\nfunction asUserWritesIt(projectRoot: string, file: string): string {\n return path.relative(projectRoot, file).split(path.sep).join(\"/\");\n}\n\n/** `null` for a host whose permission model this release cannot advise on. */\nexport async function checkPermissions(projectRoot: string): Promise<React.ReactElement | null> {\n if (!advisesOnPermissions(providerInUse(projectRoot))) return null;\n\n const files = settingsFilesFor(projectRoot);\n // The base file: the one this CLI writes and a user with neither is asked to create.\n const [base] = files;\n if (base === undefined) return null;\n\n const permissions = await loadPermissions(files);\n const settingsFile = asUserWritesIt(projectRoot, base);\n\n if (!permissions) {\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={CLI_COLORS.WARNING} padding={1}>\n <Text bold color={CLI_COLORS.WARNING}>\n Permission Notice\n </Text>\n <Text>No permissions configured in {settingsFile}</Text>\n <Text>Agents will prompt for approval on each tool use.</Text>\n <Text> </Text>\n <Text>For autonomous operation, add to {settingsFile}:</Text>\n <Text> </Text>\n <Text color={CLI_COLORS.DIM}>{\"{\"}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"permissions\": {'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"allow\": ['}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Read(*)\",'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Bash(git *)\",'}</Text>\n <Text color={CLI_COLORS.DIM}>{' \"Bash(bun *)\"'}</Text>\n <Text color={CLI_COLORS.DIM}>{\" ]\"}</Text>\n <Text color={CLI_COLORS.DIM}>{\" }\"}</Text>\n <Text color={CLI_COLORS.DIM}>{\"}\"}</Text>\n </Box>\n );\n }\n\n const hasRestrictiveBash = permissions.deny?.some(\n (rule) => rule === \"Bash(*)\" || rule === \"Bash\",\n );\n const hasNoAllows = !permissions.allow || permissions.allow.length === 0;\n\n if (hasRestrictiveBash || hasNoAllows) {\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={CLI_COLORS.WARNING} padding={1}>\n <Text bold color={CLI_COLORS.WARNING}>\n Permission Warnings\n </Text>\n {hasRestrictiveBash && (\n <Text>\n ⚠ Bash is denied in permissions. Some agents require Bash for git, testing, and build\n commands.\n </Text>\n )}\n {hasNoAllows && (\n <Text>⚠ No allow rules configured. Agents will prompt for each tool use.</Text>\n )}\n </Box>\n );\n }\n\n return null;\n}\n"],"mappings":"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","names":["Box","Text","jsx","jsxs","Text","Box"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BUILT_IN_MATRIX,
|
|
4
4
|
getSkillById,
|
|
5
|
-
|
|
5
|
+
getSkillEntryDisplayName,
|
|
6
6
|
inertLine,
|
|
7
7
|
initializeMatrix,
|
|
8
8
|
matrix,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
typedFromEntries,
|
|
14
14
|
typedKeys,
|
|
15
15
|
typedValues
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AIBVAYHS.js";
|
|
17
17
|
import {
|
|
18
18
|
AGENT_NAMES,
|
|
19
19
|
AUTHOR_HANDLE_PATTERN,
|
|
@@ -82,7 +82,7 @@ import {
|
|
|
82
82
|
seedAgentScope,
|
|
83
83
|
sourceDirName,
|
|
84
84
|
validateSelection
|
|
85
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-WUSEZFER.js";
|
|
86
86
|
import {
|
|
87
87
|
defaultCategories,
|
|
88
88
|
defaultRules,
|
|
@@ -490,8 +490,9 @@ function sourceRootOf(root) {
|
|
|
490
490
|
return { dir: path.join(root, SOURCE_ROOT_DIR), relName: SOURCE_ROOT_DIR };
|
|
491
491
|
}
|
|
492
492
|
var RETIRED_SOURCE_FOLDER = ".claude-src";
|
|
493
|
-
function
|
|
494
|
-
|
|
493
|
+
function rootsHoldingTheRetiredSourceFolder(cwd) {
|
|
494
|
+
const roots = isHomeDirectory(cwd) ? [os2.homedir()] : [os2.homedir(), cwd];
|
|
495
|
+
return roots.filter(holdsTheRetiredSourceFolder);
|
|
495
496
|
}
|
|
496
497
|
function holdsTheRetiredSourceFolder(root) {
|
|
497
498
|
return directoryExists(path.join(root, RETIRED_SOURCE_FOLDER));
|
|
@@ -504,6 +505,9 @@ var providerChosenForThisRun;
|
|
|
504
505
|
function chooseProviderForThisRun(provider) {
|
|
505
506
|
providerChosenForThisRun = provider;
|
|
506
507
|
}
|
|
508
|
+
function forgetTheProviderChosenForThisRun() {
|
|
509
|
+
providerChosenForThisRun = void 0;
|
|
510
|
+
}
|
|
507
511
|
function providerInUse(root) {
|
|
508
512
|
if (providerChosenForThisRun !== void 0) return providerChosenForThisRun;
|
|
509
513
|
if (root === void 0) return PROVIDER_OF_A_NEW_INSTALLATION;
|
|
@@ -1012,6 +1016,9 @@ function marketplaceRefreshFailed(marketplace, reason) {
|
|
|
1012
1016
|
function sourceUnreachableUsingCache(source) {
|
|
1013
1017
|
return `Could not reach ${source} \u2014 using the cached copy, which may be out of date.`;
|
|
1014
1018
|
}
|
|
1019
|
+
function sourceRefusedUsingCache(source, status) {
|
|
1020
|
+
return `${source} refused the request (${status}) \u2014 using the cached copy, which may be out of date.`;
|
|
1021
|
+
}
|
|
1015
1022
|
function marketplacesRefreshFailed(marketplaces) {
|
|
1016
1023
|
return `${plural(marketplaces.length, "marketplace")} could not be updated: ${marketplaces.join(", ")}`;
|
|
1017
1024
|
}
|
|
@@ -1215,8 +1222,9 @@ function keptAsInstalledGlobally(skillIds, agentNames, idAppliedAtHome, provider
|
|
|
1215
1222
|
]
|
|
1216
1223
|
].join("\n");
|
|
1217
1224
|
}
|
|
1218
|
-
function skillsMoved(verb, skillIds) {
|
|
1219
|
-
|
|
1225
|
+
function skillsMoved(verb, skillIds, namedBy) {
|
|
1226
|
+
const names = skillIds.map((id) => getSkillEntryDisplayName(namedBy[id] ?? { id }));
|
|
1227
|
+
return names.length === 0 ? [] : [`${verb} ${listed(names)}`];
|
|
1220
1228
|
}
|
|
1221
1229
|
function settingMoved({ setting, from, to }) {
|
|
1222
1230
|
return `${setting} ${from ?? "default"} \u2192 ${to ?? "default"}`;
|
|
@@ -1226,10 +1234,17 @@ function listed(names) {
|
|
|
1226
1234
|
return `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
|
|
1227
1235
|
}
|
|
1228
1236
|
var SKILLS_REASSIGNED = "skills reassigned";
|
|
1229
|
-
function subAgentChanged({
|
|
1237
|
+
function subAgentChanged({
|
|
1238
|
+
name,
|
|
1239
|
+
scope,
|
|
1240
|
+
gains,
|
|
1241
|
+
loses,
|
|
1242
|
+
settings,
|
|
1243
|
+
namedBy = {}
|
|
1244
|
+
}) {
|
|
1230
1245
|
const details = [
|
|
1231
|
-
...skillsMoved("gains", gains),
|
|
1232
|
-
...skillsMoved("loses", loses),
|
|
1246
|
+
...skillsMoved("gains", gains, namedBy),
|
|
1247
|
+
...skillsMoved("loses", loses, namedBy),
|
|
1233
1248
|
...settings.map(settingMoved)
|
|
1234
1249
|
];
|
|
1235
1250
|
const where = scope === "global" ? " (global)" : "";
|
|
@@ -1318,8 +1333,9 @@ function sentenceCase(text) {
|
|
|
1318
1333
|
function layoutIsCurrent(label, to) {
|
|
1319
1334
|
return `${label} is on ${to}/`;
|
|
1320
1335
|
}
|
|
1321
|
-
function
|
|
1322
|
-
|
|
1336
|
+
function retiredSourceFolderIgnored(root, provider) {
|
|
1337
|
+
const named = isHomeDirectory(root) ? "~" : root;
|
|
1338
|
+
return `${path3.join(named, RETIRED_SOURCE_FOLDER)}/ is ignored; agents-inc reads ${path3.join(named, sourceDirName(provider))}/. Delete the old folder once you have kept anything you need from it.`;
|
|
1323
1339
|
}
|
|
1324
1340
|
|
|
1325
1341
|
// src/cli/types/generated/source-types.ts
|
|
@@ -2141,6 +2157,7 @@ var projectConfigFields = z2.object({
|
|
|
2141
2157
|
id: z2.string(),
|
|
2142
2158
|
scope: z2.enum(["project", "global"]),
|
|
2143
2159
|
origin: z2.string(),
|
|
2160
|
+
displayName: z2.string().exactOptional(),
|
|
2144
2161
|
excluded: z2.boolean().exactOptional()
|
|
2145
2162
|
})
|
|
2146
2163
|
).exactOptional(),
|
|
@@ -3357,6 +3374,7 @@ var CANONICAL_SKILL_ENTRY_ORDER = [
|
|
|
3357
3374
|
"id",
|
|
3358
3375
|
"scope",
|
|
3359
3376
|
"origin",
|
|
3377
|
+
"displayName",
|
|
3360
3378
|
"excluded"
|
|
3361
3379
|
];
|
|
3362
3380
|
var CANONICAL_AGENT_ENTRY_ORDER = [
|
|
@@ -4188,7 +4206,8 @@ function toSeedSkillConfig({
|
|
|
4188
4206
|
return {
|
|
4189
4207
|
id,
|
|
4190
4208
|
scope: seedSkill.scope,
|
|
4191
|
-
origin: seedSkill.install === "eject" ? EJECT_SOURCE : sourceForSkill(catalogSkill)
|
|
4209
|
+
origin: seedSkill.install === "eject" ? EJECT_SOURCE : sourceForSkill(catalogSkill),
|
|
4210
|
+
displayName: catalogSkill.displayName
|
|
4192
4211
|
};
|
|
4193
4212
|
}
|
|
4194
4213
|
function sourceForSkill(skill) {
|
|
@@ -5417,9 +5436,11 @@ var MarketplaceUnreachableError = class extends Error {
|
|
|
5417
5436
|
reason;
|
|
5418
5437
|
};
|
|
5419
5438
|
var TarballWithheldError = class extends Error {
|
|
5439
|
+
status;
|
|
5420
5440
|
constructor({ status, statusText }) {
|
|
5421
5441
|
super(`the marketplace answered ${status} ${statusText}`.trimEnd());
|
|
5422
5442
|
this.name = "TarballWithheldError";
|
|
5443
|
+
this.status = status;
|
|
5423
5444
|
}
|
|
5424
5445
|
};
|
|
5425
5446
|
var marketplaceMustAnswer = new AsyncLocalStorage3();
|
|
@@ -5430,6 +5451,29 @@ function askingEachMarketplaceItself(body) {
|
|
|
5430
5451
|
function mustAnswer() {
|
|
5431
5452
|
return marketplaceMustAnswer.getStore() !== void 0;
|
|
5432
5453
|
}
|
|
5454
|
+
var refusalStopsTheLoad = new AsyncLocalStorage3();
|
|
5455
|
+
function stoppingOnARefusal(body) {
|
|
5456
|
+
return refusalStopsTheLoad.run(true, body);
|
|
5457
|
+
}
|
|
5458
|
+
function stopsOnARefusal() {
|
|
5459
|
+
return refusalStopsTheLoad.getStore() !== void 0;
|
|
5460
|
+
}
|
|
5461
|
+
var METHOD_NOT_ALLOWED = 405;
|
|
5462
|
+
function postureOn(status) {
|
|
5463
|
+
if (mustAnswer()) return "stop";
|
|
5464
|
+
if (status === METHOD_NOT_ALLOWED || isServerError(status)) return "keep";
|
|
5465
|
+
if (!isClientError(status)) return void 0;
|
|
5466
|
+
return stopsOnARefusal() ? "stop" : "pass over";
|
|
5467
|
+
}
|
|
5468
|
+
var FIRST_CLIENT_ERROR = 400;
|
|
5469
|
+
var FIRST_SERVER_ERROR = 500;
|
|
5470
|
+
var PAST_THE_SERVER_ERRORS = 600;
|
|
5471
|
+
function isClientError(status) {
|
|
5472
|
+
return status >= FIRST_CLIENT_ERROR && status < FIRST_SERVER_ERROR;
|
|
5473
|
+
}
|
|
5474
|
+
function isServerError(status) {
|
|
5475
|
+
return status >= FIRST_SERVER_ERROR && status < PAST_THE_SERVER_ERRORS;
|
|
5476
|
+
}
|
|
5433
5477
|
function sanitizeSourceForCache(source) {
|
|
5434
5478
|
const hash = createHash2("sha256").update(source).digest("hex").slice(0, CACHE_HASH_LENGTH);
|
|
5435
5479
|
const readable = source.replace(/[^a-zA-Z0-9]/g, "-").replace(/--+/g, "-").replace(/^-|-$/g, "").slice(0, CACHE_READABLE_PREFIX_LENGTH);
|
|
@@ -5500,7 +5544,7 @@ async function fetchFromRemoteSource(source, subdir) {
|
|
|
5500
5544
|
verbose(`Cache directory: ${cacheDir}`);
|
|
5501
5545
|
if (await directoryExists2(cacheDir)) {
|
|
5502
5546
|
const verdict = await revalidateCachedCopy(cacheDir, source);
|
|
5503
|
-
if (verdict
|
|
5547
|
+
if (keepsTheCopy(verdict)) {
|
|
5504
5548
|
verbose(`Using cached marketplace: ${cacheDir}`);
|
|
5505
5549
|
return {
|
|
5506
5550
|
path: cacheDir,
|
|
@@ -5529,6 +5573,7 @@ async function downloadFreshCopy(cacheDir, source, fullSource) {
|
|
|
5529
5573
|
offline: false
|
|
5530
5574
|
});
|
|
5531
5575
|
verbose(`Downloaded to: ${result.dir}`);
|
|
5576
|
+
if (savedTarball) await askBeforeKeepingTheSavedTarball(cacheDir, result, source);
|
|
5532
5577
|
await recordFetchedCopy(cacheDir, result, savedTarball);
|
|
5533
5578
|
markCopyCurrentForThisRun(cacheDir);
|
|
5534
5579
|
return {
|
|
@@ -5541,6 +5586,31 @@ async function downloadFreshCopy(cacheDir, source, fullSource) {
|
|
|
5541
5586
|
throw createDetailedFetchError(error, source);
|
|
5542
5587
|
}
|
|
5543
5588
|
}
|
|
5589
|
+
async function askBeforeKeepingTheSavedTarball(cacheDir, result, source) {
|
|
5590
|
+
const tar = tarballOf(result);
|
|
5591
|
+
if (tar === void 0) return;
|
|
5592
|
+
const answer = await answerAbout(tar);
|
|
5593
|
+
if (answer === "answered") return;
|
|
5594
|
+
if (answer === "unreachable") {
|
|
5595
|
+
warn(sourceUnreachableUsingCache(source));
|
|
5596
|
+
return;
|
|
5597
|
+
}
|
|
5598
|
+
if (stopsTheLoad(answer)) {
|
|
5599
|
+
await remove(cacheDir);
|
|
5600
|
+
throw answer;
|
|
5601
|
+
}
|
|
5602
|
+
announceTheCopyKept(answer, source);
|
|
5603
|
+
}
|
|
5604
|
+
async function answerAbout(tar) {
|
|
5605
|
+
try {
|
|
5606
|
+
await fetchEtag(tar);
|
|
5607
|
+
return "answered";
|
|
5608
|
+
} catch (error) {
|
|
5609
|
+
if (error instanceof TarballWithheldError) return error;
|
|
5610
|
+
verbose(`Could not ask ${tar} about the tarball giget saved: ${getErrorMessage(error)}`);
|
|
5611
|
+
return "unreachable";
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5544
5614
|
var STAGED_DOWNLOAD_SUFFIX = ".download";
|
|
5545
5615
|
var ONLY_A_SAVED_COPY_CAME_BACK = "the download failed and only a saved copy came back";
|
|
5546
5616
|
var SET_ASIDE_SUFFIX = ".set-aside";
|
|
@@ -5659,6 +5729,9 @@ async function etagSavedWith(tarballPath) {
|
|
|
5659
5729
|
function savedUnder(savedTarball, record) {
|
|
5660
5730
|
return savedTarball.etag !== void 0 && savedTarball.etag === record.etag;
|
|
5661
5731
|
}
|
|
5732
|
+
function keepsTheCopy(verdict) {
|
|
5733
|
+
return verdict === "current" || verdict === "unreachable" || verdict === "refused";
|
|
5734
|
+
}
|
|
5662
5735
|
var REVALIDATION_TIMEOUT_MS = 5e3;
|
|
5663
5736
|
var FETCH_RECORD_SUFFIX = ".etag.json";
|
|
5664
5737
|
var askedThisRun = /* @__PURE__ */ new Map();
|
|
@@ -5692,13 +5765,18 @@ async function classifyCachedCopy(cacheDir, source) {
|
|
|
5692
5765
|
try {
|
|
5693
5766
|
return judgeAnswer(record, await fetchEtag(record.tar));
|
|
5694
5767
|
} catch (error) {
|
|
5695
|
-
if (error instanceof TarballWithheldError)
|
|
5768
|
+
if (error instanceof TarballWithheldError) return stopOrKeepTheCopy(error, source);
|
|
5696
5769
|
verbose(`Could not revalidate ${record.tar}: ${getErrorMessage(error)}`);
|
|
5697
5770
|
if (mustAnswer()) throw new MarketplaceUnreachableError(source, getErrorMessage(error));
|
|
5698
5771
|
warn(sourceUnreachableUsingCache(source));
|
|
5699
5772
|
return "unreachable";
|
|
5700
5773
|
}
|
|
5701
5774
|
}
|
|
5775
|
+
function stopOrKeepTheCopy(refusal2, source) {
|
|
5776
|
+
if (stopsTheLoad(refusal2)) throw createDetailedFetchError(refusal2, source);
|
|
5777
|
+
announceTheCopyKept(refusal2, source);
|
|
5778
|
+
return "refused";
|
|
5779
|
+
}
|
|
5702
5780
|
function judgeAnswer(record, live) {
|
|
5703
5781
|
if (movedOn(record, live)) return "superseded";
|
|
5704
5782
|
if (mustAnswer()) return "answered";
|
|
@@ -5718,9 +5796,22 @@ async function fetchEtag(tar) {
|
|
|
5718
5796
|
signal: AbortSignal.timeout(REVALIDATION_TIMEOUT_MS)
|
|
5719
5797
|
});
|
|
5720
5798
|
await response.body?.cancel();
|
|
5721
|
-
if (
|
|
5799
|
+
if (withheld(response)) throw new TarballWithheldError(response);
|
|
5722
5800
|
return response.headers.get("etag") ?? void 0;
|
|
5723
5801
|
}
|
|
5802
|
+
function withheld({ ok, status }) {
|
|
5803
|
+
return !ok && postureOn(status) !== void 0;
|
|
5804
|
+
}
|
|
5805
|
+
function stopsTheLoad(refusal2) {
|
|
5806
|
+
return postureOn(refusal2.status) === "stop";
|
|
5807
|
+
}
|
|
5808
|
+
function announceTheCopyKept(refusal2, source) {
|
|
5809
|
+
if (postureOn(refusal2.status) === "keep") {
|
|
5810
|
+
warn(sourceRefusedUsingCache(source, refusal2.status));
|
|
5811
|
+
return;
|
|
5812
|
+
}
|
|
5813
|
+
verbose(`Keeping the saved copy of ${source} over its refusal: ${refusal2.message}`);
|
|
5814
|
+
}
|
|
5724
5815
|
function fetchRecordPath(cacheDir) {
|
|
5725
5816
|
return `${cacheDir}${FETCH_RECORD_SUFFIX}`;
|
|
5726
5817
|
}
|
|
@@ -7153,12 +7244,14 @@ async function countDirEntries(dir, pred) {
|
|
|
7153
7244
|
return 0;
|
|
7154
7245
|
}
|
|
7155
7246
|
}
|
|
7156
|
-
function formatInstallationDisplay(info) {
|
|
7247
|
+
function formatInstallationDisplay(info, skillLines = []) {
|
|
7248
|
+
const namedSkillLines = skillLines.map((line2) => `
|
|
7249
|
+
${line2}`).join("");
|
|
7157
7250
|
const agentDirLines = info.agentDirs.map((dir) => `
|
|
7158
7251
|
Agents: ${dir}`).join("");
|
|
7159
7252
|
return `Installation: ${info.name}
|
|
7160
7253
|
Mode: ${INSTALL_MODE_LABELS[info.mode]}
|
|
7161
|
-
Skills: ${info.skillCount}
|
|
7254
|
+
Skills: ${info.skillCount}${namedSkillLines}
|
|
7162
7255
|
Agents: ${info.agentCount}
|
|
7163
7256
|
Config: ${info.configPath}${agentDirLines}`;
|
|
7164
7257
|
}
|
|
@@ -10259,9 +10352,11 @@ export {
|
|
|
10259
10352
|
pluginRefFor,
|
|
10260
10353
|
renderAgent,
|
|
10261
10354
|
renderAgentBody,
|
|
10355
|
+
isHomeDirectory,
|
|
10262
10356
|
sourceRootOf,
|
|
10263
|
-
|
|
10357
|
+
rootsHoldingTheRetiredSourceFolder,
|
|
10264
10358
|
chooseProviderForThisRun,
|
|
10359
|
+
forgetTheProviderChosenForThisRun,
|
|
10265
10360
|
providerInUse,
|
|
10266
10361
|
sourceFolderInUse,
|
|
10267
10362
|
relativeConfigPath,
|
|
@@ -10347,7 +10442,7 @@ export {
|
|
|
10347
10442
|
scopeNoun,
|
|
10348
10443
|
scopeLabel,
|
|
10349
10444
|
layoutIsCurrent,
|
|
10350
|
-
|
|
10445
|
+
retiredSourceFolderIgnored,
|
|
10351
10446
|
GlobalPairWriteViolation,
|
|
10352
10447
|
withGateToken,
|
|
10353
10448
|
assertGateToken,
|
|
@@ -10389,7 +10484,6 @@ export {
|
|
|
10389
10484
|
resolveInstallPaths,
|
|
10390
10485
|
providerToNameAt,
|
|
10391
10486
|
initProviderToNameAt,
|
|
10392
|
-
isHomeDirectory,
|
|
10393
10487
|
SOURCE_ENV_VAR,
|
|
10394
10488
|
readSourceRepoConfig,
|
|
10395
10489
|
loadSourceRepoConfig,
|
|
@@ -10502,6 +10596,7 @@ export {
|
|
|
10502
10596
|
getMarketplaceStats,
|
|
10503
10597
|
MarketplaceUnreachableError,
|
|
10504
10598
|
askingEachMarketplaceItself,
|
|
10599
|
+
stoppingOnARefusal,
|
|
10505
10600
|
MarketplaceNameRefusedError,
|
|
10506
10601
|
fetchMarketplace,
|
|
10507
10602
|
isLocalOnlySkill,
|
|
@@ -10525,4 +10620,4 @@ export {
|
|
|
10525
10620
|
executeMigration,
|
|
10526
10621
|
keepsGlobalInstall
|
|
10527
10622
|
};
|
|
10528
|
-
//# sourceMappingURL=chunk-
|
|
10623
|
+
//# sourceMappingURL=chunk-E45IT3HC.js.map
|