@skillsmith/core 0.12.1 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +155 -0
- package/README.md +2 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts +5 -3
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +23 -33
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.registry-sync.d.ts +28 -0
- package/dist/src/api/client.registry-sync.d.ts.map +1 -0
- package/dist/src/api/client.registry-sync.js +36 -0
- package/dist/src/api/client.registry-sync.js.map +1 -0
- package/dist/src/api/client.test.js +185 -0
- package/dist/src/api/client.test.js.map +1 -1
- package/dist/src/api/client.toSkill.d.ts +16 -0
- package/dist/src/api/client.toSkill.d.ts.map +1 -0
- package/dist/src/api/client.toSkill.js +46 -0
- package/dist/src/api/client.toSkill.js.map +1 -0
- package/dist/src/api/client.types.d.ts +22 -0
- package/dist/src/api/client.types.d.ts.map +1 -1
- package/dist/src/api/index.d.ts +1 -1
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/schemas.d.ts +28 -0
- package/dist/src/api/schemas.d.ts.map +1 -1
- package/dist/src/api/schemas.js +13 -0
- package/dist/src/api/schemas.js.map +1 -1
- package/dist/src/audit/remote-audit.d.ts +85 -0
- package/dist/src/audit/remote-audit.d.ts.map +1 -1
- package/dist/src/audit/remote-audit.js +126 -3
- package/dist/src/audit/remote-audit.js.map +1 -1
- package/dist/src/audit/remote-audit.test.js +217 -1
- package/dist/src/audit/remote-audit.test.js.map +1 -1
- package/dist/src/config/index.d.ts +1 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/db/migration-runner.d.ts.map +1 -1
- package/dist/src/db/migration-runner.js +6 -0
- package/dist/src/db/migration-runner.js.map +1 -1
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts +36 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.d.ts.map +1 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js +38 -0
- package/dist/src/db/migrations/v18-skill-versions-real-content-hash.js.map +1 -0
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +3 -1
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/exports/services.d.ts +3 -7
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.install.d.ts +18 -0
- package/dist/src/exports/services.install.d.ts.map +1 -0
- package/dist/src/exports/services.install.js +62 -0
- package/dist/src/exports/services.install.js.map +1 -0
- package/dist/src/exports/services.js +12 -32
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/exports/types.d.ts +1 -1
- package/dist/src/exports/types.d.ts.map +1 -1
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/agent-config-merge.json.d.ts +5 -4
- package/dist/src/install/agent-config-merge.json.d.ts.map +1 -1
- package/dist/src/install/agent-config-merge.json.js +10 -9
- package/dist/src/install/agent-config-merge.json.js.map +1 -1
- package/dist/src/install/agent-config-merge.types.d.ts +11 -1
- package/dist/src/install/agent-config-merge.types.d.ts.map +1 -1
- package/dist/src/install/agent-config-merge.types.js.map +1 -1
- package/dist/src/install/agent-harness-targets.d.ts +30 -2
- package/dist/src/install/agent-harness-targets.d.ts.map +1 -1
- package/dist/src/install/agent-harness-targets.js +17 -0
- package/dist/src/install/agent-harness-targets.js.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.d.ts +28 -3
- package/dist/src/install/agent-manifest-path-guard.d.ts.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.js +59 -3
- package/dist/src/install/agent-manifest-path-guard.js.map +1 -1
- package/dist/src/install/agent-manifest-path-guard.test.js +27 -1
- package/dist/src/install/agent-manifest-path-guard.test.js.map +1 -1
- package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts +74 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.js +106 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.js.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js +157 -0
- package/dist/src/install/agent-pack-installer.antigravity-mcp.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts +53 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.js +207 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.js.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.js +285 -0
- package/dist/src/install/agent-pack-installer.cursor-mcp.test.js.map +1 -0
- package/dist/src/install/agent-pack-installer.d.ts +8 -0
- package/dist/src/install/agent-pack-installer.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.entry.d.ts +120 -3
- package/dist/src/install/agent-pack-installer.entry.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.entry.js +166 -3
- package/dist/src/install/agent-pack-installer.entry.js.map +1 -1
- package/dist/src/install/agent-pack-installer.js +97 -3
- package/dist/src/install/agent-pack-installer.js.map +1 -1
- package/dist/src/install/agent-pack-installer.types.d.ts +27 -0
- package/dist/src/install/agent-pack-installer.types.d.ts.map +1 -1
- package/dist/src/install/agent-pack-installer.types.js +6 -0
- package/dist/src/install/agent-pack-installer.types.js.map +1 -1
- package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts +2 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.d.ts.map +1 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.js +148 -0
- package/dist/src/install/agent-pack-installer.workspace-scope.test.js.map +1 -0
- package/dist/src/install/agent-pack-uninstaller.d.ts +18 -7
- package/dist/src/install/agent-pack-uninstaller.d.ts.map +1 -1
- package/dist/src/install/agent-pack-uninstaller.js +59 -9
- package/dist/src/install/agent-pack-uninstaller.js.map +1 -1
- package/dist/src/install/agent-pack-uninstaller.test.js +74 -1
- package/dist/src/install/agent-pack-uninstaller.test.js.map +1 -1
- package/dist/src/install/fan-out.d.ts.map +1 -1
- package/dist/src/install/fan-out.js +6 -0
- package/dist/src/install/fan-out.js.map +1 -1
- package/dist/src/install/index.d.ts +2 -0
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +2 -0
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/workspace-scope.d.ts +207 -0
- package/dist/src/install/workspace-scope.d.ts.map +1 -0
- package/dist/src/install/workspace-scope.js +275 -0
- package/dist/src/install/workspace-scope.js.map +1 -0
- package/dist/src/install/workspace-scope.test.d.ts +2 -0
- package/dist/src/install/workspace-scope.test.d.ts.map +1 -0
- package/dist/src/install/workspace-scope.test.js +378 -0
- package/dist/src/install/workspace-scope.test.js.map +1 -0
- package/dist/src/security/__tests__/pathValidation.test.js +30 -1
- package/dist/src/security/__tests__/pathValidation.test.js.map +1 -1
- package/dist/src/services/SubagentGenerator.client-profiles.d.ts +258 -0
- package/dist/src/services/SubagentGenerator.client-profiles.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.client-profiles.js +260 -0
- package/dist/src/services/SubagentGenerator.client-profiles.js.map +1 -0
- package/dist/src/services/SubagentGenerator.d.ts +19 -41
- package/dist/src/services/SubagentGenerator.d.ts.map +1 -1
- package/dist/src/services/SubagentGenerator.helpers.d.ts +64 -0
- package/dist/src/services/SubagentGenerator.helpers.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.helpers.js +228 -0
- package/dist/src/services/SubagentGenerator.helpers.js.map +1 -0
- package/dist/src/services/SubagentGenerator.js +66 -208
- package/dist/src/services/SubagentGenerator.js.map +1 -1
- package/dist/src/services/SubagentGenerator.types.d.ts +45 -0
- package/dist/src/services/SubagentGenerator.types.d.ts.map +1 -0
- package/dist/src/services/SubagentGenerator.types.js +14 -0
- package/dist/src/services/SubagentGenerator.types.js.map +1 -0
- package/dist/src/services/TransformationService.d.ts +18 -61
- package/dist/src/services/TransformationService.d.ts.map +1 -1
- package/dist/src/services/TransformationService.js +29 -17
- package/dist/src/services/TransformationService.js.map +1 -1
- package/dist/src/services/TransformationService.types.d.ts +74 -0
- package/dist/src/services/TransformationService.types.d.ts.map +1 -0
- package/dist/src/services/TransformationService.types.js +8 -0
- package/dist/src/services/TransformationService.types.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts +5 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.d.ts.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js +72 -0
- package/dist/src/services/__tests__/SubagentGenerator.client-profiles.test.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts +2 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.d.ts.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js +61 -0
- package/dist/src/services/__tests__/SubagentGenerator.helpers.test.js.map +1 -0
- package/dist/src/services/__tests__/SubagentGenerator.test.js +155 -0
- package/dist/src/services/__tests__/SubagentGenerator.test.js.map +1 -1
- package/dist/src/services/__tests__/TransformationService.test.js +48 -0
- package/dist/src/services/__tests__/TransformationService.test.js.map +1 -1
- package/dist/src/services/agent-pack/agent-pack.test.js +1 -0
- package/dist/src/services/agent-pack/agent-pack.test.js.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.js +10 -3
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -1
- package/dist/src/services/agent-pack/types.d.ts +26 -2
- package/dist/src/services/agent-pack/types.d.ts.map +1 -1
- package/dist/src/services/agent-pack/types.js +13 -0
- package/dist/src/services/agent-pack/types.js.map +1 -1
- package/dist/src/services/agent-tool-profile.d.ts.map +1 -1
- package/dist/src/services/agent-tool-profile.js +7 -0
- package/dist/src/services/agent-tool-profile.js.map +1 -1
- package/dist/src/services/agent-tool-profile.test.js +2 -2
- package/dist/src/services/skill-content-comparison.d.ts +71 -0
- package/dist/src/services/skill-content-comparison.d.ts.map +1 -0
- package/dist/src/services/skill-content-comparison.js +90 -0
- package/dist/src/services/skill-content-comparison.js.map +1 -0
- package/dist/src/services/skill-content-comparison.test.d.ts +6 -0
- package/dist/src/services/skill-content-comparison.test.d.ts.map +1 -0
- package/dist/src/services/skill-content-comparison.test.js +83 -0
- package/dist/src/services/skill-content-comparison.test.js.map +1 -0
- package/dist/src/services/skill-identity-classification.d.ts +202 -0
- package/dist/src/services/skill-identity-classification.d.ts.map +1 -0
- package/dist/src/services/skill-identity-classification.js +295 -0
- package/dist/src/services/skill-identity-classification.js.map +1 -0
- package/dist/src/services/skill-identity-classification.test.d.ts +6 -0
- package/dist/src/services/skill-identity-classification.test.d.ts.map +1 -0
- package/dist/src/services/skill-identity-classification.test.js +314 -0
- package/dist/src/services/skill-identity-classification.test.js.map +1 -0
- package/dist/src/services/skill-installation.content.d.ts.map +1 -1
- package/dist/src/services/skill-installation.content.js +6 -1
- package/dist/src/services/skill-installation.content.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.d.ts +8 -15
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +11 -105
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.test.js +106 -1
- package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
- package/dist/src/services/skill-installation.service.js +1 -1
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +33 -0
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-installation.uninstall.d.ts +84 -0
- package/dist/src/services/skill-installation.uninstall.d.ts.map +1 -0
- package/dist/src/services/skill-installation.uninstall.js +252 -0
- package/dist/src/services/skill-installation.uninstall.js.map +1 -0
- package/dist/src/services/skill-manifest.d.ts +41 -0
- package/dist/src/services/skill-manifest.d.ts.map +1 -1
- package/dist/src/services/skill-manifest.js +93 -0
- package/dist/src/services/skill-manifest.js.map +1 -1
- package/dist/src/services/skill-manifest.test.js +27 -0
- package/dist/src/services/skill-manifest.test.js.map +1 -1
- package/dist/src/sync/SyncEngine.d.ts.map +1 -1
- package/dist/src/sync/SyncEngine.js +69 -77
- package/dist/src/sync/SyncEngine.js.map +1 -1
- package/dist/src/telemetry/agent-marker.d.ts +8 -0
- package/dist/src/telemetry/agent-marker.d.ts.map +1 -1
- package/dist/src/telemetry/agent-marker.js +7 -0
- package/dist/src/telemetry/agent-marker.js.map +1 -1
- package/dist/src/telemetry/agent-marker.test.js +7 -1
- package/dist/src/telemetry/agent-marker.test.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +1 -1
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +1 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/wrap.d.ts +6 -0
- package/dist/src/telemetry/wrap.d.ts.map +1 -1
- package/dist/src/telemetry/wrap.js +65 -10
- package/dist/src/telemetry/wrap.js.map +1 -1
- package/dist/src/telemetry/wrap.test.js +81 -1
- package/dist/src/telemetry/wrap.test.js.map +1 -1
- package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts +26 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.d.ts.map +1 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.js +162 -0
- package/dist/src/telemetry/wrap.tool-call-sink.test.js.map +1 -0
- package/dist/src/types/skill.d.ts +9 -1
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/version-check.d.ts +61 -0
- package/dist/src/utils/version-check.d.ts.map +1 -1
- package/dist/src/utils/version-check.js +78 -1
- package/dist/src/utils/version-check.js.map +1 -1
- package/dist/src/utils/version-check.test.js +130 -1
- package/dist/src/utils/version-check.test.js.map +1 -1
- package/dist/tests/db/migration-runner-race.test.js +19 -9
- package/dist/tests/db/migration-runner-race.test.js.map +1 -1
- package/dist/tests/install/fan-out.test.js +27 -0
- package/dist/tests/install/fan-out.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.abort.test.js +15 -11
- package/dist/tests/sync/SyncEngine.abort.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.status.test.js +1 -1
- package/dist/tests/sync/SyncEngine.status.test.js.map +1 -1
- package/dist/tests/sync/SyncEngine.test.d.ts +11 -2
- package/dist/tests/sync/SyncEngine.test.d.ts.map +1 -1
- package/dist/tests/sync/SyncEngine.test.js +164 -13
- package/dist/tests/sync/SyncEngine.test.js.map +1 -1
- package/dist/tests/unit/migrations/migration-v18.test.d.ts +16 -0
- package/dist/tests/unit/migrations/migration-v18.test.d.ts.map +1 -0
- package/dist/tests/unit/migrations/migration-v18.test.js +192 -0
- package/dist/tests/unit/migrations/migration-v18.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.content.test.js +65 -1
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.test.js +9 -8
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/unit/sync-engine.source-aware.test.js +5 -5
- package/dist/tests/unit/sync-engine.source-aware.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1788: Pure helper functions for SubagentGenerator — tool detection,
|
|
3
|
+
* trigger-phrase extraction, model selection, and Claude-tool-named
|
|
4
|
+
* guidance text. Split out under the 500-line standard (SMI-6276) following
|
|
5
|
+
* this directory's existing `.helpers.ts` convention (see
|
|
6
|
+
* SkillAnalyzer.helpers.ts / SkillDecomposer.helpers.ts).
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolUsageAnalysis } from './SkillAnalyzer.js';
|
|
9
|
+
import { type ClaudeModel } from './SubagentGenerator.types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Tool detection patterns for analyzing skill content
|
|
12
|
+
*/
|
|
13
|
+
export declare const TOOL_PATTERNS: Record<string, {
|
|
14
|
+
patterns: string[];
|
|
15
|
+
priority: number;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Minimum tools that most subagents need
|
|
19
|
+
*/
|
|
20
|
+
export declare const BASE_TOOLS: string[];
|
|
21
|
+
/**
|
|
22
|
+
* SMI-1819: Maximum length for subagent names to prevent overly long identifiers
|
|
23
|
+
*/
|
|
24
|
+
export declare const MAX_SUBAGENT_NAME_LENGTH = 100;
|
|
25
|
+
/**
|
|
26
|
+
* Generate tool usage guidelines for a subagent (Claude-named tools).
|
|
27
|
+
* Only used for clients whose `toolsPolicy` is `'claude-native'` — see
|
|
28
|
+
* `SubagentGenerator.client-profiles.ts` and `OMITTED_TOOLS_GUIDANCE`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateToolGuidelines(tools: string[]): string;
|
|
31
|
+
/**
|
|
32
|
+
* SMI-6276: fallback tool-usage guidance for any client whose companion
|
|
33
|
+
* subagent file does not carry Claude-named tools in its `tools:`
|
|
34
|
+
* frontmatter — either because the field is omitted entirely, or because it
|
|
35
|
+
* was translated into that client's OWN vocabulary (`mapped-array`, e.g.
|
|
36
|
+
* AntiGravity's `view_file`/`run_command`). Naming Claude-specific tool
|
|
37
|
+
* identifiers in this prose body would be misleading either way, so this
|
|
38
|
+
* stays generic. See `SubagentGenerator.client-profiles.ts`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const OMITTED_TOOLS_GUIDANCE = "- Use the tools available on this platform minimally and efficiently";
|
|
41
|
+
/**
|
|
42
|
+
* Generate CLAUDE.md integration snippet
|
|
43
|
+
*
|
|
44
|
+
* NOTE (SMI-6276): deliberately NOT client-parameterized — CLAUDE.md is
|
|
45
|
+
* inherently a Claude Code artifact regardless of which client the
|
|
46
|
+
* companion-agent FILE itself targets, so this always describes the
|
|
47
|
+
* Claude-side delegation recommendation. Out of this wave's scope; see
|
|
48
|
+
* `SubagentGenerator.client-profiles.ts`'s header for what IS in scope.
|
|
49
|
+
*/
|
|
50
|
+
export declare function generateClaudeMdSnippet(skillName: string, description: string, triggerPhrases: string[], tools: string[], model: ClaudeModel): string;
|
|
51
|
+
/**
|
|
52
|
+
* Extract trigger phrases from skill description and content
|
|
53
|
+
*/
|
|
54
|
+
export declare function extractTriggerPhrases(description: string, content: string): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Determine optimal model for subagent
|
|
57
|
+
* SMI-1795: Uses CLAUDE_MODELS constants for type safety
|
|
58
|
+
*/
|
|
59
|
+
export declare function determineModel(toolUsage: ToolUsageAnalysis, lineCount: number): ClaudeModel;
|
|
60
|
+
/**
|
|
61
|
+
* Detect tools needed from skill content
|
|
62
|
+
*/
|
|
63
|
+
export declare function detectTools(content: string): string[];
|
|
64
|
+
//# sourceMappingURL=SubagentGenerator.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentGenerator.helpers.d.ts","sourceRoot":"","sources":["../../../src/services/SubagentGenerator.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAE9E;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAoDlF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,UAAW,CAAA;AAElC;;GAEG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CA6B9D;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,yEACqC,CAAA;AAExE;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,WAAW,GACjB,MAAM,CA0BR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAwDpF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAgB3F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAcrD"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1788: Pure helper functions for SubagentGenerator — tool detection,
|
|
3
|
+
* trigger-phrase extraction, model selection, and Claude-tool-named
|
|
4
|
+
* guidance text. Split out under the 500-line standard (SMI-6276) following
|
|
5
|
+
* this directory's existing `.helpers.ts` convention (see
|
|
6
|
+
* SkillAnalyzer.helpers.ts / SkillDecomposer.helpers.ts).
|
|
7
|
+
*/
|
|
8
|
+
import { CLAUDE_MODELS } from './SubagentGenerator.types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Tool detection patterns for analyzing skill content
|
|
11
|
+
*/
|
|
12
|
+
export const TOOL_PATTERNS = {
|
|
13
|
+
Read: {
|
|
14
|
+
patterns: ['read file', 'read the', 'examine', 'view file', 'Read tool', 'check file'],
|
|
15
|
+
priority: 1,
|
|
16
|
+
},
|
|
17
|
+
Write: {
|
|
18
|
+
patterns: ['write file', 'create file', 'save to', 'output to', 'Write tool', 'generate file'],
|
|
19
|
+
priority: 2,
|
|
20
|
+
},
|
|
21
|
+
Edit: {
|
|
22
|
+
patterns: [
|
|
23
|
+
'edit file',
|
|
24
|
+
'modify',
|
|
25
|
+
'update file',
|
|
26
|
+
'patch',
|
|
27
|
+
'Edit tool',
|
|
28
|
+
'change file',
|
|
29
|
+
'refactor',
|
|
30
|
+
],
|
|
31
|
+
priority: 2,
|
|
32
|
+
},
|
|
33
|
+
Bash: {
|
|
34
|
+
patterns: [
|
|
35
|
+
'bash',
|
|
36
|
+
'npm',
|
|
37
|
+
'npx',
|
|
38
|
+
'git',
|
|
39
|
+
'docker',
|
|
40
|
+
'yarn',
|
|
41
|
+
'pnpm',
|
|
42
|
+
'terminal',
|
|
43
|
+
'shell',
|
|
44
|
+
'command',
|
|
45
|
+
],
|
|
46
|
+
priority: 3,
|
|
47
|
+
},
|
|
48
|
+
Grep: {
|
|
49
|
+
patterns: ['grep', 'search for', 'find text', 'pattern match', 'Grep tool', 'search in'],
|
|
50
|
+
priority: 1,
|
|
51
|
+
},
|
|
52
|
+
Glob: {
|
|
53
|
+
patterns: ['glob', 'find file', 'file pattern', 'list files', 'Glob tool', 'locate'],
|
|
54
|
+
priority: 1,
|
|
55
|
+
},
|
|
56
|
+
WebFetch: {
|
|
57
|
+
patterns: ['fetch', 'http', 'api call', 'url', 'WebFetch', 'download', 'request'],
|
|
58
|
+
priority: 2,
|
|
59
|
+
},
|
|
60
|
+
WebSearch: {
|
|
61
|
+
patterns: ['web search', 'search online', 'lookup online', 'WebSearch', 'search the web'],
|
|
62
|
+
priority: 2,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Minimum tools that most subagents need
|
|
67
|
+
*/
|
|
68
|
+
export const BASE_TOOLS = ['Read'];
|
|
69
|
+
/**
|
|
70
|
+
* SMI-1819: Maximum length for subagent names to prevent overly long identifiers
|
|
71
|
+
*/
|
|
72
|
+
export const MAX_SUBAGENT_NAME_LENGTH = 100;
|
|
73
|
+
/**
|
|
74
|
+
* Generate tool usage guidelines for a subagent (Claude-named tools).
|
|
75
|
+
* Only used for clients whose `toolsPolicy` is `'claude-native'` — see
|
|
76
|
+
* `SubagentGenerator.client-profiles.ts` and `OMITTED_TOOLS_GUIDANCE`.
|
|
77
|
+
*/
|
|
78
|
+
export function generateToolGuidelines(tools) {
|
|
79
|
+
const guidelines = [];
|
|
80
|
+
if (tools.includes('Read')) {
|
|
81
|
+
guidelines.push('- **Read**: Use to examine files before modifications');
|
|
82
|
+
}
|
|
83
|
+
if (tools.includes('Write')) {
|
|
84
|
+
guidelines.push('- **Write**: Use for creating new files only');
|
|
85
|
+
}
|
|
86
|
+
if (tools.includes('Edit')) {
|
|
87
|
+
guidelines.push('- **Edit**: Use for modifying existing files');
|
|
88
|
+
}
|
|
89
|
+
if (tools.includes('Bash')) {
|
|
90
|
+
guidelines.push('- **Bash**: Use for command execution, prefer non-destructive commands');
|
|
91
|
+
}
|
|
92
|
+
if (tools.includes('Grep')) {
|
|
93
|
+
guidelines.push('- **Grep**: Use for searching file contents');
|
|
94
|
+
}
|
|
95
|
+
if (tools.includes('Glob')) {
|
|
96
|
+
guidelines.push('- **Glob**: Use for finding files by pattern');
|
|
97
|
+
}
|
|
98
|
+
if (tools.includes('WebFetch')) {
|
|
99
|
+
guidelines.push('- **WebFetch**: Use for fetching web content');
|
|
100
|
+
}
|
|
101
|
+
if (tools.includes('WebSearch')) {
|
|
102
|
+
guidelines.push('- **WebSearch**: Use for searching the web');
|
|
103
|
+
}
|
|
104
|
+
return guidelines.length > 0 ? guidelines.join('\n') : '- Use tools minimally and efficiently';
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* SMI-6276: fallback tool-usage guidance for any client whose companion
|
|
108
|
+
* subagent file does not carry Claude-named tools in its `tools:`
|
|
109
|
+
* frontmatter — either because the field is omitted entirely, or because it
|
|
110
|
+
* was translated into that client's OWN vocabulary (`mapped-array`, e.g.
|
|
111
|
+
* AntiGravity's `view_file`/`run_command`). Naming Claude-specific tool
|
|
112
|
+
* identifiers in this prose body would be misleading either way, so this
|
|
113
|
+
* stays generic. See `SubagentGenerator.client-profiles.ts`.
|
|
114
|
+
*/
|
|
115
|
+
export const OMITTED_TOOLS_GUIDANCE = '- Use the tools available on this platform minimally and efficiently';
|
|
116
|
+
/**
|
|
117
|
+
* Generate CLAUDE.md integration snippet
|
|
118
|
+
*
|
|
119
|
+
* NOTE (SMI-6276): deliberately NOT client-parameterized — CLAUDE.md is
|
|
120
|
+
* inherently a Claude Code artifact regardless of which client the
|
|
121
|
+
* companion-agent FILE itself targets, so this always describes the
|
|
122
|
+
* Claude-side delegation recommendation. Out of this wave's scope; see
|
|
123
|
+
* `SubagentGenerator.client-profiles.ts`'s header for what IS in scope.
|
|
124
|
+
*/
|
|
125
|
+
export function generateClaudeMdSnippet(skillName, description, triggerPhrases, tools, model) {
|
|
126
|
+
const triggerPatterns = triggerPhrases.length > 0
|
|
127
|
+
? triggerPhrases.map((p) => `- "${p}"`).join('\n')
|
|
128
|
+
: '- [add trigger patterns]';
|
|
129
|
+
const exampleTask = triggerPhrases.length > 0 ? triggerPhrases[0] : `execute ${skillName} task`;
|
|
130
|
+
return `
|
|
131
|
+
### Subagent Delegation: ${skillName}
|
|
132
|
+
|
|
133
|
+
When tasks match ${skillName} triggers, delegate to the ${skillName}-specialist
|
|
134
|
+
subagent instead of executing directly. This provides context isolation and
|
|
135
|
+
~37-97% token savings.
|
|
136
|
+
|
|
137
|
+
**Trigger Patterns:**
|
|
138
|
+
${triggerPatterns}
|
|
139
|
+
|
|
140
|
+
**Delegation Example:**
|
|
141
|
+
\`\`\`
|
|
142
|
+
Task("${skillName}-specialist", "${exampleTask}", "${skillName}-specialist")
|
|
143
|
+
\`\`\`
|
|
144
|
+
|
|
145
|
+
**Model:** ${model}
|
|
146
|
+
**Tools:** ${tools.join(', ')}
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Extract trigger phrases from skill description and content
|
|
151
|
+
*/
|
|
152
|
+
export function extractTriggerPhrases(description, content) {
|
|
153
|
+
const phrases = [];
|
|
154
|
+
// Common trigger phrase patterns. CodeQL finding (SMI-6276, polynomial
|
|
155
|
+
// regex / ReDoS): the original patterns paired an optional word group
|
|
156
|
+
// (e.g. `(?:you\s+)?`) directly against a lazy wildcard capture
|
|
157
|
+
// (`(.+?)`) — since `.` also matches the letters/spaces the optional
|
|
158
|
+
// group matches, the engine has exponentially many ways to split
|
|
159
|
+
// ambiguous input (long runs of repeated words/spaces) between "the
|
|
160
|
+
// optional group matched" and "the wildcard consumed it instead".
|
|
161
|
+
// `textToSearch` includes up to 2000 chars of externally-authored
|
|
162
|
+
// SKILL.md content (a real untrusted-input path in a skill registry).
|
|
163
|
+
// Fix: bound each capture group to a small fixed max length instead of
|
|
164
|
+
// an unbounded lazy wildcard — extracted phrases are truncated to <=50
|
|
165
|
+
// chars a few lines below regardless, so this changes no real-world
|
|
166
|
+
// behavior, but caps worst-case backtracking work to a small constant
|
|
167
|
+
// instead of growing with input length.
|
|
168
|
+
const MAX_CANDIDATE_PHRASE_LENGTH = 60;
|
|
169
|
+
const patterns = [
|
|
170
|
+
new RegExp(`when\\s+(?:you\\s+)?(?:need\\s+to\\s+)?([^.,]{1,${MAX_CANDIDATE_PHRASE_LENGTH}})(?:[.,]|$)`, 'gi'),
|
|
171
|
+
new RegExp(`use\\s+(?:this\\s+)?(?:when|for)\\s+([^.,]{1,${MAX_CANDIDATE_PHRASE_LENGTH}})(?:[.,]|$)`, 'gi'),
|
|
172
|
+
new RegExp(`(?:helps?\\s+(?:you\\s+)?(?:to\\s+)?)?([^\\n]{1,${MAX_CANDIDATE_PHRASE_LENGTH}}?)(?:\\s+tasks?|\\s+operations?)`, 'gi'),
|
|
173
|
+
];
|
|
174
|
+
const textToSearch = description + ' ' + content.slice(0, 2000); // Search first 2000 chars
|
|
175
|
+
for (const pattern of patterns) {
|
|
176
|
+
for (const match of textToSearch.matchAll(pattern)) {
|
|
177
|
+
const phrase = match[1].trim().toLowerCase();
|
|
178
|
+
if (phrase.length >= 5 && phrase.length <= 50 && !phrases.includes(phrase)) {
|
|
179
|
+
phrases.push(phrase);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Extract from "trigger" or "invoke" mentions
|
|
184
|
+
const triggerMatch = content.match(/trigger[s]?\s*[:=]\s*["`']([^"`']+)["`']/gi);
|
|
185
|
+
if (triggerMatch) {
|
|
186
|
+
for (const match of triggerMatch) {
|
|
187
|
+
const phrase = match.replace(/trigger[s]?\s*[:=]\s*["`']/i, '').replace(/["`']$/, '');
|
|
188
|
+
if (!phrases.includes(phrase.toLowerCase())) {
|
|
189
|
+
phrases.push(phrase.toLowerCase());
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return phrases.slice(0, 5); // Limit to 5 phrases
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Determine optimal model for subagent
|
|
197
|
+
* SMI-1795: Uses CLAUDE_MODELS constants for type safety
|
|
198
|
+
*/
|
|
199
|
+
export function determineModel(toolUsage, lineCount) {
|
|
200
|
+
// Haiku for simple, fast operations
|
|
201
|
+
if (toolUsage.detectedTools.length <= 2 && lineCount < 200) {
|
|
202
|
+
return CLAUDE_MODELS.HAIKU;
|
|
203
|
+
}
|
|
204
|
+
// Opus for complex, reasoning-heavy tasks
|
|
205
|
+
if (toolUsage.bashCommandCount > 5 ||
|
|
206
|
+
(toolUsage.fileReadCount > 3 && toolUsage.fileWriteCount > 3)) {
|
|
207
|
+
return CLAUDE_MODELS.OPUS;
|
|
208
|
+
}
|
|
209
|
+
// Sonnet for balanced workloads (default)
|
|
210
|
+
return CLAUDE_MODELS.SONNET;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Detect tools needed from skill content
|
|
214
|
+
*/
|
|
215
|
+
export function detectTools(content) {
|
|
216
|
+
const lowerContent = content.toLowerCase();
|
|
217
|
+
const detectedTools = new Set(BASE_TOOLS);
|
|
218
|
+
for (const [tool, config] of Object.entries(TOOL_PATTERNS)) {
|
|
219
|
+
for (const pattern of config.patterns) {
|
|
220
|
+
if (lowerContent.includes(pattern.toLowerCase())) {
|
|
221
|
+
detectedTools.add(tool);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return Array.from(detectedTools);
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=SubagentGenerator.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentGenerator.helpers.js","sourceRoot":"","sources":["../../../src/services/SubagentGenerator.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAoB,MAAM,8BAA8B,CAAA;AAE9E;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAA6D;IACrF,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC;QACtF,QAAQ,EAAE,CAAC;KACZ;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,CAAC;QAC9F,QAAQ,EAAE,CAAC;KACZ;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE;YACR,WAAW;YACX,QAAQ;YACR,aAAa;YACb,OAAO;YACP,WAAW;YACX,aAAa;YACb,UAAU;SACX;QACD,QAAQ,EAAE,CAAC;KACZ;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,KAAK;YACL,QAAQ;YACR,MAAM;YACN,MAAM;YACN,UAAU;YACV,OAAO;YACP,SAAS;SACV;QACD,QAAQ,EAAE,CAAC;KACZ;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,CAAC;QACxF,QAAQ,EAAE,CAAC;KACZ;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,CAAC;QACpF,QAAQ,EAAE,CAAC;KACZ;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC;QACjF,QAAQ,EAAE,CAAC;KACZ;IACD,SAAS,EAAE;QACT,QAAQ,EAAE,CAAC,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,CAAC;QACzF,QAAQ,EAAE,CAAC;KACZ;CACF,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,CAAA;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;AAE3C;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAe;IACpD,MAAM,UAAU,GAAa,EAAE,CAAA;IAE/B,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAA;IAC1E,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;IAC3F,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,UAAU,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,UAAU,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAA;AAChG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,sEAAsE,CAAA;AAExE;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,SAAiB,EACjB,WAAmB,EACnB,cAAwB,EACxB,KAAe,EACf,KAAkB;IAElB,MAAM,eAAe,GACnB,cAAc,CAAC,MAAM,GAAG,CAAC;QACvB,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,CAAC,CAAC,0BAA0B,CAAA;IAEhC,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,SAAS,OAAO,CAAA;IAE/F,OAAO;2BACkB,SAAS;;mBAEjB,SAAS,8BAA8B,SAAS;;;;;EAKjE,eAAe;;;;QAIT,SAAS,kBAAkB,WAAW,OAAO,SAAS;;;aAGjD,KAAK;aACL,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;CAC5B,CAAA;AACD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB,EAAE,OAAe;IACxE,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,uEAAuE;IACvE,sEAAsE;IACtE,gEAAgE;IAChE,qEAAqE;IACrE,iEAAiE;IACjE,oEAAoE;IACpE,kEAAkE;IAClE,kEAAkE;IAClE,sEAAsE;IACtE,uEAAuE;IACvE,uEAAuE;IACvE,oEAAoE;IACpE,sEAAsE;IACtE,wCAAwC;IACxC,MAAM,2BAA2B,GAAG,EAAE,CAAA;IACtC,MAAM,QAAQ,GAAG;QACf,IAAI,MAAM,CACR,mDAAmD,2BAA2B,cAAc,EAC5F,IAAI,CACL;QACD,IAAI,MAAM,CACR,gDAAgD,2BAA2B,cAAc,EACzF,IAAI,CACL;QACD,IAAI,MAAM,CACR,mDAAmD,2BAA2B,mCAAmC,EACjH,IAAI,CACL;KACF,CAAA;IAED,MAAM,YAAY,GAAG,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA,CAAC,0BAA0B;IAE1F,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YAC5C,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAA;IAChF,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YACrF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA,CAAC,qBAAqB;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAA4B,EAAE,SAAiB;IAC5E,oCAAoC;IACpC,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;QAC3D,OAAO,aAAa,CAAC,KAAK,CAAA;IAC5B,CAAC;IAED,0CAA0C;IAC1C,IACE,SAAS,CAAC,gBAAgB,GAAG,CAAC;QAC9B,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,EAC7D,CAAC;QACD,OAAO,aAAa,CAAC,IAAI,CAAA;IAC3B,CAAC;IAED,0CAA0C;IAC1C,OAAO,aAAa,CAAC,MAAM,CAAA;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;IAC1C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAA;IAEjD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3D,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACjD,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;gBACvB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;AAClC,CAAC"}
|
|
@@ -9,125 +9,69 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Part of the Skillsmith Optimization Layer for transforming
|
|
11
11
|
* community skills into more performant versions.
|
|
12
|
+
*
|
|
13
|
+
* SMI-6276 (Wave 6 Step 1): companion-agent frontmatter is now generated
|
|
14
|
+
* per TARGET CLIENT via `SubagentGenerator.client-profiles.ts` — this file
|
|
15
|
+
* no longer emits Claude-native tool names / a Claude `model:` value
|
|
16
|
+
* unconditionally for every client `COMPANION_AGENT_TARGETS` writes a
|
|
17
|
+
* companion file for. Types split to `.types.ts`, pure helpers split to
|
|
18
|
+
* `.helpers.ts` (500-line standard).
|
|
12
19
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
SONNET: 'sonnet',
|
|
19
|
-
OPUS: 'opus',
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Tool detection patterns for analyzing skill content
|
|
23
|
-
*/
|
|
24
|
-
const TOOL_PATTERNS = {
|
|
25
|
-
Read: {
|
|
26
|
-
patterns: ['read file', 'read the', 'examine', 'view file', 'Read tool', 'check file'],
|
|
27
|
-
priority: 1,
|
|
28
|
-
},
|
|
29
|
-
Write: {
|
|
30
|
-
patterns: ['write file', 'create file', 'save to', 'output to', 'Write tool', 'generate file'],
|
|
31
|
-
priority: 2,
|
|
32
|
-
},
|
|
33
|
-
Edit: {
|
|
34
|
-
patterns: [
|
|
35
|
-
'edit file',
|
|
36
|
-
'modify',
|
|
37
|
-
'update file',
|
|
38
|
-
'patch',
|
|
39
|
-
'Edit tool',
|
|
40
|
-
'change file',
|
|
41
|
-
'refactor',
|
|
42
|
-
],
|
|
43
|
-
priority: 2,
|
|
44
|
-
},
|
|
45
|
-
Bash: {
|
|
46
|
-
patterns: [
|
|
47
|
-
'bash',
|
|
48
|
-
'npm',
|
|
49
|
-
'npx',
|
|
50
|
-
'git',
|
|
51
|
-
'docker',
|
|
52
|
-
'yarn',
|
|
53
|
-
'pnpm',
|
|
54
|
-
'terminal',
|
|
55
|
-
'shell',
|
|
56
|
-
'command',
|
|
57
|
-
],
|
|
58
|
-
priority: 3,
|
|
59
|
-
},
|
|
60
|
-
Grep: {
|
|
61
|
-
patterns: ['grep', 'search for', 'find text', 'pattern match', 'Grep tool', 'search in'],
|
|
62
|
-
priority: 1,
|
|
63
|
-
},
|
|
64
|
-
Glob: {
|
|
65
|
-
patterns: ['glob', 'find file', 'file pattern', 'list files', 'Glob tool', 'locate'],
|
|
66
|
-
priority: 1,
|
|
67
|
-
},
|
|
68
|
-
WebFetch: {
|
|
69
|
-
patterns: ['fetch', 'http', 'api call', 'url', 'WebFetch', 'download', 'request'],
|
|
70
|
-
priority: 2,
|
|
71
|
-
},
|
|
72
|
-
WebSearch: {
|
|
73
|
-
patterns: ['web search', 'search online', 'lookup online', 'WebSearch', 'search the web'],
|
|
74
|
-
priority: 2,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Minimum tools that most subagents need
|
|
79
|
-
*/
|
|
80
|
-
const BASE_TOOLS = ['Read'];
|
|
81
|
-
/**
|
|
82
|
-
* SMI-1819: Maximum length for subagent names to prevent overly long identifiers
|
|
83
|
-
*/
|
|
84
|
-
const MAX_SUBAGENT_NAME_LENGTH = 100;
|
|
85
|
-
/**
|
|
86
|
-
* Generate tool usage guidelines for a subagent
|
|
87
|
-
*/
|
|
88
|
-
function generateToolGuidelines(tools) {
|
|
89
|
-
const guidelines = [];
|
|
90
|
-
if (tools.includes('Read')) {
|
|
91
|
-
guidelines.push('- **Read**: Use to examine files before modifications');
|
|
92
|
-
}
|
|
93
|
-
if (tools.includes('Write')) {
|
|
94
|
-
guidelines.push('- **Write**: Use for creating new files only');
|
|
95
|
-
}
|
|
96
|
-
if (tools.includes('Edit')) {
|
|
97
|
-
guidelines.push('- **Edit**: Use for modifying existing files');
|
|
98
|
-
}
|
|
99
|
-
if (tools.includes('Bash')) {
|
|
100
|
-
guidelines.push('- **Bash**: Use for command execution, prefer non-destructive commands');
|
|
101
|
-
}
|
|
102
|
-
if (tools.includes('Grep')) {
|
|
103
|
-
guidelines.push('- **Grep**: Use for searching file contents');
|
|
104
|
-
}
|
|
105
|
-
if (tools.includes('Glob')) {
|
|
106
|
-
guidelines.push('- **Glob**: Use for finding files by pattern');
|
|
107
|
-
}
|
|
108
|
-
if (tools.includes('WebFetch')) {
|
|
109
|
-
guidelines.push('- **WebFetch**: Use for fetching web content');
|
|
110
|
-
}
|
|
111
|
-
if (tools.includes('WebSearch')) {
|
|
112
|
-
guidelines.push('- **WebSearch**: Use for searching the web');
|
|
113
|
-
}
|
|
114
|
-
return guidelines.length > 0 ? guidelines.join('\n') : '- Use tools minimally and efficiently';
|
|
115
|
-
}
|
|
20
|
+
export { CLAUDE_MODELS } from './SubagentGenerator.types.js';
|
|
21
|
+
import { CANONICAL_CLIENT } from '../install/paths.js';
|
|
22
|
+
import { getSubagentGenerationProfile, mapToolNames } from './SubagentGenerator.client-profiles.js';
|
|
23
|
+
import { CLAUDE_MODELS, } from './SubagentGenerator.types.js';
|
|
24
|
+
import { MAX_SUBAGENT_NAME_LENGTH, generateToolGuidelines, OMITTED_TOOLS_GUIDANCE, generateClaudeMdSnippet, extractTriggerPhrases, determineModel, detectTools, } from './SubagentGenerator.helpers.js';
|
|
116
25
|
/**
|
|
117
26
|
* Generate subagent markdown content
|
|
27
|
+
*
|
|
28
|
+
* SMI-6276 (Wave 6 Step 1): frontmatter shape is now driven by the target
|
|
29
|
+
* client's generation profile (`SubagentGenerator.client-profiles.ts`) —
|
|
30
|
+
* `Read, Write, Bash, WebFetch, Grep, Glob, WebSearch` plus a Claude
|
|
31
|
+
* `model:` value are no longer emitted unconditionally for every client.
|
|
118
32
|
*/
|
|
119
|
-
function generateSubagentContent(name, description, triggerPhrases, tools, model) {
|
|
33
|
+
function generateSubagentContent(name, description, triggerPhrases, tools, model, client) {
|
|
120
34
|
const triggerString = triggerPhrases.length > 0
|
|
121
35
|
? triggerPhrases.map((p) => `"${p}"`).join(', ')
|
|
122
36
|
: '[describe trigger conditions]';
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
37
|
+
const profile = getSubagentGenerationProfile(client);
|
|
38
|
+
// SMI-6276 pr-reviewer finding: `description` is free text sourced from
|
|
39
|
+
// the SKILL.md being transformed — an unquoted plain YAML scalar breaks
|
|
40
|
+
// if it contains `: ` (reinterpreted as a nested key) or ` #` (truncated
|
|
41
|
+
// as a comment). JSON.stringify() produces a valid YAML double-quoted
|
|
42
|
+
// scalar (YAML's double-quote escaping is a superset of JSON's), so this
|
|
43
|
+
// composes the full description+trigger text as a plain JS string FIRST,
|
|
44
|
+
// then quotes the whole thing once — not per-field — so the result is
|
|
45
|
+
// safe regardless of what the source content contains.
|
|
46
|
+
const frontmatterLines = [
|
|
47
|
+
'---',
|
|
48
|
+
`name: ${name}`,
|
|
49
|
+
`description: ${JSON.stringify(`${description} Use when ${triggerString}.`)}`,
|
|
50
|
+
];
|
|
51
|
+
if (profile.includeSkillsField) {
|
|
52
|
+
frontmatterLines.push(`skills: ${name.replace('-specialist', '')}`);
|
|
53
|
+
}
|
|
54
|
+
if (profile.toolsPolicy === 'claude-native') {
|
|
55
|
+
frontmatterLines.push(`tools: ${tools.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
else if (profile.toolsPolicy === 'mapped-array') {
|
|
58
|
+
// SMI-6276: this client expects a YAML array of ITS OWN tool names, not
|
|
59
|
+
// a Claude-shaped comma list — never emit the unmapped/mis-shaped value
|
|
60
|
+
// (the AntiGravity docs' own "Known Issue" warns an unmapped name can
|
|
61
|
+
// hang the subagent process on invocation). Omit the key entirely when
|
|
62
|
+
// nothing maps, rather than an empty `tools: []` that says nothing.
|
|
63
|
+
const mappedTools = mapToolNames(tools, profile);
|
|
64
|
+
if (mappedTools.length > 0) {
|
|
65
|
+
frontmatterLines.push('tools:', ...mappedTools.map((tool) => ` - ${tool}`));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
frontmatterLines.push(...profile.extraFrontmatterLines);
|
|
69
|
+
if (profile.modelPolicy === 'claude-enum') {
|
|
70
|
+
frontmatterLines.push(`model: ${model}`);
|
|
71
|
+
}
|
|
72
|
+
frontmatterLines.push('---');
|
|
73
|
+
const toolGuidelines = profile.toolsPolicy === 'claude-native' ? generateToolGuidelines(tools) : OMITTED_TOOLS_GUIDANCE;
|
|
74
|
+
return `${frontmatterLines.join('\n')}
|
|
131
75
|
|
|
132
76
|
## Operating Protocol
|
|
133
77
|
|
|
@@ -160,98 +104,6 @@ If the task cannot be completed:
|
|
|
160
104
|
*Generated by Skillsmith Optimization Layer*
|
|
161
105
|
`;
|
|
162
106
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Generate CLAUDE.md integration snippet
|
|
165
|
-
*/
|
|
166
|
-
function generateClaudeMdSnippet(skillName, description, triggerPhrases, tools, model) {
|
|
167
|
-
const triggerPatterns = triggerPhrases.length > 0
|
|
168
|
-
? triggerPhrases.map((p) => `- "${p}"`).join('\n')
|
|
169
|
-
: '- [add trigger patterns]';
|
|
170
|
-
const exampleTask = triggerPhrases.length > 0 ? triggerPhrases[0] : `execute ${skillName} task`;
|
|
171
|
-
return `
|
|
172
|
-
### Subagent Delegation: ${skillName}
|
|
173
|
-
|
|
174
|
-
When tasks match ${skillName} triggers, delegate to the ${skillName}-specialist
|
|
175
|
-
subagent instead of executing directly. This provides context isolation and
|
|
176
|
-
~37-97% token savings.
|
|
177
|
-
|
|
178
|
-
**Trigger Patterns:**
|
|
179
|
-
${triggerPatterns}
|
|
180
|
-
|
|
181
|
-
**Delegation Example:**
|
|
182
|
-
\`\`\`
|
|
183
|
-
Task("${skillName}-specialist", "${exampleTask}", "${skillName}-specialist")
|
|
184
|
-
\`\`\`
|
|
185
|
-
|
|
186
|
-
**Model:** ${model}
|
|
187
|
-
**Tools:** ${tools.join(', ')}
|
|
188
|
-
`;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Extract trigger phrases from skill description and content
|
|
192
|
-
*/
|
|
193
|
-
function extractTriggerPhrases(description, content) {
|
|
194
|
-
const phrases = [];
|
|
195
|
-
// Common trigger phrase patterns
|
|
196
|
-
const patterns = [
|
|
197
|
-
/when\s+(?:you\s+)?(?:need\s+to\s+)?(.+?)(?:[.,]|$)/gi,
|
|
198
|
-
/use\s+(?:this\s+)?(?:when|for)\s+(.+?)(?:[.,]|$)/gi,
|
|
199
|
-
/(?:helps?\s+(?:you\s+)?(?:to\s+)?)?(.+?)(?:\s+tasks?|\s+operations?)/gi,
|
|
200
|
-
];
|
|
201
|
-
const textToSearch = description + ' ' + content.slice(0, 2000); // Search first 2000 chars
|
|
202
|
-
for (const pattern of patterns) {
|
|
203
|
-
for (const match of textToSearch.matchAll(pattern)) {
|
|
204
|
-
const phrase = match[1].trim().toLowerCase();
|
|
205
|
-
if (phrase.length >= 5 && phrase.length <= 50 && !phrases.includes(phrase)) {
|
|
206
|
-
phrases.push(phrase);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
// Extract from "trigger" or "invoke" mentions
|
|
211
|
-
const triggerMatch = content.match(/trigger[s]?\s*[:=]\s*["`']([^"`']+)["`']/gi);
|
|
212
|
-
if (triggerMatch) {
|
|
213
|
-
for (const match of triggerMatch) {
|
|
214
|
-
const phrase = match.replace(/trigger[s]?\s*[:=]\s*["`']/i, '').replace(/["`']$/, '');
|
|
215
|
-
if (!phrases.includes(phrase.toLowerCase())) {
|
|
216
|
-
phrases.push(phrase.toLowerCase());
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return phrases.slice(0, 5); // Limit to 5 phrases
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Determine optimal model for subagent
|
|
224
|
-
* SMI-1795: Uses CLAUDE_MODELS constants for type safety
|
|
225
|
-
*/
|
|
226
|
-
function determineModel(toolUsage, lineCount) {
|
|
227
|
-
// Haiku for simple, fast operations
|
|
228
|
-
if (toolUsage.detectedTools.length <= 2 && lineCount < 200) {
|
|
229
|
-
return CLAUDE_MODELS.HAIKU;
|
|
230
|
-
}
|
|
231
|
-
// Opus for complex, reasoning-heavy tasks
|
|
232
|
-
if (toolUsage.bashCommandCount > 5 ||
|
|
233
|
-
(toolUsage.fileReadCount > 3 && toolUsage.fileWriteCount > 3)) {
|
|
234
|
-
return CLAUDE_MODELS.OPUS;
|
|
235
|
-
}
|
|
236
|
-
// Sonnet for balanced workloads (default)
|
|
237
|
-
return CLAUDE_MODELS.SONNET;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Detect tools needed from skill content
|
|
241
|
-
*/
|
|
242
|
-
function detectTools(content) {
|
|
243
|
-
const lowerContent = content.toLowerCase();
|
|
244
|
-
const detectedTools = new Set(BASE_TOOLS);
|
|
245
|
-
for (const [tool, config] of Object.entries(TOOL_PATTERNS)) {
|
|
246
|
-
for (const pattern of config.patterns) {
|
|
247
|
-
if (lowerContent.includes(pattern.toLowerCase())) {
|
|
248
|
-
detectedTools.add(tool);
|
|
249
|
-
break;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return Array.from(detectedTools);
|
|
254
|
-
}
|
|
255
107
|
/**
|
|
256
108
|
* Generate a companion subagent for a skill
|
|
257
109
|
*
|
|
@@ -259,9 +111,12 @@ function detectTools(content) {
|
|
|
259
111
|
* @param description - The skill's description
|
|
260
112
|
* @param content - The full SKILL.md content
|
|
261
113
|
* @param analysis - Analysis from SkillAnalyzer
|
|
114
|
+
* @param client - SMI-6276: target client for the generated companion-agent
|
|
115
|
+
* frontmatter shape (default: canonical / `claude-code`, preserving prior
|
|
116
|
+
* behavior for every existing caller). See `SubagentGenerator.client-profiles.ts`.
|
|
262
117
|
* @returns Subagent generation result
|
|
263
118
|
*/
|
|
264
|
-
export function generateSubagent(skillName, description, content, analysis) {
|
|
119
|
+
export function generateSubagent(skillName, description, content, analysis, client = CANONICAL_CLIENT) {
|
|
265
120
|
// SMI-1815: Validate skill name is non-empty
|
|
266
121
|
if (!skillName || skillName.trim() === '') {
|
|
267
122
|
return {
|
|
@@ -291,7 +146,7 @@ export function generateSubagent(skillName, description, content, analysis) {
|
|
|
291
146
|
// Generate subagent description
|
|
292
147
|
const subagentDescription = description || `Specialist agent for ${skillName} operations`;
|
|
293
148
|
// Generate content
|
|
294
|
-
const subagentContent = generateSubagentContent(subagentName, subagentDescription, triggerPhrases, allTools, model);
|
|
149
|
+
const subagentContent = generateSubagentContent(subagentName, subagentDescription, triggerPhrases, allTools, model, client);
|
|
295
150
|
// Generate CLAUDE.md snippet
|
|
296
151
|
const claudeMdSnippet = generateClaudeMdSnippet(skillName, subagentDescription, triggerPhrases, allTools, model);
|
|
297
152
|
return {
|
|
@@ -313,9 +168,12 @@ export function generateSubagent(skillName, description, content, analysis) {
|
|
|
313
168
|
* @param skillName - The name of the skill
|
|
314
169
|
* @param description - The skill's description
|
|
315
170
|
* @param content - The full SKILL.md content
|
|
171
|
+
* @param client - SMI-6276: target client for the generated companion-agent
|
|
172
|
+
* frontmatter shape (default: canonical / `claude-code`, preserving prior
|
|
173
|
+
* behavior for every existing caller). See `SubagentGenerator.client-profiles.ts`.
|
|
316
174
|
* @returns Subagent generation result
|
|
317
175
|
*/
|
|
318
|
-
export function generateMinimalSubagent(skillName, description, content) {
|
|
176
|
+
export function generateMinimalSubagent(skillName, description, content, client = CANONICAL_CLIENT) {
|
|
319
177
|
// SMI-1815: Validate skill name is non-empty
|
|
320
178
|
if (!skillName || skillName.trim() === '') {
|
|
321
179
|
return {
|
|
@@ -333,7 +191,7 @@ export function generateMinimalSubagent(skillName, description, content) {
|
|
|
333
191
|
const baseName = skillName.length > maxBaseLength ? skillName.slice(0, maxBaseLength) : skillName;
|
|
334
192
|
const subagentName = `${baseName}${suffix}`;
|
|
335
193
|
const subagentDescription = description || `Specialist agent for ${skillName} operations`;
|
|
336
|
-
const subagentContent = generateSubagentContent(subagentName, subagentDescription, triggerPhrases, detectedTools, model);
|
|
194
|
+
const subagentContent = generateSubagentContent(subagentName, subagentDescription, triggerPhrases, detectedTools, model, client);
|
|
337
195
|
const claudeMdSnippet = generateClaudeMdSnippet(skillName, subagentDescription, triggerPhrases, detectedTools, model);
|
|
338
196
|
return {
|
|
339
197
|
generated: true,
|