@skillsmith/core 0.12.0 → 0.12.2
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 +166 -1
- package/README.md +7 -8
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts +5 -3
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +23 -33
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.registry-sync.d.ts +28 -0
- package/dist/src/api/client.registry-sync.d.ts.map +1 -0
- package/dist/src/api/client.registry-sync.js +36 -0
- package/dist/src/api/client.registry-sync.js.map +1 -0
- package/dist/src/api/client.test.js +185 -0
- package/dist/src/api/client.test.js.map +1 -1
- package/dist/src/api/client.toSkill.d.ts +16 -0
- package/dist/src/api/client.toSkill.d.ts.map +1 -0
- package/dist/src/api/client.toSkill.js +46 -0
- package/dist/src/api/client.toSkill.js.map +1 -0
- package/dist/src/api/client.types.d.ts +22 -0
- package/dist/src/api/client.types.d.ts.map +1 -1
- package/dist/src/api/index.d.ts +1 -1
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/schemas.d.ts +28 -0
- package/dist/src/api/schemas.d.ts.map +1 -1
- package/dist/src/api/schemas.js +13 -0
- package/dist/src/api/schemas.js.map +1 -1
- package/dist/src/audit/remote-audit.d.ts +85 -0
- package/dist/src/audit/remote-audit.d.ts.map +1 -1
- package/dist/src/audit/remote-audit.js +126 -3
- package/dist/src/audit/remote-audit.js.map +1 -1
- package/dist/src/audit/remote-audit.test.js +217 -1
- package/dist/src/audit/remote-audit.test.js.map +1 -1
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/token-credentials.d.ts +20 -0
- package/dist/src/config/token-credentials.d.ts.map +1 -1
- package/dist/src/config/token-credentials.js +59 -0
- package/dist/src/config/token-credentials.js.map +1 -1
- package/dist/src/config/token-credentials.test.d.ts +3 -0
- package/dist/src/config/token-credentials.test.d.ts.map +1 -1
- package/dist/src/config/token-credentials.test.js +68 -0
- package/dist/src/config/token-credentials.test.js.map +1 -1
- package/dist/src/db/migration-runner.d.ts.map +1 -1
- package/dist/src/db/migration-runner.js +6 -0
- package/dist/src/db/migration-runner.js.map +1 -1
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts +36 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts.map +1 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js +38 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js.map +1 -0
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +3 -1
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/exports/services.d.ts +3 -7
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.install.d.ts +18 -0
- package/dist/src/exports/services.install.d.ts.map +1 -0
- package/dist/src/exports/services.install.js +62 -0
- package/dist/src/exports/services.install.js.map +1 -0
- package/dist/src/exports/services.js +12 -32
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/exports/types.d.ts +1 -1
- package/dist/src/exports/types.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/agent-config-merge.json.d.ts +5 -4
- package/dist/src/install/agent-config-merge.json.d.ts.map +1 -1
- package/dist/src/install/agent-config-merge.json.js +10 -9
- package/dist/src/install/agent-config-merge.json.js.map +1 -1
- package/dist/src/install/agent-config-merge.types.d.ts +11 -1
- package/dist/src/install/agent-config-merge.types.d.ts.map +1 -1
- package/dist/src/install/agent-config-merge.types.js.map +1 -1
- package/dist/src/install/agent-harness-targets.d.ts +30 -2
- package/dist/src/install/agent-harness-targets.d.ts.map +1 -1
- package/dist/src/install/agent-harness-targets.js +17 -0
- package/dist/src/install/agent-harness-targets.js.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.d.ts +28 -3
- package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.js +59 -3
- package/dist/src/install/agent-manifest-path-guard.js.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.test.js +27 -1
- package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -1
- package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts +74 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.js +106 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.js.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js +157 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts +53 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.js +207 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.js.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.js +285 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.d.ts +8 -0
- package/dist/src/install/agent-pack-installer.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.entry.d.ts +120 -3
- package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.entry.js +166 -3
- package/dist/src/install/agent-pack-installer.entry.js.map +1 -1
- package/dist/src/install/agent-pack-installer.js +97 -3
- package/dist/src/install/agent-pack-installer.js.map +1 -1
- package/dist/src/install/agent-pack-installer.types.d.ts +27 -0
- package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.types.js +6 -0
- package/dist/src/install/agent-pack-installer.types.js.map +1 -1
- package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.js +148 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts +18 -7
- package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -1
- package/dist/src/install/agent-pack-uninstaller.js +59 -9
- package/dist/src/install/agent-pack-uninstaller.js.map +1 -1
- package/dist/src/install/agent-pack-uninstaller.test.js +74 -1
- package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -1
- package/dist/src/install/fan-out.d.ts.map +1 -1
- package/dist/src/install/fan-out.js +6 -0
- package/dist/src/install/fan-out.js.map +1 -1
- package/dist/src/install/index.d.ts +2 -0
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +2 -0
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/workspace-scope.d.ts +207 -0
- package/dist/src/install/workspace-scope.d.ts.map +1 -0
- package/dist/src/install/workspace-scope.js +275 -0
- package/dist/src/install/workspace-scope.js.map +1 -0
- package/dist/src/install/workspace-scope.test.d.ts +2 -0
- package/dist/src/install/workspace-scope.test.d.ts.map +1 -0
- package/dist/src/install/workspace-scope.test.js +378 -0
- package/dist/src/install/workspace-scope.test.js.map +1 -0
- package/dist/src/security/__tests__/pathValidation.test.js +30 -1
- package/dist/src/security/__tests__/pathValidation.test.js.map +1 -1
- package/dist/src/services/SubagentGenerator.client-profiles.d.ts +258 -0
- package/dist/src/services/SubagentGenerator.client-profiles.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.client-profiles.js +260 -0
- package/dist/src/services/SubagentGenerator.client-profiles.js.map +1 -0
- package/dist/src/services/SubagentGenerator.d.ts +19 -41
- package/dist/src/services/SubagentGenerator.d.ts.map +1 -1
- package/dist/src/services/SubagentGenerator.helpers.d.ts +64 -0
- package/dist/src/services/SubagentGenerator.helpers.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.helpers.js +228 -0
- package/dist/src/services/SubagentGenerator.helpers.js.map +1 -0
- package/dist/src/services/SubagentGenerator.js +66 -208
- package/dist/src/services/SubagentGenerator.js.map +1 -1
- package/dist/src/services/SubagentGenerator.types.d.ts +45 -0
- package/dist/src/services/SubagentGenerator.types.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.types.js +14 -0
- package/dist/src/services/SubagentGenerator.types.js.map +1 -0
- package/dist/src/services/TransformationService.d.ts +18 -61
- package/dist/src/services/TransformationService.d.ts.map +1 -1
- package/dist/src/services/TransformationService.js +29 -17
- package/dist/src/services/TransformationService.js.map +1 -1
- package/dist/src/services/TransformationService.types.d.ts +74 -0
- package/dist/src/services/TransformationService.types.d.ts.map +1 -0
- package/dist/src/services/TransformationService.types.js +8 -0
- package/dist/src/services/TransformationService.types.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts +5 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js +72 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts +2 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js +61 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.test.js +155 -0
- package/dist/src/services/__tests__/SubagentGenerator.test.js.map +1 -1
- package/dist/src/services/__tests__/TransformationService.test.js +48 -0
- package/dist/src/services/__tests__/TransformationService.test.js.map +1 -1
- package/dist/src/services/agent-pack/agent-pack.test.js +1 -0
- package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.js +10 -3
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -1
- package/dist/src/services/agent-pack/types.d.ts +26 -2
- package/dist/src/services/agent-pack/types.d.ts.map +1 -1
- package/dist/src/services/agent-pack/types.js +13 -0
- package/dist/src/services/agent-pack/types.js.map +1 -1
- package/dist/src/services/agent-tool-profile.d.ts.map +1 -1
- package/dist/src/services/agent-tool-profile.js +7 -0
- package/dist/src/services/agent-tool-profile.js.map +1 -1
- package/dist/src/services/agent-tool-profile.test.js +2 -2
- package/dist/src/services/skill-content-comparison.d.ts +71 -0
- package/dist/src/services/skill-content-comparison.d.ts.map +1 -0
- package/dist/src/services/skill-content-comparison.js +90 -0
- package/dist/src/services/skill-content-comparison.js.map +1 -0
- package/dist/src/services/skill-content-comparison.test.d.ts +6 -0
- package/dist/src/services/skill-content-comparison.test.d.ts.map +1 -0
- package/dist/src/services/skill-content-comparison.test.js +83 -0
- package/dist/src/services/skill-content-comparison.test.js.map +1 -0
- package/dist/src/services/skill-identity-classification.d.ts +202 -0
- package/dist/src/services/skill-identity-classification.d.ts.map +1 -0
- package/dist/src/services/skill-identity-classification.js +295 -0
- package/dist/src/services/skill-identity-classification.js.map +1 -0
- package/dist/src/services/skill-identity-classification.test.d.ts +6 -0
- package/dist/src/services/skill-identity-classification.test.d.ts.map +1 -0
- package/dist/src/services/skill-identity-classification.test.js +314 -0
- package/dist/src/services/skill-identity-classification.test.js.map +1 -0
- package/dist/src/services/skill-installation.content.d.ts.map +1 -1
- package/dist/src/services/skill-installation.content.js +6 -1
- package/dist/src/services/skill-installation.content.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.d.ts +8 -15
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +11 -105
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.test.js +106 -1
- package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
- package/dist/src/services/skill-installation.service.js +1 -1
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +33 -0
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-installation.uninstall.d.ts +84 -0
- package/dist/src/services/skill-installation.uninstall.d.ts.map +1 -0
- package/dist/src/services/skill-installation.uninstall.js +252 -0
- package/dist/src/services/skill-installation.uninstall.js.map +1 -0
- package/dist/src/services/skill-manifest.d.ts +41 -0
- package/dist/src/services/skill-manifest.d.ts.map +1 -1
- package/dist/src/services/skill-manifest.js +93 -0
- package/dist/src/services/skill-manifest.js.map +1 -1
- package/dist/src/services/skill-manifest.test.js +27 -0
- package/dist/src/services/skill-manifest.test.js.map +1 -1
- package/dist/src/sync/SyncEngine.d.ts.map +1 -1
- package/dist/src/sync/SyncEngine.js +69 -77
- package/dist/src/sync/SyncEngine.js.map +1 -1
- package/dist/src/telemetry/agent-marker.d.ts +8 -0
- package/dist/src/telemetry/agent-marker.d.ts.map +1 -1
- package/dist/src/telemetry/agent-marker.js +7 -0
- package/dist/src/telemetry/agent-marker.js.map +1 -1
- package/dist/src/telemetry/agent-marker.test.js +7 -1
- package/dist/src/telemetry/agent-marker.test.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +1 -1
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +1 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/wrap.d.ts +6 -0
- package/dist/src/telemetry/wrap.d.ts.map +1 -1
- package/dist/src/telemetry/wrap.js +65 -10
- package/dist/src/telemetry/wrap.js.map +1 -1
- package/dist/src/telemetry/wrap.test.js +81 -1
- package/dist/src/telemetry/wrap.test.js.map +1 -1
- package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts +26 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.js +162 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.js.map +1 -0
- package/dist/src/types/skill.d.ts +9 -1
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/version-check.d.ts +61 -0
- package/dist/src/utils/version-check.d.ts.map +1 -1
- package/dist/src/utils/version-check.js +78 -1
- package/dist/src/utils/version-check.js.map +1 -1
- package/dist/src/utils/version-check.test.js +130 -1
- package/dist/src/utils/version-check.test.js.map +1 -1
- package/dist/tests/db/migration-runner-race.test.js +19 -9
- package/dist/tests/db/migration-runner-race.test.js.map +1 -1
- package/dist/tests/install/fan-out.test.js +27 -0
- package/dist/tests/install/fan-out.test.js.map +1 -1
- package/dist/tests/skill-scanner/allowlist.test.js +7 -1
- package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.abort.test.js +15 -11
- package/dist/tests/sync/SyncEngine.abort.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.status.test.js +1 -1
- package/dist/tests/sync/SyncEngine.status.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.test.d.ts +11 -2
- package/dist/tests/sync/SyncEngine.test.d.ts.map +1 -1
- package/dist/tests/sync/SyncEngine.test.js +164 -13
- package/dist/tests/sync/SyncEngine.test.js.map +1 -1
- package/dist/tests/unit/migrations/migration-v18.test.d.ts +16 -0
- package/dist/tests/unit/migrations/migration-v18.test.d.ts.map +1 -0
- package/dist/tests/unit/migrations/migration-v18.test.js +192 -0
- package/dist/tests/unit/migrations/migration-v18.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.content.test.js +65 -1
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.test.js +9 -8
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/unit/sync-engine.source-aware.test.js +5 -5
- package/dist/tests/unit/sync-engine.source-aware.test.js.map +1 -1
- package/package.json +3 -3
|
@@ -37,13 +37,38 @@
|
|
|
37
37
|
* with one of a dozen known per-harness relative locations" — a tampered
|
|
38
38
|
* manifest can no longer name `/etc/passwd` or `~/.ssh/id_rsa`.
|
|
39
39
|
*
|
|
40
|
+
* SMI-6275 Wave 5 addendum — a SECOND, WORKSPACE-relative allowlist. Every
|
|
41
|
+
* suffix above is relative to `os.homedir()`, which is correct for every
|
|
42
|
+
* OTHER installer target but not for AntiGravity's two workspace-scoped
|
|
43
|
+
* artifacts (the `.agents/skills/skillsmith-agent/SKILL.md` pack copy, ADR-139
|
|
44
|
+
* / SMI-6274 Wave 4, and `.agents/mcp_config.json`, this wave) — both are
|
|
45
|
+
* relative to a WORKSPACE root, which is any directory a user ran
|
|
46
|
+
* `agent install --scope workspace` from, not a statically enumerable set
|
|
47
|
+
* the way `CLIENT_NATIVE_PATHS` is. There is deliberately no attempt to
|
|
48
|
+
* validate "is this THE workspace root this manifest entry was actually
|
|
49
|
+
* written under" (that would require persisting and trusting the workspace
|
|
50
|
+
* root itself, which is exactly the kind of manifest-supplied data this
|
|
51
|
+
* guard exists to NOT trust) — instead the check narrows to the fixed
|
|
52
|
+
* RELATIVE suffix each artifact is known to end with, the same "shrink the
|
|
53
|
+
* blast radius to a known relative location" philosophy as the home-relative
|
|
54
|
+
* check above, applied to a workspace base instead of a home base. This
|
|
55
|
+
* still cannot match `/etc/passwd` or `~/.ssh/id_rsa`; it CAN match any file
|
|
56
|
+
* on disk literally named `.agents/mcp_config.json` (or the SKILL.md pack
|
|
57
|
+
* path) regardless of which workspace — a real but bounded reduction from
|
|
58
|
+
* "any file the process can write," consistent with this module's existing
|
|
59
|
+
* standard.
|
|
60
|
+
*
|
|
40
61
|
* @module @skillsmith/core/install/agent-manifest-path-guard
|
|
41
62
|
*/
|
|
42
63
|
/**
|
|
43
64
|
* True when `path` structurally matches one of the installer's known
|
|
44
|
-
* relative target locations (see module header)
|
|
45
|
-
*
|
|
46
|
-
*
|
|
65
|
+
* relative target locations (see module header) — either HOME-relative
|
|
66
|
+
* (every non-AntiGravity target, plus AntiGravity's own global skills dir
|
|
67
|
+
* entry in `CLIENT_NATIVE_PATHS`) or, per the SMI-6275 Wave 5 addendum,
|
|
68
|
+
* WORKSPACE-relative (AntiGravity's `.agents/`-scoped skill pack and MCP
|
|
69
|
+
* config). Normalizes via `path.resolve` first so a `..`-laden path can't
|
|
70
|
+
* dodge either suffix check by embedding traversal segments before the
|
|
71
|
+
* matched tail.
|
|
47
72
|
*/
|
|
48
73
|
export declare function isAllowedManifestEntryPath(path: string): boolean;
|
|
49
74
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-manifest-path-guard.d.ts","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent-manifest-path-guard.d.ts","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAoFH;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAShE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAIvE"}
|
|
@@ -37,6 +37,27 @@
|
|
|
37
37
|
* with one of a dozen known per-harness relative locations" — a tampered
|
|
38
38
|
* manifest can no longer name `/etc/passwd` or `~/.ssh/id_rsa`.
|
|
39
39
|
*
|
|
40
|
+
* SMI-6275 Wave 5 addendum — a SECOND, WORKSPACE-relative allowlist. Every
|
|
41
|
+
* suffix above is relative to `os.homedir()`, which is correct for every
|
|
42
|
+
* OTHER installer target but not for AntiGravity's two workspace-scoped
|
|
43
|
+
* artifacts (the `.agents/skills/skillsmith-agent/SKILL.md` pack copy, ADR-139
|
|
44
|
+
* / SMI-6274 Wave 4, and `.agents/mcp_config.json`, this wave) — both are
|
|
45
|
+
* relative to a WORKSPACE root, which is any directory a user ran
|
|
46
|
+
* `agent install --scope workspace` from, not a statically enumerable set
|
|
47
|
+
* the way `CLIENT_NATIVE_PATHS` is. There is deliberately no attempt to
|
|
48
|
+
* validate "is this THE workspace root this manifest entry was actually
|
|
49
|
+
* written under" (that would require persisting and trusting the workspace
|
|
50
|
+
* root itself, which is exactly the kind of manifest-supplied data this
|
|
51
|
+
* guard exists to NOT trust) — instead the check narrows to the fixed
|
|
52
|
+
* RELATIVE suffix each artifact is known to end with, the same "shrink the
|
|
53
|
+
* blast radius to a known relative location" philosophy as the home-relative
|
|
54
|
+
* check above, applied to a workspace base instead of a home base. This
|
|
55
|
+
* still cannot match `/etc/passwd` or `~/.ssh/id_rsa`; it CAN match any file
|
|
56
|
+
* on disk literally named `.agents/mcp_config.json` (or the SKILL.md pack
|
|
57
|
+
* path) regardless of which workspace — a real but bounded reduction from
|
|
58
|
+
* "any file the process can write," consistent with this module's existing
|
|
59
|
+
* standard.
|
|
60
|
+
*
|
|
40
61
|
* @module @skillsmith/core/install/agent-manifest-path-guard
|
|
41
62
|
*/
|
|
42
63
|
import { homedir } from 'node:os';
|
|
@@ -44,7 +65,9 @@ import { join, relative, resolve, sep } from 'node:path';
|
|
|
44
65
|
import { AGENT_PACK_SKILL_NAME } from '../services/agent-pack/index.js';
|
|
45
66
|
import { AGENT_HOOK_TARGETS, AGENT_MCP_TARGETS, AGENT_SHIM_TARGETS, } from './agent-harness-targets.js';
|
|
46
67
|
import { getAgentInstallBackupsDir } from './agent-manifest.js';
|
|
68
|
+
import { ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS } from './agent-pack-installer.antigravity-mcp.js';
|
|
47
69
|
import { CLIENT_NATIVE_PATHS } from './paths.js';
|
|
70
|
+
import { CLIENT_WORKSPACE_SEGMENTS } from './workspace-scope.js';
|
|
48
71
|
/** Relative-to-`os.homedir()` suffix for every path the installer can ever write. */
|
|
49
72
|
function computeAllowedPathSuffixes() {
|
|
50
73
|
const suffixes = new Set();
|
|
@@ -82,11 +105,40 @@ function allowedPathSuffixes() {
|
|
|
82
105
|
cachedSuffixes = computeAllowedPathSuffixes();
|
|
83
106
|
return cachedSuffixes;
|
|
84
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Relative-to-WORKSPACE-ROOT suffix for AntiGravity's two workspace-scoped
|
|
110
|
+
* artifacts (SMI-6275 Wave 5 addendum — see module header). Both segments
|
|
111
|
+
* are sourced from the same constants the writers themselves use
|
|
112
|
+
* (`CLIENT_WORKSPACE_SEGMENTS.antigravity`, `AGENT_PACK_SKILL_NAME`,
|
|
113
|
+
* `ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS`) rather than hand-duplicated
|
|
114
|
+
* literals, so this allowlist can never silently drift from what
|
|
115
|
+
* `installAgentPack` actually writes.
|
|
116
|
+
*/
|
|
117
|
+
function computeAllowedWorkspaceRelativeSuffixes() {
|
|
118
|
+
const suffixes = new Set();
|
|
119
|
+
const antigravitySkillsSegments = CLIENT_WORKSPACE_SEGMENTS.antigravity;
|
|
120
|
+
if (antigravitySkillsSegments) {
|
|
121
|
+
suffixes.add(join(...antigravitySkillsSegments, AGENT_PACK_SKILL_NAME, 'SKILL.md'));
|
|
122
|
+
}
|
|
123
|
+
suffixes.add(join(...ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS));
|
|
124
|
+
return suffixes;
|
|
125
|
+
}
|
|
126
|
+
let cachedWorkspaceRelativeSuffixes = null;
|
|
127
|
+
function allowedWorkspaceRelativeSuffixes() {
|
|
128
|
+
if (!cachedWorkspaceRelativeSuffixes) {
|
|
129
|
+
cachedWorkspaceRelativeSuffixes = computeAllowedWorkspaceRelativeSuffixes();
|
|
130
|
+
}
|
|
131
|
+
return cachedWorkspaceRelativeSuffixes;
|
|
132
|
+
}
|
|
85
133
|
/**
|
|
86
134
|
* True when `path` structurally matches one of the installer's known
|
|
87
|
-
* relative target locations (see module header)
|
|
88
|
-
*
|
|
89
|
-
*
|
|
135
|
+
* relative target locations (see module header) — either HOME-relative
|
|
136
|
+
* (every non-AntiGravity target, plus AntiGravity's own global skills dir
|
|
137
|
+
* entry in `CLIENT_NATIVE_PATHS`) or, per the SMI-6275 Wave 5 addendum,
|
|
138
|
+
* WORKSPACE-relative (AntiGravity's `.agents/`-scoped skill pack and MCP
|
|
139
|
+
* config). Normalizes via `path.resolve` first so a `..`-laden path can't
|
|
140
|
+
* dodge either suffix check by embedding traversal segments before the
|
|
141
|
+
* matched tail.
|
|
90
142
|
*/
|
|
91
143
|
export function isAllowedManifestEntryPath(path) {
|
|
92
144
|
const normalized = resolve(path);
|
|
@@ -94,6 +146,10 @@ export function isAllowedManifestEntryPath(path) {
|
|
|
94
146
|
if (normalized.endsWith(sep + suffix) || normalized === suffix)
|
|
95
147
|
return true;
|
|
96
148
|
}
|
|
149
|
+
for (const suffix of allowedWorkspaceRelativeSuffixes()) {
|
|
150
|
+
if (normalized.endsWith(sep + suffix))
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
97
153
|
return false;
|
|
98
154
|
}
|
|
99
155
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-manifest-path-guard.js","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent-manifest-path-guard.js","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* (SMI-5456 governance follow-up, code review 2026-07-01).
|
|
4
4
|
* @module @skillsmith/core/install/agent-manifest-path-guard.test
|
|
5
5
|
*/
|
|
6
|
-
import { homedir } from 'node:os';
|
|
6
|
+
import { homedir, tmpdir } from 'node:os';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { describe, expect, it } from 'vitest';
|
|
9
9
|
import { AGENT_INSTALL_DIR_ENV_VAR, getAgentInstallBackupsDir } from './agent-manifest.js';
|
|
@@ -40,6 +40,32 @@ describe('isAllowedManifestEntryPath', () => {
|
|
|
40
40
|
it('rejects a bare directory that only partially matches (no filename)', () => {
|
|
41
41
|
expect(isAllowedManifestEntryPath(join(homedir(), '.claude', 'skills'))).toBe(false);
|
|
42
42
|
});
|
|
43
|
+
// SMI-6275 Wave 5: AntiGravity's two artifacts are WORKSPACE-relative, not
|
|
44
|
+
// HOME-relative — a separate allowlist branch (module header addendum).
|
|
45
|
+
describe('AntiGravity workspace-relative artifacts (SMI-6275 Wave 5)', () => {
|
|
46
|
+
const workspaceRoot = join(tmpdir(), 'skillsmith-guard-test-workspace');
|
|
47
|
+
it('allows the workspace-scoped skill pack path under ANY workspace root', () => {
|
|
48
|
+
expect(isAllowedManifestEntryPath(join(workspaceRoot, '.agents', 'skills', 'skillsmith-agent', 'SKILL.md'))).toBe(true);
|
|
49
|
+
// A DIFFERENT workspace root — the check is deliberately root-agnostic
|
|
50
|
+
// (any file literally named this way, per any workspace), not tied to
|
|
51
|
+
// one specific resolved root (module header explains why).
|
|
52
|
+
expect(isAllowedManifestEntryPath(join(tmpdir(), 'another-workspace', '.agents', 'skills', 'skillsmith-agent', 'SKILL.md'))).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('allows the workspace-scoped mcp_config.json path under any workspace root', () => {
|
|
55
|
+
expect(isAllowedManifestEntryPath(join(workspaceRoot, '.agents', 'mcp_config.json'))).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
it('rejects a path that merely CONTAINS the mcp_config.json suffix as a substring, not a true path segment', () => {
|
|
58
|
+
expect(isAllowedManifestEntryPath(join(workspaceRoot, 'evil.agents', 'mcp_config.json'))).toBe(false);
|
|
59
|
+
expect(isAllowedManifestEntryPath(join(workspaceRoot, '.agents', 'evil-mcp_config.json'))).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
it('rejects a hand-edited traversal string escaping the intended tail', () => {
|
|
62
|
+
expect(isAllowedManifestEntryPath(`${workspaceRoot}/.agents/mcp_config.json/../../../etc/passwd`)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it('still rejects an arbitrary sensitive path — the workspace-relative branch does not widen the home-relative rejections', () => {
|
|
65
|
+
expect(isAllowedManifestEntryPath('/etc/passwd')).toBe(false);
|
|
66
|
+
expect(isAllowedManifestEntryPath(join(homedir(), '.ssh', 'id_rsa'))).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
43
69
|
});
|
|
44
70
|
describe('isAllowedManifestBackupPath', () => {
|
|
45
71
|
it('allows a path under the current backups directory', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-manifest-path-guard.test.js","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"agent-manifest-path-guard.test.js","sourceRoot":"","sources":["../../../src/install/agent-manifest-path-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AntiGravity-specific MCP registration step for `sklx agent install`
|
|
3
|
+
* (SMI-6275 Wave 5, closing the last unshipped ask of GH#2166).
|
|
4
|
+
*
|
|
5
|
+
* Split out of `agent-pack-installer.harness.ts`'s generic `installMcpConfig`
|
|
6
|
+
* for a STRUCTURAL reason (not just a per-harness-quirk reason like Cursor's
|
|
7
|
+
* split): every other MCP-capable harness's config path is HOME-anchored
|
|
8
|
+
* (`AGENT_MCP_TARGETS`, `agent-harness-targets.ts`) and resolved via
|
|
9
|
+
* `relocateUnderHome()`. AntiGravity's `.agents/mcp_config.json` is
|
|
10
|
+
* WORKSPACE-anchored — relative to the workspace root Wave 4
|
|
11
|
+
* (`workspace-scope.ts`, ADR-139) resolves — so it cannot live in that
|
|
12
|
+
* HOME-anchored `Record` at all, and never goes through `relocateUnderHome()`.
|
|
13
|
+
* This module owns AntiGravity's path resolution + entry-value shape
|
|
14
|
+
* entirely outside that table, mirroring the Cursor precedent
|
|
15
|
+
* (`agent-pack-installer.cursor-mcp.ts`, SMI-6279 Wave 9) for the "give it
|
|
16
|
+
* its own file" convention while differing in WHY: Cursor's shape/key both
|
|
17
|
+
* diverge from the shared convention; AntiGravity's shape and key both MATCH
|
|
18
|
+
* the shared convention (see {@link ANTIGRAVITY_MCP_ENTRY_KEY} and
|
|
19
|
+
* `buildAntigravityMcpEntryValue()` in `agent-pack-installer.entry.ts}) — only
|
|
20
|
+
* its PATH RESOLUTION diverges structurally.
|
|
21
|
+
*
|
|
22
|
+
* ## Schema verification (SMI-6275 Wave 5 Step 2 point 5)
|
|
23
|
+
*
|
|
24
|
+
* Confidence: **HIGH**. Verified 2026-08-30 via live web search against two
|
|
25
|
+
* canonical Google sources (antigravity.google/docs/ide/mcp/ and
|
|
26
|
+
* antigravity.google/docs/cli/mcp/), corroborated by two independent
|
|
27
|
+
* third-party write-ups (a Google Cloud Community/Medium walkthrough and a
|
|
28
|
+
* Composio how-to guide):
|
|
29
|
+
* - Path: `.agents/mcp_config.json`, workspace-local, discovered
|
|
30
|
+
* automatically by "the SDK" (AntiGravity's own phrasing) — sibling to
|
|
31
|
+
* the GLOBAL `~/.gemini/config/mcp_config.json` (itself a sibling of
|
|
32
|
+
* `CLIENT_NATIVE_PATHS.antigravity`'s `~/.gemini/config/skills`, `paths.ts`).
|
|
33
|
+
* Matches `docs/internal/research/smi-5386-opencode-antigravity-skill-dirs.md`'s
|
|
34
|
+
* already-verified `.agents/skills/` sibling convention for the same
|
|
35
|
+
* workspace root.
|
|
36
|
+
* - Schema: a single top-level `mcpServers` object — the SAME
|
|
37
|
+
* `mcpServers`-keyed convention claude-code/copilot/windsurf/hermes
|
|
38
|
+
* already use (NOT OpenCode's distinct `local|remote`-typed shape, NOT
|
|
39
|
+
* Codex's TOML block, NOT Cursor's resolved-binary-path form). Local/
|
|
40
|
+
* command-based servers are defined with `command` + `args` + optional
|
|
41
|
+
* `env` — exactly {@link buildAgentMcpEntryValue}'s existing shape, so
|
|
42
|
+
* `buildAntigravityMcpEntryValue()` composes over it rather than
|
|
43
|
+
* reinventing it.
|
|
44
|
+
* - This is reused, not novel: `mergeJsonMcpEntry()` (`agent-config-merge.json.ts`)
|
|
45
|
+
* already speaks this exact shape for four other harnesses — only the
|
|
46
|
+
* PATH (workspace-anchored) and the entry KEY (package-scoped, matching
|
|
47
|
+
* AntiGravity's own docs snippet — see `ANTIGRAVITY_MCP_ENTRY_KEY`) are
|
|
48
|
+
* new to this wave.
|
|
49
|
+
*
|
|
50
|
+
* @module @skillsmith/core/install/agent-pack-installer.antigravity-mcp
|
|
51
|
+
*/
|
|
52
|
+
import type { HarnessInstallCtx } from './agent-pack-installer.harness.js';
|
|
53
|
+
import type { HarnessInstallReport } from './agent-pack-installer.types.js';
|
|
54
|
+
/**
|
|
55
|
+
* Relative path segments (from the resolved workspace root) to AntiGravity's
|
|
56
|
+
* MCP config file. Exported as a fixed constant — not a hand-duplicated
|
|
57
|
+
* string literal — so `agent-manifest-path-guard.ts`'s uninstall-time
|
|
58
|
+
* allowlist check can validate against the EXACT same shape this module
|
|
59
|
+
* writes, rather than an independently-maintained copy that could drift.
|
|
60
|
+
*/
|
|
61
|
+
export declare const ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS: readonly [".agents", "mcp_config.json"];
|
|
62
|
+
/**
|
|
63
|
+
* Merge AntiGravity's MCP server registration into
|
|
64
|
+
* `<workspaceRoot>/.agents/mcp_config.json` under
|
|
65
|
+
* {@link ANTIGRAVITY_MCP_ENTRY_KEY}.
|
|
66
|
+
*
|
|
67
|
+
* Caller (`agent-pack-installer.ts`) is responsible for having already
|
|
68
|
+
* confirmed `workspaceRoot` is a genuinely resolved AntiGravity workspace
|
|
69
|
+
* scope (via `resolveScopedSkillsDir()`) — this function does no scope
|
|
70
|
+
* resolution or detection of its own, per the "reuse Wave 4's resolver,
|
|
71
|
+
* don't reimplement detection" requirement.
|
|
72
|
+
*/
|
|
73
|
+
export declare function installAntigravityMcpConfig(workspaceRoot: string, ctx: HarnessInstallCtx, report: HarnessInstallReport): void;
|
|
74
|
+
//# sourceMappingURL=agent-pack-installer.antigravity-mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.antigravity-mcp.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.antigravity-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AASH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAA;AAQ3E;;;;;;GAMG;AACH,eAAO,MAAM,wCAAwC,yCAA0C,CAAA;AAE/F;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,oBAAoB,GAC3B,IAAI,CA+BN"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AntiGravity-specific MCP registration step for `sklx agent install`
|
|
3
|
+
* (SMI-6275 Wave 5, closing the last unshipped ask of GH#2166).
|
|
4
|
+
*
|
|
5
|
+
* Split out of `agent-pack-installer.harness.ts`'s generic `installMcpConfig`
|
|
6
|
+
* for a STRUCTURAL reason (not just a per-harness-quirk reason like Cursor's
|
|
7
|
+
* split): every other MCP-capable harness's config path is HOME-anchored
|
|
8
|
+
* (`AGENT_MCP_TARGETS`, `agent-harness-targets.ts`) and resolved via
|
|
9
|
+
* `relocateUnderHome()`. AntiGravity's `.agents/mcp_config.json` is
|
|
10
|
+
* WORKSPACE-anchored — relative to the workspace root Wave 4
|
|
11
|
+
* (`workspace-scope.ts`, ADR-139) resolves — so it cannot live in that
|
|
12
|
+
* HOME-anchored `Record` at all, and never goes through `relocateUnderHome()`.
|
|
13
|
+
* This module owns AntiGravity's path resolution + entry-value shape
|
|
14
|
+
* entirely outside that table, mirroring the Cursor precedent
|
|
15
|
+
* (`agent-pack-installer.cursor-mcp.ts`, SMI-6279 Wave 9) for the "give it
|
|
16
|
+
* its own file" convention while differing in WHY: Cursor's shape/key both
|
|
17
|
+
* diverge from the shared convention; AntiGravity's shape and key both MATCH
|
|
18
|
+
* the shared convention (see {@link ANTIGRAVITY_MCP_ENTRY_KEY} and
|
|
19
|
+
* `buildAntigravityMcpEntryValue()` in `agent-pack-installer.entry.ts}) — only
|
|
20
|
+
* its PATH RESOLUTION diverges structurally.
|
|
21
|
+
*
|
|
22
|
+
* ## Schema verification (SMI-6275 Wave 5 Step 2 point 5)
|
|
23
|
+
*
|
|
24
|
+
* Confidence: **HIGH**. Verified 2026-08-30 via live web search against two
|
|
25
|
+
* canonical Google sources (antigravity.google/docs/ide/mcp/ and
|
|
26
|
+
* antigravity.google/docs/cli/mcp/), corroborated by two independent
|
|
27
|
+
* third-party write-ups (a Google Cloud Community/Medium walkthrough and a
|
|
28
|
+
* Composio how-to guide):
|
|
29
|
+
* - Path: `.agents/mcp_config.json`, workspace-local, discovered
|
|
30
|
+
* automatically by "the SDK" (AntiGravity's own phrasing) — sibling to
|
|
31
|
+
* the GLOBAL `~/.gemini/config/mcp_config.json` (itself a sibling of
|
|
32
|
+
* `CLIENT_NATIVE_PATHS.antigravity`'s `~/.gemini/config/skills`, `paths.ts`).
|
|
33
|
+
* Matches `docs/internal/research/smi-5386-opencode-antigravity-skill-dirs.md`'s
|
|
34
|
+
* already-verified `.agents/skills/` sibling convention for the same
|
|
35
|
+
* workspace root.
|
|
36
|
+
* - Schema: a single top-level `mcpServers` object — the SAME
|
|
37
|
+
* `mcpServers`-keyed convention claude-code/copilot/windsurf/hermes
|
|
38
|
+
* already use (NOT OpenCode's distinct `local|remote`-typed shape, NOT
|
|
39
|
+
* Codex's TOML block, NOT Cursor's resolved-binary-path form). Local/
|
|
40
|
+
* command-based servers are defined with `command` + `args` + optional
|
|
41
|
+
* `env` — exactly {@link buildAgentMcpEntryValue}'s existing shape, so
|
|
42
|
+
* `buildAntigravityMcpEntryValue()` composes over it rather than
|
|
43
|
+
* reinventing it.
|
|
44
|
+
* - This is reused, not novel: `mergeJsonMcpEntry()` (`agent-config-merge.json.ts`)
|
|
45
|
+
* already speaks this exact shape for four other harnesses — only the
|
|
46
|
+
* PATH (workspace-anchored) and the entry KEY (package-scoped, matching
|
|
47
|
+
* AntiGravity's own docs snippet — see `ANTIGRAVITY_MCP_ENTRY_KEY`) are
|
|
48
|
+
* new to this wave.
|
|
49
|
+
*
|
|
50
|
+
* @module @skillsmith/core/install/agent-pack-installer.antigravity-mcp
|
|
51
|
+
*/
|
|
52
|
+
import { join } from 'node:path';
|
|
53
|
+
import { mergeJsonMcpEntry } from './agent-config-merge.json.js';
|
|
54
|
+
import { ANTIGRAVITY_MCP_ENTRY_KEY, buildAntigravityMcpEntryValue, } from './agent-pack-installer.entry.js';
|
|
55
|
+
/** Same predicate as `agent-pack-installer.harness.ts`'s private `mergeSucceeded` — duplicated rather than exported to keep that module's helper private. */
|
|
56
|
+
function mergeSucceeded(status) {
|
|
57
|
+
return status === 'created' || status === 'updated' || status === 'unchanged';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Relative path segments (from the resolved workspace root) to AntiGravity's
|
|
61
|
+
* MCP config file. Exported as a fixed constant — not a hand-duplicated
|
|
62
|
+
* string literal — so `agent-manifest-path-guard.ts`'s uninstall-time
|
|
63
|
+
* allowlist check can validate against the EXACT same shape this module
|
|
64
|
+
* writes, rather than an independently-maintained copy that could drift.
|
|
65
|
+
*/
|
|
66
|
+
export const ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS = ['.agents', 'mcp_config.json'];
|
|
67
|
+
/**
|
|
68
|
+
* Merge AntiGravity's MCP server registration into
|
|
69
|
+
* `<workspaceRoot>/.agents/mcp_config.json` under
|
|
70
|
+
* {@link ANTIGRAVITY_MCP_ENTRY_KEY}.
|
|
71
|
+
*
|
|
72
|
+
* Caller (`agent-pack-installer.ts`) is responsible for having already
|
|
73
|
+
* confirmed `workspaceRoot` is a genuinely resolved AntiGravity workspace
|
|
74
|
+
* scope (via `resolveScopedSkillsDir()`) — this function does no scope
|
|
75
|
+
* resolution or detection of its own, per the "reuse Wave 4's resolver,
|
|
76
|
+
* don't reimplement detection" requirement.
|
|
77
|
+
*/
|
|
78
|
+
export function installAntigravityMcpConfig(workspaceRoot, ctx, report) {
|
|
79
|
+
const path = join(workspaceRoot, ...ANTIGRAVITY_MCP_CONFIG_RELATIVE_SEGMENTS);
|
|
80
|
+
const result = mergeJsonMcpEntry({
|
|
81
|
+
path,
|
|
82
|
+
keyPath: ['mcpServers'],
|
|
83
|
+
entryKey: ANTIGRAVITY_MCP_ENTRY_KEY,
|
|
84
|
+
entryValue: buildAntigravityMcpEntryValue(),
|
|
85
|
+
backupDir: ctx.backupDir,
|
|
86
|
+
force: ctx.force,
|
|
87
|
+
alreadyBackedUpPaths: ctx.backedUpPaths,
|
|
88
|
+
});
|
|
89
|
+
report.mcpConfig = result;
|
|
90
|
+
if (result.status === 'conflict') {
|
|
91
|
+
report.notes.push(`MCP config at ${path} already has a '${ANTIGRAVITY_MCP_ENTRY_KEY}' entry that doesn't look like ours — left untouched. Re-run with --force to overwrite, or edit ${path} manually.`);
|
|
92
|
+
}
|
|
93
|
+
if (result.status === 'error') {
|
|
94
|
+
report.notes.push(`MCP config merge failed at ${path}: ${result.errorMessage}`);
|
|
95
|
+
}
|
|
96
|
+
if (mergeSucceeded(result.status)) {
|
|
97
|
+
ctx.entries.push({
|
|
98
|
+
path,
|
|
99
|
+
kind: 'mcp-config',
|
|
100
|
+
harness: 'antigravity',
|
|
101
|
+
backupPath: result.backupPath,
|
|
102
|
+
executable: false,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=agent-pack-installer.antigravity-mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.antigravity-mcp.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.antigravity-mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAChE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,iCAAiC,CAAA;AAKxC,6JAA6J;AAC7J,SAAS,cAAc,CAAC,MAA6B;IACnD,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,WAAW,CAAA;AAC/E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wCAAwC,GAAG,CAAC,SAAS,EAAE,iBAAiB,CAAU,CAAA;AAE/F;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B,CACzC,aAAqB,EACrB,GAAsB,EACtB,MAA4B;IAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,wCAAwC,CAAC,CAAA;IAE7E,MAAM,MAAM,GAAG,iBAAiB,CAAC;QAC/B,IAAI;QACJ,OAAO,EAAE,CAAC,YAAY,CAAC;QACvB,QAAQ,EAAE,yBAAyB;QACnC,UAAU,EAAE,6BAA6B,EAAE;QAC3C,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,oBAAoB,EAAE,GAAG,CAAC,aAAa;KACxC,CAAC,CAAA;IAEF,MAAM,CAAC,SAAS,GAAG,MAAM,CAAA;IACzB,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CACf,iBAAiB,IAAI,mBAAmB,yBAAyB,mGAAmG,IAAI,YAAY,CACrL,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,IAAI,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;IACjF,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YACf,IAAI;YACJ,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,KAAK;SAClB,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.antigravity-mcp.test.d.ts","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.antigravity-mcp.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AntiGravity `.agents/mcp_config.json` entry-shape + lifecycle coverage
|
|
3
|
+
* (SMI-6275 Wave 5, GH#2166 ask 3).
|
|
4
|
+
*
|
|
5
|
+
* Split from the sibling `agent-pack-installer.workspace-scope.test.ts`
|
|
6
|
+
* (which covers detection/scope-resolution behavior) and
|
|
7
|
+
* `agent-pack-installer.test.ts`/`agent-manifest-path-guard.test.ts`,
|
|
8
|
+
* mirroring this file family's existing `.cursor-mcp.test.ts` sibling
|
|
9
|
+
* convention. Covers the four things Wave 5's own required test names:
|
|
10
|
+
* 1. Entry shape — `@skillsmith/mcp-server` key, `npx` form,
|
|
11
|
+
* `SKILLSMITH_CLIENT=antigravity` + `SKILLSMITH_TOOL_PROFILE=agent`.
|
|
12
|
+
* 2. Idempotency — re-install does not duplicate or corrupt the entry.
|
|
13
|
+
* 3. Conflict/force — a foreign entry at the same key is preserved unless
|
|
14
|
+
* `--force` is passed.
|
|
15
|
+
* 4. Uninstall — removes only Skillsmith-owned keys, restoring any
|
|
16
|
+
* hand-added sibling key untouched (also the regression test for the
|
|
17
|
+
* `agent-manifest-path-guard.ts` workspace-relative allowlist fix this
|
|
18
|
+
* wave adds — without it, `uninstallAgentPack` would silently REJECT
|
|
19
|
+
* every AntiGravity manifest entry as "outside known install targets").
|
|
20
|
+
*
|
|
21
|
+
* @module @skillsmith/core/install/agent-pack-installer.antigravity-mcp.test
|
|
22
|
+
*/
|
|
23
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { tmpdir } from 'node:os';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
27
|
+
import { installAgentPack } from './agent-pack-installer.js';
|
|
28
|
+
import { uninstallAgentPack } from './agent-pack-uninstaller.js';
|
|
29
|
+
import { AGENT_INSTALL_DIR_ENV_VAR } from './agent-manifest.js';
|
|
30
|
+
let homeDir;
|
|
31
|
+
let workspaceDir;
|
|
32
|
+
let manifestDir;
|
|
33
|
+
let prevInstallDirEnv;
|
|
34
|
+
function mcpConfigPath(workspace) {
|
|
35
|
+
return join(workspace, '.agents', 'mcp_config.json');
|
|
36
|
+
}
|
|
37
|
+
function readAntigravityMcpJson(workspace) {
|
|
38
|
+
return JSON.parse(readFileSync(mcpConfigPath(workspace), 'utf-8'));
|
|
39
|
+
}
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
homeDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-home-'));
|
|
42
|
+
workspaceDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-workspace-'));
|
|
43
|
+
mkdirSync(join(workspaceDir, '.git'), { recursive: true });
|
|
44
|
+
manifestDir = mkdtempSync(join(tmpdir(), 'skillsmith-agent-install-manifest-'));
|
|
45
|
+
prevInstallDirEnv = process.env[AGENT_INSTALL_DIR_ENV_VAR];
|
|
46
|
+
process.env[AGENT_INSTALL_DIR_ENV_VAR] = manifestDir;
|
|
47
|
+
});
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
50
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
51
|
+
rmSync(manifestDir, { recursive: true, force: true });
|
|
52
|
+
if (prevInstallDirEnv !== undefined)
|
|
53
|
+
process.env[AGENT_INSTALL_DIR_ENV_VAR] = prevInstallDirEnv;
|
|
54
|
+
else
|
|
55
|
+
delete process.env[AGENT_INSTALL_DIR_ENV_VAR];
|
|
56
|
+
});
|
|
57
|
+
describe('installAgentPack — AntiGravity mcp_config.json entry shape (SMI-6275 Wave 5)', () => {
|
|
58
|
+
it('writes the entry under the @skillsmith/mcp-server key with the npx form + SKILLSMITH_CLIENT=antigravity', () => {
|
|
59
|
+
const result = installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
60
|
+
const doc = readAntigravityMcpJson(workspaceDir);
|
|
61
|
+
const entry = doc.mcpServers['@skillsmith/mcp-server'];
|
|
62
|
+
expect(entry?.command).toBe('npx');
|
|
63
|
+
expect(entry?.args).toEqual(['-y', '@skillsmith/mcp-server']);
|
|
64
|
+
expect(entry?.env?.SKILLSMITH_CLIENT).toBe('antigravity');
|
|
65
|
+
expect(entry?.env?.SKILLSMITH_TOOL_PROFILE).toBe('agent');
|
|
66
|
+
// No stray legacy 'skillsmith'-keyed entry — this is a first-ever
|
|
67
|
+
// implementation, nothing to migrate away from.
|
|
68
|
+
expect(doc.mcpServers.skillsmith).toBeUndefined();
|
|
69
|
+
const report = result.harnessReports.find((r) => r.harness === 'antigravity');
|
|
70
|
+
expect(report?.mcpConfig?.status).toBe('created');
|
|
71
|
+
});
|
|
72
|
+
it('does not regress claude-code’s own entry — still the npx form under the "skillsmith" key, no SKILLSMITH_CLIENT', () => {
|
|
73
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
74
|
+
const claudeDoc = JSON.parse(readFileSync(join(homeDir, '.claude', 'settings.json'), 'utf-8'));
|
|
75
|
+
expect(claudeDoc.mcpServers.skillsmith?.command).toBe('npx');
|
|
76
|
+
expect(claudeDoc.mcpServers.skillsmith?.env?.SKILLSMITH_TOOL_PROFILE).toBe('agent');
|
|
77
|
+
expect(claudeDoc.mcpServers.skillsmith?.env?.SKILLSMITH_CLIENT).toBeUndefined();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('installAgentPack — AntiGravity mcp_config.json idempotency (SMI-6275 Wave 5)', () => {
|
|
81
|
+
it('re-install does not create a duplicate second server entry', () => {
|
|
82
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
83
|
+
const second = installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
84
|
+
const doc = readAntigravityMcpJson(workspaceDir);
|
|
85
|
+
expect(Object.keys(doc.mcpServers)).toEqual(['@skillsmith/mcp-server']);
|
|
86
|
+
const report = second.harnessReports.find((r) => r.harness === 'antigravity');
|
|
87
|
+
expect(report?.mcpConfig?.status).toBe('unchanged');
|
|
88
|
+
});
|
|
89
|
+
it('a second install run leaves the file byte-identical', () => {
|
|
90
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
91
|
+
const afterFirst = readFileSync(mcpConfigPath(workspaceDir), 'utf-8');
|
|
92
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
93
|
+
const afterSecond = readFileSync(mcpConfigPath(workspaceDir), 'utf-8');
|
|
94
|
+
expect(afterSecond).toBe(afterFirst);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('installAgentPack — AntiGravity mcp_config.json conflict + --force (SMI-6275 Wave 5)', () => {
|
|
98
|
+
it('leaves a foreign entry at the same key untouched, reporting a conflict', () => {
|
|
99
|
+
mkdirSync(join(workspaceDir, '.agents'), { recursive: true });
|
|
100
|
+
const foreignEntry = { command: 'some-other-tool', args: ['--flag'] };
|
|
101
|
+
writeFileSync(mcpConfigPath(workspaceDir), JSON.stringify({ mcpServers: { '@skillsmith/mcp-server': foreignEntry } }, null, 2));
|
|
102
|
+
const result = installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
103
|
+
const doc = readAntigravityMcpJson(workspaceDir);
|
|
104
|
+
expect(doc.mcpServers['@skillsmith/mcp-server']).toEqual(foreignEntry);
|
|
105
|
+
const report = result.harnessReports.find((r) => r.harness === 'antigravity');
|
|
106
|
+
expect(report?.mcpConfig?.status).toBe('conflict');
|
|
107
|
+
expect(report?.notes.some((n) => n.includes('--force'))).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it('--force overwrites a foreign entry at the same key', () => {
|
|
110
|
+
mkdirSync(join(workspaceDir, '.agents'), { recursive: true });
|
|
111
|
+
writeFileSync(mcpConfigPath(workspaceDir), JSON.stringify({ mcpServers: { '@skillsmith/mcp-server': { command: 'some-other-tool' } } }, null, 2));
|
|
112
|
+
const result = installAgentPack({
|
|
113
|
+
homeDir,
|
|
114
|
+
cwd: workspaceDir,
|
|
115
|
+
scope: 'workspace',
|
|
116
|
+
force: true,
|
|
117
|
+
});
|
|
118
|
+
const doc = readAntigravityMcpJson(workspaceDir);
|
|
119
|
+
expect(doc.mcpServers['@skillsmith/mcp-server']?.command).toBe('npx');
|
|
120
|
+
const report = result.harnessReports.find((r) => r.harness === 'antigravity');
|
|
121
|
+
expect(report?.mcpConfig?.status).toBe('updated');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe('installAgentPack + uninstallAgentPack — AntiGravity workspace artifacts (SMI-6275 Wave 5)', () => {
|
|
125
|
+
it('uninstall removes the freshly-created skill pack AND mcp_config.json entirely (no manifest-guard rejection)', () => {
|
|
126
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
127
|
+
const skillPackPath = join(workspaceDir, '.agents', 'skills', 'skillsmith-agent', 'SKILL.md');
|
|
128
|
+
expect(existsSync(skillPackPath)).toBe(true);
|
|
129
|
+
expect(existsSync(mcpConfigPath(workspaceDir))).toBe(true);
|
|
130
|
+
const result = uninstallAgentPack({ homeDir });
|
|
131
|
+
// The regression this test guards: without the agent-manifest-path-guard.ts
|
|
132
|
+
// workspace-relative allowlist fix, both paths would land in `rejected`
|
|
133
|
+
// (outside the guard's home-relative-only allowlist) and never actually
|
|
134
|
+
// be deleted.
|
|
135
|
+
expect(result.rejected).toEqual([]);
|
|
136
|
+
expect(result.removed).toContain(skillPackPath);
|
|
137
|
+
expect(result.removed).toContain(mcpConfigPath(workspaceDir));
|
|
138
|
+
expect(existsSync(skillPackPath)).toBe(false);
|
|
139
|
+
expect(existsSync(mcpConfigPath(workspaceDir))).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
it('uninstall restores a hand-added sibling key in mcp_config.json untouched, removing only our own key', () => {
|
|
142
|
+
mkdirSync(join(workspaceDir, '.agents'), { recursive: true });
|
|
143
|
+
const siblingDoc = { mcpServers: { 'my-other-tool': { command: 'foo', args: ['bar'] } } };
|
|
144
|
+
writeFileSync(mcpConfigPath(workspaceDir), JSON.stringify(siblingDoc, null, 2));
|
|
145
|
+
installAgentPack({ homeDir, cwd: workspaceDir, scope: 'workspace' });
|
|
146
|
+
const afterInstall = readAntigravityMcpJson(workspaceDir);
|
|
147
|
+
expect(afterInstall.mcpServers['my-other-tool']).toEqual(siblingDoc.mcpServers['my-other-tool']);
|
|
148
|
+
expect(afterInstall.mcpServers['@skillsmith/mcp-server']).toBeDefined();
|
|
149
|
+
const result = uninstallAgentPack({ homeDir });
|
|
150
|
+
expect(result.rejected).toEqual([]);
|
|
151
|
+
expect(result.restored).toContain(mcpConfigPath(workspaceDir));
|
|
152
|
+
const afterUninstall = readAntigravityMcpJson(workspaceDir);
|
|
153
|
+
expect(afterUninstall.mcpServers['my-other-tool']).toEqual(siblingDoc.mcpServers['my-other-tool']);
|
|
154
|
+
expect(afterUninstall.mcpServers['@skillsmith/mcp-server']).toBeUndefined();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=agent-pack-installer.antigravity-mcp.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-pack-installer.antigravity-mcp.test.js","sourceRoot":"","sources":["../../../src/install/agent-pack-installer.antigravity-mcp.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAE/D,IAAI,OAAe,CAAA;AACnB,IAAI,YAAoB,CAAA;AACxB,IAAI,WAAmB,CAAA;AACvB,IAAI,iBAAqC,CAAA;AASzC,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAA;AACtD,CAAC;AAED,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAsB,CAAA;AACzF,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gCAAgC,CAAC,CAAC,CAAA;IACvE,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qCAAqC,CAAC,CAAC,CAAA;IACjF,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1D,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oCAAoC,CAAC,CAAC,CAAA;IAC/E,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;IAC1D,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,GAAG,WAAW,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACjD,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtD,MAAM,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,IAAI,iBAAiB,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,GAAG,iBAAiB,CAAA;;QAC1F,OAAO,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AACpD,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,8EAA8E,EAAE,GAAG,EAAE;IAC5F,EAAE,CAAC,yGAAyG,EAAE,GAAG,EAAE;QACjH,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QAEnF,MAAM,GAAG,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QAChD,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAA;QACtD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAA;QAC7D,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QACzD,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACzD,kEAAkE;QAClE,gDAAgD;QAChD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAA;QAEjD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,aAAa,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gHAAgH,EAAE,GAAG,EAAE;QACxH,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QAEpE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC1B,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,CAC5C,CAAA;QACtB,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5D,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACnF,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAA;IACjF,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,8EAA8E,EAAE,GAAG,EAAE;IAC5F,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACpE,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QAEnF,MAAM,GAAG,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QAChD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAA;QAEvE,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,aAAa,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACpE,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;QACrE,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACpE,MAAM,WAAW,GAAG,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;QAEtE,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,qFAAqF,EAAE,GAAG,EAAE;IACnG,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7D,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAA;QACrE,aAAa,CACX,aAAa,CAAC,YAAY,CAAC,EAC3B,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,wBAAwB,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CACpF,CAAA;QAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QAEnF,MAAM,GAAG,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QAChD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QAEtE,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,aAAa,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7D,aAAa,CACX,aAAa,CAAC,YAAY,CAAC,EAC3B,IAAI,CAAC,SAAS,CACZ,EAAE,UAAU,EAAE,EAAE,wBAAwB,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAC5E,IAAI,EACJ,CAAC,CACF,CACF,CAAA;QAED,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,OAAO;YACP,GAAG,EAAE,YAAY;YACjB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;QAEF,MAAM,GAAG,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QAChD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrE,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,aAAa,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,2FAA2F,EAAE,GAAG,EAAE;IACzG,EAAE,CAAC,6GAA6G,EAAE,GAAG,EAAE;QACrH,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACpE,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,EAAE,UAAU,CAAC,CAAA;QAC7F,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAE1D,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QAE9C,4EAA4E;QAC5E,wEAAwE;QACxE,wEAAwE;QACxE,cAAc;QACd,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;QAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;QAC7D,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7C,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qGAAqG,EAAE,GAAG,EAAE;QAC7G,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7D,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,EAAE,eAAe,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAA;QACzF,aAAa,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAE/E,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACpE,MAAM,YAAY,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QACzD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAA;QAChG,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAEvE,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACnC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;QAE9D,MAAM,cAAc,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAA;QAC3D,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CACxD,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,CACvC,CAAA;QACD,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAA;IAC7E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|