agents-inc 0.171.0 → 0.173.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/dist/{chunk-W4KAY26P.js → chunk-2RTBSLSR.js} +12 -3
- package/dist/{chunk-W4KAY26P.js.map → chunk-2RTBSLSR.js.map} +1 -1
- package/dist/{chunk-WM2N2D6Q.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-WM2N2D6Q.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-ZC6GC66J.js → chunk-3R3LHA4Q.js} +2 -2
- package/dist/{chunk-24OD7IP4.js → chunk-7OG635DK.js} +26 -4
- package/dist/chunk-7OG635DK.js.map +1 -0
- package/dist/{chunk-WDH6HHA3.js → chunk-A3ZAXL5T.js} +4 -5
- package/dist/{chunk-WDH6HHA3.js.map → chunk-A3ZAXL5T.js.map} +1 -1
- package/dist/{chunk-KMOCMVK5.js → chunk-AARQBW5L.js} +106 -60
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-WII6GOPM.js → chunk-BRZA7ZCX.js} +52 -31
- package/dist/chunk-BRZA7ZCX.js.map +1 -0
- package/dist/{chunk-AWWCRL5A.js → chunk-EHJIQDXR.js} +8 -6
- package/dist/{chunk-AWWCRL5A.js.map → chunk-EHJIQDXR.js.map} +1 -1
- package/dist/{chunk-RDXY4GRO.js → chunk-F437ICEG.js} +2 -2
- package/dist/chunk-G7NUK3BF.js +253 -0
- package/dist/chunk-G7NUK3BF.js.map +1 -0
- package/dist/{chunk-7IVLVEHX.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-QIR56IDM.js → chunk-LJQXQTFC.js} +29 -102
- package/dist/chunk-LJQXQTFC.js.map +1 -0
- package/dist/{chunk-A6OWEJGC.js → chunk-MHAQWMNJ.js} +35 -5
- package/dist/{chunk-A6OWEJGC.js.map → chunk-MHAQWMNJ.js.map} +1 -1
- package/dist/{chunk-YLUOGAW7.js → chunk-N33AKFLR.js} +2 -2
- package/dist/{chunk-TNFYBKVD.js → chunk-Q4UNHVPX.js} +25 -14
- package/dist/chunk-Q4UNHVPX.js.map +1 -0
- package/dist/chunk-Q6WRR4BN.js +195 -0
- package/dist/chunk-Q6WRR4BN.js.map +1 -0
- package/dist/{chunk-JGPE4RRE.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-EOKNEGRD.js → chunk-VR6QTK5Z.js} +8 -8
- package/dist/{chunk-S2SKVJT2.js → chunk-VSPC74SS.js} +48 -26
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-3YYHL76L.js → chunk-WVFBBZEP.js} +648 -394
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +16 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +12 -12
- package/dist/commands/doctor.js +87 -86
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +150 -152
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +25 -30
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +19 -16
- package/dist/commands/list.js +14 -17
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/marketplace.js +4 -4
- package/dist/commands/search.js +15 -13
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/share.js +11 -11
- package/dist/commands/uninstall.js +145 -130
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +6 -6
- package/dist/components/common/scroll-affordance.js +2 -2
- package/dist/components/common/select-list.js +2 -2
- package/dist/components/common/skill-agent-summary.js +3 -4
- package/dist/components/common/summary-panel.js +11 -146
- package/dist/components/common/summary-panel.js.map +1 -1
- package/dist/hooks/init.js +39 -27
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-IQANWGOP.js → recompile-project-agents-6G6M2RS6.js} +8 -8
- package/dist/{source-loader-YGG7DY2W.js → source-loader-W7XCNKNA.js} +4 -4
- package/dist/src/agents/tester/web-tester/playbook.md +1 -1
- package/package.json +1 -1
- package/src/agents/tester/web-tester/playbook.md +1 -1
- package/dist/chunk-24OD7IP4.js.map +0 -1
- package/dist/chunk-3YYHL76L.js.map +0 -1
- package/dist/chunk-4RQKCV6I.js +0 -103
- package/dist/chunk-4RQKCV6I.js.map +0 -1
- package/dist/chunk-5FM77WKW.js +0 -69
- package/dist/chunk-5FM77WKW.js.map +0 -1
- package/dist/chunk-KMOCMVK5.js.map +0 -1
- package/dist/chunk-QIR56IDM.js.map +0 -1
- package/dist/chunk-R572RLTI.js +0 -108
- package/dist/chunk-R572RLTI.js.map +0 -1
- package/dist/chunk-S2SKVJT2.js.map +0 -1
- package/dist/chunk-TNFYBKVD.js.map +0 -1
- package/dist/chunk-WII6GOPM.js.map +0 -1
- package/dist/components/common/removal-plan-confirm.js +0 -10
- package/dist/load-agent-defs-UBWITIEI.js +0 -14
- package/dist/source-loader-YGG7DY2W.js.map +0 -1
- /package/dist/{chunk-ZC6GC66J.js.map → chunk-3R3LHA4Q.js.map} +0 -0
- /package/dist/{chunk-RDXY4GRO.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-7IVLVEHX.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-YLUOGAW7.js.map → chunk-N33AKFLR.js.map} +0 -0
- /package/dist/{chunk-JGPE4RRE.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-EOKNEGRD.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{components/common/removal-plan-confirm.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-IQANWGOP.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{load-agent-defs-UBWITIEI.js.map → source-loader-W7XCNKNA.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SCROLL_VIEWPORT
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MHAQWMNJ.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/components/common/scroll-affordance.tsx
|
|
7
7
|
import { Box, Text } from "ink";
|
|
@@ -21,4 +21,4 @@ var ScrollAffordance = ({ hiddenAbove, hiddenBelow }) => {
|
|
|
21
21
|
export {
|
|
22
22
|
ScrollAffordance
|
|
23
23
|
};
|
|
24
|
-
//# sourceMappingURL=chunk-
|
|
24
|
+
//# sourceMappingURL=chunk-N33AKFLR.js.map
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
SEED_API_URL,
|
|
4
3
|
SEED_USER_AGENT,
|
|
5
4
|
arrivedAsText,
|
|
6
5
|
jsonBodyOrUndefined,
|
|
7
6
|
retryAfterSeconds
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-A3ZAXL5T.js";
|
|
9
8
|
import {
|
|
10
9
|
withoutExcludedAssignments
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EHJIQDXR.js";
|
|
12
11
|
import {
|
|
13
12
|
readCarriedSkills
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LJQXQTFC.js";
|
|
15
14
|
import {
|
|
16
15
|
ERROR_MESSAGES,
|
|
17
16
|
directoryExists,
|
|
@@ -21,24 +20,25 @@ import {
|
|
|
21
20
|
loadProjectConfig,
|
|
22
21
|
loadProjectConfigFromDir,
|
|
23
22
|
readForkedFromMetadata,
|
|
24
|
-
resolveInstallPaths
|
|
25
|
-
|
|
26
|
-
typedValues
|
|
27
|
-
} from "./chunk-3YYHL76L.js";
|
|
23
|
+
resolveInstallPaths
|
|
24
|
+
} from "./chunk-WVFBBZEP.js";
|
|
28
25
|
import {
|
|
29
26
|
plural,
|
|
30
|
-
truncateText
|
|
31
|
-
|
|
27
|
+
truncateText,
|
|
28
|
+
typedEntries,
|
|
29
|
+
typedValues
|
|
30
|
+
} from "./chunk-7OG635DK.js";
|
|
32
31
|
import {
|
|
33
32
|
CLI_INVOKE_COMMAND,
|
|
34
33
|
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
35
34
|
EJECT_SOURCE,
|
|
36
35
|
MATRIX_VERSION,
|
|
36
|
+
SEED_API_URL,
|
|
37
37
|
SEED_VERSION,
|
|
38
38
|
activeAgentScopeMap,
|
|
39
39
|
activeSkillScopeMap,
|
|
40
40
|
seedModelSchema
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-MHAQWMNJ.js";
|
|
42
42
|
|
|
43
43
|
// src/cli/lib/seed/installation-payload.ts
|
|
44
44
|
import os from "os";
|
|
@@ -175,14 +175,24 @@ async function seedPayloadForInstallation(projectDir) {
|
|
|
175
175
|
const agents = Object.keys(payload.agents).length;
|
|
176
176
|
if (skills === 0 && agents === 0) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };
|
|
177
177
|
const leftBehind = skillsItsMarketplaceLeavesBehind(roundTrip.config, payload);
|
|
178
|
-
return { ok: true, payload, skills, agents, leftBehind };
|
|
178
|
+
return { ok: true, payload, skills, agents, leftBehind, inProject: installed.inProject };
|
|
179
|
+
}
|
|
180
|
+
async function editorPayloadForInstallation(projectDir) {
|
|
181
|
+
const prepared = await seedPayloadForInstallation(projectDir);
|
|
182
|
+
if (!prepared.ok || !prepared.inProject) return prepared;
|
|
183
|
+
return { ...prepared, payload: { ...prepared.payload, fromProject: true } };
|
|
179
184
|
}
|
|
180
185
|
async function readInstalledConfig(projectDir) {
|
|
181
186
|
try {
|
|
182
187
|
const loaded = await loadProjectConfig(projectDir);
|
|
183
188
|
if (!loaded) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };
|
|
184
189
|
const inheritedFrom = await readInheritedConfig(loaded);
|
|
185
|
-
return {
|
|
190
|
+
return {
|
|
191
|
+
ok: true,
|
|
192
|
+
config: withInheritedCuration(loaded.config, inheritedFrom),
|
|
193
|
+
inheritedFrom,
|
|
194
|
+
inProject: !isGlobalConfig(loaded)
|
|
195
|
+
};
|
|
186
196
|
} catch (error) {
|
|
187
197
|
return { ok: false, error: getErrorMessage(error) };
|
|
188
198
|
}
|
|
@@ -357,7 +367,8 @@ function sentenceOf(issue) {
|
|
|
357
367
|
|
|
358
368
|
export {
|
|
359
369
|
seedPayloadForInstallation,
|
|
370
|
+
editorPayloadForInstallation,
|
|
360
371
|
skillsAuthoredHere,
|
|
361
372
|
publishSeedConfig
|
|
362
373
|
};
|
|
363
|
-
//# sourceMappingURL=chunk-
|
|
374
|
+
//# sourceMappingURL=chunk-Q4UNHVPX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/lib/seed/installation-payload.ts","../src/cli/lib/seed/config-to-seed.ts","../src/cli/lib/seed/publish-seed.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\n\nimport {\n configToSeedPayload,\n isInstalled,\n skillsItsMarketplaceLeavesBehind,\n} from \"./config-to-seed.js\";\nimport { readCarriedSkills } from \"./external-skills.js\";\nimport { EJECT_SOURCE } from \"../../consts.js\";\nimport { withoutExcludedAssignments } from \"../agents/agent-recompiler.js\";\nimport { loadProjectConfig, loadProjectConfigFromDir } from \"../configuration/project-config.js\";\nimport { activeAgentScopeMap, activeSkillScopeMap } from \"../configuration/scope-predicates.js\";\nimport { getProjectConfigPath, resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { readForkedFromMetadata } from \"../skills/skill-metadata.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { ERROR_MESSAGES } from \"../../utils/messages.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading, OwnedSkillDir } from \"./external-skills.js\";\nimport type { LoadedProjectConfig } from \"../configuration/project-config.js\";\nimport type { AgentScopeConfig, ProjectConfig, SkillConfig, SkillId } from \"../../types/index.js\";\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/**\n * Counts come off the payload, not the config, so what is announced matches what is posted.\n * `leftBehind`: carried skills the payload's one marketplace does not serve. `inProject`: read from\n * a project's config rather than HOME's.\n */\nexport type InstallationPayload =\n | {\n ok: true;\n payload: SeedPayload;\n skills: number;\n agents: number;\n leftBehind: SkillId[];\n inProject: boolean;\n }\n | { ok: false; error: string };\n\n/** `inheritedFrom` is absent when the config read is the global one already. */\ntype InstalledConfig =\n | {\n ok: true;\n config: ProjectConfig;\n inheritedFrom: ProjectConfig | undefined;\n inProject: boolean;\n }\n | { ok: false; error: string };\n\ntype MappedPayload = { ok: true; payload: SeedPayload } | { ok: false; error: string };\n\ntype RoundTrip = { config: ProjectConfig; content: ContentReading };\n\ntype SkillJudgement = { skill: SkillConfig; owned: boolean; carried: OwnedSkillDir | null };\n\n/** `share`'s, and what `edit --ui` marks; fails as a message, never a throw. */\nexport async function seedPayloadForInstallation(projectDir: string): Promise<InstallationPayload> {\n const installed = await readInstalledConfig(projectDir);\n if (!installed.ok) return installed;\n\n const roundTrip = await readRoundTrip(installed.config, projectDir);\n const mapped = mapOrRefuse(roundTrip, installed.inheritedFrom);\n if (!mapped.ok) return mapped;\n\n const { payload } = mapped;\n const skills = Object.keys(payload.skills).length;\n const agents = Object.keys(payload.agents).length;\n\n // A sub-agent is installable without skills, so only neither-skills-nor-agents is empty.\n if (skills === 0 && agents === 0) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n\n const leftBehind = skillsItsMarketplaceLeavesBehind(roundTrip.config, payload);\n return { ok: true, payload, skills, agents, leftBehind, inProject: installed.inProject };\n}\n\n/**\n * Made in a project, the link says so: the editor holds its global entries, which a run there\n * cannot change. A share's recipient has a global install of their own, so `share` never marks.\n */\nexport async function editorPayloadForInstallation(\n projectDir: string,\n): Promise<InstallationPayload> {\n const prepared = await seedPayloadForInstallation(projectDir);\n if (!prepared.ok || !prepared.inProject) return prepared;\n\n return { ...prepared, payload: { ...prepared.payload, fromProject: true } };\n}\n\n/** An unloadable config, HOME's included, is reported as its own error, not \"not installed\". */\nasync function readInstalledConfig(projectDir: string): Promise<InstalledConfig> {\n try {\n const loaded = await loadProjectConfig(projectDir);\n if (!loaded) return { ok: false, error: ERROR_MESSAGES.NO_INSTALLATION };\n const inheritedFrom = await readInheritedConfig(loaded);\n return {\n ok: true,\n config: withInheritedCuration(loaded.config, inheritedFrom),\n inheritedFrom,\n inProject: !isGlobalConfig(loaded),\n };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n\nasync function readInheritedConfig(\n loaded: LoadedProjectConfig,\n): Promise<ProjectConfig | undefined> {\n if (isGlobalConfig(loaded)) return undefined;\n\n // Aborts: a throw reaches readInstalledConfig and refuses the share.\n const home = await loadProjectConfigFromDir(os.homedir(), loaded.provider);\n return home?.config;\n}\n\nfunction isGlobalConfig(loaded: LoadedProjectConfig): boolean {\n return loaded.configPath === getProjectConfigPath(os.homedir(), loaded.provider);\n}\n\n/**\n * A project file keeps stack rows for its own sub-agents only, so inherited sub-agents take their\n * rows from the global config (which wins, since it compiles them).\n */\nfunction withInheritedCuration(\n config: ProjectConfig,\n inheritedFrom: ProjectConfig | undefined,\n): ProjectConfig {\n if (inheritedFrom?.stack === undefined) return config;\n\n return { ...config, stack: { ...config.stack, ...inheritedRows(config, inheritedFrom.stack) } };\n}\n\n/** Narrowed to inherited sub-agents and skills, so no global row lands on a project-scoped entry. */\nfunction inheritedRows(\n config: ProjectConfig,\n globalStack: NonNullable<ProjectConfig[\"stack\"]>,\n): NonNullable<ProjectConfig[\"stack\"]> {\n const agents = inheritedAgents(config.agents);\n const rows = Object.fromEntries(typedEntries(globalStack).filter(([agent]) => agents.has(agent)));\n return withoutExcludedAssignments(rows, skillsNotInherited(config.skills));\n}\n\nfunction inheritedAgents(agents: AgentScopeConfig[]): Set<string> {\n const scopes = activeAgentScopeMap(agents);\n return new Set(agents.map((agent) => agent.name).filter((name) => scopes.get(name) === \"global\"));\n}\n\nfunction skillsNotInherited(skills: SkillConfig[]): Set<SkillId> {\n const scopes = activeSkillScopeMap(skills);\n return new Set(skills.map((skill) => skill.id).filter((id) => scopes.get(id) !== \"global\"));\n}\n\n/**\n * Drops skills the CLI did not write (no `forkedFrom`): a user-authored skill is outside the round\n * trip, neither carried nor refused.\n */\nasync function readRoundTrip(config: ProjectConfig, projectDir: string): Promise<RoundTrip> {\n const owned = (await judgeSkills(config, projectDir)).filter((entry) => entry.owned);\n\n return {\n config: { ...config, skills: owned.map((entry) => entry.skill) },\n content: await readCarriedSkills(owned.flatMap((entry) => entry.carried ?? [])),\n };\n}\n\nfunction judgeSkills(config: ProjectConfig, projectDir: string): Promise<SkillJudgement[]> {\n return Promise.all(config.skills.map((skill) => judgeSkill(skill, projectDir)));\n}\n\n/** User-authored skills, which `edit --from` must not read a payload's silence as deleting. */\nexport async function skillsAuthoredHere(\n config: ProjectConfig,\n projectDir: string,\n): Promise<Set<SkillId>> {\n const judged = await judgeSkills(config, projectDir);\n return new Set(judged.filter((entry) => !entry.owned).map((entry) => entry.skill.id));\n}\n\nfunction travelsAsAnId(skill: SkillConfig): SkillJudgement {\n return { skill, owned: true, carried: null };\n}\n\n/** Only an existing directory with no provenance is the user's own work. */\nasync function judgeSkill(skill: SkillConfig, projectDir: string): Promise<SkillJudgement> {\n if (skill.origin !== EJECT_SOURCE) return travelsAsAnId(skill);\n if (!isInstalled(skill)) return travelsAsAnId(skill);\n\n const skillsDir = resolveInstallPaths(projectDir, skill.scope).skillsDir;\n const skillDir = path.join(skillsDir, skill.id);\n if (!(await directoryExists(skillDir))) return travelsAsAnId(skill);\n\n const provenance = await readForkedFromMetadata(skillDir);\n if (provenance === null) return { skill, owned: false, carried: null };\n\n return { skill, owned: true, carried: { id: skill.id, skillDir, provenance } };\n}\n\nfunction mapOrRefuse(\n { config, content }: RoundTrip,\n inheritedFrom: ProjectConfig | undefined,\n): MappedPayload {\n try {\n return { ok: true, payload: configToSeedPayload(config, content, inheritedFrom) };\n } catch (error) {\n return { ok: false, error: getErrorMessage(error) };\n }\n}\n","import { MATRIX_VERSION } from \"@workspace/matrix\";\nimport { SEED_VERSION, seedModelSchema } from \"@workspace/matrix/seed\";\n\nimport { DEFAULT_PUBLIC_SOURCE_NAME, EJECT_SOURCE } from \"../../consts.js\";\nimport { isScopePairCompatible } from \"../configuration/config-generator.js\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object.js\";\n\nimport type { ContentReading } from \"./external-skills.js\";\nimport type {\n AgentScopeConfig,\n ProjectConfig,\n SkillConfig,\n SkillScope,\n} from \"../../types/config.js\";\nimport type { ModelName } from \"../../types/matrix.js\";\nimport type { SkillId } from \"../../types/skills.js\";\nimport type {\n SeedAgent,\n SeedLoadState,\n SeedModel,\n SeedPayload,\n SeedSkill,\n} from \"@workspace/matrix/seed\";\n\ntype SeedAssignments = Record<string, SeedLoadState>;\n\ntype StackReading = {\n assignments: Map<SkillId, SeedAssignments>;\n unwritable: string[];\n};\n\n/** A tombstone describes something not installed, so it has nothing to say on the wire. */\nexport function isInstalled(entry: { excluded?: boolean }): boolean {\n return !entry.excluded;\n}\n\n/** An ejected copy travels with the project, and the default catalogue is what no ref means. */\nfunction needsMarketplaceNamed(origin: string): boolean {\n return origin !== EJECT_SOURCE && origin !== DEFAULT_PUBLIC_SOURCE_NAME;\n}\n\n/** The contract's own enum, so widening `MODEL_NAMES` alone cannot silently drop a pin. */\nfunction isSeedModel(model: ModelName): model is SeedModel {\n return seedModelSchema.safeParse(model).success;\n}\n\nfunction seedLoadState(preloaded: boolean | undefined): SeedLoadState {\n return preloaded === true ? \"preloaded\" : \"lazy\";\n}\n\nfunction unnameableOriginMessage(skill: SkillConfig): string {\n return `${skill.id} comes from the marketplace '${skill.origin}', and this installation does not record where that marketplace is fetched from`;\n}\n\nfunction unnameableModelMessage(agent: AgentScopeConfig[\"name\"], model: ModelName): string {\n return `${agent} pins model '${model}', which this contract has no word for — leaving it out would say \"keep the sub-agent's own metadata\", which is a different instruction`;\n}\n\nfunction unwritablePairMessage(skillId: SkillId, agent: string): string {\n return `${skillId} -> ${agent}: a project-scoped skill never reaches a sub-agent that rests at global scope`;\n}\n\nfunction unshareableConfigError(unshareable: string[]): string {\n return [\n \"This installation cannot be shared as it stands — a shared configuration has no way to carry:\",\n ...unshareable.map((line) => ` ${line}`),\n \"Sharing it anyway would mint an id that installs something else.\",\n ].join(\"\\n\");\n}\n\ntype MarketplaceReading = {\n ref: string | undefined;\n unnameable: string[];\n};\n\ntype MarketplaceRecord = Pick<ProjectConfig, \"marketplace\" | \"marketplaceName\">;\n\n/** `origin` is a marketplace name, `marketplace` its ref, and `marketplaceName` joins them. */\nfunction isRecordedMarketplace(record: MarketplaceRecord | undefined, skill: SkillConfig): boolean {\n return record?.marketplace !== undefined && skill.origin === record.marketplaceName;\n}\n\n/** A payload names one marketplace; only a skill whose marketplace neither config records is refused. */\nfunction readMarketplace(\n config: ProjectConfig,\n skills: SkillConfig[],\n inheritedFrom: MarketplaceRecord | undefined,\n): MarketplaceReading {\n const served = skills.filter((skill) => needsMarketplaceNamed(skill.origin));\n const unaccounted = served.filter(\n (skill) =>\n !isRecordedMarketplace(config, skill) && !isRecordedMarketplace(inheritedFrom, skill),\n );\n if (unaccounted.length > 0) {\n return { ref: undefined, unnameable: unaccounted.map(unnameableOriginMessage) };\n }\n\n const servesItsOwn = served.some((skill) => isRecordedMarketplace(config, skill));\n return { ref: servesItsOwn ? config.marketplace : undefined, unnameable: [] };\n}\n\n/** Plugins from a marketplace other than the payload's one, which an install will skip. */\nexport function skillsItsMarketplaceLeavesBehind(\n config: ProjectConfig,\n payload: SeedPayload,\n): SkillId[] {\n const namedMarketplace =\n payload.marketplace === undefined ? DEFAULT_PUBLIC_SOURCE_NAME : config.marketplaceName;\n const isPluginFromElsewhere = (skill: SkillConfig): boolean =>\n skill.origin !== EJECT_SOURCE && skill.origin !== namedMarketplace;\n\n return config.skills\n .filter(isInstalled)\n .filter(isPluginFromElsewhere)\n .map((skill) => skill.id);\n}\n\nfunction unnameableModels(agents: AgentScopeConfig[]): string[] {\n return agents.flatMap((agent) =>\n agent.model !== undefined && !isSeedModel(agent.model)\n ? [unnameableModelMessage(agent.name, agent.model)]\n : [],\n );\n}\n\n/** Re-keys rows by skill; rows the decoder would refuse are collected for the refusal. */\nfunction readStack(\n stack: ProjectConfig[\"stack\"],\n skillScopes: Map<SkillId, SkillScope>,\n agentScopes: Map<string, SkillScope>,\n): StackReading {\n const assignments = new Map<SkillId, SeedAssignments>();\n const unwritable: string[] = [];\n\n for (const [agent, agentStack] of typedEntries(stack ?? {})) {\n const agentScope = agentScopes.get(agent);\n if (agentScope === undefined) continue;\n\n for (const { id, preloaded } of typedValues(agentStack).flat()) {\n const skillScope = skillScopes.get(id);\n if (skillScope === undefined) continue;\n\n if (!isScopePairCompatible(skillScope, agentScope)) {\n unwritable.push(unwritablePairMessage(id, agent));\n continue;\n }\n\n const forSkill = assignments.get(id) ?? {};\n forSkill[agent] = seedLoadState(preloaded);\n assignments.set(id, forSkill);\n }\n }\n\n return { assignments, unwritable };\n}\n\nfunction toSeedSkill(skill: SkillConfig, assignments: SeedAssignments | undefined): SeedSkill {\n return {\n // A plugin's marketplace has already been checked against the envelope's ref.\n install: skill.origin === EJECT_SOURCE ? \"eject\" : \"plugin\",\n scope: skill.scope,\n assignments: assignments ?? {},\n };\n}\n\n/** Always `on`: it carries a sub-agent that owns no skill, which assignments cannot. */\nfunction toSeedAgent(agent: AgentScopeConfig): SeedAgent {\n return {\n on: true,\n scope: agent.scope,\n ...(agent.model !== undefined && isSeedModel(agent.model) && { model: agent.model }),\n ...(agent.codexModel !== undefined && { codexModel: agent.codexModel }),\n ...(agent.effort !== undefined && { effort: agent.effort }),\n };\n}\n\n/** Inverse of `seedToInstallSelection`; anything the contract cannot state is refused by name. */\nexport function configToSeedPayload(\n config: ProjectConfig,\n carried: ContentReading,\n inheritedFrom?: MarketplaceRecord,\n): SeedPayload {\n const skills = config.skills.filter(isInstalled);\n const agents = config.agents.filter(isInstalled);\n const skillScopes = new Map(skills.map((skill) => [skill.id, skill.scope]));\n const agentScopes = new Map<string, SkillScope>(agents.map((agent) => [agent.name, agent.scope]));\n\n const { assignments, unwritable } = readStack(config.stack, skillScopes, agentScopes);\n const marketplace = readMarketplace(config, skills, inheritedFrom);\n\n const unshareable = [\n ...marketplace.unnameable,\n ...unnameableModels(agents),\n ...unwritable,\n ...carried.uncarryable,\n ];\n if (unshareable.length > 0) throw new Error(unshareableConfigError(unshareable));\n\n return {\n v: SEED_VERSION,\n matrixVersion: MATRIX_VERSION,\n stackId: null,\n // Absent rather than empty: an id is the hash of its body.\n ...(config.description !== undefined && { description: config.description }),\n ...(marketplace.ref !== undefined && { marketplace: marketplace.ref }),\n skills: Object.fromEntries(\n skills.map((skill) => [skill.id, toSeedSkill(skill, assignments.get(skill.id))]),\n ),\n ...(Object.keys(carried.external).length > 0 && { external: carried.external }),\n agents: Object.fromEntries(agents.map((agent) => [agent.name, toSeedAgent(agent)])),\n };\n}\n","import { STATUS_CODES } from \"node:http\";\n\nimport { retryAfterSeconds } from \"@workspace/api\";\nimport { z } from \"zod\";\n\nimport { SEED_API_URL } from \"../../consts.js\";\nimport { arrivedAsText, jsonBodyOrUndefined, SEED_USER_AGENT } from \"./fetch-seed.js\";\nimport { CLI_INVOKE_COMMAND } from \"../../consts.js\";\nimport { plural, truncateText } from \"../../utils/string.js\";\n\nimport type { SeedPayload } from \"@workspace/matrix/seed\";\n\n/** Revalidated: the deployed worker may not match the one this CLI was built against. */\nconst mintedSchema = z.object({ id: z.string().min(1) });\n\n/** `@hono/zod-validator` sends the `safeParse` result; its error crosses as `{ name, message }`. */\nconst refusalSchema = z.object({ error: z.object({ message: z.string() }) });\n\n/** Zod renders its issues into `message` as JSON; the readable sentences are inside. */\nconst refusedIssuesSchema = z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string().min(1),\n }),\n )\n .min(1);\n\n/** Holds about two of the store's refusal sentences; a longer body must not paint the terminal. */\nconst EXPLANATION_BUDGET = 300;\n\nconst CONTRACT_MISMATCH = 409;\n\nconst RATE_LIMITED = 429;\n\n/** The editor's `limitReachedNote` wording, so both front doors say it alike. */\nconst LIMIT_REACHED = \"rate limit reached — try again in\";\n\nconst SECONDS_PER_MINUTE = 60;\n\n/**\n * The store's 409 body says \"Reload the page\", which a terminal cannot do. The seed version is\n * bundled into the CLI, so only a newer CLI fixes it.\n */\nconst OUT_OF_DATE_AGAINST_STORE =\n `This CLI is out of date against the configuration store: it writes a version of the sharing ` +\n `contract the store does not serve, and that version travels inside the CLI rather than with ` +\n `the configuration. Re-run this command through '${CLI_INVOKE_COMMAND}@latest'.`;\n\nexport type PublishSeedResult = { ok: true; id: string } | { ok: false; error: string };\n\n/** Every failure is a message rather than a throw. */\nexport async function publishSeedConfig(payload: SeedPayload): Promise<PublishSeedResult> {\n const response = await postToStore(payload);\n if (response === null) {\n return { ok: false, error: `Could not reach ${SEED_API_URL} — check your connection.` };\n }\n\n if (!response.ok) return { ok: false, error: await refusalMessage(response) };\n\n return mintedIdIn(await jsonBodyOrUndefined(response));\n}\n\n/** Null where the store could not be reached at all. */\nasync function postToStore(payload: SeedPayload): Promise<Response | null> {\n try {\n return await fetch(`${SEED_API_URL}/configs`, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n // Tells the store the configuration came from the CLI rather than a browser.\n \"user-agent\": SEED_USER_AGENT,\n },\n body: JSON.stringify(payload),\n });\n } catch {\n return null;\n }\n}\n\nfunction mintedIdIn(body: unknown): PublishSeedResult {\n if (body === undefined) {\n return { ok: false, error: \"The configuration store returned something that is not JSON.\" };\n }\n\n const minted = mintedSchema.safeParse(body);\n if (!minted.success) {\n return { ok: false, error: \"The configuration store did not return an id for this share.\" };\n }\n\n return { ok: true, id: minted.data.id };\n}\n\n/** Always names the status, and quotes the store's own explanation when it gives one. */\nasync function refusalMessage(response: Response): Promise<string> {\n const failed = `Sharing this configuration failed (HTTP ${response.status})`;\n const refused = `${failed}.`;\n\n if (response.status === CONTRACT_MISMATCH) return `${refused} ${OUT_OF_DATE_AGAINST_STORE}`;\n\n const window = rateLimitWindow(response);\n if (window !== null) return `${failed}: ${LIMIT_REACHED} ${waitOf(window)}.`;\n\n const explanation = explanationOf(response, await refusalBody(response));\n\n return explanation === undefined ? refused : `${refused} The store said: ${explanation}`;\n}\n\n/** Seconds to wait out, or `null` where this is no 429 or its window is unreadable. */\nfunction rateLimitWindow(response: Response): number | null {\n return response.status === RATE_LIMITED ? retryAfterSeconds(response) : null;\n}\n\n/** Minutes round up, so nobody is sent back early. */\nfunction waitOf(seconds: number): string {\n return seconds < SECONDS_PER_MINUTE\n ? plural(seconds, \"second\")\n : plural(Math.ceil(seconds / SECONDS_PER_MINUTE), \"minute\");\n}\n\n/** Not gated on content type: this route refuses as JSON and as plain text. */\nasync function refusalBody(response: Response): Promise<string | undefined> {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n}\n\nfunction jsonOf(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction explanationOf(response: Response, body: string | undefined): string | undefined {\n if (body === undefined) return undefined;\n\n const said = schemaIssuesIn(body) ?? quotableProseIn(response, body);\n\n return said === undefined ? undefined : truncateText(said, EXPLANATION_BUDGET);\n}\n\nfunction schemaIssuesIn(body: string): string | undefined {\n const refusal = refusalSchema.safeParse(jsonOf(body));\n if (!refusal.success) return undefined;\n\n const issues = refusedIssuesSchema.safeParse(jsonOf(refusal.data.error.message));\n if (!issues.success) return undefined;\n\n return issues.data.map(sentenceOf).join(\"; \");\n}\n\n/** Quoted only when it adds something to the status printed beside it. */\nfunction quotableProseIn(response: Response, body: string): string | undefined {\n if (!arrivedAsText(response)) return undefined;\n\n const said = body.trim();\n if (said === \"\") return undefined;\n if (restatesItsOwnStatus(said, response.status)) return undefined;\n\n return said;\n}\n\n/** Case-insensitive: the worker writes sentence case where the reason phrase is title case. */\nfunction restatesItsOwnStatus(said: string, status: number): boolean {\n const reason = STATUS_CODES[status];\n\n return reason !== undefined && said.toLowerCase() === reason.toLowerCase();\n}\n\ntype RefusedIssue = z.infer<typeof refusedIssuesSchema>[number];\n\n/** Renders like `formatZodIssue`, which cannot take a plain object read off the wire. */\nfunction sentenceOf(issue: RefusedIssue): string {\n const path = issue.path.join(\".\");\n return path === \"\" ? issue.message : `${path}: ${issue.message}`;\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ScrollAffordance
|
|
4
|
+
} from "./chunk-N33AKFLR.js";
|
|
5
|
+
import {
|
|
6
|
+
SkillAgentSummary
|
|
7
|
+
} from "./chunk-G7NUK3BF.js";
|
|
8
|
+
import {
|
|
9
|
+
ALL_SKILLS_EJECTED_LABEL,
|
|
10
|
+
CLI_COLORS,
|
|
11
|
+
DEFAULT_PUBLIC_SOURCE_NAME,
|
|
12
|
+
EJECT_SOURCE,
|
|
13
|
+
formatSourceDisplayName
|
|
14
|
+
} from "./chunk-MHAQWMNJ.js";
|
|
15
|
+
|
|
16
|
+
// src/cli/components/common/summary-panel.tsx
|
|
17
|
+
import { Box, Text, renderToString } from "ink";
|
|
18
|
+
import "react";
|
|
19
|
+
import { unique } from "remeda";
|
|
20
|
+
|
|
21
|
+
// src/cli/components/hooks/use-panel-scroll.ts
|
|
22
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
23
|
+
import { measureElement as measureElement2, useInput } from "ink";
|
|
24
|
+
|
|
25
|
+
// src/cli/components/hooks/use-measured-height.ts
|
|
26
|
+
import { useRef, useState, useEffect } from "react";
|
|
27
|
+
import { measureElement, useStdout } from "ink";
|
|
28
|
+
function useMeasuredHeight() {
|
|
29
|
+
const ref = useRef(null);
|
|
30
|
+
const [measuredHeight, setMeasuredHeight] = useState(0);
|
|
31
|
+
const { stdout } = useStdout();
|
|
32
|
+
const measure = () => {
|
|
33
|
+
if (!ref.current) return;
|
|
34
|
+
const { height } = measureElement(ref.current);
|
|
35
|
+
setMeasuredHeight((prev) => prev !== height ? height : prev);
|
|
36
|
+
};
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
measure();
|
|
39
|
+
});
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const RETRY_DELAYS_MS = [0, 16, 50];
|
|
42
|
+
const timers = [];
|
|
43
|
+
for (const delay of RETRY_DELAYS_MS) {
|
|
44
|
+
timers.push(setTimeout(measure, delay));
|
|
45
|
+
}
|
|
46
|
+
return () => {
|
|
47
|
+
for (const timer of timers) {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}, []);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
stdout.on("resize", measure);
|
|
54
|
+
return () => {
|
|
55
|
+
stdout.off("resize", measure);
|
|
56
|
+
};
|
|
57
|
+
}, [stdout]);
|
|
58
|
+
return { ref, measuredHeight };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/cli/components/hooks/use-panel-scroll.ts
|
|
62
|
+
function usePanelScroll() {
|
|
63
|
+
const { ref: viewportRef, measuredHeight: viewportHeight } = useMeasuredHeight();
|
|
64
|
+
const contentRef = useRef2(null);
|
|
65
|
+
const [contentHeight, setContentHeight] = useState2(0);
|
|
66
|
+
const [scrollOffset, setScrollOffset] = useState2(0);
|
|
67
|
+
useEffect2(() => {
|
|
68
|
+
if (!contentRef.current) return;
|
|
69
|
+
const { height } = measureElement2(contentRef.current);
|
|
70
|
+
setContentHeight((prev) => Math.max(prev, height));
|
|
71
|
+
});
|
|
72
|
+
const maxScroll = Math.max(0, contentHeight - viewportHeight);
|
|
73
|
+
const hiddenBelow = Math.max(0, maxScroll - scrollOffset);
|
|
74
|
+
useInput((_input, key) => {
|
|
75
|
+
if (key.upArrow) setScrollOffset((prev) => Math.max(0, prev - 1));
|
|
76
|
+
if (key.downArrow) setScrollOffset((prev) => Math.min(maxScroll, prev + 1));
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
viewportRef,
|
|
80
|
+
contentRef,
|
|
81
|
+
contentMarginTop: scrollOffset > 0 ? -scrollOffset : 0,
|
|
82
|
+
hiddenAbove: scrollOffset,
|
|
83
|
+
hiddenBelow
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/cli/components/hooks/use-terminal-dimensions.ts
|
|
88
|
+
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
89
|
+
import { useStdout as useStdout2 } from "ink";
|
|
90
|
+
var DEFAULT_COLUMNS = 80;
|
|
91
|
+
var DEFAULT_ROWS = 24;
|
|
92
|
+
function dimensionsOf(stdout) {
|
|
93
|
+
return {
|
|
94
|
+
columns: stdout.columns || DEFAULT_COLUMNS,
|
|
95
|
+
rows: stdout.rows || DEFAULT_ROWS
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function useTerminalDimensions() {
|
|
99
|
+
const { stdout } = useStdout2();
|
|
100
|
+
const [dimensions, setDimensions] = useState3(() => dimensionsOf(stdout));
|
|
101
|
+
useEffect3(() => {
|
|
102
|
+
const handleResize = () => {
|
|
103
|
+
setDimensions(dimensionsOf(stdout));
|
|
104
|
+
};
|
|
105
|
+
stdout.on("resize", handleResize);
|
|
106
|
+
return () => {
|
|
107
|
+
stdout.off("resize", handleResize);
|
|
108
|
+
};
|
|
109
|
+
}, [stdout]);
|
|
110
|
+
return dimensions;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/cli/components/common/summary-panel.tsx
|
|
114
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
115
|
+
function skillsTheHeaderNames({
|
|
116
|
+
skillConfigs,
|
|
117
|
+
installedSkillConfigs
|
|
118
|
+
}) {
|
|
119
|
+
return skillConfigs.length > 0 ? skillConfigs : installedSkillConfigs ?? [];
|
|
120
|
+
}
|
|
121
|
+
function formatSkillMarketplaces(skillConfigs) {
|
|
122
|
+
if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);
|
|
123
|
+
const marketplaceNames = unique(
|
|
124
|
+
skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE)
|
|
125
|
+
);
|
|
126
|
+
if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;
|
|
127
|
+
return marketplaceNames.map((name) => formatSourceDisplayName(name)).sort().join(" \xB7 ");
|
|
128
|
+
}
|
|
129
|
+
var PanelHeader = ({ sourceNames, stackName }) => /* @__PURE__ */ jsxs(
|
|
130
|
+
Box,
|
|
131
|
+
{
|
|
132
|
+
flexDirection: "column",
|
|
133
|
+
flexShrink: 0,
|
|
134
|
+
borderStyle: "single",
|
|
135
|
+
borderBottom: true,
|
|
136
|
+
borderTop: false,
|
|
137
|
+
borderLeft: false,
|
|
138
|
+
borderRight: false,
|
|
139
|
+
borderColor: CLI_COLORS.NEUTRAL,
|
|
140
|
+
borderBottomDimColor: true,
|
|
141
|
+
paddingBottom: 1,
|
|
142
|
+
marginBottom: 1,
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
|
|
145
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Marketplace" }),
|
|
146
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: sourceNames })
|
|
147
|
+
] }),
|
|
148
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", columnGap: 1, children: [
|
|
149
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, bold: true, children: "Stack" }),
|
|
150
|
+
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: stackName ?? "none" })
|
|
151
|
+
] })
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
var SummaryPanel = ({ stackName, ...summary }) => {
|
|
156
|
+
const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();
|
|
157
|
+
const sourceNames = formatSkillMarketplaces(skillsTheHeaderNames(summary));
|
|
158
|
+
return /* @__PURE__ */ jsxs(
|
|
159
|
+
Box,
|
|
160
|
+
{
|
|
161
|
+
flexDirection: "column",
|
|
162
|
+
flexGrow: 1,
|
|
163
|
+
flexBasis: 0,
|
|
164
|
+
borderStyle: "single",
|
|
165
|
+
borderColor: CLI_COLORS.NEUTRAL,
|
|
166
|
+
paddingX: 2,
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsx(Box, { ref: viewportRef, flexDirection: "column", flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsxs(Box, { ref: contentRef, flexDirection: "column", flexShrink: 0, marginTop: contentMarginTop, children: [
|
|
169
|
+
/* @__PURE__ */ jsx(PanelHeader, { sourceNames, stackName }),
|
|
170
|
+
/* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(SkillAgentSummary, { ...summary }) })
|
|
171
|
+
] }) }),
|
|
172
|
+
/* @__PURE__ */ jsx(ScrollAffordance, { hiddenAbove, hiddenBelow })
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
function summaryPanelText(props, columns = dimensionsOf(process.stdout).columns) {
|
|
178
|
+
return renderToString(/* @__PURE__ */ jsx(SummaryPanel, { ...props }), { columns });
|
|
179
|
+
}
|
|
180
|
+
function summaryPanelBlock(panel, linesUnder, statements) {
|
|
181
|
+
return [
|
|
182
|
+
summaryPanelText(panel),
|
|
183
|
+
...linesUnder,
|
|
184
|
+
...statements.flatMap((statement) => ["", statement]),
|
|
185
|
+
""
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export {
|
|
190
|
+
useTerminalDimensions,
|
|
191
|
+
SummaryPanel,
|
|
192
|
+
summaryPanelText,
|
|
193
|
+
summaryPanelBlock
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=chunk-Q6WRR4BN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/components/common/summary-panel.tsx","../src/cli/components/hooks/use-panel-scroll.ts","../src/cli/components/hooks/use-measured-height.ts","../src/cli/components/hooks/use-terminal-dimensions.ts"],"sourcesContent":["import { Box, Text, renderToString } from \"ink\";\nimport React from \"react\";\nimport { unique } from \"remeda\";\nimport {\n ALL_SKILLS_EJECTED_LABEL,\n CLI_COLORS,\n DEFAULT_PUBLIC_SOURCE_NAME,\n EJECT_SOURCE,\n formatSourceDisplayName,\n} from \"../../consts.js\";\nimport type { SkillConfig } from \"../../types/config.js\";\nimport { usePanelScroll } from \"../hooks/use-panel-scroll.js\";\nimport { dimensionsOf } from \"../hooks/use-terminal-dimensions.js\";\nimport { ScrollAffordance } from \"./scroll-affordance.js\";\nimport { SkillAgentSummary, type SkillAgentSummaryProps } from \"./skill-agent-summary.js\";\n\nexport type SummaryPanelProps = SkillAgentSummaryProps & {\n /** `undefined` when the configuration was built from no stack. */\n stackName: string | undefined;\n};\n\n/**\n * The skills the panel leaves in place; leaving none, as an uninstall does, those it removes. The\n * default marketplace is only for a panel with no skill either way.\n */\nfunction skillsTheHeaderNames({\n skillConfigs,\n installedSkillConfigs,\n}: SkillAgentSummaryProps): SkillConfig[] {\n return skillConfigs.length > 0 ? skillConfigs : (installedSkillConfigs ?? []);\n}\n\n/**\n * No skills shows the default marketplace; all-ejected names none. Tombstoned entries count: the\n * summary below renders them as rows.\n */\nfunction formatSkillMarketplaces(skillConfigs: SkillConfig[]): string {\n if (skillConfigs.length === 0) return formatSourceDisplayName(DEFAULT_PUBLIC_SOURCE_NAME);\n\n const marketplaceNames = unique(\n skillConfigs.map((config) => config.origin).filter((origin) => origin !== EJECT_SOURCE),\n );\n if (marketplaceNames.length === 0) return ALL_SKILLS_EJECTED_LABEL;\n\n return marketplaceNames\n .map((name) => formatSourceDisplayName(name))\n .sort()\n .join(\" · \");\n}\n\ntype PanelHeaderProps = {\n sourceNames: string;\n stackName: string | undefined;\n};\n\n/** `flexShrink={0}`: squeezed by Yoga on a short terminal, its two rows overprint. */\nconst PanelHeader: React.FC<PanelHeaderProps> = ({ sourceNames, stackName }) => (\n <Box\n flexDirection=\"column\"\n flexShrink={0}\n borderStyle=\"single\"\n borderBottom={true}\n borderTop={false}\n borderLeft={false}\n borderRight={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderBottomDimColor\n paddingBottom={1}\n marginBottom={1}\n >\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Marketplace\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{sourceNames}</Text>\n </Box>\n <Box flexDirection=\"row\" columnGap={1}>\n <Text color={CLI_COLORS.WARNING} bold>\n Stack\n </Text>\n <Text color={CLI_COLORS.NEUTRAL}>{stackName ?? \"none\"}</Text>\n </Box>\n </Box>\n);\n\n/** Horizontal padding only: unshrinkable vertical padding starves the viewport on a short terminal. */\nexport const SummaryPanel: React.FC<SummaryPanelProps> = ({ stackName, ...summary }) => {\n const { viewportRef, contentRef, contentMarginTop, hiddenAbove, hiddenBelow } = usePanelScroll();\n\n const sourceNames = formatSkillMarketplaces(skillsTheHeaderNames(summary));\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={0}\n borderStyle=\"single\"\n borderColor={CLI_COLORS.NEUTRAL}\n paddingX={2}\n >\n <Box ref={viewportRef} flexDirection=\"column\" flexGrow={1} flexBasis={0} overflow=\"hidden\">\n <Box ref={contentRef} flexDirection=\"column\" flexShrink={0} marginTop={contentMarginTop}>\n <PanelHeader sourceNames={sourceNames} stackName={stackName} />\n\n <Box width=\"100%\">\n <SkillAgentSummary {...summary} />\n </Box>\n </Box>\n </Box>\n <ScrollAffordance hiddenAbove={hiddenAbove} hiddenBelow={hiddenBelow} />\n </Box>\n );\n};\n\n/**\n * The whole panel as text, drawn once: printed, it scrolls with the terminal like any other line,\n * and a run with no terminal prints the same thing.\n */\nexport function summaryPanelText(\n props: SummaryPanelProps,\n columns: number = dimensionsOf(process.stdout).columns,\n): string {\n return renderToString(<SummaryPanel {...props} />, { columns });\n}\n\n/**\n * What a question shows, or where none is asked, what prints in its place: the panel, the lines\n * under it marking what it cannot show, then each statement after a blank line, and a blank line\n * before what follows.\n */\nexport function summaryPanelBlock(\n panel: SummaryPanelProps,\n linesUnder: readonly string[],\n statements: readonly string[],\n): string[] {\n return [\n summaryPanelText(panel),\n ...linesUnder,\n ...statements.flatMap((statement) => [\"\", statement]),\n \"\",\n ];\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { Ref, RefObject } from \"react\";\nimport { type DOMElement, measureElement, useInput } from \"ink\";\nimport { useMeasuredHeight } from \"./use-measured-height.js\";\n\nexport type UsePanelScrollResult = {\n /** The `overflow=\"hidden\"` box. */\n viewportRef: Ref<DOMElement>;\n contentRef: RefObject<DOMElement | null>;\n contentMarginTop: number;\n hiddenAbove: number;\n hiddenBelow: number;\n};\n\n/** `↑`/`↓` line scrolling for one clipped viewport; hosts add their own `useInput` for other keys. */\nexport function usePanelScroll(): UsePanelScrollResult {\n const { ref: viewportRef, measuredHeight: viewportHeight } = useMeasuredHeight();\n const contentRef = useRef<DOMElement>(null);\n const [contentHeight, setContentHeight] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps -- re-measures every render; layout changes are invisible to React\n useEffect(() => {\n if (!contentRef.current) return;\n const { height } = measureElement(contentRef.current);\n // Yoga under-reports inside a squeezed viewport; trusting that loops the render.\n setContentHeight((prev) => Math.max(prev, height));\n });\n\n // Not returned: gating the clip on contentHeight paints content over the border.\n const maxScroll = Math.max(0, contentHeight - viewportHeight);\n const hiddenBelow = Math.max(0, maxScroll - scrollOffset);\n\n useInput((_input, key) => {\n if (key.upArrow) setScrollOffset((prev) => Math.max(0, prev - 1));\n if (key.downArrow) setScrollOffset((prev) => Math.min(maxScroll, prev + 1));\n });\n\n return {\n viewportRef,\n contentRef,\n contentMarginTop: scrollOffset > 0 ? -scrollOffset : 0,\n hiddenAbove: scrollOffset,\n hiddenBelow,\n };\n}\n","import { useRef, useState, useEffect } from \"react\";\nimport { type DOMElement, measureElement, useStdout } from \"ink\";\n\n/** Attach to a `flexGrow={1}` Box under an ancestor of constrained height; 0 before first layout. */\nexport function useMeasuredHeight(): {\n ref: React.Ref<DOMElement>;\n measuredHeight: number;\n} {\n const ref = useRef<DOMElement>(null);\n const [measuredHeight, setMeasuredHeight] = useState(0);\n const { stdout } = useStdout();\n\n const measure = () => {\n if (!ref.current) return;\n const { height } = measureElement(ref.current);\n setMeasuredHeight((prev) => (prev !== height ? height : prev));\n };\n\n // Every render, so late-mounted refs are picked up.\n useEffect(() => {\n measure();\n });\n\n // Yoga may not have laid out yet on first render, so retry a few times.\n useEffect(() => {\n const RETRY_DELAYS_MS = [0, 16, 50];\n const timers: ReturnType<typeof setTimeout>[] = [];\n\n for (const delay of RETRY_DELAYS_MS) {\n timers.push(setTimeout(measure, delay));\n }\n\n return () => {\n for (const timer of timers) {\n clearTimeout(timer);\n }\n };\n // Mount-only: listing `measure` would re-arm the timers every render.\n }, []);\n\n useEffect(() => {\n stdout.on(\"resize\", measure);\n return () => {\n stdout.off(\"resize\", measure);\n };\n }, [stdout]);\n\n return { ref, measuredHeight };\n}\n","import { useState, useEffect } from \"react\";\nimport { useStdout } from \"ink\";\n\nconst DEFAULT_COLUMNS = 80;\nconst DEFAULT_ROWS = 24;\n\nexport type TerminalDimensions = {\n columns: number;\n rows: number;\n};\n\n/** A stream that is not a terminal reports no size, so it gets the defaults. */\nexport function dimensionsOf(stdout: NodeJS.WriteStream): TerminalDimensions {\n return {\n columns: stdout.columns || DEFAULT_COLUMNS,\n rows: stdout.rows || DEFAULT_ROWS,\n };\n}\n\nexport function useTerminalDimensions(): TerminalDimensions {\n const { stdout } = useStdout();\n\n const [dimensions, setDimensions] = useState<TerminalDimensions>(() => dimensionsOf(stdout));\n\n useEffect(() => {\n const handleResize = () => {\n setDimensions(dimensionsOf(stdout));\n };\n\n stdout.on(\"resize\", handleResize);\n return () => {\n stdout.off(\"resize\", handleResize);\n };\n }, [stdout]);\n\n return dimensions;\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","measureElement","useRef","useState","useEffect","measureElement","useState","useEffect","useStdout"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
execCommand,
|
|
4
4
|
getErrorMessage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WVFBBZEP.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-SPQSNZMM.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
pruneStaleCompiledAgents,
|
|
4
4
|
recompileAgents
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EHJIQDXR.js";
|
|
6
6
|
import {
|
|
7
7
|
agentCodec,
|
|
8
8
|
buildAgentScopeMap,
|
|
@@ -24,17 +24,17 @@ import {
|
|
|
24
24
|
sayingEachWarningOnce,
|
|
25
25
|
skillsDir,
|
|
26
26
|
skillsPathPrefix,
|
|
27
|
-
typedEntries,
|
|
28
|
-
typedKeys,
|
|
29
27
|
verbose
|
|
30
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-WVFBBZEP.js";
|
|
31
29
|
import {
|
|
32
30
|
initializeMatrix,
|
|
33
|
-
matrix
|
|
34
|
-
|
|
31
|
+
matrix,
|
|
32
|
+
typedEntries,
|
|
33
|
+
typedKeys
|
|
34
|
+
} from "./chunk-7OG635DK.js";
|
|
35
35
|
import {
|
|
36
36
|
globalInstallRoot
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-MHAQWMNJ.js";
|
|
38
38
|
|
|
39
39
|
// src/cli/lib/operations/skills/discover-skills.ts
|
|
40
40
|
var NO_LOCAL_SKILLS = { skills: {}, unusableMetadata: [] };
|
|
@@ -274,4 +274,4 @@ export {
|
|
|
274
274
|
removeCompiledAgents,
|
|
275
275
|
compileAgents
|
|
276
276
|
};
|
|
277
|
-
//# sourceMappingURL=chunk-
|
|
277
|
+
//# sourceMappingURL=chunk-VR6QTK5Z.js.map
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileAgents,
|
|
4
4
|
withCatalogueSeatedFor
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VR6QTK5Z.js";
|
|
6
6
|
import {
|
|
7
7
|
loadAgentDefs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ITQF35UQ.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigLoadError,
|
|
11
|
+
EXTRACTED_FIELDS,
|
|
11
12
|
GlobalPairWriteViolation,
|
|
12
13
|
INDENT_STEP,
|
|
13
14
|
assertGateToken,
|
|
@@ -45,19 +46,19 @@ import {
|
|
|
45
46
|
sourceFolderInUse,
|
|
46
47
|
spaces,
|
|
47
48
|
splitConfigByScope,
|
|
48
|
-
typedEntries,
|
|
49
|
-
|
|
50
|
-
typedKeys,
|
|
51
|
-
typedKeys2,
|
|
49
|
+
typedEntries as typedEntries2,
|
|
50
|
+
typedKeys as typedKeys2,
|
|
52
51
|
unionLayout,
|
|
53
52
|
verbose,
|
|
54
53
|
warn,
|
|
55
54
|
withGateToken,
|
|
56
55
|
writeFile
|
|
57
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-WVFBBZEP.js";
|
|
58
57
|
import {
|
|
59
|
-
matrix
|
|
60
|
-
|
|
58
|
+
matrix,
|
|
59
|
+
typedEntries,
|
|
60
|
+
typedKeys
|
|
61
|
+
} from "./chunk-7OG635DK.js";
|
|
61
62
|
import {
|
|
62
63
|
CLI_INVOKE_COMMAND,
|
|
63
64
|
CODEX_MODEL_NAMES,
|
|
@@ -75,7 +76,7 @@ import {
|
|
|
75
76
|
isExclusiveCategory,
|
|
76
77
|
isGlobalTombstone,
|
|
77
78
|
skillDomain
|
|
78
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-MHAQWMNJ.js";
|
|
79
80
|
|
|
80
81
|
// src/cli/lib/operations/source/load-source.ts
|
|
81
82
|
async function loadSource(options) {
|
|
@@ -238,17 +239,26 @@ function typeReference(name) {
|
|
|
238
239
|
}
|
|
239
240
|
function renderAlias(name, rhs) {
|
|
240
241
|
const head = `export type ${name} =`;
|
|
241
|
-
|
|
242
|
-
|
|
242
|
+
switch (rhs.kind) {
|
|
243
|
+
case "plain":
|
|
244
|
+
return renderPlainAlias(head, rhs.members);
|
|
245
|
+
case "sectioned":
|
|
246
|
+
return `${head}
|
|
243
247
|
${renderSectionedUnion(rhs.custom, rhs.marketplace)}`;
|
|
248
|
+
default: {
|
|
249
|
+
const _exhaustive = rhs;
|
|
250
|
+
return _exhaustive;
|
|
251
|
+
}
|
|
244
252
|
}
|
|
245
|
-
|
|
253
|
+
}
|
|
254
|
+
function renderPlainAlias(head, members) {
|
|
255
|
+
const layout = unionLayout(members, {
|
|
246
256
|
headWidth: head.length + " ".length,
|
|
247
257
|
tailWidth: 0,
|
|
248
258
|
bodyIndent: INDENT_STEP
|
|
249
259
|
});
|
|
250
|
-
return layout === "inline" ? `${head} ${flatUnion(
|
|
251
|
-
${renderUnionBody(
|
|
260
|
+
return layout === "inline" ? `${head} ${flatUnion(members)}` : `${head}
|
|
261
|
+
${renderUnionBody(members, layout, INDENT_STEP)}`;
|
|
252
262
|
}
|
|
253
263
|
function renderSectionedUnion(custom, marketplace) {
|
|
254
264
|
if (marketplace.length > 0) {
|
|
@@ -1039,9 +1049,12 @@ var NO_CHANGES = {
|
|
|
1039
1049
|
scalarsChanged: [],
|
|
1040
1050
|
projectsChanged: false
|
|
1041
1051
|
};
|
|
1042
|
-
var
|
|
1052
|
+
var extractedFields = new Set(EXTRACTED_FIELDS);
|
|
1043
1053
|
var REGISTRATION_FIELD = "projects";
|
|
1044
|
-
var EMPTY_MEANS_ABSENT = /* @__PURE__ */ new Set([
|
|
1054
|
+
var EMPTY_MEANS_ABSENT = /* @__PURE__ */ new Set([
|
|
1055
|
+
"stack",
|
|
1056
|
+
"selectedDomains"
|
|
1057
|
+
]);
|
|
1045
1058
|
function isEmptyCollection(value) {
|
|
1046
1059
|
return Array.isArray(value) ? value.length === 0 : isRecord(value) && Object.keys(value).length === 0;
|
|
1047
1060
|
}
|
|
@@ -1062,7 +1075,7 @@ function agentsByName(config) {
|
|
|
1062
1075
|
return new Map(agents.map((agent) => [agent.name, agent]));
|
|
1063
1076
|
}
|
|
1064
1077
|
function scalarKeys(prev, next) {
|
|
1065
|
-
const isScalarKey = (key) => !
|
|
1078
|
+
const isScalarKey = (key) => !extractedFields.has(key) && key !== REGISTRATION_FIELD;
|
|
1066
1079
|
const nextKeys = Object.keys(next).filter(isScalarKey);
|
|
1067
1080
|
const extraPrevKeys = Object.keys(prev).filter(
|
|
1068
1081
|
(key) => isScalarKey(key) && !nextKeys.includes(key)
|
|
@@ -1119,14 +1132,20 @@ function consequenceTier(changes) {
|
|
|
1119
1132
|
if (changes.projectsChanged) return "T3";
|
|
1120
1133
|
return "T4";
|
|
1121
1134
|
}
|
|
1135
|
+
var TIER_CONSEQUENCES = {
|
|
1136
|
+
T1: { needsDeps: true, regeneratesTypes: true, propagates: true },
|
|
1137
|
+
T2: { needsDeps: true, regeneratesTypes: false, propagates: true },
|
|
1138
|
+
T3: { needsDeps: false, regeneratesTypes: false, propagates: false },
|
|
1139
|
+
T4: { needsDeps: false, regeneratesTypes: false, propagates: false }
|
|
1140
|
+
};
|
|
1122
1141
|
function tierNeedsDeps(tier) {
|
|
1123
|
-
return tier
|
|
1142
|
+
return TIER_CONSEQUENCES[tier].needsDeps;
|
|
1124
1143
|
}
|
|
1125
1144
|
function tierRegeneratesTypes(tier) {
|
|
1126
|
-
return tier
|
|
1145
|
+
return TIER_CONSEQUENCES[tier].regeneratesTypes;
|
|
1127
1146
|
}
|
|
1128
1147
|
function tierPropagates(tier) {
|
|
1129
|
-
return tier
|
|
1148
|
+
return TIER_CONSEQUENCES[tier].propagates;
|
|
1130
1149
|
}
|
|
1131
1150
|
|
|
1132
1151
|
// src/cli/lib/config-gate/deps.ts
|
|
@@ -1212,7 +1231,7 @@ var NOTHING_RECOMPILED = {
|
|
|
1212
1231
|
};
|
|
1213
1232
|
async function recompilePropagated(projectDirs, pairsRewritten) {
|
|
1214
1233
|
if (projectDirs.length === 0) return NOTHING_RECOMPILED;
|
|
1215
|
-
const { recompilePropagatedProjectAgents } = await import("./recompile-project-agents-
|
|
1234
|
+
const { recompilePropagatedProjectAgents } = await import("./recompile-project-agents-6G6M2RS6.js");
|
|
1216
1235
|
return recompilePropagatedProjectAgents(projectDirs, pairsRewritten);
|
|
1217
1236
|
}
|
|
1218
1237
|
function pairRewriteSummary(projectDirs, pairsRewritten) {
|
|
@@ -1308,7 +1327,7 @@ async function applyConsequences(globalConfig, changes, deps, provider, currentP
|
|
|
1308
1327
|
function lazyGateDeps(projectDir) {
|
|
1309
1328
|
return {
|
|
1310
1329
|
loadMatrix: async () => {
|
|
1311
|
-
const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-
|
|
1330
|
+
const { loadSkillsMatrixFromSource: loadSkillsMatrixFromSource2 } = await import("./source-loader-W7XCNKNA.js");
|
|
1312
1331
|
const { matrix: matrix2 } = await loadSkillsMatrixFromSource2({
|
|
1313
1332
|
projectDir,
|
|
1314
1333
|
skipExtraSources: true,
|
|
@@ -1317,7 +1336,7 @@ function lazyGateDeps(projectDir) {
|
|
|
1317
1336
|
return matrix2;
|
|
1318
1337
|
},
|
|
1319
1338
|
loadAgents: async () => {
|
|
1320
|
-
const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-
|
|
1339
|
+
const { loadAgentDefs: loadAgentDefs2 } = await import("./load-agent-defs-E67DSYTN.js");
|
|
1321
1340
|
return (await loadAgentDefs2()).agents;
|
|
1322
1341
|
}
|
|
1323
1342
|
};
|
|
@@ -1478,13 +1497,16 @@ function applyMutation(mutation, current) {
|
|
|
1478
1497
|
}
|
|
1479
1498
|
}
|
|
1480
1499
|
}
|
|
1500
|
+
function globalProviderFor(mutation, homeDir) {
|
|
1501
|
+
return mutation.kind === "deregister-project" ? mutation.provider : providerInUse(homeDir);
|
|
1502
|
+
}
|
|
1481
1503
|
function fallbackNameFor(mutation) {
|
|
1482
1504
|
return mutation.kind === "set-source" ? mutation.fallbackName : void 0;
|
|
1483
1505
|
}
|
|
1484
1506
|
async function mutateGlobal(mutation, deps) {
|
|
1485
1507
|
return withGateToken(async () => {
|
|
1486
1508
|
const homeDir = os2.homedir();
|
|
1487
|
-
const provider =
|
|
1509
|
+
const provider = globalProviderFor(mutation, homeDir);
|
|
1488
1510
|
const loadedGlobal = await loadProjectConfigFromDir(homeDir, provider);
|
|
1489
1511
|
if (!loadedGlobal) return report(false, NO_CHANGES);
|
|
1490
1512
|
const current = loadedGlobal.config;
|
|
@@ -1642,4 +1664,4 @@ export {
|
|
|
1642
1664
|
compileAgentsAllScopes,
|
|
1643
1665
|
compileProjectScope
|
|
1644
1666
|
};
|
|
1645
|
-
//# sourceMappingURL=chunk-
|
|
1667
|
+
//# sourceMappingURL=chunk-VSPC74SS.js.map
|