@cleocode/caamp 1.7.1 → 1.8.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 +0 -0
- package/dist/{chunk-6T3TJQFF.js → chunk-YWO4I7LI.js} +162 -837
- package/dist/chunk-YWO4I7LI.js.map +1 -0
- package/dist/chunk-ZVRDBY6L.js +756 -0
- package/dist/chunk-ZVRDBY6L.js.map +1 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +20 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +194 -12
- package/dist/index.js +201 -47
- package/dist/index.js.map +1 -1
- package/dist/injector-XGI7NNZA.js +19 -0
- package/dist/injector-XGI7NNZA.js.map +1 -0
- package/package.json +1 -1
- package/providers/registry.json +0 -0
- package/dist/chunk-6T3TJQFF.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1446,7 +1446,7 @@ interface InstructionUpdateSummary {
|
|
|
1446
1446
|
updatedFiles: number;
|
|
1447
1447
|
actions: Array<{
|
|
1448
1448
|
file: string;
|
|
1449
|
-
action: "created" | "added" | "updated";
|
|
1449
|
+
action: "created" | "added" | "updated" | "intact";
|
|
1450
1450
|
providers: string[];
|
|
1451
1451
|
configFormats: ConfigFormat[];
|
|
1452
1452
|
}>;
|
|
@@ -1490,8 +1490,8 @@ interface DualScopeConfigureResult {
|
|
|
1490
1490
|
project: InstallResult[];
|
|
1491
1491
|
};
|
|
1492
1492
|
instructions: {
|
|
1493
|
-
global?: Map<string, "created" | "added" | "updated">;
|
|
1494
|
-
project?: Map<string, "created" | "added" | "updated">;
|
|
1493
|
+
global?: Map<string, "created" | "added" | "updated" | "intact">;
|
|
1494
|
+
project?: Map<string, "created" | "added" | "updated" | "intact">;
|
|
1495
1495
|
};
|
|
1496
1496
|
}
|
|
1497
1497
|
/**
|
|
@@ -2606,6 +2606,104 @@ declare function checkAllSkillUpdates(): Promise<Record<string, {
|
|
|
2606
2606
|
status: "up-to-date" | "update-available" | "unknown";
|
|
2607
2607
|
}>>;
|
|
2608
2608
|
|
|
2609
|
+
/**
|
|
2610
|
+
* Skill integrity checking
|
|
2611
|
+
*
|
|
2612
|
+
* Validates that installed skills have intact symlinks, correct canonical paths,
|
|
2613
|
+
* and enforces ct-* prefix priority for CAAMP-shipped skills.
|
|
2614
|
+
*/
|
|
2615
|
+
|
|
2616
|
+
/**
|
|
2617
|
+
* Status of a single skill's integrity check.
|
|
2618
|
+
*/
|
|
2619
|
+
type SkillIntegrityStatus = "intact" | "broken-symlink" | "missing-canonical" | "missing-link" | "not-tracked" | "tampered";
|
|
2620
|
+
/**
|
|
2621
|
+
* Result of checking a single skill's integrity.
|
|
2622
|
+
*/
|
|
2623
|
+
interface SkillIntegrityResult {
|
|
2624
|
+
/** Skill name. */
|
|
2625
|
+
name: string;
|
|
2626
|
+
/** Overall integrity status. */
|
|
2627
|
+
status: SkillIntegrityStatus;
|
|
2628
|
+
/** Whether the canonical directory exists. */
|
|
2629
|
+
canonicalExists: boolean;
|
|
2630
|
+
/** Expected canonical path from lock file. */
|
|
2631
|
+
canonicalPath: string | null;
|
|
2632
|
+
/** Provider link statuses — which agents have valid symlinks. */
|
|
2633
|
+
linkStatuses: Array<{
|
|
2634
|
+
providerId: string;
|
|
2635
|
+
linkPath: string;
|
|
2636
|
+
exists: boolean;
|
|
2637
|
+
isSymlink: boolean;
|
|
2638
|
+
pointsToCanonical: boolean;
|
|
2639
|
+
}>;
|
|
2640
|
+
/** Whether this is a CAAMP-reserved (ct-*) skill. */
|
|
2641
|
+
isCaampOwned: boolean;
|
|
2642
|
+
/** Human-readable issue description, if any. */
|
|
2643
|
+
issue?: string;
|
|
2644
|
+
}
|
|
2645
|
+
/**
|
|
2646
|
+
* Check whether a skill name is reserved by CAAMP (ct-* prefix).
|
|
2647
|
+
*
|
|
2648
|
+
* @param skillName - Skill name to check
|
|
2649
|
+
* @returns `true` if the skill name starts with `ct-`
|
|
2650
|
+
*/
|
|
2651
|
+
declare function isCaampOwnedSkill(skillName: string): boolean;
|
|
2652
|
+
/**
|
|
2653
|
+
* Check the integrity of a single installed skill.
|
|
2654
|
+
*
|
|
2655
|
+
* Validates:
|
|
2656
|
+
* - Canonical directory exists on disk
|
|
2657
|
+
* - Lock file entry matches actual state
|
|
2658
|
+
* - Symlinks from provider skill directories point to the canonical path
|
|
2659
|
+
*
|
|
2660
|
+
* @param skillName - Name of the skill to check
|
|
2661
|
+
* @param providers - Providers to check symlinks for
|
|
2662
|
+
* @param scope - Whether to check global or project links
|
|
2663
|
+
* @param projectDir - Project directory (for project scope)
|
|
2664
|
+
* @returns Integrity check result
|
|
2665
|
+
*/
|
|
2666
|
+
declare function checkSkillIntegrity(skillName: string, providers: Provider[], scope?: "global" | "project", projectDir?: string): Promise<SkillIntegrityResult>;
|
|
2667
|
+
/**
|
|
2668
|
+
* Check integrity of all tracked skills.
|
|
2669
|
+
*
|
|
2670
|
+
* @param providers - Providers to check symlinks for
|
|
2671
|
+
* @param scope - Whether to check global or project links
|
|
2672
|
+
* @param projectDir - Project directory (for project scope)
|
|
2673
|
+
* @returns Map of skill name to integrity result
|
|
2674
|
+
*/
|
|
2675
|
+
declare function checkAllSkillIntegrity(providers: Provider[], scope?: "global" | "project", projectDir?: string): Promise<Map<string, SkillIntegrityResult>>;
|
|
2676
|
+
/**
|
|
2677
|
+
* Resolve a skill name conflict where a user-installed skill collides
|
|
2678
|
+
* with a CAAMP-owned (ct-*) skill.
|
|
2679
|
+
*
|
|
2680
|
+
* CAAMP-owned skills always win. Returns `true` if the incoming skill
|
|
2681
|
+
* should take precedence over the existing installation.
|
|
2682
|
+
*
|
|
2683
|
+
* @param skillName - Skill name to check
|
|
2684
|
+
* @param incomingSource - Source of the incoming skill installation
|
|
2685
|
+
* @param existingEntry - Existing lock entry, if any
|
|
2686
|
+
* @returns `true` if the incoming installation should proceed
|
|
2687
|
+
*/
|
|
2688
|
+
declare function shouldOverrideSkill(skillName: string, incomingSource: string, existingEntry: LockEntry | undefined): boolean;
|
|
2689
|
+
/**
|
|
2690
|
+
* Validate instruction file injection status across all providers.
|
|
2691
|
+
*
|
|
2692
|
+
* Checks that CAAMP blocks exist and are current in all relevant
|
|
2693
|
+
* instruction files.
|
|
2694
|
+
*
|
|
2695
|
+
* @param providers - Providers to check
|
|
2696
|
+
* @param projectDir - Project directory
|
|
2697
|
+
* @param scope - Whether to check global or project files
|
|
2698
|
+
* @param expectedContent - Expected CAAMP block content
|
|
2699
|
+
* @returns Array of file paths with issues
|
|
2700
|
+
*/
|
|
2701
|
+
declare function validateInstructionIntegrity(providers: Provider[], projectDir: string, scope: "project" | "global", expectedContent?: string): Promise<Array<{
|
|
2702
|
+
file: string;
|
|
2703
|
+
providerId: string;
|
|
2704
|
+
issue: string;
|
|
2705
|
+
}>>;
|
|
2706
|
+
|
|
2609
2707
|
/**
|
|
2610
2708
|
* Unified marketplace client
|
|
2611
2709
|
*
|
|
@@ -2711,21 +2809,25 @@ declare function checkInjection(filePath: string, expectedContent?: string): Pro
|
|
|
2711
2809
|
* Inject content into an instruction file between CAAMP markers.
|
|
2712
2810
|
*
|
|
2713
2811
|
* Behavior depends on the file state:
|
|
2714
|
-
* - File does not exist: creates the file with the injection block
|
|
2715
|
-
* - File exists without markers: prepends the injection block
|
|
2716
|
-
* - File exists with markers: replaces the
|
|
2812
|
+
* - File does not exist: creates the file with the injection block → `"created"`
|
|
2813
|
+
* - File exists without markers: prepends the injection block → `"added"`
|
|
2814
|
+
* - File exists with markers, content differs: replaces the block → `"updated"`
|
|
2815
|
+
* - File exists with markers, content matches: no-op → `"intact"`
|
|
2816
|
+
*
|
|
2817
|
+
* This function is **idempotent** — calling it multiple times with the same
|
|
2818
|
+
* content will not modify the file after the first write.
|
|
2717
2819
|
*
|
|
2718
2820
|
* @param filePath - Absolute path to the instruction file
|
|
2719
2821
|
* @param content - Content to inject between CAAMP markers
|
|
2720
|
-
* @returns Action taken: `"created"`, `"added"`, or `"
|
|
2822
|
+
* @returns Action taken: `"created"`, `"added"`, `"updated"`, or `"intact"`
|
|
2721
2823
|
*
|
|
2722
2824
|
* @example
|
|
2723
2825
|
* ```typescript
|
|
2724
2826
|
* const action = await inject("/project/CLAUDE.md", "## My Config\nSome content");
|
|
2725
|
-
* console.log(`File ${action}`);
|
|
2827
|
+
* console.log(`File ${action}`); // "created" on first call, "intact" on subsequent
|
|
2726
2828
|
* ```
|
|
2727
2829
|
*/
|
|
2728
|
-
declare function inject(filePath: string, content: string): Promise<"created" | "added" | "updated">;
|
|
2830
|
+
declare function inject(filePath: string, content: string): Promise<"created" | "added" | "updated" | "intact">;
|
|
2729
2831
|
/**
|
|
2730
2832
|
* Remove the CAAMP injection block from an instruction file.
|
|
2731
2833
|
*
|
|
@@ -2768,7 +2870,7 @@ declare function checkAllInjections(providers: Provider[], projectDir: string, s
|
|
|
2768
2870
|
* @param projectDir - Absolute path to the project directory
|
|
2769
2871
|
* @param scope - Whether to target project or global instruction files
|
|
2770
2872
|
* @param content - Content to inject between CAAMP markers
|
|
2771
|
-
* @returns Map of file path to action taken (`"created"`, `"added"`, or `"
|
|
2873
|
+
* @returns Map of file path to action taken (`"created"`, `"added"`, `"updated"`, or `"intact"`)
|
|
2772
2874
|
*
|
|
2773
2875
|
* @example
|
|
2774
2876
|
* ```typescript
|
|
@@ -2778,7 +2880,87 @@ declare function checkAllInjections(providers: Provider[], projectDir: string, s
|
|
|
2778
2880
|
* }
|
|
2779
2881
|
* ```
|
|
2780
2882
|
*/
|
|
2781
|
-
declare function injectAll(providers: Provider[], projectDir: string, scope: "project" | "global", content: string): Promise<Map<string, "created" | "added" | "updated">>;
|
|
2883
|
+
declare function injectAll(providers: Provider[], projectDir: string, scope: "project" | "global", content: string): Promise<Map<string, "created" | "added" | "updated" | "intact">>;
|
|
2884
|
+
/**
|
|
2885
|
+
* Options for ensuring a provider instruction file.
|
|
2886
|
+
*/
|
|
2887
|
+
interface EnsureProviderInstructionFileOptions {
|
|
2888
|
+
/** `@` references to inject (e.g. `["@AGENTS.md"]`). */
|
|
2889
|
+
references: string[];
|
|
2890
|
+
/** Optional inline content blocks. */
|
|
2891
|
+
content?: string[];
|
|
2892
|
+
/** Whether this is a global or project-level file. Defaults to `"project"`. */
|
|
2893
|
+
scope?: "project" | "global";
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
2896
|
+
* Result of ensuring a provider instruction file.
|
|
2897
|
+
*/
|
|
2898
|
+
interface EnsureProviderInstructionFileResult {
|
|
2899
|
+
/** Absolute path to the instruction file. */
|
|
2900
|
+
filePath: string;
|
|
2901
|
+
/** Instruction file name from the provider registry. */
|
|
2902
|
+
instructFile: string;
|
|
2903
|
+
/** Action taken. */
|
|
2904
|
+
action: "created" | "added" | "updated" | "intact";
|
|
2905
|
+
/** Provider ID. */
|
|
2906
|
+
providerId: string;
|
|
2907
|
+
}
|
|
2908
|
+
/**
|
|
2909
|
+
* Ensure a provider's instruction file exists with the correct CAAMP block.
|
|
2910
|
+
*
|
|
2911
|
+
* This is the canonical API for adapters and external packages to manage
|
|
2912
|
+
* provider instruction files. Instead of directly creating/modifying
|
|
2913
|
+
* CLAUDE.md, GEMINI.md, etc., callers should use this function to
|
|
2914
|
+
* delegate instruction file management to CAAMP.
|
|
2915
|
+
*
|
|
2916
|
+
* The instruction file name is resolved from CAAMP's provider registry
|
|
2917
|
+
* (single source of truth), not hardcoded by the caller.
|
|
2918
|
+
*
|
|
2919
|
+
* @param providerId - Provider ID from the registry (e.g. `"claude-code"`, `"gemini-cli"`)
|
|
2920
|
+
* @param projectDir - Absolute path to the project directory
|
|
2921
|
+
* @param options - References, content, and scope configuration
|
|
2922
|
+
* @returns Result with file path, action taken, and provider metadata
|
|
2923
|
+
* @throws {Error} If the provider ID is not found in the registry
|
|
2924
|
+
*
|
|
2925
|
+
* @example
|
|
2926
|
+
* ```typescript
|
|
2927
|
+
* // Adapter delegates instruction file creation to CAAMP:
|
|
2928
|
+
* const result = await ensureProviderInstructionFile("claude-code", "/project", {
|
|
2929
|
+
* references: ["@AGENTS.md"],
|
|
2930
|
+
* });
|
|
2931
|
+
* // result.filePath → "/project/CLAUDE.md"
|
|
2932
|
+
* // result.action → "created" | "added" | "updated" | "intact"
|
|
2933
|
+
*
|
|
2934
|
+
* // Global scope:
|
|
2935
|
+
* const globalResult = await ensureProviderInstructionFile("claude-code", homedir(), {
|
|
2936
|
+
* references: ["@~/.agents/AGENTS.md"],
|
|
2937
|
+
* scope: "global",
|
|
2938
|
+
* });
|
|
2939
|
+
* ```
|
|
2940
|
+
*/
|
|
2941
|
+
declare function ensureProviderInstructionFile(providerId: string, projectDir: string, options: EnsureProviderInstructionFileOptions): Promise<EnsureProviderInstructionFileResult>;
|
|
2942
|
+
/**
|
|
2943
|
+
* Ensure instruction files for multiple providers at once.
|
|
2944
|
+
*
|
|
2945
|
+
* Deduplicates by file path — providers sharing the same instruction file
|
|
2946
|
+
* (e.g. many providers use AGENTS.md) are only written once.
|
|
2947
|
+
*
|
|
2948
|
+
* @param providerIds - Array of provider IDs from the registry
|
|
2949
|
+
* @param projectDir - Absolute path to the project directory
|
|
2950
|
+
* @param options - References, content, and scope configuration
|
|
2951
|
+
* @returns Array of results, one per unique instruction file
|
|
2952
|
+
* @throws {Error} If any provider ID is not found in the registry
|
|
2953
|
+
*
|
|
2954
|
+
* @example
|
|
2955
|
+
* ```typescript
|
|
2956
|
+
* const results = await ensureAllProviderInstructionFiles(
|
|
2957
|
+
* ["claude-code", "cursor", "gemini-cli"],
|
|
2958
|
+
* "/project",
|
|
2959
|
+
* { references: ["@AGENTS.md"] },
|
|
2960
|
+
* );
|
|
2961
|
+
* ```
|
|
2962
|
+
*/
|
|
2963
|
+
declare function ensureAllProviderInstructionFiles(providerIds: string[], projectDir: string, options: EnsureProviderInstructionFileOptions): Promise<EnsureProviderInstructionFileResult[]>;
|
|
2782
2964
|
|
|
2783
2965
|
/**
|
|
2784
2966
|
* Instruction template management
|
|
@@ -3043,4 +3225,4 @@ declare function isVerbose(): boolean;
|
|
|
3043
3225
|
*/
|
|
3044
3226
|
declare function isQuiet(): boolean;
|
|
3045
3227
|
|
|
3046
|
-
export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, type CaampLockFile, type CleoChannel, type CleoProfileBuildResult, type ConfigFormat, type ConflictPolicy, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, type DetectionCacheOptions, type DetectionResult, type DualScopeConfigureOptions, type DualScopeConfigureResult, type GlobalOptions, type HookEvent, type InferredLockData, type InjectionCheckResult, type InjectionStatus, type InjectionTemplate, type InstallResult, type InstructionUpdateSummary, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpBatchOperation, type McpConflict, type McpConflictCode, type McpPlanApplyResult, type McpServerConfig, type McpServerEntry, type NormalizedRecommendationCriteria, type ParsedSource, type PlatformPaths, type Provider, type ProviderCapabilities, type ProviderHooksCapability, type ProviderPriority, type ProviderSkillsCapability, type ProviderSpawnCapability, type ProviderStatus, RECOMMENDATION_ERROR_CODES, type RankedSkillRecommendation, type RecommendSkillsResult, type RecommendationCriteriaInput, type RecommendationErrorCode, type RecommendationOptions, type RecommendationReason, type RecommendationReasonCode, type RecommendationScoreBreakdown, type RecommendationValidationIssue, type RecommendationValidationResult, type RecommendationWeights, type ReconcileOptions, type ReconcileResult, type SkillBatchOperation, type SkillEntry, type SkillInstallResult, type SkillLibrary, type SkillLibraryDispatchMatrix, type SkillLibraryEntry, type SkillLibraryManifest, type SkillLibraryManifestSkill, type SkillLibraryProfile, type SkillLibraryValidationIssue, type SkillLibraryValidationResult, type SkillMetadata, type SkillsPrecedence, type SourceType, type SpawnAdapter, type SpawnMechanism, type SpawnOptions, type SpawnResult, type SystemInfo, type TransportType, type ValidationIssue, type ValidationResult, _resetPlatformPathsCache, applyMcpInstallWithPolicy, buildCleoProfile, buildInjectionContent, buildLibraryFromFiles, buildServerConfig, buildSkillsMap, catalog, checkAllInjections, checkAllSkillUpdates, checkCommandReachability, checkInjection, checkSkillUpdate, clearRegisteredLibrary, configureProviderGlobalAndProject, deepMerge, detectAllProviders, detectMcpConfigConflicts, detectProjectProviders, detectProvider, discoverSkill, discoverSkills, ensureDir, extractVersionTag, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllProviders, getCanonicalSkillsDir, getCommonHookEvents, getEffectiveSkillsPaths, getInstalledProviders, getInstructionFiles, getLastSelectedAgents, getLockFilePath, getNestedValue, getPlatformLocations, getPlatformPaths, getProjectAgentsDir, getProvider, getProviderCapabilities, getProviderCount, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getRegistryVersion, getSpawnCapableProviders, getSystemInfo, getTrackedMcpServers, getTrackedSkills, getTransform, groupByInstructFile, inferCleoLockData, inject, injectAll, installBatchWithRollback, installMcpServer, installMcpServerToAll, installSkill, isCleoSource, isMarketplaceScoped, isQuiet, isVerbose, listAgentsMcpServers, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, normalizeCleoChannel, normalizeRecommendationCriteria, parseEnvAssignments, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, readLockFile, recommendSkills, reconcileCleoLock, recordMcpInstall, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpFromLock, removeMcpServer, removeSkill, removeSkillFromLock, resetDetectionCache, resolveAlias, resolveChannelFromServerName, resolveCleoServerName, resolveConfigPath, resolveProviderSkillsDirs, resolveRegistryTemplatePath, saveLastSelectedAgents, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setQuiet, setVerbose, toSarif, tokenizeCriteriaValue, updateInstructionsSingleOperation, validateRecommendationCriteria, validateSkill, writeConfig };
|
|
3228
|
+
export { type AuditFinding, type AuditResult, type AuditRule, type AuditSeverity, type BatchInstallOptions, type BatchInstallResult, type CaampLockFile, type CleoChannel, type CleoProfileBuildResult, type ConfigFormat, type ConflictPolicy, type CtDispatchMatrix, type CtManifest, type CtManifestSkill, type CtProfileDefinition, type CtSkillEntry, type CtValidationIssue, type CtValidationResult, type DetectionCacheOptions, type DetectionResult, type DualScopeConfigureOptions, type DualScopeConfigureResult, type EnsureProviderInstructionFileOptions, type EnsureProviderInstructionFileResult, type GlobalOptions, type HookEvent, type InferredLockData, type InjectionCheckResult, type InjectionStatus, type InjectionTemplate, type InstallResult, type InstructionUpdateSummary, type LockEntry, MarketplaceClient, type MarketplaceResult, type MarketplaceSearchResult, type MarketplaceSkill, type McpBatchOperation, type McpConflict, type McpConflictCode, type McpPlanApplyResult, type McpServerConfig, type McpServerEntry, type NormalizedRecommendationCriteria, type ParsedSource, type PlatformPaths, type Provider, type ProviderCapabilities, type ProviderHooksCapability, type ProviderPriority, type ProviderSkillsCapability, type ProviderSpawnCapability, type ProviderStatus, RECOMMENDATION_ERROR_CODES, type RankedSkillRecommendation, type RecommendSkillsResult, type RecommendationCriteriaInput, type RecommendationErrorCode, type RecommendationOptions, type RecommendationReason, type RecommendationReasonCode, type RecommendationScoreBreakdown, type RecommendationValidationIssue, type RecommendationValidationResult, type RecommendationWeights, type ReconcileOptions, type ReconcileResult, type SkillBatchOperation, type SkillEntry, type SkillInstallResult, type SkillIntegrityResult, type SkillIntegrityStatus, type SkillLibrary, type SkillLibraryDispatchMatrix, type SkillLibraryEntry, type SkillLibraryManifest, type SkillLibraryManifestSkill, type SkillLibraryProfile, type SkillLibraryValidationIssue, type SkillLibraryValidationResult, type SkillMetadata, type SkillsPrecedence, type SourceType, type SpawnAdapter, type SpawnMechanism, type SpawnOptions, type SpawnResult, type SystemInfo, type TransportType, type ValidationIssue, type ValidationResult, _resetPlatformPathsCache, applyMcpInstallWithPolicy, buildCleoProfile, buildInjectionContent, buildLibraryFromFiles, buildServerConfig, buildSkillsMap, catalog, checkAllInjections, checkAllSkillIntegrity, checkAllSkillUpdates, checkCommandReachability, checkInjection, checkSkillIntegrity, checkSkillUpdate, clearRegisteredLibrary, configureProviderGlobalAndProject, deepMerge, detectAllProviders, detectMcpConfigConflicts, detectProjectProviders, detectProvider, discoverSkill, discoverSkills, ensureAllProviderInstructionFiles, ensureDir, ensureProviderInstructionFile, extractVersionTag, formatSkillRecommendations, generateInjectionContent, generateSkillsSection, getAgentsConfigPath, getAgentsHome, getAgentsInstructFile, getAgentsLinksDir, getAgentsMcpDir, getAgentsMcpServersPath, getAgentsSpecDir, getAgentsWikiDir, getAllProviders, getCanonicalSkillsDir, getCommonHookEvents, getEffectiveSkillsPaths, getInstalledProviders, getInstructionFiles, getLastSelectedAgents, getLockFilePath, getNestedValue, getPlatformLocations, getPlatformPaths, getProjectAgentsDir, getProvider, getProviderCapabilities, getProviderCount, getProvidersByHookEvent, getProvidersByInstructFile, getProvidersByPriority, getProvidersBySkillsPrecedence, getProvidersBySpawnCapability, getProvidersByStatus, getRegistryVersion, getSpawnCapableProviders, getSystemInfo, getTrackedMcpServers, getTrackedSkills, getTransform, groupByInstructFile, inferCleoLockData, inject, injectAll, installBatchWithRollback, installMcpServer, installMcpServerToAll, installSkill, isCaampOwnedSkill, isCleoSource, isMarketplaceScoped, isQuiet, isVerbose, listAgentsMcpServers, listAllMcpServers, listCanonicalSkills, listMcpServers, loadLibraryFromModule, normalizeCleoChannel, normalizeRecommendationCriteria, parseEnvAssignments, parseInjectionContent, parseSkillFile, parseSource, providerSupports, providerSupportsById, rankSkills, readConfig, readLockFile, recommendSkills, reconcileCleoLock, recordMcpInstall, recordSkillInstall, registerSkillLibrary, registerSkillLibraryFromPath, removeConfig, removeInjection, removeMcpFromLock, removeMcpServer, removeSkill, removeSkillFromLock, resetDetectionCache, resolveAlias, resolveChannelFromServerName, resolveCleoServerName, resolveConfigPath, resolveProviderSkillsDirs, resolveRegistryTemplatePath, saveLastSelectedAgents, scanDirectory, scanFile, scoreSkillRecommendation, searchSkills, selectProvidersByMinimumPriority, setQuiet, setVerbose, shouldOverrideSkill, toSarif, tokenizeCriteriaValue, updateInstructionsSingleOperation, validateInstructionIntegrity, validateRecommendationCriteria, validateSkill, writeConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MarketplaceClient,
|
|
3
3
|
RECOMMENDATION_ERROR_CODES,
|
|
4
|
-
_resetPlatformPathsCache,
|
|
5
4
|
applyMcpInstallWithPolicy,
|
|
6
5
|
buildCleoProfile,
|
|
7
|
-
buildInjectionContent,
|
|
8
6
|
buildLibraryFromFiles,
|
|
9
7
|
buildServerConfig,
|
|
10
|
-
buildSkillsMap,
|
|
11
8
|
catalog_exports,
|
|
12
|
-
checkAllInjections,
|
|
13
9
|
checkAllSkillUpdates,
|
|
14
10
|
checkCommandReachability,
|
|
15
|
-
checkInjection,
|
|
16
11
|
checkSkillUpdate,
|
|
17
12
|
clearRegisteredLibrary,
|
|
18
13
|
configureProviderGlobalAndProject,
|
|
@@ -26,47 +21,13 @@ import {
|
|
|
26
21
|
ensureDir,
|
|
27
22
|
extractVersionTag,
|
|
28
23
|
formatSkillRecommendations,
|
|
29
|
-
generateInjectionContent,
|
|
30
|
-
generateSkillsSection,
|
|
31
|
-
getAgentsConfigPath,
|
|
32
|
-
getAgentsHome,
|
|
33
|
-
getAgentsInstructFile,
|
|
34
|
-
getAgentsLinksDir,
|
|
35
|
-
getAgentsMcpDir,
|
|
36
|
-
getAgentsMcpServersPath,
|
|
37
|
-
getAgentsSpecDir,
|
|
38
|
-
getAgentsWikiDir,
|
|
39
|
-
getAllProviders,
|
|
40
|
-
getCanonicalSkillsDir,
|
|
41
|
-
getCommonHookEvents,
|
|
42
|
-
getEffectiveSkillsPaths,
|
|
43
24
|
getInstalledProviders,
|
|
44
|
-
getInstructionFiles,
|
|
45
25
|
getLastSelectedAgents,
|
|
46
|
-
getLockFilePath,
|
|
47
26
|
getNestedValue,
|
|
48
|
-
getPlatformLocations,
|
|
49
|
-
getPlatformPaths,
|
|
50
|
-
getProjectAgentsDir,
|
|
51
|
-
getProvider,
|
|
52
|
-
getProviderCapabilities,
|
|
53
|
-
getProviderCount,
|
|
54
|
-
getProvidersByHookEvent,
|
|
55
|
-
getProvidersByInstructFile,
|
|
56
|
-
getProvidersByPriority,
|
|
57
|
-
getProvidersBySkillsPrecedence,
|
|
58
|
-
getProvidersBySpawnCapability,
|
|
59
|
-
getProvidersByStatus,
|
|
60
|
-
getRegistryVersion,
|
|
61
|
-
getSpawnCapableProviders,
|
|
62
|
-
getSystemInfo,
|
|
63
27
|
getTrackedMcpServers,
|
|
64
28
|
getTrackedSkills,
|
|
65
29
|
getTransform,
|
|
66
|
-
groupByInstructFile,
|
|
67
30
|
inferCleoLockData,
|
|
68
|
-
inject,
|
|
69
|
-
injectAll,
|
|
70
31
|
installBatchWithRollback,
|
|
71
32
|
installMcpServer,
|
|
72
33
|
installMcpServerToAll,
|
|
@@ -83,11 +44,8 @@ import {
|
|
|
83
44
|
normalizeCleoChannel,
|
|
84
45
|
normalizeRecommendationCriteria,
|
|
85
46
|
parseEnvAssignments,
|
|
86
|
-
parseInjectionContent,
|
|
87
47
|
parseSkillFile,
|
|
88
48
|
parseSource,
|
|
89
|
-
providerSupports,
|
|
90
|
-
providerSupportsById,
|
|
91
49
|
rankSkills,
|
|
92
50
|
readConfig,
|
|
93
51
|
readLockFile,
|
|
@@ -98,18 +56,14 @@ import {
|
|
|
98
56
|
registerSkillLibrary,
|
|
99
57
|
registerSkillLibraryFromPath,
|
|
100
58
|
removeConfig,
|
|
101
|
-
removeInjection,
|
|
102
59
|
removeMcpFromLock,
|
|
103
60
|
removeMcpServer,
|
|
104
61
|
removeSkill,
|
|
105
62
|
removeSkillFromLock,
|
|
106
63
|
resetDetectionCache,
|
|
107
|
-
resolveAlias,
|
|
108
64
|
resolveChannelFromServerName,
|
|
109
65
|
resolveCleoServerName,
|
|
110
66
|
resolveConfigPath,
|
|
111
|
-
resolveProviderSkillsDirs,
|
|
112
|
-
resolveRegistryTemplatePath,
|
|
113
67
|
saveLastSelectedAgents,
|
|
114
68
|
scanDirectory,
|
|
115
69
|
scanFile,
|
|
@@ -124,7 +78,200 @@ import {
|
|
|
124
78
|
validateRecommendationCriteria,
|
|
125
79
|
validateSkill,
|
|
126
80
|
writeConfig
|
|
127
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-YWO4I7LI.js";
|
|
82
|
+
import {
|
|
83
|
+
_resetPlatformPathsCache,
|
|
84
|
+
buildInjectionContent,
|
|
85
|
+
buildSkillsMap,
|
|
86
|
+
checkAllInjections,
|
|
87
|
+
checkInjection,
|
|
88
|
+
ensureAllProviderInstructionFiles,
|
|
89
|
+
ensureProviderInstructionFile,
|
|
90
|
+
generateInjectionContent,
|
|
91
|
+
generateSkillsSection,
|
|
92
|
+
getAgentsConfigPath,
|
|
93
|
+
getAgentsHome,
|
|
94
|
+
getAgentsInstructFile,
|
|
95
|
+
getAgentsLinksDir,
|
|
96
|
+
getAgentsMcpDir,
|
|
97
|
+
getAgentsMcpServersPath,
|
|
98
|
+
getAgentsSpecDir,
|
|
99
|
+
getAgentsWikiDir,
|
|
100
|
+
getAllProviders,
|
|
101
|
+
getCanonicalSkillsDir,
|
|
102
|
+
getCommonHookEvents,
|
|
103
|
+
getEffectiveSkillsPaths,
|
|
104
|
+
getInstructionFiles,
|
|
105
|
+
getLockFilePath,
|
|
106
|
+
getPlatformLocations,
|
|
107
|
+
getPlatformPaths,
|
|
108
|
+
getProjectAgentsDir,
|
|
109
|
+
getProvider,
|
|
110
|
+
getProviderCapabilities,
|
|
111
|
+
getProviderCount,
|
|
112
|
+
getProvidersByHookEvent,
|
|
113
|
+
getProvidersByInstructFile,
|
|
114
|
+
getProvidersByPriority,
|
|
115
|
+
getProvidersBySkillsPrecedence,
|
|
116
|
+
getProvidersBySpawnCapability,
|
|
117
|
+
getProvidersByStatus,
|
|
118
|
+
getRegistryVersion,
|
|
119
|
+
getSpawnCapableProviders,
|
|
120
|
+
getSystemInfo,
|
|
121
|
+
groupByInstructFile,
|
|
122
|
+
inject,
|
|
123
|
+
injectAll,
|
|
124
|
+
parseInjectionContent,
|
|
125
|
+
providerSupports,
|
|
126
|
+
providerSupportsById,
|
|
127
|
+
removeInjection,
|
|
128
|
+
resolveAlias,
|
|
129
|
+
resolveProviderSkillsDirs,
|
|
130
|
+
resolveRegistryTemplatePath
|
|
131
|
+
} from "./chunk-ZVRDBY6L.js";
|
|
132
|
+
|
|
133
|
+
// src/core/skills/integrity.ts
|
|
134
|
+
import { existsSync, lstatSync, readlinkSync } from "fs";
|
|
135
|
+
import { join, resolve } from "path";
|
|
136
|
+
var CAAMP_SKILL_PREFIX = "ct-";
|
|
137
|
+
function isCaampOwnedSkill(skillName) {
|
|
138
|
+
return skillName.startsWith(CAAMP_SKILL_PREFIX);
|
|
139
|
+
}
|
|
140
|
+
async function checkSkillIntegrity(skillName, providers, scope = "global", projectDir) {
|
|
141
|
+
const lock = await readLockFile();
|
|
142
|
+
const entry = lock.skills[skillName];
|
|
143
|
+
const isCaampOwned = isCaampOwnedSkill(skillName);
|
|
144
|
+
if (!entry) {
|
|
145
|
+
const canonicalPath2 = join(getCanonicalSkillsDir(), skillName);
|
|
146
|
+
return {
|
|
147
|
+
name: skillName,
|
|
148
|
+
status: "not-tracked",
|
|
149
|
+
canonicalExists: existsSync(canonicalPath2),
|
|
150
|
+
canonicalPath: null,
|
|
151
|
+
linkStatuses: [],
|
|
152
|
+
isCaampOwned,
|
|
153
|
+
issue: "Skill is not tracked in the CAAMP lock file"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const canonicalPath = entry.canonicalPath;
|
|
157
|
+
const canonicalExists = existsSync(canonicalPath);
|
|
158
|
+
const linkStatuses = [];
|
|
159
|
+
for (const provider of providers) {
|
|
160
|
+
const targetDirs = resolveProviderSkillsDirs(provider, scope, projectDir);
|
|
161
|
+
for (const skillsDir of targetDirs) {
|
|
162
|
+
if (!skillsDir) continue;
|
|
163
|
+
const linkPath = join(skillsDir, skillName);
|
|
164
|
+
const exists = existsSync(linkPath);
|
|
165
|
+
let isSymlink = false;
|
|
166
|
+
let pointsToCanonical = false;
|
|
167
|
+
if (exists) {
|
|
168
|
+
try {
|
|
169
|
+
const stat = lstatSync(linkPath);
|
|
170
|
+
isSymlink = stat.isSymbolicLink();
|
|
171
|
+
if (isSymlink) {
|
|
172
|
+
const target = resolve(readlinkSync(linkPath));
|
|
173
|
+
pointsToCanonical = target === resolve(canonicalPath);
|
|
174
|
+
}
|
|
175
|
+
} catch {
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
linkStatuses.push({
|
|
179
|
+
providerId: provider.id,
|
|
180
|
+
linkPath,
|
|
181
|
+
exists,
|
|
182
|
+
isSymlink,
|
|
183
|
+
pointsToCanonical
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!canonicalExists) {
|
|
188
|
+
return {
|
|
189
|
+
name: skillName,
|
|
190
|
+
status: "missing-canonical",
|
|
191
|
+
canonicalExists,
|
|
192
|
+
canonicalPath,
|
|
193
|
+
linkStatuses,
|
|
194
|
+
isCaampOwned,
|
|
195
|
+
issue: `Canonical directory missing: ${canonicalPath}`
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const brokenLinks = linkStatuses.filter((l) => !l.exists);
|
|
199
|
+
const tamperedLinks = linkStatuses.filter((l) => l.exists && !l.pointsToCanonical);
|
|
200
|
+
if (tamperedLinks.length > 0) {
|
|
201
|
+
return {
|
|
202
|
+
name: skillName,
|
|
203
|
+
status: "tampered",
|
|
204
|
+
canonicalExists,
|
|
205
|
+
canonicalPath,
|
|
206
|
+
linkStatuses,
|
|
207
|
+
isCaampOwned,
|
|
208
|
+
issue: `${tamperedLinks.length} link(s) do not point to canonical path`
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (brokenLinks.length > 0) {
|
|
212
|
+
return {
|
|
213
|
+
name: skillName,
|
|
214
|
+
status: "broken-symlink",
|
|
215
|
+
canonicalExists,
|
|
216
|
+
canonicalPath,
|
|
217
|
+
linkStatuses,
|
|
218
|
+
isCaampOwned,
|
|
219
|
+
issue: `${brokenLinks.length} symlink(s) missing`
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
name: skillName,
|
|
224
|
+
status: "intact",
|
|
225
|
+
canonicalExists,
|
|
226
|
+
canonicalPath,
|
|
227
|
+
linkStatuses,
|
|
228
|
+
isCaampOwned
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async function checkAllSkillIntegrity(providers, scope = "global", projectDir) {
|
|
232
|
+
const lock = await readLockFile();
|
|
233
|
+
const results = /* @__PURE__ */ new Map();
|
|
234
|
+
for (const skillName of Object.keys(lock.skills)) {
|
|
235
|
+
const result = await checkSkillIntegrity(skillName, providers, scope, projectDir);
|
|
236
|
+
results.set(skillName, result);
|
|
237
|
+
}
|
|
238
|
+
return results;
|
|
239
|
+
}
|
|
240
|
+
function shouldOverrideSkill(skillName, incomingSource, existingEntry) {
|
|
241
|
+
if (!existingEntry) return true;
|
|
242
|
+
if (isCaampOwnedSkill(skillName)) {
|
|
243
|
+
if (existingEntry.sourceType === "library") return true;
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
async function validateInstructionIntegrity(providers, projectDir, scope, expectedContent) {
|
|
249
|
+
const { checkAllInjections: checkAllInjections2 } = await import("./injector-XGI7NNZA.js");
|
|
250
|
+
const results = await checkAllInjections2(providers, projectDir, scope, expectedContent);
|
|
251
|
+
const issues = [];
|
|
252
|
+
for (const result of results) {
|
|
253
|
+
if (result.status === "missing") {
|
|
254
|
+
issues.push({
|
|
255
|
+
file: result.file,
|
|
256
|
+
providerId: result.provider,
|
|
257
|
+
issue: "Instruction file does not exist"
|
|
258
|
+
});
|
|
259
|
+
} else if (result.status === "none") {
|
|
260
|
+
issues.push({
|
|
261
|
+
file: result.file,
|
|
262
|
+
providerId: result.provider,
|
|
263
|
+
issue: "No CAAMP injection block found"
|
|
264
|
+
});
|
|
265
|
+
} else if (result.status === "outdated") {
|
|
266
|
+
issues.push({
|
|
267
|
+
file: result.file,
|
|
268
|
+
providerId: result.provider,
|
|
269
|
+
issue: "CAAMP injection block is outdated"
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return issues;
|
|
274
|
+
}
|
|
128
275
|
export {
|
|
129
276
|
MarketplaceClient,
|
|
130
277
|
RECOMMENDATION_ERROR_CODES,
|
|
@@ -137,9 +284,11 @@ export {
|
|
|
137
284
|
buildSkillsMap,
|
|
138
285
|
catalog_exports as catalog,
|
|
139
286
|
checkAllInjections,
|
|
287
|
+
checkAllSkillIntegrity,
|
|
140
288
|
checkAllSkillUpdates,
|
|
141
289
|
checkCommandReachability,
|
|
142
290
|
checkInjection,
|
|
291
|
+
checkSkillIntegrity,
|
|
143
292
|
checkSkillUpdate,
|
|
144
293
|
clearRegisteredLibrary,
|
|
145
294
|
configureProviderGlobalAndProject,
|
|
@@ -150,7 +299,9 @@ export {
|
|
|
150
299
|
detectProvider,
|
|
151
300
|
discoverSkill,
|
|
152
301
|
discoverSkills,
|
|
302
|
+
ensureAllProviderInstructionFiles,
|
|
153
303
|
ensureDir,
|
|
304
|
+
ensureProviderInstructionFile,
|
|
154
305
|
extractVersionTag,
|
|
155
306
|
formatSkillRecommendations,
|
|
156
307
|
generateInjectionContent,
|
|
@@ -198,6 +349,7 @@ export {
|
|
|
198
349
|
installMcpServer,
|
|
199
350
|
installMcpServerToAll,
|
|
200
351
|
installSkill,
|
|
352
|
+
isCaampOwnedSkill,
|
|
201
353
|
isCleoSource,
|
|
202
354
|
isMarketplaceScoped,
|
|
203
355
|
isQuiet,
|
|
@@ -245,9 +397,11 @@ export {
|
|
|
245
397
|
selectProvidersByMinimumPriority,
|
|
246
398
|
setQuiet,
|
|
247
399
|
setVerbose,
|
|
400
|
+
shouldOverrideSkill,
|
|
248
401
|
toSarif,
|
|
249
402
|
tokenizeCriteriaValue,
|
|
250
403
|
updateInstructionsSingleOperation,
|
|
404
|
+
validateInstructionIntegrity,
|
|
251
405
|
validateRecommendationCriteria,
|
|
252
406
|
validateSkill,
|
|
253
407
|
writeConfig
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/skills/integrity.ts"],"sourcesContent":["/**\n * Skill integrity checking\n *\n * Validates that installed skills have intact symlinks, correct canonical paths,\n * and enforces ct-* prefix priority for CAAMP-shipped skills.\n */\n\nimport { existsSync, lstatSync, readlinkSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { LockEntry, Provider } from \"../../types.js\";\nimport { getCanonicalSkillsDir, resolveProviderSkillsDirs } from \"../paths/standard.js\";\nimport { readLockFile, updateLockFile } from \"../lock-utils.js\";\n\n/** CAAMP-reserved skill prefix. Skills with this prefix are owned by CAAMP. */\nconst CAAMP_SKILL_PREFIX = \"ct-\";\n\n/**\n * Status of a single skill's integrity check.\n */\nexport type SkillIntegrityStatus =\n | \"intact\"\n | \"broken-symlink\"\n | \"missing-canonical\"\n | \"missing-link\"\n | \"not-tracked\"\n | \"tampered\";\n\n/**\n * Result of checking a single skill's integrity.\n */\nexport interface SkillIntegrityResult {\n /** Skill name. */\n name: string;\n /** Overall integrity status. */\n status: SkillIntegrityStatus;\n /** Whether the canonical directory exists. */\n canonicalExists: boolean;\n /** Expected canonical path from lock file. */\n canonicalPath: string | null;\n /** Provider link statuses — which agents have valid symlinks. */\n linkStatuses: Array<{\n providerId: string;\n linkPath: string;\n exists: boolean;\n isSymlink: boolean;\n pointsToCanonical: boolean;\n }>;\n /** Whether this is a CAAMP-reserved (ct-*) skill. */\n isCaampOwned: boolean;\n /** Human-readable issue description, if any. */\n issue?: string;\n}\n\n/**\n * Check whether a skill name is reserved by CAAMP (ct-* prefix).\n *\n * @param skillName - Skill name to check\n * @returns `true` if the skill name starts with `ct-`\n */\nexport function isCaampOwnedSkill(skillName: string): boolean {\n return skillName.startsWith(CAAMP_SKILL_PREFIX);\n}\n\n/**\n * Check the integrity of a single installed skill.\n *\n * Validates:\n * - Canonical directory exists on disk\n * - Lock file entry matches actual state\n * - Symlinks from provider skill directories point to the canonical path\n *\n * @param skillName - Name of the skill to check\n * @param providers - Providers to check symlinks for\n * @param scope - Whether to check global or project links\n * @param projectDir - Project directory (for project scope)\n * @returns Integrity check result\n */\nexport async function checkSkillIntegrity(\n skillName: string,\n providers: Provider[],\n scope: \"global\" | \"project\" = \"global\",\n projectDir?: string,\n): Promise<SkillIntegrityResult> {\n const lock = await readLockFile();\n const entry = lock.skills[skillName];\n const isCaampOwned = isCaampOwnedSkill(skillName);\n\n // Not tracked in lock file\n if (!entry) {\n const canonicalPath = join(getCanonicalSkillsDir(), skillName);\n return {\n name: skillName,\n status: \"not-tracked\",\n canonicalExists: existsSync(canonicalPath),\n canonicalPath: null,\n linkStatuses: [],\n isCaampOwned,\n issue: \"Skill is not tracked in the CAAMP lock file\",\n };\n }\n\n const canonicalPath = entry.canonicalPath;\n const canonicalExists = existsSync(canonicalPath);\n\n // Check symlinks for each provider\n const linkStatuses: SkillIntegrityResult[\"linkStatuses\"] = [];\n\n for (const provider of providers) {\n const targetDirs = resolveProviderSkillsDirs(provider, scope, projectDir);\n for (const skillsDir of targetDirs) {\n if (!skillsDir) continue;\n\n const linkPath = join(skillsDir, skillName);\n const exists = existsSync(linkPath);\n let isSymlink = false;\n let pointsToCanonical = false;\n\n if (exists) {\n try {\n const stat = lstatSync(linkPath);\n isSymlink = stat.isSymbolicLink();\n if (isSymlink) {\n const target = resolve(readlinkSync(linkPath));\n pointsToCanonical = target === resolve(canonicalPath);\n }\n } catch {\n // Can't stat — treat as broken\n }\n }\n\n linkStatuses.push({\n providerId: provider.id,\n linkPath,\n exists,\n isSymlink,\n pointsToCanonical,\n });\n }\n }\n\n // Determine overall status\n if (!canonicalExists) {\n return {\n name: skillName,\n status: \"missing-canonical\",\n canonicalExists,\n canonicalPath,\n linkStatuses,\n isCaampOwned,\n issue: `Canonical directory missing: ${canonicalPath}`,\n };\n }\n\n const brokenLinks = linkStatuses.filter((l) => !l.exists);\n const tamperedLinks = linkStatuses.filter((l) => l.exists && !l.pointsToCanonical);\n\n if (tamperedLinks.length > 0) {\n return {\n name: skillName,\n status: \"tampered\",\n canonicalExists,\n canonicalPath,\n linkStatuses,\n isCaampOwned,\n issue: `${tamperedLinks.length} link(s) do not point to canonical path`,\n };\n }\n\n if (brokenLinks.length > 0) {\n return {\n name: skillName,\n status: \"broken-symlink\",\n canonicalExists,\n canonicalPath,\n linkStatuses,\n isCaampOwned,\n issue: `${brokenLinks.length} symlink(s) missing`,\n };\n }\n\n return {\n name: skillName,\n status: \"intact\",\n canonicalExists,\n canonicalPath,\n linkStatuses,\n isCaampOwned,\n };\n}\n\n/**\n * Check integrity of all tracked skills.\n *\n * @param providers - Providers to check symlinks for\n * @param scope - Whether to check global or project links\n * @param projectDir - Project directory (for project scope)\n * @returns Map of skill name to integrity result\n */\nexport async function checkAllSkillIntegrity(\n providers: Provider[],\n scope: \"global\" | \"project\" = \"global\",\n projectDir?: string,\n): Promise<Map<string, SkillIntegrityResult>> {\n const lock = await readLockFile();\n const results = new Map<string, SkillIntegrityResult>();\n\n for (const skillName of Object.keys(lock.skills)) {\n const result = await checkSkillIntegrity(skillName, providers, scope, projectDir);\n results.set(skillName, result);\n }\n\n return results;\n}\n\n/**\n * Resolve a skill name conflict where a user-installed skill collides\n * with a CAAMP-owned (ct-*) skill.\n *\n * CAAMP-owned skills always win. Returns `true` if the incoming skill\n * should take precedence over the existing installation.\n *\n * @param skillName - Skill name to check\n * @param incomingSource - Source of the incoming skill installation\n * @param existingEntry - Existing lock entry, if any\n * @returns `true` if the incoming installation should proceed\n */\nexport function shouldOverrideSkill(\n skillName: string,\n incomingSource: string,\n existingEntry: LockEntry | undefined,\n): boolean {\n // No existing entry — always allow\n if (!existingEntry) return true;\n\n // For ct-* skills, CAAMP package source always wins\n if (isCaampOwnedSkill(skillName)) {\n // If incoming is from CAAMP package (library source), it always wins\n if (existingEntry.sourceType === \"library\") return true;\n // If existing is from CAAMP but incoming is user, CAAMP wins (block user)\n return true;\n }\n\n // Non-ct-* skills: user always wins\n return true;\n}\n\n/**\n * Validate instruction file injection status across all providers.\n *\n * Checks that CAAMP blocks exist and are current in all relevant\n * instruction files.\n *\n * @param providers - Providers to check\n * @param projectDir - Project directory\n * @param scope - Whether to check global or project files\n * @param expectedContent - Expected CAAMP block content\n * @returns Array of file paths with issues\n */\nexport async function validateInstructionIntegrity(\n providers: Provider[],\n projectDir: string,\n scope: \"project\" | \"global\",\n expectedContent?: string,\n): Promise<Array<{ file: string; providerId: string; issue: string }>> {\n const { checkAllInjections } = await import(\"../instructions/injector.js\");\n const results = await checkAllInjections(providers, projectDir, scope, expectedContent);\n const issues: Array<{ file: string; providerId: string; issue: string }> = [];\n\n for (const result of results) {\n if (result.status === \"missing\") {\n issues.push({\n file: result.file,\n providerId: result.provider,\n issue: \"Instruction file does not exist\",\n });\n } else if (result.status === \"none\") {\n issues.push({\n file: result.file,\n providerId: result.provider,\n issue: \"No CAAMP injection block found\",\n });\n } else if (result.status === \"outdated\") {\n issues.push({\n file: result.file,\n providerId: result.provider,\n issue: \"CAAMP injection block is outdated\",\n });\n }\n }\n\n return issues;\n}\n"],"mappings":"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","names":["canonicalPath","checkAllInjections"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkAllInjections,
|
|
3
|
+
checkInjection,
|
|
4
|
+
ensureAllProviderInstructionFiles,
|
|
5
|
+
ensureProviderInstructionFile,
|
|
6
|
+
inject,
|
|
7
|
+
injectAll,
|
|
8
|
+
removeInjection
|
|
9
|
+
} from "./chunk-ZVRDBY6L.js";
|
|
10
|
+
export {
|
|
11
|
+
checkAllInjections,
|
|
12
|
+
checkInjection,
|
|
13
|
+
ensureAllProviderInstructionFiles,
|
|
14
|
+
ensureProviderInstructionFile,
|
|
15
|
+
inject,
|
|
16
|
+
injectAll,
|
|
17
|
+
removeInjection
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=injector-XGI7NNZA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
package/providers/registry.json
CHANGED
|
File without changes
|