sneakoscope 8.1.2 → 8.2.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 +96 -58
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +5 -51
- package/dist/cli/command-manifest-lite.js +2 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/global-mode-router.js +1 -1
- package/dist/cli/install-helpers-codex-lb-config.js +112 -914
- package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
- package/dist/cli/install-helpers-install-support.js +4 -20
- package/dist/cli/install-helpers.js +36 -2716
- package/dist/cli/router.js +9 -9
- package/dist/commands/bridge-command-output.js +111 -0
- package/dist/commands/bridge.js +320 -0
- package/dist/commands/codex-app.js +39 -123
- package/dist/commands/doctor-helpers.js +380 -0
- package/dist/commands/doctor-profile.js +3 -0
- package/dist/commands/doctor.js +114 -873
- package/dist/commands/mad-sks.js +0 -4
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/agents/agent-effort-policy.js +11 -21
- package/dist/core/agents/agent-recursion-guard.js +26 -0
- package/dist/core/agents/agent-runner-codex-exec.js +7 -9
- package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
- package/dist/core/architecture-hardening/state/state-service.js +49 -13
- package/dist/core/auto-review.js +15 -9
- package/dist/core/codex/codex-config-guard.js +8 -0
- package/dist/core/codex-adapter.js +8 -10
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
- package/dist/core/codex-app/codex-app-launcher.js +10 -12
- package/dist/core/codex-app/codex-app-restart.js +10 -12
- package/dist/core/codex-app/menubar/constants.js +2 -5
- package/dist/core/codex-app/menubar/global-install.js +3 -2
- package/dist/core/codex-app/menubar/installer/result.js +23 -0
- package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
- package/dist/core/codex-app/menubar/installer.js +5 -96
- package/dist/core/codex-app/menubar/migration.js +1 -42
- package/dist/core/codex-app/openrouter-provider.js +0 -78
- package/dist/core/codex-app.js +97 -360
- package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
- package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
- package/dist/core/codex-control/codex-task-runner.js +16 -60
- package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
- package/dist/core/codex-exec-output-schema.js +11 -13
- package/dist/core/codex-lb/bridge-contracts.js +2 -0
- package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
- package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
- package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
- package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
- package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
- package/dist/core/codex-lb/capability-runner.js +505 -201
- package/dist/core/codex-lb/codex-lb-env.js +179 -12
- package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
- package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
- package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
- package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
- package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
- package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
- package/dist/core/codex-lb/combined-catalog.js +12 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
- package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
- package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
- package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
- package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
- package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
- package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
- package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
- package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
- package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
- package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
- package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
- package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
- package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
- package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
- package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
- package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
- package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
- package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
- package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
- package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
- package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
- package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
- package/dist/core/codex-lb/desktop-controller.js +2 -1730
- package/dist/core/codex-lb/desktop-service.js +462 -627
- package/dist/core/codex-lb/migration-receipt.js +560 -118
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
- package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
- package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
- package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
- package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
- package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
- package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
- package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
- package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
- package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
- package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
- package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
- package/dist/core/codex-lb/provider-credentials/types.js +1 -0
- package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
- package/dist/core/codex-lb/provider-credentials.js +5 -0
- package/dist/core/codex-lb/provider-registry.js +323 -0
- package/dist/core/codex-lb/provider-route-policy.js +118 -0
- package/dist/core/codex-lb/request-route-resolver.js +172 -0
- package/dist/core/codex-lb/route-index.js +148 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/check-command.js +3 -10
- package/dist/core/commands/gate-result-contract.js +10 -14
- package/dist/core/commands/intent-normalization/normalizer.js +1 -1
- package/dist/core/commands/mad-sks-command.js +2 -6
- package/dist/core/commands/release-command.js +11 -1
- package/dist/core/commands/telegram-command.js +46 -6
- package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
- package/dist/core/doctor/skill-legacy-surface.js +5 -5
- package/dist/core/evidence/v2/evidence-key.js +30 -3
- package/dist/core/feature-fixtures.js +8 -1
- package/dist/core/feature-registry.js +3 -2
- package/dist/core/hooks-runtime/stop-finalization.js +11 -1
- package/dist/core/hooks-runtime/subagent-context.js +15 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +73 -87
- package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
- package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
- package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
- package/dist/core/imagegen/imagegen-capability.js +43 -151
- package/dist/core/init/skills/filesystem.js +89 -0
- package/dist/core/init/skills/inventory.js +97 -0
- package/dist/core/init/skills/manifest.js +151 -0
- package/dist/core/init/skills.js +5 -325
- package/dist/core/init.js +0 -63
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
- package/dist/core/policy/latest-version-guidance.js +15 -2
- package/dist/core/preflight/parallel-preflight-engine.js +27 -51
- package/dist/core/provider/provider-badge.js +9 -4
- package/dist/core/provider/provider-context.js +57 -107
- package/dist/core/providers/openrouter/openrouter-account.js +3 -1
- package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
- package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
- package/dist/core/release/gate-manifest.js +0 -1
- package/dist/core/release/main-push-guard.js +13 -0
- package/dist/core/release/main-push-receipt.js +11 -0
- package/dist/core/release/physical-release-gates.js +664 -61
- package/dist/core/release/publish-preflight.js +3 -3
- package/dist/core/release/release-gate-batch-runner.js +19 -6
- package/dist/core/release/release-gate-dag.js +33 -6
- package/dist/core/release/release-gate-node.js +1 -3
- package/dist/core/release/release-gate-output-contract.js +55 -0
- package/dist/core/release/release-pack-contract.js +1 -1
- package/dist/core/release/release-pack-receipt.js +209 -8
- package/dist/core/release/release-real-contract.js +1 -1
- package/dist/core/release/stage-publish.js +106 -28
- package/dist/core/retention/temp-lease.js +204 -0
- package/dist/core/retention.js +18 -195
- package/dist/core/routes.js +1 -2
- package/dist/core/safety/intent-contract/intent-contract.js +3 -3
- package/dist/core/subagents/naruto-host-credentials.js +6 -1
- package/dist/core/subagents/official-subagent-config.js +27 -9
- package/dist/core/subagents/official-subagent-runner.js +14 -31
- package/dist/core/subagents/wave-lifecycle.js +36 -8
- package/dist/core/subagents/wave-parent-guidance.js +2 -1
- package/dist/core/telegram/doctor.js +2 -2
- package/dist/core/telegram/liveness.js +10 -4
- package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
- package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
- package/dist/core/update/update-migration-state/session-state-split.js +247 -0
- package/dist/core/update/update-migration-state/simple-stages.js +46 -0
- package/dist/core/update/update-migration-state.js +4 -481
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
- package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
- package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
- package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-runtime-schemas.js +7 -2
- package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
- package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
- package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
- package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
- package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
- package/dist/scripts/desktop-bridge-transport-client.js +116 -0
- package/dist/scripts/desktop-bridge-unification-check.js +276 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
- package/dist/scripts/gate-policy-audit-check.js +52 -2
- package/dist/scripts/provider-badge-context-check.js +55 -12
- package/dist/scripts/publish-preflight.js +1 -2
- package/dist/scripts/release-affected-selector-check.js +1 -2
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +9 -0
- package/dist/scripts/release-gate-dag-runner-check.js +6 -0
- package/dist/scripts/release-gate-dag-runner.js +4 -2
- package/dist/scripts/release-metadata-check.js +16 -3
- package/dist/scripts/release-pack-receipt.js +29 -6
- package/dist/scripts/release-physical-gates-check.js +39 -0
- package/dist/scripts/release-real-check.js +7 -5
- package/package.json +6 -8
- package/release-gates.v2.json +156 -157
- package/runtime-required-scripts.json +11 -11
- package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
- package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
- package/schemas/release/release-gate-node.schema.json +2 -3
- package/dist/cli/codex-lb-setup-warning-output.js +0 -17
- package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
- package/dist/commands/codex-lb.js +0 -1232
- package/dist/core/architecture-hardening/migration/migration.js +0 -111
- package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
- package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
- package/dist/core/codex-app/child-policy/child-policy.js +0 -35
- package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
- package/dist/core/codex-app/glm-model-profile.js +0 -1
- package/dist/core/codex-app/glm-profile-installer.js +0 -191
- package/dist/core/codex-app/glm-profile-schema.js +0 -42
- package/dist/core/codex-app/multi-provider-router.js +0 -391
- package/dist/core/codex-app/openrouter-activate.js +0 -405
- package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
- package/dist/core/codex-app/provider-child-policy.js +0 -64
- package/dist/core/codex-app/provider-mode.js +0 -91
- package/dist/core/codex-app/provider-session-policy.js +0 -85
- package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
- package/dist/core/codex-lb/codex-lb-setup.js +0 -293
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
- package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
- package/dist/core/codex-lb/desktop-mode.js +0 -32
- package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
- package/dist/core/codex-lb/legacy-migration.js +0 -576
- package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
- package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
- package/dist/core/codex-lb/routing-truth.js +0 -327
- package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { PACKAGE_VERSION } from '../../fsx.js';
|
|
2
|
+
import { buildSksCoreSkillManifest, isCoreSkillName, legacyCoreSkillNames } from '../../codex-native/core-skill-manifest.js';
|
|
3
|
+
import { DOLLAR_COMMANDS, DOLLAR_SKILL_NAMES, LEGACY_DOLLAR_SKILL_NAMES, RECOMMENDED_SKILLS } from '../../routes.js';
|
|
4
|
+
export const SKS_SKILL_MANIFEST_FILE = '.sks-generated.json';
|
|
5
|
+
export const PACKAGED_SKILLS_MANIFEST_SCHEMA = 'sks.skills-manifest.v1';
|
|
6
|
+
export const SKILLS_HASH_LEDGER_SCHEMA = 'sks.skills-hash-ledger.v1';
|
|
7
|
+
export const MAX_SKILL_HASH_HISTORY = 8;
|
|
8
|
+
export const RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIASES = [
|
|
9
|
+
'sks-ux-review',
|
|
10
|
+
'sks-visual-review',
|
|
11
|
+
'sks-ui-ux-review'
|
|
12
|
+
];
|
|
13
|
+
export const RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIAS_SET = new Set(RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIASES);
|
|
14
|
+
export const REMOVED_SKS_SKILL_NAMES = [
|
|
15
|
+
'old-workflow',
|
|
16
|
+
'team-legacy',
|
|
17
|
+
'team',
|
|
18
|
+
'agent-team',
|
|
19
|
+
'agent',
|
|
20
|
+
'mad-db',
|
|
21
|
+
'tmux',
|
|
22
|
+
'xai',
|
|
23
|
+
'swarm',
|
|
24
|
+
'shadow-clone',
|
|
25
|
+
'shadow-clone-legacy',
|
|
26
|
+
'kage-bunshin',
|
|
27
|
+
'qaloop',
|
|
28
|
+
'wiki-refresh',
|
|
29
|
+
'wikirefresh',
|
|
30
|
+
'research-discovery',
|
|
31
|
+
'sks-research-discovery',
|
|
32
|
+
'ralph',
|
|
33
|
+
'ralph-supervisor',
|
|
34
|
+
'ralph-resolver',
|
|
35
|
+
'loop',
|
|
36
|
+
'sks-loop'
|
|
37
|
+
];
|
|
38
|
+
export const LEGACY_SKS_SUPPORT_SKILL_NAMES = [
|
|
39
|
+
'autoresearch-loop',
|
|
40
|
+
'context7-docs',
|
|
41
|
+
'db-safety-guard',
|
|
42
|
+
'design-artifact-expert',
|
|
43
|
+
'design-system-builder',
|
|
44
|
+
'design-ui-editor',
|
|
45
|
+
'from-chat-img',
|
|
46
|
+
'getdesign-reference',
|
|
47
|
+
'gx-visual-generate',
|
|
48
|
+
'gx-visual-read',
|
|
49
|
+
'gx-visual-validate',
|
|
50
|
+
'honest-mode',
|
|
51
|
+
'hproof-claim-ledger',
|
|
52
|
+
'hproof-evidence-bind',
|
|
53
|
+
'imagegen',
|
|
54
|
+
'imagegen-source-scout',
|
|
55
|
+
'performance-evaluator',
|
|
56
|
+
'pipeline-runner',
|
|
57
|
+
'prompt-pipeline',
|
|
58
|
+
'reasoning-router',
|
|
59
|
+
'reflection',
|
|
60
|
+
'solution-scout',
|
|
61
|
+
'turbo-context-pack'
|
|
62
|
+
];
|
|
63
|
+
export const LEGACY_UNPREFIXED_SKS_SKILL_NAMES = Array.from(new Set([
|
|
64
|
+
...LEGACY_DOLLAR_SKILL_NAMES,
|
|
65
|
+
...legacyCoreSkillNames(),
|
|
66
|
+
...LEGACY_SKS_SUPPORT_SKILL_NAMES
|
|
67
|
+
].map((name) => canonicalSkillNameFromValue(name)).filter((name) => name && name !== 'sks'))).sort();
|
|
68
|
+
export const SKS_SKILL_NAMES_TO_CLEAN_UP = Array.from(new Set([
|
|
69
|
+
...REMOVED_SKS_SKILL_NAMES,
|
|
70
|
+
...LEGACY_UNPREFIXED_SKS_SKILL_NAMES
|
|
71
|
+
]));
|
|
72
|
+
export const REMOVED_SKS_SKILL_NAME_SET = new Set(SKS_SKILL_NAMES_TO_CLEAN_UP);
|
|
73
|
+
export const SKILL_ALIASES = {};
|
|
74
|
+
export function canonicalSkillNameFromValue(value) {
|
|
75
|
+
return String(value || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
76
|
+
}
|
|
77
|
+
export function buildFallbackSkillsManifest() {
|
|
78
|
+
const names = new Set([
|
|
79
|
+
...DOLLAR_SKILL_NAMES.map((name) => canonicalSkillNameFromValue(name)),
|
|
80
|
+
...RECOMMENDED_SKILLS.map((name) => canonicalSkillNameFromValue(name)),
|
|
81
|
+
...DOLLAR_COMMANDS.map((command) => canonicalSkillNameFromValue(String(command.command || '').replace(/^\$/, ''))),
|
|
82
|
+
...buildSksCoreSkillManifest().skills.map((skill) => skill.canonical_name)
|
|
83
|
+
].filter((name) => Boolean(name)
|
|
84
|
+
&& !REMOVED_SKS_SKILL_NAME_SET.has(name)
|
|
85
|
+
&& !RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIAS_SET.has(name)));
|
|
86
|
+
return {
|
|
87
|
+
schema: PACKAGED_SKILLS_MANIFEST_SCHEMA,
|
|
88
|
+
package_version: PACKAGE_VERSION,
|
|
89
|
+
skills: [...names].sort().map((name) => ({
|
|
90
|
+
canonical_name: name,
|
|
91
|
+
type: isCoreSkillName(name) ? 'core' : 'official',
|
|
92
|
+
content_sha256: '',
|
|
93
|
+
hash_history: [],
|
|
94
|
+
deprecated_aliases: SKILL_ALIASES[name] || []
|
|
95
|
+
}))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { PACKAGE_VERSION, readJson, sha256 } from '../../fsx.js';
|
|
5
|
+
import { isCoreSkillName } from '../../codex-native/core-skill-manifest.js';
|
|
6
|
+
import { MAX_SKILL_HASH_HISTORY, PACKAGED_SKILLS_MANIFEST_SCHEMA, REMOVED_SKS_SKILL_NAME_SET, SKILLS_HASH_LEDGER_SCHEMA, SKILL_ALIASES, buildFallbackSkillsManifest, canonicalSkillNameFromValue } from './inventory.js';
|
|
7
|
+
export async function loadSkillsManifest() {
|
|
8
|
+
const bundled = await loadBundledSkillsManifest();
|
|
9
|
+
if (bundled)
|
|
10
|
+
return bundled;
|
|
11
|
+
const candidates = [
|
|
12
|
+
path.join(path.resolve(process.env.HOME || os.homedir()), '.agents', 'skills', 'skills-manifest.json')
|
|
13
|
+
];
|
|
14
|
+
return (await loadFirstCompleteSkillsManifest(candidates)) || buildFallbackSkillsManifest();
|
|
15
|
+
}
|
|
16
|
+
export async function loadBundledSkillsManifest() {
|
|
17
|
+
const packaged = await loadFirstCompleteSkillsManifest([
|
|
18
|
+
path.join(packageRootDir(), 'dist', 'config', 'skills-manifest.json'),
|
|
19
|
+
path.join(packageRootDir(), 'config', 'skills-manifest.json')
|
|
20
|
+
]);
|
|
21
|
+
if (packaged)
|
|
22
|
+
return packaged;
|
|
23
|
+
const ledger = await readJson(path.join(packageRootDir(), 'config', 'skills-hash-ledger.v1.json'), null);
|
|
24
|
+
return skillsManifestFromHashLedger(ledger);
|
|
25
|
+
}
|
|
26
|
+
export function skillsManifestFromHashLedger(ledger) {
|
|
27
|
+
if (ledger?.schema !== SKILLS_HASH_LEDGER_SCHEMA || !Array.isArray(ledger?.skills))
|
|
28
|
+
return null;
|
|
29
|
+
const expected = new Set(buildFallbackSkillsManifest().skills.map((skill) => canonicalSkillNameFromValue(skill.canonical_name)));
|
|
30
|
+
const names = new Set();
|
|
31
|
+
const skills = [];
|
|
32
|
+
for (const row of ledger.skills) {
|
|
33
|
+
const canonicalName = canonicalSkillNameFromValue(row?.canonical_name);
|
|
34
|
+
const trusted = Array.isArray(row?.trusted_sha256)
|
|
35
|
+
? row.trusted_sha256.map((value) => String(value || '').trim().toLowerCase())
|
|
36
|
+
: [];
|
|
37
|
+
if (!canonicalName
|
|
38
|
+
|| canonicalName !== row?.canonical_name
|
|
39
|
+
|| names.has(canonicalName)
|
|
40
|
+
|| trusted.length < 1
|
|
41
|
+
|| trusted.length > MAX_SKILL_HASH_HISTORY + 1
|
|
42
|
+
|| trusted.some((digest) => !/^[a-f0-9]{64}$/.test(digest))
|
|
43
|
+
|| new Set(trusted).size !== trusted.length)
|
|
44
|
+
return null;
|
|
45
|
+
names.add(canonicalName);
|
|
46
|
+
if (REMOVED_SKS_SKILL_NAME_SET.has(canonicalName))
|
|
47
|
+
continue;
|
|
48
|
+
skills.push({
|
|
49
|
+
canonical_name: canonicalName,
|
|
50
|
+
type: isCoreSkillName(canonicalName) ? 'core' : 'official',
|
|
51
|
+
content_sha256: trusted[0],
|
|
52
|
+
hash_history: trusted.slice(1),
|
|
53
|
+
deprecated_aliases: SKILL_ALIASES[canonicalName] || []
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if ([...expected].some((name) => !names.has(name)))
|
|
57
|
+
return null;
|
|
58
|
+
const manifest = {
|
|
59
|
+
schema: PACKAGED_SKILLS_MANIFEST_SCHEMA,
|
|
60
|
+
package_version: PACKAGE_VERSION,
|
|
61
|
+
skills: skills.sort((left, right) => left.canonical_name.localeCompare(right.canonical_name))
|
|
62
|
+
};
|
|
63
|
+
return skillsManifestHasContentDigests(manifest) ? manifest : null;
|
|
64
|
+
}
|
|
65
|
+
export function normalizeSkillsManifest(manifest) {
|
|
66
|
+
const skills = (manifest.skills || [])
|
|
67
|
+
.map((skill) => ({
|
|
68
|
+
...skill,
|
|
69
|
+
deprecated_aliases: (skill.deprecated_aliases || [])
|
|
70
|
+
.filter((name) => !REMOVED_SKS_SKILL_NAME_SET.has(canonicalSkillNameFromValue(name)))
|
|
71
|
+
}))
|
|
72
|
+
.filter((skill) => !REMOVED_SKS_SKILL_NAME_SET.has(canonicalSkillNameFromValue(skill.canonical_name)));
|
|
73
|
+
const { removed_skills: _retiredInventory, ...current } = manifest || {};
|
|
74
|
+
return { ...current, skills };
|
|
75
|
+
}
|
|
76
|
+
export function mergePackagedSkillsManifestHashHistory(currentManifest, previousManifest) {
|
|
77
|
+
const previousByName = new Map((Array.isArray(previousManifest?.skills) ? previousManifest.skills : [])
|
|
78
|
+
.map((row) => [canonicalSkillNameFromValue(row?.canonical_name), row])
|
|
79
|
+
.filter(([name]) => Boolean(name)));
|
|
80
|
+
return {
|
|
81
|
+
...currentManifest,
|
|
82
|
+
skills: (Array.isArray(currentManifest?.skills) ? currentManifest.skills : []).map((row) => {
|
|
83
|
+
const canonicalName = canonicalSkillNameFromValue(row?.canonical_name);
|
|
84
|
+
const currentDigest = String(row?.content_sha256 || '').trim().toLowerCase();
|
|
85
|
+
const previous = previousByName.get(canonicalName);
|
|
86
|
+
const history = [
|
|
87
|
+
previous?.content_sha256,
|
|
88
|
+
...(Array.isArray(previous?.hash_history) ? previous.hash_history : []),
|
|
89
|
+
...(Array.isArray(row?.hash_history) ? row.hash_history : [])
|
|
90
|
+
]
|
|
91
|
+
.map((value) => String(value || '').trim().toLowerCase())
|
|
92
|
+
.filter((value, index, values) => (/^[a-f0-9]{64}$/.test(value)
|
|
93
|
+
&& value !== currentDigest
|
|
94
|
+
&& values.indexOf(value) === index))
|
|
95
|
+
.slice(0, MAX_SKILL_HASH_HISTORY);
|
|
96
|
+
return { ...row, hash_history: history };
|
|
97
|
+
})
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function skillManifestGenerationSha256(manifest) {
|
|
101
|
+
if (manifest?.schema !== PACKAGED_SKILLS_MANIFEST_SCHEMA || !Array.isArray(manifest?.skills))
|
|
102
|
+
return null;
|
|
103
|
+
const rows = manifest.skills
|
|
104
|
+
.map((skill) => ({
|
|
105
|
+
canonical_name: canonicalSkillNameFromValue(skill?.canonical_name),
|
|
106
|
+
content_sha256: String(skill?.content_sha256 || '').trim().toLowerCase()
|
|
107
|
+
}))
|
|
108
|
+
.filter((skill) => skill.canonical_name && /^[a-f0-9]{64}$/.test(skill.content_sha256))
|
|
109
|
+
.sort((left, right) => left.canonical_name.localeCompare(right.canonical_name));
|
|
110
|
+
return rows.length ? sha256(JSON.stringify(rows)) : null;
|
|
111
|
+
}
|
|
112
|
+
export async function runtimeBuildSourceTime() {
|
|
113
|
+
const stamp = await readJson(path.join(packageRootDir(), 'dist', '.sks-build-stamp.json'), null);
|
|
114
|
+
return Number.isFinite(stamp?.built_at_source_time) && stamp.built_at_source_time > 0
|
|
115
|
+
? stamp.built_at_source_time
|
|
116
|
+
: null;
|
|
117
|
+
}
|
|
118
|
+
async function loadFirstCompleteSkillsManifest(candidates) {
|
|
119
|
+
for (const file of candidates) {
|
|
120
|
+
const data = await readJson(file, null);
|
|
121
|
+
if (data?.schema !== PACKAGED_SKILLS_MANIFEST_SCHEMA
|
|
122
|
+
|| data?.package_version !== PACKAGE_VERSION
|
|
123
|
+
|| !Array.isArray(data.skills))
|
|
124
|
+
continue;
|
|
125
|
+
const normalized = normalizeSkillsManifest(data);
|
|
126
|
+
if (!skillsManifestHasContentDigests(normalized))
|
|
127
|
+
continue;
|
|
128
|
+
return normalized;
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
function skillsManifestHasContentDigests(manifest) {
|
|
133
|
+
const skills = Array.isArray(manifest?.skills) ? manifest.skills : [];
|
|
134
|
+
if (!skills.length)
|
|
135
|
+
return false;
|
|
136
|
+
const names = new Set();
|
|
137
|
+
for (const skill of skills) {
|
|
138
|
+
const name = canonicalSkillNameFromValue(skill?.canonical_name);
|
|
139
|
+
if (!name
|
|
140
|
+
|| names.has(name)
|
|
141
|
+
|| typeof skill?.content_sha256 !== 'string'
|
|
142
|
+
|| !/^[a-f0-9]{64}$/i.test(skill.content_sha256))
|
|
143
|
+
return false;
|
|
144
|
+
names.add(name);
|
|
145
|
+
}
|
|
146
|
+
return buildFallbackSkillsManifest().skills.every((skill) => (names.has(canonicalSkillNameFromValue(skill.canonical_name))));
|
|
147
|
+
}
|
|
148
|
+
function packageRootDir() {
|
|
149
|
+
return path.resolve(process.env.SKS_BUILD_SOURCE_ROOT
|
|
150
|
+
|| path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..'));
|
|
151
|
+
}
|
package/dist/core/init/skills.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fsp from 'node:fs/promises';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
4
|
import { ensureDir, exists, nowIso, PACKAGE_VERSION, readJson, readText, sha256, withScratchDir, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
6
5
|
import { buildSksCoreSkillManifest, isCoreSkillName, legacyCoreSkillNames } from '../codex-native/core-skill-manifest.js';
|
|
7
6
|
import { syncCoreSkillsIntegrity } from '../codex-native/core-skill-integrity.js';
|
|
@@ -18,81 +17,16 @@ import { AWESOME_DESIGN_MD_REFERENCE, CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_
|
|
|
18
17
|
import { prefixKnownSksDollarReferences, sksPrefixedSkillName } from '../routes/dollar-prefix.js';
|
|
19
18
|
import { escapeRegExp } from '../text/regex.js';
|
|
20
19
|
import { compactSkillDiscoveryDescription, renderSkillAgentMetadata, skillFrontmatterDescription } from '../skills/skill-agent-metadata.js';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
import { REMOVED_SKS_SKILL_NAMES, LEGACY_UNPREFIXED_SKS_SKILL_NAMES, LEGACY_SKS_SUPPORT_SKILL_NAMES, PACKAGED_SKILLS_MANIFEST_SCHEMA, REMOVED_SKS_SKILL_NAME_SET, RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIASES, RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIAS_SET, SKILL_ALIASES, SKS_SKILL_MANIFEST_FILE, SKS_SKILL_NAMES_TO_CLEAN_UP, canonicalSkillNameFromValue } from './skills/inventory.js';
|
|
21
|
+
import { listSkillDirs, pruneProjectGeneratedManifest, rootFromSkillsDir } from './skills/filesystem.js';
|
|
22
|
+
import { loadBundledSkillsManifest, loadSkillsManifest, mergePackagedSkillsManifestHashHistory, normalizeSkillsManifest, runtimeBuildSourceTime, skillManifestGenerationSha256, skillsManifestFromHashLedger } from './skills/manifest.js';
|
|
23
|
+
export { REMOVED_SKS_SKILL_NAMES, LEGACY_UNPREFIXED_SKS_SKILL_NAMES } from './skills/inventory.js';
|
|
24
|
+
export { loadBundledSkillsManifest, loadSkillsManifest, mergePackagedSkillsManifestHashHistory, skillsManifestFromHashLedger } from './skills/manifest.js';
|
|
24
25
|
const MANAGED_SKILL_MARKER_VERSION = '1';
|
|
25
|
-
const MAX_SKILL_HASH_HISTORY = 8;
|
|
26
26
|
const GENERATED_PRUNE_POLICY = 'remove_previous_sks_generated_paths_absent_from_current_manifest';
|
|
27
27
|
const REFLECTION_MEMORY_PATH = '.sneakoscope/memory/q2_facts/post-route-reflection.md';
|
|
28
28
|
const MANAGED_SKILL_MARKER_RE = /BEGIN SKS (?:IMMUTABLE CORE|MANAGED) SKILL/;
|
|
29
29
|
const FORGE_SKILL_MARKER_RE = /BEGIN SKS FORGE SKILL/;
|
|
30
|
-
const RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIASES = [
|
|
31
|
-
'sks-ux-review',
|
|
32
|
-
'sks-visual-review',
|
|
33
|
-
'sks-ui-ux-review'
|
|
34
|
-
];
|
|
35
|
-
const RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIAS_SET = new Set(RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIASES);
|
|
36
|
-
export const REMOVED_SKS_SKILL_NAMES = [
|
|
37
|
-
'old-workflow',
|
|
38
|
-
'team-legacy',
|
|
39
|
-
'team',
|
|
40
|
-
'agent-team',
|
|
41
|
-
'agent',
|
|
42
|
-
'mad-db',
|
|
43
|
-
'tmux',
|
|
44
|
-
'xai',
|
|
45
|
-
'swarm',
|
|
46
|
-
'shadow-clone',
|
|
47
|
-
'shadow-clone-legacy',
|
|
48
|
-
'kage-bunshin',
|
|
49
|
-
'qaloop',
|
|
50
|
-
'wiki-refresh',
|
|
51
|
-
'wikirefresh',
|
|
52
|
-
'research-discovery',
|
|
53
|
-
'sks-research-discovery',
|
|
54
|
-
'ralph',
|
|
55
|
-
'ralph-supervisor',
|
|
56
|
-
'ralph-resolver',
|
|
57
|
-
'loop',
|
|
58
|
-
'sks-loop'
|
|
59
|
-
];
|
|
60
|
-
const LEGACY_SKS_SUPPORT_SKILL_NAMES = [
|
|
61
|
-
'autoresearch-loop',
|
|
62
|
-
'context7-docs',
|
|
63
|
-
'db-safety-guard',
|
|
64
|
-
'design-artifact-expert',
|
|
65
|
-
'design-system-builder',
|
|
66
|
-
'design-ui-editor',
|
|
67
|
-
'from-chat-img',
|
|
68
|
-
'getdesign-reference',
|
|
69
|
-
'gx-visual-generate',
|
|
70
|
-
'gx-visual-read',
|
|
71
|
-
'gx-visual-validate',
|
|
72
|
-
'honest-mode',
|
|
73
|
-
'hproof-claim-ledger',
|
|
74
|
-
'hproof-evidence-bind',
|
|
75
|
-
'imagegen',
|
|
76
|
-
'imagegen-source-scout',
|
|
77
|
-
'performance-evaluator',
|
|
78
|
-
'pipeline-runner',
|
|
79
|
-
'prompt-pipeline',
|
|
80
|
-
'reasoning-router',
|
|
81
|
-
'reflection',
|
|
82
|
-
'solution-scout',
|
|
83
|
-
'turbo-context-pack'
|
|
84
|
-
];
|
|
85
|
-
export const LEGACY_UNPREFIXED_SKS_SKILL_NAMES = Array.from(new Set([
|
|
86
|
-
...LEGACY_DOLLAR_SKILL_NAMES,
|
|
87
|
-
...legacyCoreSkillNames(),
|
|
88
|
-
...LEGACY_SKS_SUPPORT_SKILL_NAMES
|
|
89
|
-
].map((name) => canonicalSkillNameFromValue(name)).filter((name) => name && name !== 'sks'))).sort();
|
|
90
|
-
const SKS_SKILL_NAMES_TO_CLEAN_UP = Array.from(new Set([
|
|
91
|
-
...REMOVED_SKS_SKILL_NAMES,
|
|
92
|
-
...LEGACY_UNPREFIXED_SKS_SKILL_NAMES
|
|
93
|
-
]));
|
|
94
|
-
const REMOVED_SKS_SKILL_NAME_SET = new Set(SKS_SKILL_NAMES_TO_CLEAN_UP);
|
|
95
|
-
const SKILL_ALIASES = {};
|
|
96
30
|
function reflectionInstructionText(commandPrefix = 'sks') {
|
|
97
31
|
return `Post-route reflection: full routes load \`reflection\` after work/tests and before final; DFix/Answer/Help/Wiki/SKS discovery are exempt. Write reflection.md; record only real misses/gaps, or no_issue_acknowledged. For lessons, append TriWiki claim rows to ${REFLECTION_MEMORY_PATH}. Run "${commandPrefix} wiki refresh" or pack, validate, then pass reflection-gate.json.`;
|
|
98
32
|
}
|
|
@@ -954,96 +888,6 @@ async function quarantineSkillDir(root, sourceDir, name, reason) {
|
|
|
954
888
|
}
|
|
955
889
|
return target;
|
|
956
890
|
}
|
|
957
|
-
export async function loadSkillsManifest() {
|
|
958
|
-
const bundled = await loadBundledSkillsManifest();
|
|
959
|
-
if (bundled)
|
|
960
|
-
return bundled;
|
|
961
|
-
const candidates = [
|
|
962
|
-
path.join(path.resolve(process.env.HOME || os.homedir()), '.agents', 'skills', 'skills-manifest.json')
|
|
963
|
-
];
|
|
964
|
-
return (await loadFirstCompleteSkillsManifest(candidates)) || buildFallbackSkillsManifest();
|
|
965
|
-
}
|
|
966
|
-
export async function loadBundledSkillsManifest() {
|
|
967
|
-
const packaged = await loadFirstCompleteSkillsManifest([
|
|
968
|
-
path.join(packageRootDir(), 'dist', 'config', 'skills-manifest.json'),
|
|
969
|
-
path.join(packageRootDir(), 'config', 'skills-manifest.json')
|
|
970
|
-
]);
|
|
971
|
-
if (packaged)
|
|
972
|
-
return packaged;
|
|
973
|
-
const ledger = await readJson(path.join(packageRootDir(), 'config', 'skills-hash-ledger.v1.json'), null);
|
|
974
|
-
return skillsManifestFromHashLedger(ledger);
|
|
975
|
-
}
|
|
976
|
-
async function loadFirstCompleteSkillsManifest(candidates) {
|
|
977
|
-
for (const file of candidates) {
|
|
978
|
-
const data = await readJson(file, null);
|
|
979
|
-
if (data?.schema !== PACKAGED_SKILLS_MANIFEST_SCHEMA
|
|
980
|
-
|| data?.package_version !== PACKAGE_VERSION
|
|
981
|
-
|| !Array.isArray(data.skills))
|
|
982
|
-
continue;
|
|
983
|
-
const normalized = normalizeSkillsManifest(data);
|
|
984
|
-
if (!skillsManifestHasContentDigests(normalized))
|
|
985
|
-
continue;
|
|
986
|
-
return normalized;
|
|
987
|
-
}
|
|
988
|
-
return null;
|
|
989
|
-
}
|
|
990
|
-
function skillsManifestHasContentDigests(manifest) {
|
|
991
|
-
const skills = Array.isArray(manifest?.skills) ? manifest.skills : [];
|
|
992
|
-
if (!skills.length)
|
|
993
|
-
return false;
|
|
994
|
-
const names = new Set();
|
|
995
|
-
for (const skill of skills) {
|
|
996
|
-
const name = canonicalSkillNameFromValue(skill?.canonical_name);
|
|
997
|
-
if (!name
|
|
998
|
-
|| names.has(name)
|
|
999
|
-
|| typeof skill?.content_sha256 !== 'string'
|
|
1000
|
-
|| !/^[a-f0-9]{64}$/i.test(skill.content_sha256)) {
|
|
1001
|
-
return false;
|
|
1002
|
-
}
|
|
1003
|
-
names.add(name);
|
|
1004
|
-
}
|
|
1005
|
-
return buildFallbackSkillsManifest().skills.every((skill) => (names.has(canonicalSkillNameFromValue(skill.canonical_name))));
|
|
1006
|
-
}
|
|
1007
|
-
export function skillsManifestFromHashLedger(ledger) {
|
|
1008
|
-
if (ledger?.schema !== SKILLS_HASH_LEDGER_SCHEMA || !Array.isArray(ledger?.skills)) {
|
|
1009
|
-
return null;
|
|
1010
|
-
}
|
|
1011
|
-
const expected = new Set(buildFallbackSkillsManifest().skills.map((skill) => canonicalSkillNameFromValue(skill.canonical_name)));
|
|
1012
|
-
const names = new Set();
|
|
1013
|
-
const skills = [];
|
|
1014
|
-
for (const row of ledger.skills) {
|
|
1015
|
-
const canonicalName = canonicalSkillNameFromValue(row?.canonical_name);
|
|
1016
|
-
const trusted = Array.isArray(row?.trusted_sha256)
|
|
1017
|
-
? row.trusted_sha256.map((value) => String(value || '').trim().toLowerCase())
|
|
1018
|
-
: [];
|
|
1019
|
-
if (!canonicalName
|
|
1020
|
-
|| canonicalName !== row?.canonical_name
|
|
1021
|
-
|| names.has(canonicalName)
|
|
1022
|
-
|| trusted.length < 1
|
|
1023
|
-
|| trusted.length > MAX_SKILL_HASH_HISTORY + 1
|
|
1024
|
-
|| trusted.some((digest) => !/^[a-f0-9]{64}$/.test(digest))
|
|
1025
|
-
|| new Set(trusted).size !== trusted.length) {
|
|
1026
|
-
return null;
|
|
1027
|
-
}
|
|
1028
|
-
names.add(canonicalName);
|
|
1029
|
-
skills.push({
|
|
1030
|
-
canonical_name: canonicalName,
|
|
1031
|
-
type: isCoreSkillName(canonicalName) ? 'core' : 'official',
|
|
1032
|
-
content_sha256: trusted[0],
|
|
1033
|
-
hash_history: trusted.slice(1),
|
|
1034
|
-
deprecated_aliases: SKILL_ALIASES[canonicalName] || []
|
|
1035
|
-
});
|
|
1036
|
-
}
|
|
1037
|
-
if ([...expected].some((name) => !names.has(name))) {
|
|
1038
|
-
return null;
|
|
1039
|
-
}
|
|
1040
|
-
const manifest = {
|
|
1041
|
-
schema: PACKAGED_SKILLS_MANIFEST_SCHEMA,
|
|
1042
|
-
package_version: PACKAGE_VERSION,
|
|
1043
|
-
skills: skills.sort((left, right) => (left.canonical_name.localeCompare(right.canonical_name)))
|
|
1044
|
-
};
|
|
1045
|
-
return skillsManifestHasContentDigests(manifest) ? manifest : null;
|
|
1046
|
-
}
|
|
1047
891
|
async function quarantineUntrustedGlobalManagedSkills(root, targetDir, manifest) {
|
|
1048
892
|
const trusted = new Map();
|
|
1049
893
|
for (const row of Array.isArray(manifest?.skills) ? manifest.skills : []) {
|
|
@@ -1077,55 +921,6 @@ async function quarantineUntrustedGlobalManagedSkills(root, targetDir, manifest)
|
|
|
1077
921
|
}
|
|
1078
922
|
return [...new Set(quarantined)].sort();
|
|
1079
923
|
}
|
|
1080
|
-
function skillManifestGenerationSha256(manifest) {
|
|
1081
|
-
if (manifest?.schema !== PACKAGED_SKILLS_MANIFEST_SCHEMA || !Array.isArray(manifest?.skills)) {
|
|
1082
|
-
return null;
|
|
1083
|
-
}
|
|
1084
|
-
const rows = manifest.skills
|
|
1085
|
-
.map((skill) => ({
|
|
1086
|
-
canonical_name: canonicalSkillNameFromValue(skill?.canonical_name),
|
|
1087
|
-
content_sha256: String(skill?.content_sha256 || '').trim().toLowerCase()
|
|
1088
|
-
}))
|
|
1089
|
-
.filter((skill) => (skill.canonical_name && /^[a-f0-9]{64}$/.test(skill.content_sha256)))
|
|
1090
|
-
.sort((left, right) => left.canonical_name.localeCompare(right.canonical_name));
|
|
1091
|
-
return rows.length ? sha256(JSON.stringify(rows)) : null;
|
|
1092
|
-
}
|
|
1093
|
-
function normalizeSkillsManifest(manifest) {
|
|
1094
|
-
const skills = (manifest.skills || [])
|
|
1095
|
-
.map((skill) => ({
|
|
1096
|
-
...skill,
|
|
1097
|
-
deprecated_aliases: (skill.deprecated_aliases || [])
|
|
1098
|
-
.filter((name) => !REMOVED_SKS_SKILL_NAME_SET.has(canonicalSkillNameFromValue(name)))
|
|
1099
|
-
}))
|
|
1100
|
-
.filter((skill) => !REMOVED_SKS_SKILL_NAME_SET.has(canonicalSkillNameFromValue(skill.canonical_name)));
|
|
1101
|
-
const { removed_skills: _retiredInventory, ...current } = manifest || {};
|
|
1102
|
-
return { ...current, skills };
|
|
1103
|
-
}
|
|
1104
|
-
export function mergePackagedSkillsManifestHashHistory(currentManifest, previousManifest) {
|
|
1105
|
-
const previousByName = new Map((Array.isArray(previousManifest?.skills) ? previousManifest.skills : [])
|
|
1106
|
-
.map((row) => [canonicalSkillNameFromValue(row?.canonical_name), row])
|
|
1107
|
-
.filter(([name]) => Boolean(name)));
|
|
1108
|
-
return {
|
|
1109
|
-
...currentManifest,
|
|
1110
|
-
skills: (Array.isArray(currentManifest?.skills) ? currentManifest.skills : [])
|
|
1111
|
-
.map((row) => {
|
|
1112
|
-
const canonicalName = canonicalSkillNameFromValue(row?.canonical_name);
|
|
1113
|
-
const currentDigest = String(row?.content_sha256 || '').trim().toLowerCase();
|
|
1114
|
-
const previous = previousByName.get(canonicalName);
|
|
1115
|
-
const history = [
|
|
1116
|
-
previous?.content_sha256,
|
|
1117
|
-
...(Array.isArray(previous?.hash_history) ? previous.hash_history : []),
|
|
1118
|
-
...(Array.isArray(row?.hash_history) ? row.hash_history : [])
|
|
1119
|
-
]
|
|
1120
|
-
.map((value) => String(value || '').trim().toLowerCase())
|
|
1121
|
-
.filter((value, index, values) => (/^[a-f0-9]{64}$/.test(value)
|
|
1122
|
-
&& value !== currentDigest
|
|
1123
|
-
&& values.indexOf(value) === index))
|
|
1124
|
-
.slice(0, MAX_SKILL_HASH_HISTORY);
|
|
1125
|
-
return { ...row, hash_history: history };
|
|
1126
|
-
})
|
|
1127
|
-
};
|
|
1128
|
-
}
|
|
1129
924
|
export async function generatePackagedSkillsManifest() {
|
|
1130
925
|
return withScratchDir('skills-manifest-', async (dir) => {
|
|
1131
926
|
await installOfficialSkills(dir);
|
|
@@ -1154,115 +949,6 @@ export async function writePackagedSkillManifest(targetDir, manifest) {
|
|
|
1154
949
|
await writeJsonAtomic(file, manifest);
|
|
1155
950
|
return file;
|
|
1156
951
|
}
|
|
1157
|
-
function buildFallbackSkillsManifest() {
|
|
1158
|
-
const names = new Set([
|
|
1159
|
-
...DOLLAR_SKILL_NAMES.map((name) => canonicalSkillNameFromValue(name)),
|
|
1160
|
-
...RECOMMENDED_SKILLS.map((name) => canonicalSkillNameFromValue(name)),
|
|
1161
|
-
...DOLLAR_COMMANDS.map((command) => canonicalSkillNameFromValue(String(command.command || '').replace(/^\$/, ''))),
|
|
1162
|
-
...buildSksCoreSkillManifest().skills.map((skill) => skill.canonical_name)
|
|
1163
|
-
].filter((name) => Boolean(name)
|
|
1164
|
-
&& !REMOVED_SKS_SKILL_NAME_SET.has(String(name))
|
|
1165
|
-
&& !RETIRED_PUBLIC_IMAGE_UX_REVIEW_SKILL_ALIAS_SET.has(String(name))));
|
|
1166
|
-
return {
|
|
1167
|
-
schema: PACKAGED_SKILLS_MANIFEST_SCHEMA,
|
|
1168
|
-
package_version: PACKAGE_VERSION,
|
|
1169
|
-
skills: [...names].sort().map((name) => ({
|
|
1170
|
-
canonical_name: name,
|
|
1171
|
-
type: isCoreSkillName(name) ? 'core' : 'official',
|
|
1172
|
-
content_sha256: '',
|
|
1173
|
-
hash_history: [],
|
|
1174
|
-
deprecated_aliases: SKILL_ALIASES[name] || []
|
|
1175
|
-
}))
|
|
1176
|
-
};
|
|
1177
|
-
}
|
|
1178
|
-
async function listSkillDirs(targetDir, opts = {}) {
|
|
1179
|
-
const boundary = rootFromSkillsDir(targetDir);
|
|
1180
|
-
let rootInspection;
|
|
1181
|
-
try {
|
|
1182
|
-
rootInspection = await inspectConfinedPath(boundary, targetDir);
|
|
1183
|
-
}
|
|
1184
|
-
catch (error) {
|
|
1185
|
-
if (nodeErrorCode(error) === 'ENOENT')
|
|
1186
|
-
return [];
|
|
1187
|
-
throw error;
|
|
1188
|
-
}
|
|
1189
|
-
if (!rootInspection.exists)
|
|
1190
|
-
return [];
|
|
1191
|
-
if (rootInspection.leafSymlink || !rootInspection.stat?.isDirectory()) {
|
|
1192
|
-
throw new Error(`skill_target_not_safe_directory:${targetDir}`);
|
|
1193
|
-
}
|
|
1194
|
-
const rows = await fsp.readdir(targetDir, { withFileTypes: true });
|
|
1195
|
-
const out = [];
|
|
1196
|
-
for (const row of rows) {
|
|
1197
|
-
const dir = path.join(targetDir, row.name);
|
|
1198
|
-
const directoryCanonical = canonicalSkillNameFromValue(row.name);
|
|
1199
|
-
if (row.isSymbolicLink() || !row.isDirectory()) {
|
|
1200
|
-
if (opts.includeUnsafeEntries) {
|
|
1201
|
-
out.push({
|
|
1202
|
-
name: row.name,
|
|
1203
|
-
dir,
|
|
1204
|
-
skillMdPath: null,
|
|
1205
|
-
text: '',
|
|
1206
|
-
canonical: directoryCanonical,
|
|
1207
|
-
declaredCanonical: '',
|
|
1208
|
-
directoryCanonical,
|
|
1209
|
-
hash: '',
|
|
1210
|
-
unsafeEntry: row.isSymbolicLink() ? 'symlink' : 'non-directory'
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1213
|
-
continue;
|
|
1214
|
-
}
|
|
1215
|
-
const skillMdPath = path.join(dir, 'SKILL.md');
|
|
1216
|
-
const inspected = await inspectConfinedPath(boundary, skillMdPath);
|
|
1217
|
-
if (!inspected.exists || inspected.leafSymlink || !inspected.stat?.isFile()) {
|
|
1218
|
-
if (opts.includeUnsafeEntries) {
|
|
1219
|
-
out.push({
|
|
1220
|
-
name: row.name,
|
|
1221
|
-
dir,
|
|
1222
|
-
skillMdPath,
|
|
1223
|
-
text: '',
|
|
1224
|
-
canonical: directoryCanonical,
|
|
1225
|
-
declaredCanonical: '',
|
|
1226
|
-
directoryCanonical,
|
|
1227
|
-
hash: '',
|
|
1228
|
-
unsafeEntry: inspected.leafSymlink ? 'skill-file-symlink' : 'missing-or-non-file-skill'
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
continue;
|
|
1232
|
-
}
|
|
1233
|
-
const text = await fsp.readFile(skillMdPath, 'utf8');
|
|
1234
|
-
const displayName = /^name:\s*(.+)\s*$/m.exec(text)?.[1] || row.name;
|
|
1235
|
-
const declaredCanonical = canonicalSkillNameFromValue(displayName);
|
|
1236
|
-
out.push({
|
|
1237
|
-
name: row.name,
|
|
1238
|
-
dir,
|
|
1239
|
-
skillMdPath,
|
|
1240
|
-
text,
|
|
1241
|
-
canonical: declaredCanonical,
|
|
1242
|
-
declaredCanonical,
|
|
1243
|
-
directoryCanonical,
|
|
1244
|
-
hash: sha256(text)
|
|
1245
|
-
});
|
|
1246
|
-
}
|
|
1247
|
-
return out;
|
|
1248
|
-
}
|
|
1249
|
-
function rootFromSkillsDir(targetDir) {
|
|
1250
|
-
const normalized = path.resolve(targetDir);
|
|
1251
|
-
if (path.basename(normalized) === 'skills' && path.basename(path.dirname(normalized)) === '.agents') {
|
|
1252
|
-
return path.dirname(path.dirname(normalized));
|
|
1253
|
-
}
|
|
1254
|
-
return path.dirname(path.dirname(normalized));
|
|
1255
|
-
}
|
|
1256
|
-
function canonicalSkillNameFromValue(value) {
|
|
1257
|
-
return String(value || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
1258
|
-
}
|
|
1259
|
-
function packageRootDir() {
|
|
1260
|
-
return path.resolve(process.env.SKS_BUILD_SOURCE_ROOT
|
|
1261
|
-
|| path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..'));
|
|
1262
|
-
}
|
|
1263
|
-
async function pruneProjectGeneratedManifest(targetDir) {
|
|
1264
|
-
await fsp.rm(path.join(targetDir, SKS_SKILL_MANIFEST_FILE), { force: true }).catch(() => undefined);
|
|
1265
|
-
}
|
|
1266
952
|
function generatedSkillFiles(skillNames) {
|
|
1267
953
|
return skillNames.flatMap((name) => [
|
|
1268
954
|
`.agents/skills/${name}/SKILL.md`,
|
|
@@ -1301,12 +987,6 @@ async function writeGeneratedSkillManifest(root, skillNames) {
|
|
|
1301
987
|
files: generatedSkillFiles(skillNames)
|
|
1302
988
|
});
|
|
1303
989
|
}
|
|
1304
|
-
async function runtimeBuildSourceTime() {
|
|
1305
|
-
const stamp = await readJson(path.join(packageRootDir(), 'dist', '.sks-build-stamp.json'), null);
|
|
1306
|
-
return Number.isFinite(stamp?.built_at_source_time) && stamp.built_at_source_time > 0
|
|
1307
|
-
? stamp.built_at_source_time
|
|
1308
|
-
: null;
|
|
1309
|
-
}
|
|
1310
990
|
async function removeStaleGeneratedSkillsFromManifest(root, skillNames) {
|
|
1311
991
|
const previous = await readJson(generatedSkillManifestPath(root), null);
|
|
1312
992
|
const previousSkills = Array.isArray(previous?.skills) ? previous.skills : [];
|