@canonical/pragma-cli 0.35.0 → 0.37.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/README.md +2 -2
- package/bundled-skills/add-standard/SKILL.md +338 -0
- package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
- package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
- package/bundled-skills/anatomy-author/SKILL.md +1226 -0
- package/bundled-skills/design-auditor/SKILL.md +455 -0
- package/bundled-skills/implement-component/SKILL.md +333 -0
- package/bundled-skills/specify-component/SKILL.md +331 -0
- package/bundled-skills/specify-pattern/SKILL.md +292 -0
- package/dist/package.json +24 -20
- package/dist/pragma.conf.js +266 -34
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/bin.js +1 -1
- package/dist/src/bin.js.map +1 -1
- package/dist/src/capabilities/capabilities/hints.js +1 -1
- package/dist/src/capabilities/capabilities/hints.js.map +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
- package/dist/src/capabilities/create/create.verb.js +2 -1
- package/dist/src/capabilities/create/create.verb.js.map +1 -1
- package/dist/src/capabilities/create/createSurface.generated.js +23 -1
- package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
- package/dist/src/capabilities/create/mount.js +4 -3
- package/dist/src/capabilities/create/mount.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +60 -4
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +8 -8
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
- package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/index.js +6 -6
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js +194 -50
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.render.js +43 -64
- package/dist/src/capabilities/doctor/doctor.render.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.verb.js +6 -2
- package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
- package/dist/src/capabilities/doctor/runChecks.js +14 -11
- package/dist/src/capabilities/doctor/runChecks.js.map +1 -1
- package/dist/src/capabilities/graph/query.render.js +2 -2
- package/dist/src/capabilities/graph/query.render.js.map +1 -1
- package/dist/src/capabilities/info/collectInfo.js +8 -2
- package/dist/src/capabilities/info/collectInfo.js.map +1 -1
- package/dist/src/capabilities/info/info.render.js +6 -2
- package/dist/src/capabilities/info/info.render.js.map +1 -1
- package/dist/src/capabilities/prompt/prompt.render.js +2 -2
- package/dist/src/capabilities/prompt/prompt.render.js.map +1 -1
- package/dist/src/capabilities/setup/buildPlan.js +43 -39
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
- package/dist/src/capabilities/setup/mode.js +2 -2
- package/dist/src/capabilities/setup/operations/index.js +4 -4
- package/dist/src/capabilities/setup/operations/index.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
- package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
- package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupGenerator.js +156 -58
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupLsp.js +136 -38
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupMcp.js +101 -52
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupSkills.js +329 -49
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
- package/dist/src/capabilities/setup/plan.js.map +1 -1
- package/dist/src/capabilities/setup/plan.render.js +144 -66
- package/dist/src/capabilities/setup/plan.render.js.map +1 -1
- package/dist/src/capabilities/setup/setup.render.js +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +165 -63
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/setup/targets.js +122 -51
- package/dist/src/capabilities/setup/targets.js.map +1 -1
- package/dist/src/capabilities/shared/index.js +7 -6
- package/dist/src/capabilities/shared/index.js.map +1 -1
- package/dist/src/capabilities/shared/packageManager.js +300 -54
- package/dist/src/capabilities/shared/packageManager.js.map +1 -1
- package/dist/src/capabilities/skill/discover.js +97 -11
- package/dist/src/capabilities/skill/discover.js.map +1 -1
- package/dist/src/capabilities/skill/render.js +2 -2
- package/dist/src/capabilities/skill/render.js.map +1 -1
- package/dist/src/capabilities/sources/installSkills.js +145 -3
- package/dist/src/capabilities/sources/installSkills.js.map +1 -1
- package/dist/src/capabilities/sources/runUpdate.js +68 -2
- package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
- package/dist/src/capabilities/sources/update.verb.js +3 -3
- package/dist/src/capabilities/sources/update.verb.js.map +1 -1
- package/dist/src/capabilities/upgrade/runUpgrade.js +43 -7
- package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -1
- package/dist/src/capabilities/upgrade/upgrade.render.js +10 -2
- package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -1
- package/dist/src/constants.js +13 -2
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/index.js +11 -2
- package/dist/src/kernel/index.js.map +1 -1
- package/dist/src/kernel/interactivity.js +68 -0
- package/dist/src/kernel/interactivity.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +3 -3
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +63 -12
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +57 -4
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +54 -2
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/applyFilters.js +104 -5
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -1
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +310 -43
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +46 -24
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/globalFlags.js +4 -1
- package/dist/src/kernel/project/cli/globalFlags.js.map +1 -1
- package/dist/src/kernel/project/cli/helpFormat.js +1 -2
- package/dist/src/kernel/project/cli/helpFormat.js.map +1 -1
- package/dist/src/kernel/project/cli/rootHelp.js +42 -9
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +16 -1
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +1 -1
- package/dist/src/kernel/render/style.js +29 -9
- package/dist/src/kernel/render/style.js.map +1 -1
- package/dist/src/kernel/render/vocabulary.js +174 -0
- package/dist/src/kernel/render/vocabulary.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
- package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/read.js +14 -9
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
- package/dist/src/kernel/runtime/loadSession.js +3 -1
- package/dist/src/kernel/runtime/loadSession.js.map +1 -1
- package/dist/src/kernel/runtime/probe.js +1 -1
- package/dist/src/kernel/runtime/probe.js.map +1 -1
- package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
- package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
- package/dist/src/kernel/runtime/refs/resolve.js +9 -3
- package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
- package/dist/src/kernel/spec/emitReference.js +1 -1
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/package.json +24 -20
- package/pragma.conf.ts +272 -34
- package/src/bin.ts +8 -1
- package/src/capabilities/block.parity.test.ts +25 -11
- package/src/capabilities/block.shipped.exec.test.ts +282 -0
- package/src/capabilities/block.tierRank.exec.test.ts +300 -0
- package/src/capabilities/capabilities/hints.ts +1 -1
- package/src/capabilities/colophon/colophon.render.ts +1 -2
- package/src/capabilities/colophon/colophon.test.ts +2 -2
- package/src/capabilities/config/collectConfigShow.test.ts +1 -0
- package/src/capabilities/create/byteEquality.test.ts +28 -1
- package/src/capabilities/create/create.test.ts +1 -0
- package/src/capabilities/create/create.verb.ts +2 -1
- package/src/capabilities/create/createGrammar.test.ts +5 -2
- package/src/capabilities/create/createSurface.generated.ts +23 -1
- package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
- package/src/capabilities/create/mount.ts +3 -3
- package/src/capabilities/distribution.parity.test.ts +4 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +69 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +6 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +8 -8
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
- package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
- package/src/capabilities/doctor/checks/index.ts +6 -6
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
- package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
- package/src/capabilities/doctor/checks/targetHealth.ts +229 -59
- package/src/capabilities/doctor/doctor.render.test.ts +108 -32
- package/src/capabilities/doctor/doctor.render.ts +56 -80
- package/src/capabilities/doctor/doctor.test.ts +247 -35
- package/src/capabilities/doctor/doctor.verb.ts +7 -2
- package/src/capabilities/doctor/runChecks.ts +14 -11
- package/src/capabilities/doctor/types.ts +15 -24
- package/src/capabilities/emptyRecovery.test.ts +10 -2
- package/src/capabilities/graph/query.render.ts +2 -2
- package/src/capabilities/info/collectInfo.ts +8 -1
- package/src/capabilities/info/info.render.ts +6 -2
- package/src/capabilities/info/info.test.ts +37 -1
- package/src/capabilities/info/types.ts +10 -2
- package/src/capabilities/lazy.test.ts +26 -2
- package/src/capabilities/listLookup.shipped.exec.test.ts +340 -0
- package/src/capabilities/prompt/prompt.render.ts +2 -2
- package/src/capabilities/renderVocabularySync.test.ts +82 -0
- package/src/capabilities/resources/resources.test.ts +38 -2
- package/src/capabilities/scopeTypeSync.test.ts +29 -15
- package/src/capabilities/setup/buildPlan.ts +45 -41
- package/src/capabilities/setup/index.ts +1 -1
- package/src/capabilities/setup/mode.ts +2 -2
- package/src/capabilities/setup/operations/index.ts +6 -1
- package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
- package/src/capabilities/setup/operations/setupConfig.ts +7 -2
- package/src/capabilities/setup/operations/setupGenerator.ts +227 -84
- package/src/capabilities/setup/operations/setupLsp.ts +203 -38
- package/src/capabilities/setup/operations/setupMcp.ts +139 -62
- package/src/capabilities/setup/operations/setupSkills.ts +399 -60
- package/src/capabilities/setup/plan.render.ts +171 -76
- package/src/capabilities/setup/plan.ts +17 -12
- package/src/capabilities/setup/setup.mcp.correctness.test.ts +9 -9
- package/src/capabilities/setup/setup.render.test.ts +50 -36
- package/src/capabilities/setup/setup.render.ts +1 -1
- package/src/capabilities/setup/setup.test.ts +1126 -50
- package/src/capabilities/setup/setup.verb.ts +174 -68
- package/src/capabilities/setup/targets.ts +138 -60
- package/src/capabilities/setup/types.ts +10 -18
- package/src/capabilities/shared/index.ts +18 -6
- package/src/capabilities/shared/packageManager.test.ts +421 -6
- package/src/capabilities/shared/packageManager.ts +394 -59
- package/src/capabilities/skill/bundledSkills.test.ts +347 -0
- package/src/capabilities/skill/discover.ts +100 -11
- package/src/capabilities/skill/render.ts +2 -2
- package/src/capabilities/skill/skill.test.ts +17 -4
- package/src/capabilities/sources/installSkills.ts +181 -3
- package/src/capabilities/sources/runUpdate.ts +78 -2
- package/src/capabilities/sources/sources.test.ts +228 -0
- package/src/capabilities/sources/update.verb.ts +3 -3
- package/src/capabilities/surface.test.ts +14 -6
- package/src/capabilities/upgrade/runUpgrade.ts +45 -6
- package/src/capabilities/upgrade/types.ts +10 -2
- package/src/capabilities/upgrade/upgrade.render.ts +9 -2
- package/src/capabilities/upgrade/upgrade.test.ts +72 -0
- package/src/constants.ts +14 -1
- package/src/identity.test.ts +18 -5
- package/src/kernel/completion/entitySource.test.ts +15 -2
- package/src/kernel/completion/safety.test.ts +16 -9
- package/src/kernel/config/defaults.test.ts +19 -3
- package/src/kernel/config/readConfig.test.ts +1 -1
- package/src/kernel/index.ts +11 -2
- package/src/kernel/interactivity.test.ts +76 -0
- package/src/kernel/interactivity.ts +69 -0
- package/src/kernel/packs/compile.test.ts +92 -0
- package/src/kernel/packs/renderPack.ts +3 -3
- package/src/kernel/packs/resolveEntity.test.ts +75 -14
- package/src/kernel/packs/resolveEntity.ts +88 -24
- package/src/kernel/packs/runBodies.ts +84 -19
- package/src/kernel/packs/schema.ts +60 -4
- package/src/kernel/packs/sparql/applyFilters.ts +125 -4
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +327 -45
- package/src/kernel/packs/toolDescription.test.ts +35 -1
- package/src/kernel/packs/types.ts +125 -2
- package/src/kernel/project/cli/buildProgram.test.ts +73 -2
- package/src/kernel/project/cli/buildProgram.ts +8 -1
- package/src/kernel/project/cli/dispatch.test.ts +5 -4
- package/src/kernel/project/cli/dispatch.ts +48 -25
- package/src/kernel/project/cli/globalFlags.ts +4 -1
- package/src/kernel/project/cli/helpFormat.ts +1 -2
- package/src/kernel/project/cli/rootHelp.ts +44 -8
- package/src/kernel/project/mcp/registerVerb.ts +20 -1
- package/src/kernel/render/prefixes.test.ts +2 -0
- package/src/kernel/render/renderers.ts +1 -1
- package/src/kernel/render/style.ts +32 -9
- package/src/kernel/render/vocabulary.ts +276 -0
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +14 -6
- package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
- package/src/kernel/runtime/graphpack/read.ts +14 -12
- package/src/kernel/runtime/loadSession.ts +3 -1
- package/src/kernel/runtime/probe.ts +1 -1
- package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
- package/src/kernel/runtime/refs/parseRef.ts +25 -1
- package/src/kernel/runtime/refs/resolve.ts +9 -3
- package/src/kernel/runtime/types.ts +17 -0
- package/src/kernel/spec/emitReference.ts +1 -1
- package/src/kernel/spec/types.ts +35 -6
- package/src/testing/PARITY_GAPS.ts +9 -3
- package/src/testing/behavioral/docExamples.test.ts +4 -2
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +110 -7
- package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
- package/src/testing/behavioral/journeys.packageStories.test.ts +6 -3
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
- package/src/testing/eval/cases/readNouns.ts +245 -9
- package/src/testing/fixtures/blockGraph.ts +28 -13
- package/src/testing/fixtures/graph/canonical.ts +95 -12
- package/src/testing/helpers/runCli.test.ts +44 -0
- package/src/testing/helpers/runCli.ts +27 -3
- package/dist/src/capabilities/shared/bands.js +0 -16
- package/dist/src/capabilities/shared/bands.js.map +0 -1
- package/src/capabilities/shared/bands.ts +0 -16
|
@@ -1,30 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Storeless install-source
|
|
2
|
+
* Storeless install-source detector, shared by `info`, `upgrade`, and
|
|
3
3
|
* `doctor`'s `pragma version` check.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
14
|
-
/** The package manager from npm's user-agent, else the honest runtime. */
|
|
15
|
-
function packageManager() {
|
|
16
|
-
const agent = process.env.npm_config_user_agent;
|
|
17
|
-
const name = agent?.split("/")[0];
|
|
18
|
-
if (name)
|
|
19
|
-
return name;
|
|
20
|
-
return process.versions.bun ? "bun" : "node";
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Detect how the binary was installed — package manager and scope.
|
|
5
|
+
* Detection is driven by the FILESYSTEM — the resolved entry path, the invoked
|
|
6
|
+
* bin path, and the symlinks between them — not by environment variables. The
|
|
7
|
+
* previous heuristic read `npm_config_user_agent`, which npm/pnpm/yarn/bun set
|
|
8
|
+
* only when THEY run a script; a user typing the bin name in a shell never has
|
|
9
|
+
* it, so on the path that mattered the detector always fell through to the
|
|
10
|
+
* honest runtime and reported `node` for every install. The agent survives
|
|
11
|
+
* only as a last-resort corroboration for a workspace install whose tree
|
|
12
|
+
* carries no other marker.
|
|
24
13
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
14
|
+
* The two paths that matter, and why both are needed:
|
|
15
|
+
*
|
|
16
|
+
* - `import.meta.url` is REALPATH-RESOLVED by the module loader. For a normal
|
|
17
|
+
* install it sits inside `node_modules/<pkg>`; for a linked development
|
|
18
|
+
* install (`npm link` / `bun link`) it has already escaped to the source
|
|
19
|
+
* checkout and contains no `node_modules` at all — which is precisely why an
|
|
20
|
+
* entry-only detector cannot see a link.
|
|
21
|
+
* - `process.argv[1]` preserves the path the user actually invoked, symlinks
|
|
22
|
+
* intact. Walking its link chain finds the `node_modules/<pkg>` entry the
|
|
23
|
+
* bin points through, and whether THAT directory is itself a symlink
|
|
24
|
+
* pointing outside the install root — the linked-install signal. The chain
|
|
25
|
+
* is only trusted when the package directory it names really contains the
|
|
26
|
+
* running module (`realPath` identity check), so a foreign bin on argv[1]
|
|
27
|
+
* (vitest, a wrapper script) never misattributes the install.
|
|
28
|
+
*
|
|
29
|
+
* The manager is identified by path SHAPE (`.bun/`, `.pnpm`/`pnpm`, `.volta`,
|
|
30
|
+
* `.asdf`, yarn's global dir), ephemeral runners by their cache shapes
|
|
31
|
+
* (`_npx`, `bunx-*`, pnpm's `dlx`), and a workspace's manager by the lockfile
|
|
32
|
+
* beside the install root. When no signal is conclusive the detector answers
|
|
33
|
+
* `unknown` — a state with NO update command, because a confidently wrong
|
|
34
|
+
* `npm i -g` is worse than none (against a linked checkout it would overwrite
|
|
35
|
+
* the link to the tree being developed). `pmUpdateCommand` accepts only the
|
|
36
|
+
* {@link GlobalInstall} arm, so offering a command to any other state is a
|
|
37
|
+
* type error, not a convention.
|
|
38
|
+
*
|
|
39
|
+
* Read-only and storeless: a handful of `lstat`/`readlink`/`realpath`/`exists`
|
|
40
|
+
* probes, bounded by the link-chain cap — nothing is ever written. The module
|
|
41
|
+
* sits on the fast-path static graph (via the shared barrel), so all probing
|
|
42
|
+
* happens at call time; module load stays inert.
|
|
43
|
+
*
|
|
44
|
+
* Windows note: segment matching splits on both separators, so the SHAPE
|
|
45
|
+
* checks (`managerFromPath`, `ephemeralRunner`) are exercised against
|
|
46
|
+
* win32-style fixtures — but scope containment goes through the host's
|
|
47
|
+
* `node:path` and, like `platformPaths.ts`, the win32 arm is a conventional
|
|
48
|
+
* best guess that has NOT been validated on a real Windows machine.
|
|
27
49
|
*/
|
|
50
|
+
import { existsSync, readlinkSync, realpathSync } from "node:fs";
|
|
51
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
52
|
+
import { fileURLToPath } from "node:url";
|
|
53
|
+
import { INSTALL_UPDATE_GUIDANCE, installSourceLabel, } from "../../kernel/render/vocabulary.js";
|
|
54
|
+
/** Split on both separators, so shape checks read win32 paths too. */
|
|
55
|
+
const splitPath = (path) => path.split(/[\\/]/);
|
|
56
|
+
/** The separator the input path itself uses (win32 fixtures keep theirs). */
|
|
57
|
+
const sepOf = (path) => (path.includes("\\") ? "\\" : "/");
|
|
28
58
|
/**
|
|
29
59
|
* The directory a package was installed INTO — the parent of the `node_modules`
|
|
30
60
|
* holding it, so `/proj/node_modules/@scope/x/dist/bin.js` yields `/proj`.
|
|
@@ -38,9 +68,9 @@ function packageManager() {
|
|
|
38
68
|
* @remarks Exported for its unit test; not part of the package's public surface.
|
|
39
69
|
*/
|
|
40
70
|
export function findInstallRoot(entry) {
|
|
41
|
-
const segments = entry
|
|
71
|
+
const segments = splitPath(entry);
|
|
42
72
|
const index = segments.lastIndexOf("node_modules");
|
|
43
|
-
return index === -1 ? undefined : segments.slice(0, index).join(
|
|
73
|
+
return index === -1 ? undefined : segments.slice(0, index).join(sepOf(entry));
|
|
44
74
|
}
|
|
45
75
|
/**
|
|
46
76
|
* Whether `directory` contains `candidate`, or is it.
|
|
@@ -58,46 +88,262 @@ export function containsPath(directory, candidate) {
|
|
|
58
88
|
const offset = relative(directory, candidate);
|
|
59
89
|
return offset === "" || (!offset.startsWith("..") && !isAbsolute(offset));
|
|
60
90
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
:
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Locate the `node_modules` package a path sits inside — root and package
|
|
93
|
+
* directory, scope-aware. `node_modules/.bin/...` is NOT a package (the shim
|
|
94
|
+
* there is a symlink the chain walk should follow instead).
|
|
95
|
+
*/
|
|
96
|
+
function locatePackage(path) {
|
|
97
|
+
const segments = splitPath(path);
|
|
98
|
+
const index = segments.lastIndexOf("node_modules");
|
|
99
|
+
if (index === -1)
|
|
100
|
+
return undefined;
|
|
101
|
+
const first = segments[index + 1];
|
|
102
|
+
if (first === undefined || first === ".bin")
|
|
103
|
+
return undefined;
|
|
104
|
+
const span = first.startsWith("@") ? 2 : 1;
|
|
105
|
+
if (span === 2 && segments[index + 2] === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
const sep = sepOf(path);
|
|
108
|
+
return {
|
|
109
|
+
root: segments.slice(0, index).join(sep),
|
|
110
|
+
pkgDir: segments.slice(0, index + 1 + span).join(sep),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** The manager a path's shape names, or `undefined` when it names none. */
|
|
114
|
+
export function managerFromPath(path) {
|
|
115
|
+
const segments = splitPath(path).map((s) => s.toLowerCase());
|
|
116
|
+
const has = (name) => segments.includes(name);
|
|
117
|
+
if (has(".bun"))
|
|
118
|
+
return "bun";
|
|
119
|
+
if (has(".pnpm") || has("pnpm"))
|
|
120
|
+
return "pnpm";
|
|
121
|
+
if (has(".volta") ||
|
|
122
|
+
segments.some((s, i) => s === "volta" && segments[i + 1] === "tools")) {
|
|
123
|
+
return "volta";
|
|
124
|
+
}
|
|
125
|
+
// asdf/nvm host an ordinary npm global tree inside a versioned node install.
|
|
126
|
+
if (has(".asdf") || has(".nvm"))
|
|
127
|
+
return "npm";
|
|
128
|
+
const yarn = segments.findIndex((s) => s === "yarn" || s === ".yarn");
|
|
129
|
+
if (yarn !== -1 && segments.indexOf("global", yarn) !== -1)
|
|
130
|
+
return "yarn";
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The ephemeral runner a path's cache shape names, if any.
|
|
135
|
+
*
|
|
136
|
+
* Each pattern is anchored to the runner's ACTUAL cache layout, not to a bare
|
|
137
|
+
* directory name appearing anywhere in the path. A loose match reclassifies an
|
|
138
|
+
* ordinary project — `/work/dlx/app`, or anything under a directory someone
|
|
139
|
+
* named `_npx` — as ephemeral, and because that verdict is reached BEFORE the
|
|
140
|
+
* workspace containment check it wins even when a lockfile sits beside the
|
|
141
|
+
* root. The failure is quiet rather than loud: an ephemeral install correctly
|
|
142
|
+
* offers no upgrade command, so the user simply never learns how to update.
|
|
143
|
+
*/
|
|
144
|
+
export function ephemeralRunner(path) {
|
|
145
|
+
const segments = splitPath(path);
|
|
146
|
+
// npx caches at `<npm cache>/_npx/<hash>/…` — `~/.npm` on unix,
|
|
147
|
+
// `%LOCALAPPDATA%\npm-cache` on Windows.
|
|
148
|
+
const npx = segments.indexOf("_npx");
|
|
149
|
+
const npxParent = npx > 0 ? segments[npx - 1] : undefined;
|
|
150
|
+
if (npxParent === ".npm" || npxParent === "npm-cache")
|
|
151
|
+
return "npx";
|
|
152
|
+
// bunx materialises `$TMPDIR/bunx-<uid>-<pkg>@<ver>/…`; requiring the uid
|
|
153
|
+
// keeps a hand-made `bunx-tools` directory from matching.
|
|
154
|
+
if (segments.some((s) => /^bunx-\d+-/.test(s)))
|
|
155
|
+
return "bunx";
|
|
156
|
+
// pnpm caches at `<pnpm cache>/dlx/<hash>/…`.
|
|
157
|
+
const dlx = segments.indexOf("dlx");
|
|
158
|
+
if (dlx > 0 && segments[dlx - 1] === "pnpm")
|
|
159
|
+
return "pnpm dlx";
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
/** The lockfile beside an install root, mapped to its manager. */
|
|
163
|
+
function lockfileManager(root, exists, sep) {
|
|
164
|
+
const beside = (name) => exists(`${root}${sep}${name}`);
|
|
165
|
+
if (beside("bun.lock") || beside("bun.lockb"))
|
|
166
|
+
return "bun";
|
|
167
|
+
if (beside("pnpm-lock.yaml"))
|
|
168
|
+
return "pnpm";
|
|
169
|
+
if (beside("yarn.lock"))
|
|
170
|
+
return "yarn";
|
|
171
|
+
if (beside("package-lock.json"))
|
|
172
|
+
return "npm";
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
/** The manager `npm_config_user_agent` names, when present and recognized. */
|
|
176
|
+
function agentManager(agent) {
|
|
177
|
+
const name = agent?.split("/")[0];
|
|
178
|
+
return name === "npm" || name === "pnpm" || name === "yarn" || name === "bun"
|
|
179
|
+
? name
|
|
180
|
+
: undefined;
|
|
181
|
+
}
|
|
182
|
+
/** The link-chain hop cap — a symlink cycle must not spin the detector. */
|
|
183
|
+
const MAX_LINK_HOPS = 10;
|
|
184
|
+
/**
|
|
185
|
+
* Walk `argv[1]`'s symlink chain to the `node_modules` entry it points
|
|
186
|
+
* through, and trust it only when that package directory really contains the
|
|
187
|
+
* running module. Returns the FIRST chain path inside a package — before the
|
|
188
|
+
* package-level symlink is resolved away, which is where the linked-install
|
|
189
|
+
* signal lives.
|
|
190
|
+
*/
|
|
191
|
+
function resolveInvokedEntry(probe) {
|
|
192
|
+
if (probe.invoked === undefined)
|
|
193
|
+
return undefined;
|
|
194
|
+
let path = resolve(probe.cwd, probe.invoked);
|
|
195
|
+
for (let hop = 0; hop < MAX_LINK_HOPS; hop++) {
|
|
196
|
+
const located = locatePackage(path);
|
|
197
|
+
if (located !== undefined) {
|
|
198
|
+
// Identity check: only OUR package's bin may classify this process.
|
|
199
|
+
const real = probe.realPath(located.pkgDir);
|
|
200
|
+
return real !== undefined && containsPath(real, probe.entry)
|
|
201
|
+
? path
|
|
202
|
+
: undefined;
|
|
203
|
+
}
|
|
204
|
+
const target = probe.readLink(path);
|
|
205
|
+
if (target === undefined)
|
|
206
|
+
return undefined;
|
|
207
|
+
path = resolve(dirname(path), target);
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
const unknownInstall = (runtime) => ({
|
|
212
|
+
kind: "unknown",
|
|
213
|
+
runtime,
|
|
214
|
+
label: installSourceLabel("unknown", runtime),
|
|
215
|
+
});
|
|
216
|
+
/**
|
|
217
|
+
* Classify an install from a captured probe — the PURE core of
|
|
218
|
+
* {@link detectInstallSource}, exercised by the fixture matrix in its test.
|
|
219
|
+
*
|
|
220
|
+
* @param probe - The captured paths, environment, and filesystem readers.
|
|
221
|
+
* @returns The classified install source.
|
|
222
|
+
*/
|
|
223
|
+
export function classifyInstall(probe) {
|
|
224
|
+
const invokedEntry = resolveInvokedEntry(probe);
|
|
225
|
+
const installed = invokedEntry ??
|
|
226
|
+
(locatePackage(probe.entry) !== undefined ? probe.entry : undefined);
|
|
227
|
+
if (installed === undefined)
|
|
228
|
+
return unknownInstall(probe.runtime);
|
|
229
|
+
const located = locatePackage(installed);
|
|
230
|
+
/* v8 ignore next -- `installed` is only set when locatePackage succeeded */
|
|
231
|
+
if (located === undefined)
|
|
232
|
+
return unknownInstall(probe.runtime);
|
|
233
|
+
const { root, pkgDir } = located;
|
|
234
|
+
// A package dir that is a symlink pointing OUTSIDE its install root is a
|
|
235
|
+
// linked development install (`npm link`/`bun link`). Inside the root it is
|
|
236
|
+
// a store or workspace layout (pnpm's `.pnpm`, a monorepo package) — normal.
|
|
237
|
+
const rawTarget = probe.readLink(pkgDir);
|
|
238
|
+
if (rawTarget !== undefined) {
|
|
239
|
+
const target = resolve(dirname(pkgDir), rawTarget);
|
|
240
|
+
if (!containsPath(root, target)) {
|
|
241
|
+
const pm = managerFromPath(installed);
|
|
242
|
+
return {
|
|
243
|
+
kind: "linked",
|
|
244
|
+
...(pm !== undefined ? { pm } : {}),
|
|
245
|
+
target,
|
|
246
|
+
label: installSourceLabel("linked", pm),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const runner = ephemeralRunner(installed);
|
|
251
|
+
if (runner !== undefined) {
|
|
252
|
+
return {
|
|
253
|
+
kind: "ephemeral",
|
|
254
|
+
runner,
|
|
255
|
+
label: installSourceLabel("ephemeral", runner),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
const shaped = managerFromPath(installed);
|
|
259
|
+
if (containsPath(root, resolve(probe.cwd))) {
|
|
260
|
+
// A workspace tree can belong to any manager; the lockfile beside its
|
|
261
|
+
// root is the marker, the user-agent (when a script runner set it) the
|
|
262
|
+
// corroboration of last resort.
|
|
263
|
+
const pm = shaped ??
|
|
264
|
+
lockfileManager(root, probe.exists, sepOf(installed)) ??
|
|
265
|
+
agentManager(probe.userAgent);
|
|
266
|
+
return {
|
|
267
|
+
kind: "workspace",
|
|
268
|
+
...(pm !== undefined ? { pm } : {}),
|
|
269
|
+
root,
|
|
270
|
+
label: installSourceLabel("workspace", pm),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// A global tree with none of the distinctive shapes is npm's: bun, pnpm,
|
|
274
|
+
// volta and yarn all mark their global roots, npm (and nvm/asdf node
|
|
275
|
+
// installs, which npm serves) do not. The user-agent is NOT consulted here —
|
|
276
|
+
// it names whoever ran the script (`bun run …`), not who installed the bin.
|
|
277
|
+
const pm = shaped ?? "npm";
|
|
278
|
+
return { kind: "global", pm, label: installSourceLabel("global", pm) };
|
|
279
|
+
}
|
|
280
|
+
/** Capture the live process into a probe (the only impure code here). */
|
|
281
|
+
function liveProbe() {
|
|
282
|
+
return {
|
|
283
|
+
entry: fileURLToPath(import.meta.url),
|
|
284
|
+
invoked: process.argv[1],
|
|
285
|
+
cwd: process.cwd(),
|
|
286
|
+
userAgent: process.env.npm_config_user_agent,
|
|
287
|
+
runtime: process.versions.bun ? "bun" : "node",
|
|
288
|
+
readLink: (path) => {
|
|
289
|
+
try {
|
|
290
|
+
return readlinkSync(path);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
realPath: (path) => {
|
|
297
|
+
try {
|
|
298
|
+
return realpathSync(path);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
exists: (path) => existsSync(path),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Detect how the binary was installed.
|
|
309
|
+
*
|
|
310
|
+
* @param probe - Injected probe (tests); defaults to the live process.
|
|
311
|
+
* @returns The classified install source.
|
|
312
|
+
* @note Impure by default — reads `import.meta.url`, `process`, and a bounded
|
|
313
|
+
* handful of symlink/realpath/exists probes. Never writes.
|
|
314
|
+
*/
|
|
315
|
+
export function detectInstallSource(probe = liveProbe()) {
|
|
316
|
+
return classifyInstall(probe);
|
|
83
317
|
}
|
|
84
|
-
/** The npm global-update command — also the fallback for an unknown manager. */
|
|
85
|
-
const npmUpdateCommand = (pkg) => `npm i -g ${pkg}`;
|
|
86
318
|
/** The global-update command per package manager (install-style). */
|
|
87
319
|
const PM_UPDATE_COMMAND = {
|
|
88
320
|
bun: (pkg) => `bun add -g ${pkg}`,
|
|
89
|
-
npm:
|
|
321
|
+
npm: (pkg) => `npm i -g ${pkg}`,
|
|
90
322
|
pnpm: (pkg) => `pnpm add -g ${pkg}`,
|
|
91
323
|
yarn: (pkg) => `yarn global add ${pkg}`,
|
|
324
|
+
volta: (pkg) => `volta install ${pkg}`,
|
|
92
325
|
};
|
|
93
326
|
/**
|
|
94
|
-
* The command that updates `pkg
|
|
327
|
+
* The command that updates a GLOBAL install of `pkg`. Accepting only the
|
|
328
|
+
* {@link GlobalInstall} arm is the point: a linked, ephemeral, workspace, or
|
|
329
|
+
* unknown install has no sanctioned command, and asking for one is a type
|
|
330
|
+
* error — {@link updateGuidance} is what those states say instead.
|
|
95
331
|
*
|
|
96
|
-
* @param
|
|
332
|
+
* @param install - The detected global install.
|
|
97
333
|
* @param pkg - The package to update.
|
|
98
|
-
* @returns The shell command
|
|
334
|
+
* @returns The shell command.
|
|
335
|
+
*/
|
|
336
|
+
export function pmUpdateCommand(install, pkg) {
|
|
337
|
+
return PM_UPDATE_COMMAND[install.pm](pkg);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* The honest sentence a command-less install state shows when a newer release
|
|
341
|
+
* exists — see {@link INSTALL_UPDATE_GUIDANCE} for the words.
|
|
342
|
+
*
|
|
343
|
+
* @param install - Any non-global install.
|
|
344
|
+
* @returns The guidance sentence for its state.
|
|
99
345
|
*/
|
|
100
|
-
export function
|
|
101
|
-
return
|
|
346
|
+
export function updateGuidance(install) {
|
|
347
|
+
return INSTALL_UPDATE_GUIDANCE[install.kind];
|
|
102
348
|
}
|
|
103
349
|
//# sourceMappingURL=packageManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../../../src/capabilities/shared/packageManager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../../../src/capabilities/shared/packageManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
* A skill is a folder with a `SKILL.md` carrying YAML frontmatter (`name`,
|
|
5
5
|
* `description`, and the #856 `prompt` flag among others). Skills are discovered
|
|
6
6
|
* from conventional roots — project skills under `<cwd>/.pragma/skills`, which
|
|
7
|
-
* take precedence, then installed skills under `$XDG_DATA_HOME/pragma/skills
|
|
8
|
-
*
|
|
7
|
+
* take precedence, then installed skills under `$XDG_DATA_HOME/pragma/skills`,
|
|
8
|
+
* then the BUNDLED snapshot this package ships (`bundled-skills/`) — with
|
|
9
|
+
* missing files and invalid frontmatter skipped gracefully. Reads only the
|
|
9
10
|
* filesystem, never the graph store, so `skill list`/`lookup` are storeless
|
|
10
11
|
* (needsStore: false).
|
|
11
12
|
*/
|
|
12
|
-
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
13
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
13
14
|
import { homedir } from "node:os";
|
|
14
|
-
import { basename, join } from "node:path";
|
|
15
|
+
import { basename, dirname, join } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
15
17
|
import { BIN_NAME } from "../../constants.js";
|
|
16
18
|
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
17
19
|
/** Parse one YAML scalar (string, boolean, number, or inline array). */
|
|
@@ -105,8 +107,8 @@ export function installedSkillsDir() {
|
|
|
105
107
|
/**
|
|
106
108
|
* The project skills root: `<cwd>/.<bin>/skills` — skills that belong to THIS
|
|
107
109
|
* repository and travel with it. Named separately from {@link skillRoots}
|
|
108
|
-
* because the two roots are also the two setup
|
|
109
|
-
* links this root into the project's harness directories, while the global
|
|
110
|
+
* because the two roots are also the two setup SCOPES: `setup skills --local`
|
|
111
|
+
* links this root into the project's harness directories, while the global scope
|
|
110
112
|
* links {@link installedSkillsDir} into the user-level ones. Mixing them leaks
|
|
111
113
|
* machine state into a repository's directories, or applies one repository's
|
|
112
114
|
* skills machine-wide.
|
|
@@ -114,15 +116,99 @@ export function installedSkillsDir() {
|
|
|
114
116
|
export function projectSkillsDir(cwd) {
|
|
115
117
|
return join(cwd, `.${BIN_NAME}`, "skills");
|
|
116
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* The directory name of the SNAPSHOT of pack skills this package ships, at its
|
|
121
|
+
* own root. Written by `scripts/bundle.ts` and COMMITTED, exactly as
|
|
122
|
+
* `src/kernel/runtime/graphpack/embedded/pack.generated.ts` is — see
|
|
123
|
+
* {@link bundledSkillsDir}.
|
|
124
|
+
*/
|
|
125
|
+
const BUNDLED_SKILLS_DIRNAME = "bundled-skills";
|
|
126
|
+
/**
|
|
127
|
+
* How far above this module the package root can be. `src/capabilities/skill`
|
|
128
|
+
* is three levels up; the emitted `dist/src/capabilities/skill` is four. The
|
|
129
|
+
* bound exists so a tree that is MISSING the artifact stops at the package
|
|
130
|
+
* instead of walking to `/` and adopting an unrelated directory.
|
|
131
|
+
*/
|
|
132
|
+
const BUNDLED_SEARCH_DEPTH = 6;
|
|
133
|
+
/**
|
|
134
|
+
* The BUNDLED-skills root: `<package root>/bundled-skills`, the snapshot of the
|
|
135
|
+
* declared packs' `skills/<name>/` that `scripts/bundle.ts` commits alongside
|
|
136
|
+
* the embedded graph — `undefined` when this build ships none.
|
|
137
|
+
*
|
|
138
|
+
* WHY IT EXISTS. The embedded pack (`pack.generated.ts`) is what lets a fresh
|
|
139
|
+
* install answer `block lookup` offline. The skills came out of the very same
|
|
140
|
+
* `resolvePackage` calls and were left on the build machine's disk, so the same
|
|
141
|
+
* fresh install listed ZERO skills and told the user to run `sources update`
|
|
142
|
+
* first — a network round trip and two commands for something already resolved
|
|
143
|
+
* at release time. This is the skills half of the snapshot the graph has had
|
|
144
|
+
* all along.
|
|
145
|
+
*
|
|
146
|
+
* WHY IT IS FOUND BY WALKING UP rather than by a fixed relative path. `files`
|
|
147
|
+
* ships BOTH `src` and `dist`, and `tsconfig.build.json` sets `rootDir: "."`,
|
|
148
|
+
* so this module runs from `src/capabilities/skill/` in a source or test run
|
|
149
|
+
* and from `dist/src/capabilities/skill/` in the shipped one — the package root
|
|
150
|
+
* is three levels up in one and four in the other, and no single
|
|
151
|
+
* `new URL("../../..")` is right for both. The walk anchors on the artifact's
|
|
152
|
+
* own name sitting NEXT TO a `package.json`, which is true only at the package
|
|
153
|
+
* root: `dist/` carries a `package.json` too (`resolveJsonModule` copies it)
|
|
154
|
+
* but never the snapshot.
|
|
155
|
+
*
|
|
156
|
+
* @returns The bundled root, or `undefined` when no ancestor holds one.
|
|
157
|
+
* @note Impure — stats up to {@link BUNDLED_SEARCH_DEPTH} ancestor directories.
|
|
158
|
+
* Reached from the `__complete` fast path, so it stays `node:fs` /
|
|
159
|
+
* `node:path` / `node:url` only and costs a handful of `stat`s.
|
|
160
|
+
*/
|
|
161
|
+
export function bundledSkillsDir() {
|
|
162
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
163
|
+
for (let up = 0; up < BUNDLED_SEARCH_DEPTH; up += 1) {
|
|
164
|
+
const candidate = join(dir, BUNDLED_SKILLS_DIRNAME);
|
|
165
|
+
if (existsSync(join(dir, "package.json")) && existsSync(candidate)) {
|
|
166
|
+
return candidate;
|
|
167
|
+
}
|
|
168
|
+
const parent = dirname(dir);
|
|
169
|
+
if (parent === dir)
|
|
170
|
+
break;
|
|
171
|
+
dir = parent;
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
117
175
|
/**
|
|
118
176
|
* The conventional roots skills are discovered from, in PRECEDENCE order: the
|
|
119
177
|
* project root (`<cwd>/.<bin>/skills`) FIRST so a project-local skill overrides
|
|
120
178
|
* an installed skill of the same name (`discoverSkills` dedups first-seen-wins),
|
|
121
179
|
* then installed skills under `$XDG_DATA_HOME/<bin>/skills` (where package
|
|
122
|
-
* skills land on `sources update`)
|
|
180
|
+
* skills land on `sources update`), then the BUNDLED snapshot
|
|
181
|
+
* ({@link bundledSkillsDir}).
|
|
182
|
+
*
|
|
183
|
+
* BUNDLED IS LAST, and that order is the whole contract. The snapshot is as old
|
|
184
|
+
* as the release; an installed skill came from a `sources update` the user ran
|
|
185
|
+
* deliberately, and a project skill is the repository's own. So someone who
|
|
186
|
+
* updates gets the CURRENT skill and never the shipped copy, while a fresh
|
|
187
|
+
* install — which has neither of the first two roots — still gets the packs'
|
|
188
|
+
* skills instead of an empty list and a two-command recovery.
|
|
123
189
|
*/
|
|
124
190
|
export function skillRoots(cwd) {
|
|
125
|
-
return [projectSkillsDir(cwd),
|
|
191
|
+
return [projectSkillsDir(cwd), ...globalSkillRoots()];
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The GLOBAL scope's source roots, in precedence order: the INSTALLED root
|
|
195
|
+
* (`sources update`'s output) first, then the BUNDLED snapshot.
|
|
196
|
+
*
|
|
197
|
+
* Named separately from {@link skillRoots} for the reason
|
|
198
|
+
* {@link projectSkillsDir} is: these are the two roots `setup skills --global`
|
|
199
|
+
* links into the user-level harness directories, and `skillRoots` is discovery,
|
|
200
|
+
* which spans both scopes. Reading the project root for the global scope is
|
|
201
|
+
* exactly the cross-scope leak the scope split exists to prevent.
|
|
202
|
+
*
|
|
203
|
+
* A BAND CAN HOLD MORE THAN ONE ROOT, and this is where that became true. The
|
|
204
|
+
* global scope's ownership test and its stale-link sweep therefore range over
|
|
205
|
+
* the SET (see `setup/operations/setupSkills.ts`), never over one path.
|
|
206
|
+
*/
|
|
207
|
+
export function globalSkillRoots() {
|
|
208
|
+
const bundled = bundledSkillsDir();
|
|
209
|
+
return bundled === undefined
|
|
210
|
+
? [installedSkillsDir()]
|
|
211
|
+
: [installedSkillsDir(), bundled];
|
|
126
212
|
}
|
|
127
213
|
/** Immediate subdirectories of `root` (each a candidate skill folder). */
|
|
128
214
|
function subdirs(root) {
|
|
@@ -146,10 +232,10 @@ function subdirs(root) {
|
|
|
146
232
|
* Discover every skill reachable from an EXPLICIT list of roots, in precedence
|
|
147
233
|
* order (first-seen wins on a duplicate name).
|
|
148
234
|
*
|
|
149
|
-
* Split out of {@link discoverSkills} so a caller that owns one
|
|
150
|
-
* exactly that
|
|
235
|
+
* Split out of {@link discoverSkills} so a caller that owns one scope can read
|
|
236
|
+
* exactly that scope's root: `setup skills` links the project root into project
|
|
151
237
|
* harness directories and the installed root into user-level ones, and reading
|
|
152
|
-
* both roots for either
|
|
238
|
+
* both roots for either scope is what used to mix the two.
|
|
153
239
|
*
|
|
154
240
|
* @param roots - The roots to read, in precedence order.
|
|
155
241
|
* @returns Discovered skills, sorted by name; malformed ones are skipped.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../../src/capabilities/skill/discover.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../../src/capabilities/skill/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAoB9C,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAErD,wEAAwE;AACxE,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,OAAO;aACX,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aACZ,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;aAChD,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IACrD,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,uEAAuE;AACvE,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,MAAM,GAAmC,IAAI,CAAC;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACtD,IAAI,QAAQ,IAAI,UAAU,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,MAAM;gBAAE,MAAM,GAAG,EAAE,CAAC;YACzB,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAW,CAAC,GAAG,cAAc,CAC5C,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAC3B,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC;gBAC5B,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAW,CAAC;YAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,UAAU,GAAG,GAAG,CAAC;YACjB,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;gBACjB,MAAM,GAAG,EAAE,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;gBACpC,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,UAAU,IAAI,MAAM;QAAE,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACvE,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,EAAE,EAAE,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,oBAAoB,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACnE,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,OAAO,OAAO,KAAK,SAAS;QAC1B,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,0EAA0E;AAC1E,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,CAAC;aACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aAC/B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACf,IAAI,CAAC;gBACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAwB;IAExB,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC;gBAAE,SAAS;YACzD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,WAAW,EAAE,WAAW,CAAC,WAAW;gBACpC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC;gBACzB,UAAU,EAAE,GAAG;gBACf,WAAW;aACZ,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1B,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -6,12 +6,12 @@ import { BIN_NAME } from "../../constants.js";
|
|
|
6
6
|
const EMPTY_PLAIN = `No skills found.\nSkills come from design-system packs — add one to your config's packs, run \`${BIN_NAME} sources update\`, then \`${BIN_NAME} setup skills\`.`;
|
|
7
7
|
const EMPTY_LLM = `## Skills (0)\n\nNo skills found. Skills come from design-system packs — add one to the project config's packs, run \`${BIN_NAME} sources update\`, then \`${BIN_NAME} setup skills\`.`;
|
|
8
8
|
export const skillListFormatters = {
|
|
9
|
-
// Zero skills: plain stdout stays empty — the guidance is `
|
|
9
|
+
// Zero skills: plain stdout stays empty — the guidance is `notice`,
|
|
10
10
|
// which the dispatcher routes to stderr (exit 0) so a pipe reads no prose.
|
|
11
11
|
plain: (skills) => skills
|
|
12
12
|
.map((s) => `${s.name}${s.frontmatter.prompt ? " (prompt)" : ""} ${s.description}`)
|
|
13
13
|
.join("\n"),
|
|
14
|
-
|
|
14
|
+
notice: (skills) => (skills.length === 0 ? EMPTY_PLAIN : undefined),
|
|
15
15
|
llm: (skills) => skills.length === 0
|
|
16
16
|
? EMPTY_LLM
|
|
17
17
|
: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../src/capabilities/skill/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAK9C,mFAAmF;AACnF,MAAM,WAAW,GAAG,kGAAkG,QAAQ,6BAA6B,QAAQ,kBAAkB,CAAC;AACtL,MAAM,SAAS,GAAG,yHAAyH,QAAQ,6BAA6B,QAAQ,kBAAkB,CAAC;AAE3M,MAAM,CAAC,MAAM,mBAAmB,GAAkC;IAChE,
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../src/capabilities/skill/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAK9C,mFAAmF;AACnF,MAAM,WAAW,GAAG,kGAAkG,QAAQ,6BAA6B,QAAQ,kBAAkB,CAAC;AACtL,MAAM,SAAS,GAAG,yHAAyH,QAAQ,6BAA6B,QAAQ,kBAAkB,CAAC;AAE3M,MAAM,CAAC,MAAM,mBAAmB,GAAkC;IAChE,oEAAoE;IACpE,2EAA2E;IAC3E,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAChB,MAAM;SACH,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAC1E;SACA,IAAI,CAAC,IAAI,CAAC;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,CACd,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC;YACE,cAAc,MAAM,CAAC,MAAM,GAAG;YAC9B,EAAE;YACF,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,CACjF;SACF,CAAC,IAAI,CAAC,IAAI,CAAC;IAClB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAA4B;IAC5D,KAAK,CAAC,KAAK;QACT,MAAM,KAAK,GAAG;YACZ,KAAK,CAAC,IAAI;YACV,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE;YACF,KAAK,KAAK,CAAC,WAAW,EAAE;SACzB,CAAC;QACF,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,KAAK,CAAC,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,GAAG,CAAC,KAAK;QACP,MAAM,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC9D,IAAI,KAAK,CAAC,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;CAChD,CAAC"}
|