@google/gemini-cli-core 0.24.0-nightly.20251231.05049b5ab → 0.24.0-preview.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/dist/docs/cli/settings.md +1 -0
- package/dist/docs/cli/skills.md +156 -0
- package/dist/docs/cli/telemetry.md +3 -3
- package/dist/docs/cli/tutorials/skills-getting-started.md +124 -0
- package/dist/docs/cli/tutorials.md +4 -0
- package/dist/docs/get-started/configuration.md +32 -11
- package/dist/docs/hooks/best-practices.md +177 -127
- package/dist/docs/hooks/index.md +22 -0
- package/dist/docs/sidebar.json +4 -0
- package/dist/src/agents/a2a-client-manager.d.ts +5 -0
- package/dist/src/agents/a2a-client-manager.js +130 -0
- package/dist/src/agents/a2a-client-manager.js.map +1 -1
- package/dist/src/agents/a2a-client-manager.test.js +27 -1
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
- package/dist/src/agents/a2aUtils.d.ts +28 -0
- package/dist/src/agents/a2aUtils.js +111 -0
- package/dist/src/agents/a2aUtils.js.map +1 -0
- package/dist/src/agents/a2aUtils.test.js +147 -0
- package/dist/src/agents/a2aUtils.test.js.map +1 -0
- package/dist/src/agents/delegate-to-agent-tool.d.ts +2 -2
- package/dist/src/agents/delegate-to-agent-tool.js +6 -6
- package/dist/src/agents/delegate-to-agent-tool.js.map +1 -1
- package/dist/src/agents/delegate-to-agent-tool.test.js +37 -7
- package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -1
- package/dist/src/agents/introspection-agent.js +2 -2
- package/dist/src/agents/introspection-agent.js.map +1 -1
- package/dist/src/agents/introspection-agent.test.js +2 -2
- package/dist/src/agents/introspection-agent.test.js.map +1 -1
- package/dist/src/agents/local-executor.js +1 -1
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +2 -2
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.d.ts +2 -2
- package/dist/src/agents/local-invocation.js +3 -3
- package/dist/src/agents/local-invocation.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +7 -5
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.d.ts +17 -3
- package/dist/src/agents/remote-invocation.js +104 -6
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +184 -18
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.d.ts +2 -2
- package/dist/src/agents/subagent-tool-wrapper.js +6 -5
- package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +17 -10
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
- package/dist/src/agents/types.d.ts +6 -0
- package/dist/src/code_assist/oauth2.js +31 -1
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +75 -3
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +5 -0
- package/dist/src/code_assist/server.js +19 -4
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +19 -0
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/setup.js +6 -4
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js +63 -0
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +18 -0
- package/dist/src/config/config.d.ts +20 -6
- package/dist/src/config/config.js +63 -37
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +81 -4
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/flashFallback.test.js +13 -0
- package/dist/src/config/flashFallback.test.js.map +1 -1
- package/dist/src/config/models.js +6 -4
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +21 -1
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/core/client.js +39 -7
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +93 -1
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.js +1 -1
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +1 -1
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.test.js +11 -9
- package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +1 -0
- package/dist/src/core/coreToolScheduler.js +30 -106
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +21 -22
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.js +14 -2
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +0 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +29 -5
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +40 -1
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/sessionHookTriggers.d.ts +3 -2
- package/dist/src/core/sessionHookTriggers.js +8 -1
- package/dist/src/core/sessionHookTriggers.js.map +1 -1
- package/dist/src/core/turn.d.ts +16 -2
- package/dist/src/core/turn.js +2 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +3 -3
- package/dist/src/generated/git-commit.js +3 -3
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.d.ts +6 -2
- package/dist/src/hooks/hookEventHandler.js +24 -3
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.test.js +31 -8
- package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
- package/dist/src/hooks/hookRunner.d.ts +2 -2
- package/dist/src/hooks/hookRunner.js +12 -4
- package/dist/src/hooks/hookRunner.js.map +1 -1
- package/dist/src/hooks/hookRunner.test.js +33 -0
- package/dist/src/hooks/hookRunner.test.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/policy/config.js +60 -22
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/config.test.js +21 -0
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/persistence.test.js +1 -1
- package/dist/src/policy/persistence.test.js.map +1 -1
- package/dist/src/policy/policies/write.toml +5 -0
- package/dist/src/policy/policy-engine.d.ts +4 -0
- package/dist/src/policy/policy-engine.js +75 -51
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +272 -1
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/policy-updater.test.js +2 -2
- package/dist/src/policy/policy-updater.test.js.map +1 -1
- package/dist/src/policy/toml-loader.d.ts +0 -8
- package/dist/src/policy/toml-loader.js +7 -70
- package/dist/src/policy/toml-loader.js.map +1 -1
- package/dist/src/policy/toml-loader.test.js +16 -6
- package/dist/src/policy/toml-loader.test.js.map +1 -1
- package/dist/src/policy/types.d.ts +6 -0
- package/dist/src/policy/utils.d.ts +21 -0
- package/dist/src/policy/utils.js +42 -0
- package/dist/src/policy/utils.js.map +1 -0
- package/dist/src/policy/utils.test.js +64 -0
- package/dist/src/policy/utils.test.js.map +1 -0
- package/dist/src/scheduler/tool-executor.d.ts +22 -0
- package/dist/src/scheduler/tool-executor.js +198 -0
- package/dist/src/scheduler/tool-executor.js.map +1 -0
- package/dist/src/scheduler/tool-executor.test.d.ts +6 -0
- package/dist/src/scheduler/tool-executor.test.js +231 -0
- package/dist/src/scheduler/tool-executor.test.js.map +1 -0
- package/dist/src/skills/skillLoader.d.ts +28 -0
- package/dist/src/skills/skillLoader.js +77 -0
- package/dist/src/skills/skillLoader.js.map +1 -0
- package/dist/src/skills/skillLoader.test.d.ts +6 -0
- package/dist/src/skills/skillLoader.test.js +73 -0
- package/dist/src/skills/skillLoader.test.js.map +1 -0
- package/dist/src/{services → skills}/skillManager.d.ts +10 -20
- package/dist/src/skills/skillManager.js +89 -0
- package/dist/src/skills/skillManager.js.map +1 -0
- package/dist/src/skills/skillManager.test.d.ts +6 -0
- package/dist/src/skills/skillManager.test.js +128 -0
- package/dist/src/skills/skillManager.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +5 -5
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +8 -8
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +2 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +4 -4
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +3 -3
- package/dist/src/telemetry/loggers.js +4 -4
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +6 -8
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +7 -7
- package/dist/src/telemetry/types.js +10 -10
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/test-utils/mock-message-bus.d.ts +1 -0
- package/dist/src/test-utils/mock-message-bus.js +29 -0
- package/dist/src/test-utils/mock-message-bus.js.map +1 -1
- package/dist/src/test-utils/mock-tool.d.ts +5 -3
- package/dist/src/test-utils/mock-tool.js +11 -10
- package/dist/src/test-utils/mock-tool.js.map +1 -1
- package/dist/src/tools/activate-skill.d.ts +27 -0
- package/dist/src/tools/activate-skill.js +120 -0
- package/dist/src/tools/activate-skill.js.map +1 -0
- package/dist/src/tools/activate-skill.test.d.ts +6 -0
- package/dist/src/tools/activate-skill.test.js +95 -0
- package/dist/src/tools/activate-skill.test.js.map +1 -0
- package/dist/src/tools/confirmation-policy.test.js +2 -12
- package/dist/src/tools/confirmation-policy.test.js.map +1 -1
- package/dist/src/tools/edit.d.ts +27 -5
- package/dist/src/tools/edit.js +444 -137
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +257 -525
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/get-internal-docs.d.ts +2 -2
- package/dist/src/tools/get-internal-docs.js +6 -6
- package/dist/src/tools/get-internal-docs.js.map +1 -1
- package/dist/src/tools/get-internal-docs.test.js +2 -1
- package/dist/src/tools/get-internal-docs.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +2 -2
- package/dist/src/tools/glob.js +1 -1
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +2 -1
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +2 -2
- package/dist/src/tools/grep.js +1 -1
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +5 -4
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +2 -2
- package/dist/src/tools/ls.js +2 -2
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +2 -1
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.js +14 -7
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +28 -0
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +2 -2
- package/dist/src/tools/mcp-client.js +2 -1
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +2 -2
- package/dist/src/tools/mcp-tool.js +7 -7
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +11 -6
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +3 -3
- package/dist/src/tools/memoryTool.js +2 -2
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +5 -2
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/message-bus-integration.test.js +10 -37
- package/dist/src/tools/message-bus-integration.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +2 -2
- package/dist/src/tools/read-file.js +1 -1
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +3 -2
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +2 -2
- package/dist/src/tools/read-many-files.js +2 -3
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +3 -2
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/ripGrep.d.ts +2 -2
- package/dist/src/tools/ripGrep.js +3 -4
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +7 -6
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +3 -6
- package/dist/src/tools/shell.js +15 -48
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +35 -59
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +2 -1
- package/dist/src/tools/tool-names.js +2 -0
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +11 -6
- package/dist/src/tools/tool-registry.js +13 -8
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +14 -10
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +5 -5
- package/dist/src/tools/tools.js +15 -17
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/tools.test.js +3 -1
- package/dist/src/tools/tools.test.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +2 -2
- package/dist/src/tools/web-fetch.js +4 -4
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +17 -19
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +2 -2
- package/dist/src/tools/web-search.js +3 -4
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +2 -1
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +2 -2
- package/dist/src/tools/write-file.js +3 -3
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +4 -1
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.d.ts +2 -2
- package/dist/src/tools/write-todos.js +5 -4
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/tools/write-todos.test.js +2 -1
- package/dist/src/tools/write-todos.test.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +1 -1
- package/dist/src/utils/editCorrector.test.js.map +1 -1
- package/dist/src/utils/events.d.ts +46 -1
- package/dist/src/utils/events.js +21 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/events.test.js +25 -0
- package/dist/src/utils/events.test.js.map +1 -1
- package/dist/src/utils/getFolderStructure.js +6 -1
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/shell-permissions.test.js +27 -0
- package/dist/src/utils/shell-permissions.test.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +6 -0
- package/dist/src/utils/shell-utils.js +72 -8
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +99 -1
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/terminal.d.ts +2 -0
- package/dist/src/utils/terminal.js +6 -0
- package/dist/src/utils/terminal.js.map +1 -1
- package/dist/src/utils/tokenCalculation.js +20 -5
- package/dist/src/utils/tokenCalculation.js.map +1 -1
- package/dist/src/utils/tokenCalculation.test.js +11 -2
- package/dist/src/utils/tokenCalculation.test.js.map +1 -1
- package/dist/src/utils/tool-utils.test.js +2 -1
- package/dist/src/utils/tool-utils.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.24.0-nightly.20251227.37be16243.tgz +0 -0
- package/dist/src/services/skillManager.js +0 -157
- package/dist/src/services/skillManager.js.map +0 -1
- package/dist/src/services/skillManager.test.js +0 -169
- package/dist/src/services/skillManager.test.js.map +0 -1
- package/dist/src/tools/smart-edit.d.ts +0 -78
- package/dist/src/tools/smart-edit.js +0 -722
- package/dist/src/tools/smart-edit.js.map +0 -1
- package/dist/src/tools/smart-edit.test.js +0 -592
- package/dist/src/tools/smart-edit.test.js.map +0 -1
- /package/dist/src/{services/skillManager.test.d.ts → agents/a2aUtils.test.d.ts} +0 -0
- /package/dist/src/{tools/smart-edit.test.d.ts → policy/utils.test.d.ts} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs/promises';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { glob } from 'glob';
|
|
9
|
+
import yaml from 'js-yaml';
|
|
10
|
+
import { debugLogger } from '../utils/debugLogger.js';
|
|
11
|
+
import { coreEvents } from '../utils/events.js';
|
|
12
|
+
const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)/;
|
|
13
|
+
/**
|
|
14
|
+
* Discovers and loads all skills in the provided directory.
|
|
15
|
+
*/
|
|
16
|
+
export async function loadSkillsFromDir(dir) {
|
|
17
|
+
const discoveredSkills = [];
|
|
18
|
+
try {
|
|
19
|
+
const absoluteSearchPath = path.resolve(dir);
|
|
20
|
+
const stats = await fs.stat(absoluteSearchPath).catch(() => null);
|
|
21
|
+
if (!stats || !stats.isDirectory()) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const skillFiles = await glob('*/SKILL.md', {
|
|
25
|
+
cwd: absoluteSearchPath,
|
|
26
|
+
absolute: true,
|
|
27
|
+
nodir: true,
|
|
28
|
+
});
|
|
29
|
+
for (const skillFile of skillFiles) {
|
|
30
|
+
const metadata = await loadSkillFromFile(skillFile);
|
|
31
|
+
if (metadata) {
|
|
32
|
+
discoveredSkills.push(metadata);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (discoveredSkills.length === 0) {
|
|
36
|
+
const files = await fs.readdir(absoluteSearchPath);
|
|
37
|
+
if (files.length > 0) {
|
|
38
|
+
coreEvents.emitFeedback('warning', `Failed to load skills from ${absoluteSearchPath}. The directory is not empty but no valid skills were discovered. Please ensure SKILL.md files are present in subdirectories and have valid frontmatter.`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
coreEvents.emitFeedback('warning', `Error discovering skills in ${dir}:`, error);
|
|
44
|
+
}
|
|
45
|
+
return discoveredSkills;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Loads a single skill from a SKILL.md file.
|
|
49
|
+
*/
|
|
50
|
+
export async function loadSkillFromFile(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
53
|
+
const match = content.match(FRONTMATTER_REGEX);
|
|
54
|
+
if (!match) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const frontmatter = yaml.load(match[1]);
|
|
58
|
+
if (!frontmatter || typeof frontmatter !== 'object') {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const { name, description } = frontmatter;
|
|
62
|
+
if (typeof name !== 'string' || typeof description !== 'string') {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
name,
|
|
67
|
+
description,
|
|
68
|
+
location: filePath,
|
|
69
|
+
body: match[2].trim(),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
debugLogger.log(`Error parsing skill file ${filePath}:`, error);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=skillLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillLoader.js","sourceRoot":"","sources":["../../../src/skills/skillLoader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAkBhD,MAAM,iBAAiB,GAAG,2CAA2C,CAAC;AAEtE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW;IAEX,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE;YAC1C,GAAG,EAAE,kBAAkB;YACvB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,QAAQ,EAAE,CAAC;gBACb,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,UAAU,CAAC,YAAY,CACrB,SAAS,EACT,8BAA8B,kBAAkB,0JAA0J,CAC3M,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,UAAU,CAAC,YAAY,CACrB,SAAS,EACT,+BAA+B,GAAG,GAAG,EACrC,KAAK,CACN,CAAC;IACJ,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,WAAsC,CAAC;QACrE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,IAAI;YACJ,WAAW;YACX,QAAQ,EAAE,QAAQ;YAClB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACtB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,GAAG,CAAC,4BAA4B,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { loadSkillsFromDir } from './skillLoader.js';
|
|
11
|
+
import { coreEvents } from '../utils/events.js';
|
|
12
|
+
describe('skillLoader', () => {
|
|
13
|
+
let testRootDir;
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
testRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'skill-loader-test-'));
|
|
16
|
+
vi.spyOn(coreEvents, 'emitFeedback');
|
|
17
|
+
});
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await fs.rm(testRootDir, { recursive: true, force: true });
|
|
20
|
+
vi.restoreAllMocks();
|
|
21
|
+
});
|
|
22
|
+
it('should load skills from a directory with valid SKILL.md', async () => {
|
|
23
|
+
const skillDir = path.join(testRootDir, 'my-skill');
|
|
24
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
25
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
26
|
+
await fs.writeFile(skillFile, `---\nname: my-skill\ndescription: A test skill\n---\n# Instructions\nDo something.\n`);
|
|
27
|
+
const skills = await loadSkillsFromDir(testRootDir);
|
|
28
|
+
expect(skills).toHaveLength(1);
|
|
29
|
+
expect(skills[0].name).toBe('my-skill');
|
|
30
|
+
expect(skills[0].description).toBe('A test skill');
|
|
31
|
+
expect(skills[0].location).toBe(skillFile);
|
|
32
|
+
expect(skills[0].body).toBe('# Instructions\nDo something.');
|
|
33
|
+
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
|
34
|
+
});
|
|
35
|
+
it('should emit feedback when no valid skills are found in a non-empty directory', async () => {
|
|
36
|
+
const notASkillDir = path.join(testRootDir, 'not-a-skill');
|
|
37
|
+
await fs.mkdir(notASkillDir, { recursive: true });
|
|
38
|
+
await fs.writeFile(path.join(notASkillDir, 'some-file.txt'), 'hello');
|
|
39
|
+
const skills = await loadSkillsFromDir(testRootDir);
|
|
40
|
+
expect(skills).toHaveLength(0);
|
|
41
|
+
expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('Failed to load skills from'));
|
|
42
|
+
});
|
|
43
|
+
it('should ignore empty directories and not emit feedback', async () => {
|
|
44
|
+
const skills = await loadSkillsFromDir(testRootDir);
|
|
45
|
+
expect(skills).toHaveLength(0);
|
|
46
|
+
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
|
47
|
+
});
|
|
48
|
+
it('should ignore directories without SKILL.md', async () => {
|
|
49
|
+
const notASkillDir = path.join(testRootDir, 'not-a-skill');
|
|
50
|
+
await fs.mkdir(notASkillDir, { recursive: true });
|
|
51
|
+
// With a subdirectory, even if empty, it might still trigger readdir
|
|
52
|
+
// But my current logic is if discoveredSkills.length === 0, then check readdir
|
|
53
|
+
// If readdir is empty, it's fine.
|
|
54
|
+
const skills = await loadSkillsFromDir(testRootDir);
|
|
55
|
+
expect(skills).toHaveLength(0);
|
|
56
|
+
// If notASkillDir is empty, no warning.
|
|
57
|
+
});
|
|
58
|
+
it('should ignore SKILL.md without valid frontmatter and emit warning if directory is not empty', async () => {
|
|
59
|
+
const skillDir = path.join(testRootDir, 'invalid-skill');
|
|
60
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
61
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
62
|
+
await fs.writeFile(skillFile, '# No frontmatter here');
|
|
63
|
+
const skills = await loadSkillsFromDir(testRootDir);
|
|
64
|
+
expect(skills).toHaveLength(0);
|
|
65
|
+
expect(coreEvents.emitFeedback).toHaveBeenCalledWith('warning', expect.stringContaining('Failed to load skills from'));
|
|
66
|
+
});
|
|
67
|
+
it('should return empty array for non-existent directory', async () => {
|
|
68
|
+
const skills = await loadSkillsFromDir('/non/existent/path');
|
|
69
|
+
expect(skills).toEqual([]);
|
|
70
|
+
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=skillLoader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillLoader.test.js","sourceRoot":"","sources":["../../../src/skills/skillLoader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,13 +4,9 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { Storage } from '../config/storage.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
location: string;
|
|
11
|
-
body: string;
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
}
|
|
7
|
+
import { type SkillDefinition } from './skillLoader.js';
|
|
8
|
+
import type { GeminiCLIExtension } from '../config/config.js';
|
|
9
|
+
export { type SkillDefinition };
|
|
14
10
|
export declare class SkillManager {
|
|
15
11
|
private skills;
|
|
16
12
|
private activeSkillNames;
|
|
@@ -19,28 +15,23 @@ export declare class SkillManager {
|
|
|
19
15
|
*/
|
|
20
16
|
clearSkills(): void;
|
|
21
17
|
/**
|
|
22
|
-
* Discovers skills from standard user and project locations.
|
|
23
|
-
*
|
|
18
|
+
* Discovers skills from standard user and project locations, as well as extensions.
|
|
19
|
+
* Precedence: Extensions (lowest) -> User -> Project (highest).
|
|
24
20
|
*/
|
|
25
|
-
discoverSkills(storage: Storage): Promise<void>;
|
|
21
|
+
discoverSkills(storage: Storage, extensions?: GeminiCLIExtension[]): Promise<void>;
|
|
26
22
|
private addSkillsWithPrecedence;
|
|
27
|
-
/**
|
|
28
|
-
* Discovered skills in the provided paths and adds them to the manager.
|
|
29
|
-
* Internal helper for tiered discovery.
|
|
30
|
-
*/
|
|
31
|
-
discoverSkillsInternal(paths: string[]): Promise<SkillMetadata[]>;
|
|
32
23
|
/**
|
|
33
24
|
* Returns the list of enabled discovered skills.
|
|
34
25
|
*/
|
|
35
|
-
getSkills():
|
|
26
|
+
getSkills(): SkillDefinition[];
|
|
36
27
|
/**
|
|
37
28
|
* Returns all discovered skills, including disabled ones.
|
|
38
29
|
*/
|
|
39
|
-
getAllSkills():
|
|
30
|
+
getAllSkills(): SkillDefinition[];
|
|
40
31
|
/**
|
|
41
32
|
* Filters discovered skills by name.
|
|
42
33
|
*/
|
|
43
|
-
filterSkills(predicate: (skill:
|
|
34
|
+
filterSkills(predicate: (skill: SkillDefinition) => boolean): void;
|
|
44
35
|
/**
|
|
45
36
|
* Sets the list of disabled skill names.
|
|
46
37
|
*/
|
|
@@ -48,7 +39,7 @@ export declare class SkillManager {
|
|
|
48
39
|
/**
|
|
49
40
|
* Reads the full content (metadata + body) of a skill by name.
|
|
50
41
|
*/
|
|
51
|
-
getSkill(name: string):
|
|
42
|
+
getSkill(name: string): SkillDefinition | null;
|
|
52
43
|
/**
|
|
53
44
|
* Activates a skill by name.
|
|
54
45
|
*/
|
|
@@ -57,5 +48,4 @@ export declare class SkillManager {
|
|
|
57
48
|
* Checks if a skill is active.
|
|
58
49
|
*/
|
|
59
50
|
isSkillActive(name: string): boolean;
|
|
60
|
-
private parseSkillFile;
|
|
61
51
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Storage } from '../config/storage.js';
|
|
7
|
+
import { loadSkillsFromDir } from './skillLoader.js';
|
|
8
|
+
export {};
|
|
9
|
+
export class SkillManager {
|
|
10
|
+
skills = [];
|
|
11
|
+
activeSkillNames = new Set();
|
|
12
|
+
/**
|
|
13
|
+
* Clears all discovered skills.
|
|
14
|
+
*/
|
|
15
|
+
clearSkills() {
|
|
16
|
+
this.skills = [];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Discovers skills from standard user and project locations, as well as extensions.
|
|
20
|
+
* Precedence: Extensions (lowest) -> User -> Project (highest).
|
|
21
|
+
*/
|
|
22
|
+
async discoverSkills(storage, extensions = []) {
|
|
23
|
+
this.clearSkills();
|
|
24
|
+
// 1. Extension skills (lowest precedence)
|
|
25
|
+
for (const extension of extensions) {
|
|
26
|
+
if (extension.isActive && extension.skills) {
|
|
27
|
+
this.addSkillsWithPrecedence(extension.skills);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// 2. User skills
|
|
31
|
+
const userSkills = await loadSkillsFromDir(Storage.getUserSkillsDir());
|
|
32
|
+
this.addSkillsWithPrecedence(userSkills);
|
|
33
|
+
// 3. Project skills (highest precedence)
|
|
34
|
+
const projectSkills = await loadSkillsFromDir(storage.getProjectSkillsDir());
|
|
35
|
+
this.addSkillsWithPrecedence(projectSkills);
|
|
36
|
+
}
|
|
37
|
+
addSkillsWithPrecedence(newSkills) {
|
|
38
|
+
const skillMap = new Map();
|
|
39
|
+
for (const skill of [...this.skills, ...newSkills]) {
|
|
40
|
+
skillMap.set(skill.name, skill);
|
|
41
|
+
}
|
|
42
|
+
this.skills = Array.from(skillMap.values());
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns the list of enabled discovered skills.
|
|
46
|
+
*/
|
|
47
|
+
getSkills() {
|
|
48
|
+
return this.skills.filter((s) => !s.disabled);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns all discovered skills, including disabled ones.
|
|
52
|
+
*/
|
|
53
|
+
getAllSkills() {
|
|
54
|
+
return this.skills;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Filters discovered skills by name.
|
|
58
|
+
*/
|
|
59
|
+
filterSkills(predicate) {
|
|
60
|
+
this.skills = this.skills.filter(predicate);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sets the list of disabled skill names.
|
|
64
|
+
*/
|
|
65
|
+
setDisabledSkills(disabledNames) {
|
|
66
|
+
for (const skill of this.skills) {
|
|
67
|
+
skill.disabled = disabledNames.includes(skill.name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reads the full content (metadata + body) of a skill by name.
|
|
72
|
+
*/
|
|
73
|
+
getSkill(name) {
|
|
74
|
+
return this.skills.find((s) => s.name === name) ?? null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Activates a skill by name.
|
|
78
|
+
*/
|
|
79
|
+
activateSkill(name) {
|
|
80
|
+
this.activeSkillNames.add(name);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Checks if a skill is active.
|
|
84
|
+
*/
|
|
85
|
+
isSkillActive(name) {
|
|
86
|
+
return this.activeSkillNames.has(name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=skillManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillManager.js","sourceRoot":"","sources":["../../../src/skills/skillManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAwB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAwB,CAAC;AAEhC,MAAM,OAAO,YAAY;IACf,MAAM,GAAsB,EAAE,CAAC;IAC/B,gBAAgB,GAAgB,IAAI,GAAG,EAAE,CAAC;IAElD;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc,CAClB,OAAgB,EAChB,aAAmC,EAAE;QAErC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,0CAA0C;QAC1C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;gBAC3C,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAEzC,yCAAyC;QACzC,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAC3C,OAAO,CAAC,mBAAmB,EAAE,CAC9B,CAAC;QACF,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAEO,uBAAuB,CAAC,SAA4B;QAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;QACpD,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;YACnD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,SAA8C;QACzD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,aAAuB;QACvC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAY;QACxB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { SkillManager } from './skillManager.js';
|
|
11
|
+
import { Storage } from '../config/storage.js';
|
|
12
|
+
import {} from '../config/config.js';
|
|
13
|
+
describe('SkillManager', () => {
|
|
14
|
+
let testRootDir;
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
testRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'skill-manager-test-'));
|
|
17
|
+
});
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await fs.rm(testRootDir, { recursive: true, force: true });
|
|
20
|
+
vi.restoreAllMocks();
|
|
21
|
+
});
|
|
22
|
+
it('should discover skills from extensions, user, and project with precedence', async () => {
|
|
23
|
+
const userDir = path.join(testRootDir, 'user');
|
|
24
|
+
const projectDir = path.join(testRootDir, 'project');
|
|
25
|
+
await fs.mkdir(path.join(userDir, 'skill-a'), { recursive: true });
|
|
26
|
+
await fs.mkdir(path.join(projectDir, 'skill-b'), { recursive: true });
|
|
27
|
+
await fs.writeFile(path.join(userDir, 'skill-a', 'SKILL.md'), `---
|
|
28
|
+
name: skill-user
|
|
29
|
+
description: user-desc
|
|
30
|
+
---
|
|
31
|
+
`);
|
|
32
|
+
await fs.writeFile(path.join(projectDir, 'skill-b', 'SKILL.md'), `---
|
|
33
|
+
name: skill-project
|
|
34
|
+
description: project-desc
|
|
35
|
+
---
|
|
36
|
+
`);
|
|
37
|
+
const mockExtension = {
|
|
38
|
+
name: 'test-ext',
|
|
39
|
+
version: '1.0.0',
|
|
40
|
+
isActive: true,
|
|
41
|
+
path: '/ext',
|
|
42
|
+
contextFiles: [],
|
|
43
|
+
id: 'ext-id',
|
|
44
|
+
skills: [
|
|
45
|
+
{
|
|
46
|
+
name: 'skill-extension',
|
|
47
|
+
description: 'ext-desc',
|
|
48
|
+
location: '/ext/skills/SKILL.md',
|
|
49
|
+
body: 'body',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
vi.spyOn(Storage, 'getUserSkillsDir').mockReturnValue(userDir);
|
|
54
|
+
const storage = new Storage('/dummy');
|
|
55
|
+
vi.spyOn(storage, 'getProjectSkillsDir').mockReturnValue(projectDir);
|
|
56
|
+
const service = new SkillManager();
|
|
57
|
+
await service.discoverSkills(storage, [mockExtension]);
|
|
58
|
+
const skills = service.getSkills();
|
|
59
|
+
expect(skills).toHaveLength(3);
|
|
60
|
+
const names = skills.map((s) => s.name);
|
|
61
|
+
expect(names).toContain('skill-extension');
|
|
62
|
+
expect(names).toContain('skill-user');
|
|
63
|
+
expect(names).toContain('skill-project');
|
|
64
|
+
});
|
|
65
|
+
it('should respect precedence: Project > User > Extension', async () => {
|
|
66
|
+
const userDir = path.join(testRootDir, 'user');
|
|
67
|
+
const projectDir = path.join(testRootDir, 'project');
|
|
68
|
+
await fs.mkdir(path.join(userDir, 'skill'), { recursive: true });
|
|
69
|
+
await fs.mkdir(path.join(projectDir, 'skill'), { recursive: true });
|
|
70
|
+
await fs.writeFile(path.join(userDir, 'skill', 'SKILL.md'), `---
|
|
71
|
+
name: same-name
|
|
72
|
+
description: user-desc
|
|
73
|
+
---
|
|
74
|
+
`);
|
|
75
|
+
await fs.writeFile(path.join(projectDir, 'skill', 'SKILL.md'), `---
|
|
76
|
+
name: same-name
|
|
77
|
+
description: project-desc
|
|
78
|
+
---
|
|
79
|
+
`);
|
|
80
|
+
const mockExtension = {
|
|
81
|
+
name: 'test-ext',
|
|
82
|
+
version: '1.0.0',
|
|
83
|
+
isActive: true,
|
|
84
|
+
path: '/ext',
|
|
85
|
+
contextFiles: [],
|
|
86
|
+
id: 'ext-id',
|
|
87
|
+
skills: [
|
|
88
|
+
{
|
|
89
|
+
name: 'same-name',
|
|
90
|
+
description: 'ext-desc',
|
|
91
|
+
location: '/ext/skills/SKILL.md',
|
|
92
|
+
body: 'body',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
vi.spyOn(Storage, 'getUserSkillsDir').mockReturnValue(userDir);
|
|
97
|
+
const storage = new Storage('/dummy');
|
|
98
|
+
vi.spyOn(storage, 'getProjectSkillsDir').mockReturnValue(projectDir);
|
|
99
|
+
const service = new SkillManager();
|
|
100
|
+
await service.discoverSkills(storage, [mockExtension]);
|
|
101
|
+
const skills = service.getSkills();
|
|
102
|
+
expect(skills).toHaveLength(1);
|
|
103
|
+
expect(skills[0].description).toBe('project-desc');
|
|
104
|
+
// Test User > Extension
|
|
105
|
+
vi.spyOn(storage, 'getProjectSkillsDir').mockReturnValue('/non-existent');
|
|
106
|
+
await service.discoverSkills(storage, [mockExtension]);
|
|
107
|
+
expect(service.getSkills()[0].description).toBe('user-desc');
|
|
108
|
+
});
|
|
109
|
+
it('should filter disabled skills in getSkills but not in getAllSkills', async () => {
|
|
110
|
+
const skillDir = path.join(testRootDir, 'skill1');
|
|
111
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
112
|
+
await fs.writeFile(path.join(skillDir, 'SKILL.md'), `---
|
|
113
|
+
name: skill1
|
|
114
|
+
description: desc1
|
|
115
|
+
---
|
|
116
|
+
`);
|
|
117
|
+
const storage = new Storage('/dummy');
|
|
118
|
+
vi.spyOn(storage, 'getProjectSkillsDir').mockReturnValue(testRootDir);
|
|
119
|
+
vi.spyOn(Storage, 'getUserSkillsDir').mockReturnValue('/non-existent');
|
|
120
|
+
const service = new SkillManager();
|
|
121
|
+
await service.discoverSkills(storage);
|
|
122
|
+
service.setDisabledSkills(['skill1']);
|
|
123
|
+
expect(service.getSkills()).toHaveLength(0);
|
|
124
|
+
expect(service.getAllSkills()).toHaveLength(1);
|
|
125
|
+
expect(service.getAllSkills()[0].disabled).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=skillManager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillManager.test.js","sourceRoot":"","sources":["../../../src/skills/skillManager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
7
|
-
import type { StartSessionEvent, UserPromptEvent, ToolCallEvent, ApiRequestEvent, ApiResponseEvent, ApiErrorEvent, LoopDetectedEvent, NextSpeakerCheckEvent, SlashCommandEvent, MalformedJsonResponseEvent, IdeConnectionEvent, ConversationFinishedEvent, ChatCompressionEvent, FileOperationEvent, InvalidChunkEvent, ContentRetryEvent, ContentRetryFailureEvent, ExtensionInstallEvent, ToolOutputTruncatedEvent, ExtensionUninstallEvent, ModelRoutingEvent, ExtensionEnableEvent, ModelSlashCommandEvent, ExtensionDisableEvent,
|
|
7
|
+
import type { StartSessionEvent, UserPromptEvent, ToolCallEvent, ApiRequestEvent, ApiResponseEvent, ApiErrorEvent, LoopDetectedEvent, NextSpeakerCheckEvent, SlashCommandEvent, MalformedJsonResponseEvent, IdeConnectionEvent, ConversationFinishedEvent, ChatCompressionEvent, FileOperationEvent, InvalidChunkEvent, ContentRetryEvent, ContentRetryFailureEvent, ExtensionInstallEvent, ToolOutputTruncatedEvent, ExtensionUninstallEvent, ModelRoutingEvent, ExtensionEnableEvent, ModelSlashCommandEvent, ExtensionDisableEvent, EditStrategyEvent, EditCorrectionEvent, AgentStartEvent, AgentFinishEvent, RecoveryAttemptEvent, WebFetchFallbackAttemptEvent, ExtensionUpdateEvent, LlmLoopCheckEvent, HookCallEvent } from '../types.js';
|
|
8
8
|
import { EventMetadataKey } from './event-metadata-key.js';
|
|
9
9
|
import type { Config } from '../../config/config.js';
|
|
10
10
|
export declare enum EventNames {
|
|
@@ -38,8 +38,8 @@ export declare enum EventNames {
|
|
|
38
38
|
TOOL_OUTPUT_TRUNCATED = "tool_output_truncated",
|
|
39
39
|
MODEL_ROUTING = "model_routing",
|
|
40
40
|
MODEL_SLASH_COMMAND = "model_slash_command",
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
EDIT_STRATEGY = "edit_strategy",
|
|
42
|
+
EDIT_CORRECTION = "edit_correction",
|
|
43
43
|
AGENT_START = "agent_start",
|
|
44
44
|
AGENT_FINISH = "agent_finish",
|
|
45
45
|
RECOVERY_ATTEMPT = "recovery_attempt",
|
|
@@ -137,8 +137,8 @@ export declare class ClearcutLogger {
|
|
|
137
137
|
logExtensionEnableEvent(event: ExtensionEnableEvent): Promise<void>;
|
|
138
138
|
logModelSlashCommandEvent(event: ModelSlashCommandEvent): void;
|
|
139
139
|
logExtensionDisableEvent(event: ExtensionDisableEvent): Promise<void>;
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
logEditStrategyEvent(event: EditStrategyEvent): void;
|
|
141
|
+
logEditCorrectionEvent(event: EditCorrectionEvent): void;
|
|
142
142
|
logAgentStartEvent(event: AgentStartEvent): void;
|
|
143
143
|
logAgentFinishEvent(event: AgentFinishEvent): void;
|
|
144
144
|
logRecoveryAttemptEvent(event: RecoveryAttemptEvent): void;
|
|
@@ -45,8 +45,8 @@ export var EventNames;
|
|
|
45
45
|
EventNames["TOOL_OUTPUT_TRUNCATED"] = "tool_output_truncated";
|
|
46
46
|
EventNames["MODEL_ROUTING"] = "model_routing";
|
|
47
47
|
EventNames["MODEL_SLASH_COMMAND"] = "model_slash_command";
|
|
48
|
-
EventNames["
|
|
49
|
-
EventNames["
|
|
48
|
+
EventNames["EDIT_STRATEGY"] = "edit_strategy";
|
|
49
|
+
EventNames["EDIT_CORRECTION"] = "edit_correction";
|
|
50
50
|
EventNames["AGENT_START"] = "agent_start";
|
|
51
51
|
EventNames["AGENT_FINISH"] = "agent_finish";
|
|
52
52
|
EventNames["RECOVERY_ATTEMPT"] = "recovery_attempt";
|
|
@@ -988,24 +988,24 @@ export class ClearcutLogger {
|
|
|
988
988
|
debugLogger.debug('Error flushing to Clearcut:', error);
|
|
989
989
|
});
|
|
990
990
|
}
|
|
991
|
-
|
|
991
|
+
logEditStrategyEvent(event) {
|
|
992
992
|
const data = [
|
|
993
993
|
{
|
|
994
|
-
gemini_cli_key: EventMetadataKey.
|
|
994
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EDIT_STRATEGY,
|
|
995
995
|
value: event.strategy,
|
|
996
996
|
},
|
|
997
997
|
];
|
|
998
|
-
this.enqueueLogEvent(this.createLogEvent(EventNames.
|
|
998
|
+
this.enqueueLogEvent(this.createLogEvent(EventNames.EDIT_STRATEGY, data));
|
|
999
999
|
this.flushIfNeeded();
|
|
1000
1000
|
}
|
|
1001
|
-
|
|
1001
|
+
logEditCorrectionEvent(event) {
|
|
1002
1002
|
const data = [
|
|
1003
1003
|
{
|
|
1004
|
-
gemini_cli_key: EventMetadataKey.
|
|
1004
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EDIT_CORRECTION,
|
|
1005
1005
|
value: event.correction,
|
|
1006
1006
|
},
|
|
1007
1007
|
];
|
|
1008
|
-
this.enqueueLogEvent(this.createLogEvent(EventNames.
|
|
1008
|
+
this.enqueueLogEvent(this.createLogEvent(EventNames.EDIT_CORRECTION, data));
|
|
1009
1009
|
this.flushIfNeeded();
|
|
1010
1010
|
}
|
|
1011
1011
|
logAgentStartEvent(event) {
|