@wxp212/gemini-cli 0.28.3-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/LICENSE +202 -0
- package/README.md +393 -0
- package/bundle/builtin/skill-creator/SKILL.md +382 -0
- package/bundle/builtin/skill-creator/scripts/init_skill.cjs +235 -0
- package/bundle/builtin/skill-creator/scripts/package_skill.cjs +102 -0
- package/bundle/builtin/skill-creator/scripts/validate_skill.cjs +127 -0
- package/bundle/docs/architecture.md +80 -0
- package/bundle/docs/assets/connected_devtools.png +0 -0
- package/bundle/docs/assets/gemini-screenshot.png +0 -0
- package/bundle/docs/assets/monitoring-dashboard-logs.png +0 -0
- package/bundle/docs/assets/monitoring-dashboard-metrics.png +0 -0
- package/bundle/docs/assets/monitoring-dashboard-overview.png +0 -0
- package/bundle/docs/assets/release_patch.png +0 -0
- package/bundle/docs/assets/theme-ansi-light.png +0 -0
- package/bundle/docs/assets/theme-ansi.png +0 -0
- package/bundle/docs/assets/theme-atom-one.png +0 -0
- package/bundle/docs/assets/theme-ayu-light.png +0 -0
- package/bundle/docs/assets/theme-ayu.png +0 -0
- package/bundle/docs/assets/theme-custom.png +0 -0
- package/bundle/docs/assets/theme-default-light.png +0 -0
- package/bundle/docs/assets/theme-default.png +0 -0
- package/bundle/docs/assets/theme-dracula.png +0 -0
- package/bundle/docs/assets/theme-github-light.png +0 -0
- package/bundle/docs/assets/theme-github.png +0 -0
- package/bundle/docs/assets/theme-google-light.png +0 -0
- package/bundle/docs/assets/theme-xcode-light.png +0 -0
- package/bundle/docs/changelogs/index.md +743 -0
- package/bundle/docs/changelogs/latest.md +338 -0
- package/bundle/docs/changelogs/preview.md +437 -0
- package/bundle/docs/cli/authentication.md +3 -0
- package/bundle/docs/cli/checkpointing.md +94 -0
- package/bundle/docs/cli/cli-reference.md +101 -0
- package/bundle/docs/cli/commands.md +430 -0
- package/bundle/docs/cli/creating-skills.md +80 -0
- package/bundle/docs/cli/custom-commands.md +315 -0
- package/bundle/docs/cli/enterprise.md +582 -0
- package/bundle/docs/cli/gemini-ignore.md +71 -0
- package/bundle/docs/cli/gemini-md.md +108 -0
- package/bundle/docs/cli/generation-settings.md +210 -0
- package/bundle/docs/cli/headless.md +388 -0
- package/bundle/docs/cli/index.md +65 -0
- package/bundle/docs/cli/keyboard-shortcuts.md +141 -0
- package/bundle/docs/cli/model-routing.md +42 -0
- package/bundle/docs/cli/model.md +62 -0
- package/bundle/docs/cli/rewind.md +51 -0
- package/bundle/docs/cli/sandbox.md +171 -0
- package/bundle/docs/cli/session-management.md +158 -0
- package/bundle/docs/cli/settings.md +141 -0
- package/bundle/docs/cli/skills.md +112 -0
- package/bundle/docs/cli/system-prompt.md +125 -0
- package/bundle/docs/cli/telemetry.md +826 -0
- package/bundle/docs/cli/themes.md +235 -0
- package/bundle/docs/cli/token-caching.md +20 -0
- package/bundle/docs/cli/trusted-folders.md +95 -0
- package/bundle/docs/cli/tutorials/skills-getting-started.md +97 -0
- package/bundle/docs/cli/tutorials.md +87 -0
- package/bundle/docs/cli/uninstall.md +65 -0
- package/bundle/docs/core/index.md +107 -0
- package/bundle/docs/core/memport.md +246 -0
- package/bundle/docs/core/policy-engine.md +305 -0
- package/bundle/docs/core/remote-agents.md +84 -0
- package/bundle/docs/core/subagents.md +191 -0
- package/bundle/docs/core/tools-api.md +131 -0
- package/bundle/docs/examples/proxy-script.md +83 -0
- package/bundle/docs/extensions/best-practices.md +139 -0
- package/bundle/docs/extensions/index.md +45 -0
- package/bundle/docs/extensions/reference.md +336 -0
- package/bundle/docs/extensions/releasing.md +183 -0
- package/bundle/docs/extensions/writing-extensions.md +281 -0
- package/bundle/docs/faq.md +154 -0
- package/bundle/docs/get-started/authentication.md +321 -0
- package/bundle/docs/get-started/configuration-v1.md +880 -0
- package/bundle/docs/get-started/configuration.md +1602 -0
- package/bundle/docs/get-started/examples.md +219 -0
- package/bundle/docs/get-started/gemini-3.md +101 -0
- package/bundle/docs/get-started/index.md +71 -0
- package/bundle/docs/get-started/installation.md +141 -0
- package/bundle/docs/hooks/best-practices.md +677 -0
- package/bundle/docs/hooks/index.md +164 -0
- package/bundle/docs/hooks/reference.md +322 -0
- package/bundle/docs/hooks/writing-hooks.md +450 -0
- package/bundle/docs/ide-integration/ide-companion-spec.md +267 -0
- package/bundle/docs/ide-integration/index.md +202 -0
- package/bundle/docs/index.md +123 -0
- package/bundle/docs/integration-tests.md +211 -0
- package/bundle/docs/issue-and-pr-automation.md +134 -0
- package/bundle/docs/local-development.md +128 -0
- package/bundle/docs/mermaid/context.mmd +103 -0
- package/bundle/docs/mermaid/render-path.mmd +64 -0
- package/bundle/docs/npm.md +62 -0
- package/bundle/docs/quota-and-pricing.md +158 -0
- package/bundle/docs/release-confidence.md +164 -0
- package/bundle/docs/releases.md +540 -0
- package/bundle/docs/sidebar.json +152 -0
- package/bundle/docs/tools/file-system.md +216 -0
- package/bundle/docs/tools/index.md +98 -0
- package/bundle/docs/tools/mcp-server.md +1068 -0
- package/bundle/docs/tools/memory.md +54 -0
- package/bundle/docs/tools/shell.md +260 -0
- package/bundle/docs/tools/todos.md +57 -0
- package/bundle/docs/tools/web-fetch.md +59 -0
- package/bundle/docs/tools/web-search.md +42 -0
- package/bundle/docs/tos-privacy.md +96 -0
- package/bundle/docs/troubleshooting.md +173 -0
- package/bundle/gemini.js +538280 -0
- package/bundle/policies/discovered.toml +8 -0
- package/bundle/policies/plan.toml +86 -0
- package/bundle/policies/read-only.toml +51 -0
- package/bundle/policies/write.toml +78 -0
- package/bundle/policies/yolo.toml +32 -0
- package/bundle/sandbox-macos-permissive-closed.sb +32 -0
- package/bundle/sandbox-macos-permissive-open.sb +27 -0
- package/bundle/sandbox-macos-permissive-proxied.sb +37 -0
- package/bundle/sandbox-macos-restrictive-closed.sb +93 -0
- package/bundle/sandbox-macos-restrictive-open.sb +96 -0
- package/bundle/sandbox-macos-restrictive-proxied.sb +98 -0
- package/package.json +154 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-env node */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Skill Packager - Creates a distributable .skill file of a skill folder
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node package_skill.js <path/to/skill-folder> [output-directory]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const path = require('node:path');
|
|
13
|
+
const { spawnSync } = require('node:child_process');
|
|
14
|
+
const { validateSkill } = require('./validate_skill.cjs');
|
|
15
|
+
|
|
16
|
+
async function main() {
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
if (args.length < 1) {
|
|
19
|
+
console.log(
|
|
20
|
+
'Usage: node package_skill.js <path/to/skill-folder> [output-directory]',
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const skillPathArg = args[0];
|
|
26
|
+
const outputDirArg = args[1];
|
|
27
|
+
|
|
28
|
+
if (
|
|
29
|
+
skillPathArg.includes('..') ||
|
|
30
|
+
(outputDirArg && outputDirArg.includes('..'))
|
|
31
|
+
) {
|
|
32
|
+
console.error('❌ Error: Path traversal detected in arguments.');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const skillPath = path.resolve(skillPathArg);
|
|
37
|
+
const outputDir = outputDirArg ? path.resolve(outputDirArg) : process.cwd();
|
|
38
|
+
const skillName = path.basename(skillPath);
|
|
39
|
+
|
|
40
|
+
// 1. Validate first
|
|
41
|
+
console.log('🔍 Validating skill...');
|
|
42
|
+
const result = validateSkill(skillPath);
|
|
43
|
+
if (!result.valid) {
|
|
44
|
+
console.error(`❌ Validation failed: ${result.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (result.warning) {
|
|
49
|
+
console.warn(`⚠️ ${result.warning}`);
|
|
50
|
+
console.log('Please resolve all TODOs before packaging.');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
console.log('✅ Skill is valid!');
|
|
54
|
+
|
|
55
|
+
// 2. Package
|
|
56
|
+
const outputFilename = path.join(outputDir, `${skillName}.skill`);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Zip everything except junk, keeping the folder structure
|
|
60
|
+
// We'll use the native 'zip' command for simplicity in a CLI environment
|
|
61
|
+
// or we could use a JS library, but zip is ubiquitous on darwin/linux.
|
|
62
|
+
|
|
63
|
+
// Command to zip:
|
|
64
|
+
// -r: recursive
|
|
65
|
+
// -x: exclude patterns
|
|
66
|
+
// Run the zip command from within the directory to avoid parent folder nesting
|
|
67
|
+
let zipProcess = spawnSync('zip', ['-r', outputFilename, '.'], {
|
|
68
|
+
cwd: skillPath,
|
|
69
|
+
stdio: 'inherit',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (zipProcess.error || zipProcess.status !== 0) {
|
|
73
|
+
// Fallback to tar --format=zip if zip is not available (common on Windows)
|
|
74
|
+
console.log('zip command not found, falling back to tar...');
|
|
75
|
+
zipProcess = spawnSync(
|
|
76
|
+
'tar',
|
|
77
|
+
['-a', '-c', '--format=zip', '-f', outputFilename, '.'],
|
|
78
|
+
{
|
|
79
|
+
cwd: skillPath,
|
|
80
|
+
stdio: 'inherit',
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (zipProcess.error) {
|
|
86
|
+
throw zipProcess.error;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (zipProcess.status !== 0) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Packaging command failed with exit code ${zipProcess.status}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log(`✅ Successfully packaged skill to: ${outputFilename}`);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.error(`❌ Error packaging: ${err.message}`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
main();
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Quick validation logic for skills.
|
|
5
|
+
* Leveraging existing dependencies when possible or providing a zero-dep fallback.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('node:fs');
|
|
9
|
+
const path = require('node:path');
|
|
10
|
+
|
|
11
|
+
function validateSkill(skillPath) {
|
|
12
|
+
if (!fs.existsSync(skillPath) || !fs.statSync(skillPath).isDirectory()) {
|
|
13
|
+
return { valid: false, message: `Path is not a directory: ${skillPath}` };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
|
17
|
+
if (!fs.existsSync(skillMdPath)) {
|
|
18
|
+
return { valid: false, message: 'SKILL.md not found' };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const content = fs.readFileSync(skillMdPath, 'utf8');
|
|
22
|
+
if (!content.startsWith('---')) {
|
|
23
|
+
return { valid: false, message: 'No YAML frontmatter found' };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const parts = content.split('---');
|
|
27
|
+
if (parts.length < 3) {
|
|
28
|
+
return { valid: false, message: 'Invalid frontmatter format' };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const frontmatterText = parts[1];
|
|
32
|
+
|
|
33
|
+
const nameMatch = frontmatterText.match(/^name:\s*(.+)$/m);
|
|
34
|
+
// Match description: "text" or description: 'text' or description: text
|
|
35
|
+
const descMatch = frontmatterText.match(
|
|
36
|
+
/^description:\s*(?:'([^']*)'|"([^"]*)"|(.+))$/m,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (!nameMatch)
|
|
40
|
+
return { valid: false, message: 'Missing "name" in frontmatter' };
|
|
41
|
+
if (!descMatch)
|
|
42
|
+
return {
|
|
43
|
+
valid: false,
|
|
44
|
+
message: 'Description must be a single-line string: description: ...',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const name = nameMatch[1].trim();
|
|
48
|
+
const description = (
|
|
49
|
+
descMatch[1] !== undefined
|
|
50
|
+
? descMatch[1]
|
|
51
|
+
: descMatch[2] !== undefined
|
|
52
|
+
? descMatch[2]
|
|
53
|
+
: descMatch[3] || ''
|
|
54
|
+
).trim();
|
|
55
|
+
|
|
56
|
+
if (description.includes('\n')) {
|
|
57
|
+
return {
|
|
58
|
+
valid: false,
|
|
59
|
+
message: 'Description must be a single line (no newlines)',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
64
|
+
return { valid: false, message: `Name "${name}" should be hyphen-case` };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (description.length > 1024) {
|
|
68
|
+
return { valid: false, message: 'Description is too long (max 1024)' };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check for TODOs
|
|
72
|
+
const files = getAllFiles(skillPath);
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
const fileContent = fs.readFileSync(file, 'utf8');
|
|
75
|
+
if (fileContent.includes('TODO:')) {
|
|
76
|
+
return {
|
|
77
|
+
valid: true,
|
|
78
|
+
message: 'Skill has unresolved TODOs',
|
|
79
|
+
warning: `Found unresolved TODO in ${path.relative(skillPath, file)}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return { valid: true, message: 'Skill is valid!' };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getAllFiles(dir, fileList = []) {
|
|
88
|
+
const files = fs.readdirSync(dir);
|
|
89
|
+
files.forEach((file) => {
|
|
90
|
+
const name = path.join(dir, file);
|
|
91
|
+
if (fs.statSync(name).isDirectory()) {
|
|
92
|
+
if (!['node_modules', '.git', '__pycache__'].includes(file)) {
|
|
93
|
+
getAllFiles(name, fileList);
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
fileList.push(name);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return fileList;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (require.main === module) {
|
|
103
|
+
const args = process.argv.slice(2);
|
|
104
|
+
if (args.length !== 1) {
|
|
105
|
+
console.log('Usage: node validate_skill.js <skill_directory>');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const skillDirArg = args[0];
|
|
110
|
+
if (skillDirArg.includes('..')) {
|
|
111
|
+
console.error('❌ Error: Path traversal detected in skill directory path.');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const result = validateSkill(path.resolve(skillDirArg));
|
|
116
|
+
if (result.warning) {
|
|
117
|
+
console.warn(`⚠️ ${result.warning}`);
|
|
118
|
+
}
|
|
119
|
+
if (result.valid) {
|
|
120
|
+
console.log(`✅ ${result.message}`);
|
|
121
|
+
} else {
|
|
122
|
+
console.error(`❌ ${result.message}`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = { validateSkill };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Gemini CLI Architecture Overview
|
|
2
|
+
|
|
3
|
+
This document provides a high-level overview of the Gemini CLI's architecture.
|
|
4
|
+
|
|
5
|
+
## Core components
|
|
6
|
+
|
|
7
|
+
The Gemini CLI is primarily composed of two main packages, along with a suite of
|
|
8
|
+
tools that can be used by the system in the course of handling command-line
|
|
9
|
+
input:
|
|
10
|
+
|
|
11
|
+
1. **CLI package (`packages/cli`):**
|
|
12
|
+
- **Purpose:** This contains the user-facing portion of the Gemini CLI, such
|
|
13
|
+
as handling the initial user input, presenting the final output, and
|
|
14
|
+
managing the overall user experience.
|
|
15
|
+
- **Key functions contained in the package:**
|
|
16
|
+
- [Input processing](/docs/cli/commands)
|
|
17
|
+
- History management
|
|
18
|
+
- Display rendering
|
|
19
|
+
- [Theme and UI customization](/docs/cli/themes)
|
|
20
|
+
- [CLI configuration settings](/docs/get-started/configuration)
|
|
21
|
+
|
|
22
|
+
2. **Core package (`packages/core`):**
|
|
23
|
+
- **Purpose:** This acts as the backend for the Gemini CLI. It receives
|
|
24
|
+
requests sent from `packages/cli`, orchestrates interactions with the
|
|
25
|
+
Gemini API, and manages the execution of available tools.
|
|
26
|
+
- **Key functions contained in the package:**
|
|
27
|
+
- API client for communicating with the Google Gemini API
|
|
28
|
+
- Prompt construction and management
|
|
29
|
+
- Tool registration and execution logic
|
|
30
|
+
- State management for conversations or sessions
|
|
31
|
+
- Server-side configuration
|
|
32
|
+
|
|
33
|
+
3. **Tools (`packages/core/src/tools/`):**
|
|
34
|
+
- **Purpose:** These are individual modules that extend the capabilities of
|
|
35
|
+
the Gemini model, allowing it to interact with the local environment
|
|
36
|
+
(e.g., file system, shell commands, web fetching).
|
|
37
|
+
- **Interaction:** `packages/core` invokes these tools based on requests
|
|
38
|
+
from the Gemini model.
|
|
39
|
+
|
|
40
|
+
## Interaction flow
|
|
41
|
+
|
|
42
|
+
A typical interaction with the Gemini CLI follows this flow:
|
|
43
|
+
|
|
44
|
+
1. **User input:** The user types a prompt or command into the terminal, which
|
|
45
|
+
is managed by `packages/cli`.
|
|
46
|
+
2. **Request to core:** `packages/cli` sends the user's input to
|
|
47
|
+
`packages/core`.
|
|
48
|
+
3. **Request processed:** The core package:
|
|
49
|
+
- Constructs an appropriate prompt for the Gemini API, possibly including
|
|
50
|
+
conversation history and available tool definitions.
|
|
51
|
+
- Sends the prompt to the Gemini API.
|
|
52
|
+
4. **Gemini API response:** The Gemini API processes the prompt and returns a
|
|
53
|
+
response. This response might be a direct answer or a request to use one of
|
|
54
|
+
the available tools.
|
|
55
|
+
5. **Tool execution (if applicable):**
|
|
56
|
+
- When the Gemini API requests a tool, the core package prepares to execute
|
|
57
|
+
it.
|
|
58
|
+
- If the requested tool can modify the file system or execute shell
|
|
59
|
+
commands, the user is first given details of the tool and its arguments,
|
|
60
|
+
and the user must approve the execution.
|
|
61
|
+
- Read-only operations, such as reading files, might not require explicit
|
|
62
|
+
user confirmation to proceed.
|
|
63
|
+
- Once confirmed, or if confirmation is not required, the core package
|
|
64
|
+
executes the relevant action within the relevant tool, and the result is
|
|
65
|
+
sent back to the Gemini API by the core package.
|
|
66
|
+
- The Gemini API processes the tool result and generates a final response.
|
|
67
|
+
6. **Response to CLI:** The core package sends the final response back to the
|
|
68
|
+
CLI package.
|
|
69
|
+
7. **Display to user:** The CLI package formats and displays the response to
|
|
70
|
+
the user in the terminal.
|
|
71
|
+
|
|
72
|
+
## Key design principles
|
|
73
|
+
|
|
74
|
+
- **Modularity:** Separating the CLI (frontend) from the Core (backend) allows
|
|
75
|
+
for independent development and potential future extensions (e.g., different
|
|
76
|
+
frontends for the same backend).
|
|
77
|
+
- **Extensibility:** The tool system is designed to be extensible, allowing new
|
|
78
|
+
capabilities to be added.
|
|
79
|
+
- **User experience:** The CLI focuses on providing a rich and interactive
|
|
80
|
+
terminal experience.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|