@genspark/cli 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -1
- package/dist/config.d.ts +11 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +100 -13
- package/dist/config.js.map +1 -1
- package/dist/index.js +85 -25
- package/dist/index.js.map +1 -1
- package/dist/localFiles.d.ts +62 -0
- package/dist/localFiles.d.ts.map +1 -0
- package/dist/localFiles.js +130 -0
- package/dist/localFiles.js.map +1 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +13 -0
- package/dist/logger.js.map +1 -1
- package/dist/mesh/checkupdate.js +3 -3
- package/dist/mesh/checkupdate.js.map +1 -1
- package/dist/runtime.d.ts +44 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +62 -0
- package/dist/runtime.js.map +1 -0
- package/dist/updater.d.ts +1 -0
- package/dist/updater.d.ts.map +1 -1
- package/dist/updater.js +10 -0
- package/dist/updater.js.map +1 -1
- package/docs/skills.md +20 -20
- package/package.json +1 -1
- package/skills/gsk-analyze-media/SKILL.md +2 -1
- package/skills/gsk-audio-generation/SKILL.md +1 -1
- package/skills/gsk-connector/SKILL.md +52 -0
- package/skills/gsk-github/SKILL.md +2 -0
- package/skills/gsk-gmail/SKILL.md +2 -0
- package/skills/gsk-google-calendar/SKILL.md +4 -1
- package/skills/gsk-google-chat/SKILL.md +4 -1
- package/skills/gsk-google-contacts/SKILL.md +2 -0
- package/skills/gsk-google-docs/SKILL.md +2 -0
- package/skills/gsk-google-drive/SKILL.md +3 -0
- package/skills/gsk-google-sheets/SKILL.md +4 -2
- package/skills/gsk-hub/SKILL.md +15 -5
- package/skills/gsk-image-generation/SKILL.md +2 -2
- package/skills/gsk-microsoft-teams/SKILL.md +4 -2
- package/skills/gsk-notion/SKILL.md +2 -0
- package/skills/gsk-onedrive/SKILL.md +3 -0
- package/skills/gsk-outlook-calendar/SKILL.md +3 -1
- package/skills/gsk-outlook-contacts/SKILL.md +2 -0
- package/skills/gsk-outlook-email/SKILL.md +3 -10
- package/skills/gsk-salesforce/SKILL.md +2 -0
- package/skills/gsk-shared/SKILL.md +12 -1
- package/skills/gsk-sharepoint/SKILL.md +3 -0
- package/skills/gsk-sharepoint-upload/SKILL.md +2 -0
- package/skills/gsk-slack/SKILL.md +12 -7
- package/skills/gsk-task-continue/SKILL.md +4 -3
- package/skills/gsk-video-generation/SKILL.md +8 -7
package/README.md
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
- [Media Analysis & Transcription](#media-analysis--transcription)
|
|
42
42
|
- [AI Drive (Cloud Storage)](#ai-drive-cloud-storage)
|
|
43
43
|
- [AI Agents & Tasks](#ai-agents--tasks)
|
|
44
|
+
- [Connectors (Unified)](#connectors-unified)
|
|
44
45
|
- [Service-Level Tools](#service-level-tools)
|
|
45
46
|
- [AI Phone Calls](#ai-phone-calls)
|
|
46
47
|
- [Stock Prices](#stock-prices)
|
|
@@ -84,7 +85,10 @@ Log in with your Genspark account:
|
|
|
84
85
|
gsk login
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
This opens a browser for authentication and saves the API key
|
|
88
|
+
This opens a browser for authentication and saves the API key plus the effective
|
|
89
|
+
API base URL to the selected config. The default is
|
|
90
|
+
`~/.genspark-tool-cli/config.json`; use `--config <path>` or `GSK_CONFIG` for a
|
|
91
|
+
separate profile.
|
|
88
92
|
|
|
89
93
|
Alternatively, provide an API key directly:
|
|
90
94
|
|
|
@@ -138,6 +142,7 @@ Config is loaded from three sources (highest priority first):
|
|
|
138
142
|
| `--timeout <ms>` | — | `300000` (5 min) | Request timeout |
|
|
139
143
|
| `--output <format>` | — | `json` | Output format: `json` or `text` |
|
|
140
144
|
| `--refresh` | — | — | Force refresh cached tool schemas |
|
|
145
|
+
| `--config <path>` | `GSK_CONFIG` | `~/.genspark-tool-cli/config.json` | Config profile path |
|
|
141
146
|
|
|
142
147
|
## Commands
|
|
143
148
|
|
|
@@ -526,10 +531,27 @@ gsk stock AAPL
|
|
|
526
531
|
gsk stock MSFT
|
|
527
532
|
```
|
|
528
533
|
|
|
534
|
+
### Connectors (unified)
|
|
535
|
+
|
|
536
|
+
One fixed flow discovers and invokes **any** connector — Gmail, Slack, Notion, HubSpot, custom MCP servers, and every connector added after this README was written:
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
gsk connector list # what is already connected?
|
|
540
|
+
gsk connector search <keyword> # does a connector for X exist?
|
|
541
|
+
gsk connector tools <identifier> # full JSON schema per tool
|
|
542
|
+
gsk connector call <identifier> -t <tool> -a '<json>' # invoke it
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
`<identifier>` accepts a connector id (`gmail`, `slack`, `hubspot`), a display name (`"Google Drive"`), or an MCP slug. Prefer this over the per-service commands below — see `skills/gsk-connector/SKILL.md` for the full flow, error codes, and examples.
|
|
546
|
+
|
|
547
|
+
> **Requirements:** Connect services in [Genspark Account Settings → Integrations](https://www.genspark.ai/settings/integrations).
|
|
548
|
+
|
|
529
549
|
### Service-Level Tools
|
|
530
550
|
|
|
531
551
|
External service integrations are available as **service-level tools** — each service is a single command with an `action` parameter that dispatches to the underlying operation.
|
|
532
552
|
|
|
553
|
+
> **Deprecated but working:** these per-service commands still work and are documented below for reference, but new integrations only ship in the unified `gsk connector` flow above — prefer that for anything new.
|
|
554
|
+
|
|
533
555
|
> **Requirements:** Connect services in [Genspark Account Settings → Integrations](https://www.genspark.ai/settings/integrations).
|
|
534
556
|
|
|
535
557
|
#### gmail
|
package/dist/config.d.ts
CHANGED
|
@@ -34,23 +34,26 @@ export declare function setConfigPathOverride(absPath: string | undefined): void
|
|
|
34
34
|
* Get the path to the config file — honours a `--config` override.
|
|
35
35
|
*/
|
|
36
36
|
export declare function getConfigPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Keep one canonical spelling for endpoint persistence and cache keys.
|
|
39
|
+
*/
|
|
40
|
+
export declare function normalizeBaseUrl(baseUrl: string): string;
|
|
37
41
|
/**
|
|
38
42
|
* Load configuration from the config file
|
|
39
43
|
* Returns an empty object if the file doesn't exist or is invalid
|
|
40
44
|
*/
|
|
41
45
|
export declare function loadConfigFile(): ConfigFile;
|
|
42
46
|
/**
|
|
43
|
-
*
|
|
47
|
+
* Replace the selected config file.
|
|
44
48
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* `--config /tmp/my-profile.json` is active, the write lands on
|
|
48
|
-
* `/tmp/my-profile.json`, not `/tmp/config.json`. Using the raw
|
|
49
|
-
* `CONFIG_FILE` constant here would make `login`/`logout` silently write
|
|
50
|
-
* to the wrong file while reads still target the override — a
|
|
51
|
-
* split-brain state.
|
|
49
|
+
* Prefer `updateConfigFile` for login/logout-style field changes because this
|
|
50
|
+
* replacement API intentionally cannot preserve fields absent from `config`.
|
|
52
51
|
*/
|
|
53
52
|
export declare function saveConfigFile(config: ConfigFile): void;
|
|
53
|
+
/**
|
|
54
|
+
* Patch known fields in the selected config without dropping extension fields.
|
|
55
|
+
*/
|
|
56
|
+
export declare function updateConfigFile(updates: Partial<ConfigFile>, removeKeys?: (keyof ConfigFile)[]): void;
|
|
54
57
|
/**
|
|
55
58
|
* Load tools from the cache file.
|
|
56
59
|
* Returns null if cache doesn't exist, is stale (>24h), or base_url doesn't match.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAYD,eAAO,MAAM,YAAY,+BAA+B,CAAA;AA+BxD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEvE;AAYD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,CAiC3C;AAmFD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAEvD;AAuBD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,EAC5B,UAAU,GAAE,CAAC,MAAM,UAAU,CAAC,EAAO,GACpC,IAAI,CASN;AA8BD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CAyCnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAmBzE"}
|
package/dist/config.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import * as fs from 'fs';
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import * as os from 'os';
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
12
13
|
// Capability string sent on every request (X-GSK-CLI-Caps) and stamped into
|
|
13
14
|
// the tools cache. The server tailors /tools CLI metadata to it (grouped
|
|
14
15
|
// phone-call view vs the flat legacy view), so a cache written by a CLI with
|
|
@@ -66,6 +67,12 @@ export function getConfigPath() {
|
|
|
66
67
|
}
|
|
67
68
|
return path.join(getConfigDir(), CONFIG_FILE);
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Keep one canonical spelling for endpoint persistence and cache keys.
|
|
72
|
+
*/
|
|
73
|
+
export function normalizeBaseUrl(baseUrl) {
|
|
74
|
+
return baseUrl.trim().replace(/\/+$/, '');
|
|
75
|
+
}
|
|
69
76
|
/**
|
|
70
77
|
* Load configuration from the config file
|
|
71
78
|
* Returns an empty object if the file doesn't exist or is invalid
|
|
@@ -99,23 +106,101 @@ export function loadConfigFile() {
|
|
|
99
106
|
}
|
|
100
107
|
}
|
|
101
108
|
/**
|
|
102
|
-
*
|
|
109
|
+
* Write a complete configuration object atomically with private permissions.
|
|
110
|
+
*
|
|
111
|
+
* The temporary file lives beside the destination so rename is atomic. Its
|
|
112
|
+
* mode is fixed before rename, so an API key is never exposed through the
|
|
113
|
+
* process umask or a partially written destination.
|
|
114
|
+
*/
|
|
115
|
+
function resolveConfigWriteTarget(configPath, visited = new Set()) {
|
|
116
|
+
const absolutePath = path.resolve(configPath);
|
|
117
|
+
if (visited.has(absolutePath)) {
|
|
118
|
+
throw new Error(`Cannot update config through symlink cycle at ${configPath}`);
|
|
119
|
+
}
|
|
120
|
+
let stats;
|
|
121
|
+
try {
|
|
122
|
+
stats = fs.lstatSync(absolutePath);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
if (err.code === 'ENOENT') {
|
|
126
|
+
return absolutePath;
|
|
127
|
+
}
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
if (!stats.isSymbolicLink()) {
|
|
131
|
+
return absolutePath;
|
|
132
|
+
}
|
|
133
|
+
visited.add(absolutePath);
|
|
134
|
+
const linkTarget = fs.readlinkSync(absolutePath);
|
|
135
|
+
return resolveConfigWriteTarget(path.resolve(path.dirname(absolutePath), linkTarget), visited);
|
|
136
|
+
}
|
|
137
|
+
function writeConfigFileAtomic(configPath, config) {
|
|
138
|
+
const targetPath = resolveConfigWriteTarget(configPath);
|
|
139
|
+
const configDir = path.dirname(targetPath);
|
|
140
|
+
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
141
|
+
const tempPath = path.join(configDir, `.${path.basename(targetPath)}.${process.pid}.${randomUUID()}.tmp`);
|
|
142
|
+
let fileDescriptor;
|
|
143
|
+
try {
|
|
144
|
+
fileDescriptor = fs.openSync(tempPath, 'wx', 0o600);
|
|
145
|
+
fs.writeFileSync(fileDescriptor, `${JSON.stringify(config, null, 2)}\n`, 'utf-8');
|
|
146
|
+
fs.fsyncSync(fileDescriptor);
|
|
147
|
+
if (process.platform !== 'win32') {
|
|
148
|
+
fs.fchmodSync(fileDescriptor, 0o600);
|
|
149
|
+
}
|
|
150
|
+
fs.closeSync(fileDescriptor);
|
|
151
|
+
fileDescriptor = undefined;
|
|
152
|
+
fs.renameSync(tempPath, targetPath);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
if (fileDescriptor !== undefined) {
|
|
156
|
+
fs.closeSync(fileDescriptor);
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
fs.unlinkSync(tempPath);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// The file may not have been created or may already have been renamed.
|
|
163
|
+
}
|
|
164
|
+
throw err;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Replace the selected config file.
|
|
103
169
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* `--config /tmp/my-profile.json` is active, the write lands on
|
|
107
|
-
* `/tmp/my-profile.json`, not `/tmp/config.json`. Using the raw
|
|
108
|
-
* `CONFIG_FILE` constant here would make `login`/`logout` silently write
|
|
109
|
-
* to the wrong file while reads still target the override — a
|
|
110
|
-
* split-brain state.
|
|
170
|
+
* Prefer `updateConfigFile` for login/logout-style field changes because this
|
|
171
|
+
* replacement API intentionally cannot preserve fields absent from `config`.
|
|
111
172
|
*/
|
|
112
173
|
export function saveConfigFile(config) {
|
|
174
|
+
writeConfigFileAtomic(getConfigPath(), { ...config });
|
|
175
|
+
}
|
|
176
|
+
function loadConfigObjectForUpdate(configPath) {
|
|
177
|
+
if (!fs.existsSync(configPath)) {
|
|
178
|
+
return {};
|
|
179
|
+
}
|
|
180
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
181
|
+
let parsed;
|
|
182
|
+
try {
|
|
183
|
+
parsed = JSON.parse(content);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
throw new Error(`Cannot update invalid config JSON at ${configPath}`);
|
|
187
|
+
}
|
|
188
|
+
if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') {
|
|
189
|
+
throw new Error(`Cannot update invalid config object at ${configPath}`);
|
|
190
|
+
}
|
|
191
|
+
return parsed;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Patch known fields in the selected config without dropping extension fields.
|
|
195
|
+
*/
|
|
196
|
+
export function updateConfigFile(updates, removeKeys = []) {
|
|
113
197
|
const configPath = getConfigPath();
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
198
|
+
const config = loadConfigObjectForUpdate(configPath);
|
|
199
|
+
for (const key of removeKeys) {
|
|
200
|
+
delete config[key];
|
|
117
201
|
}
|
|
118
|
-
|
|
202
|
+
Object.assign(config, updates);
|
|
203
|
+
writeConfigFileAtomic(configPath, config);
|
|
119
204
|
}
|
|
120
205
|
/**
|
|
121
206
|
* Delete a legacy `tools-cache.json` that was written by a caps-bearing CLI
|
|
@@ -132,7 +217,9 @@ function healPoisonedLegacyCache() {
|
|
|
132
217
|
return;
|
|
133
218
|
}
|
|
134
219
|
const legacy = JSON.parse(fs.readFileSync(legacyPath, 'utf-8'));
|
|
135
|
-
if (legacy &&
|
|
220
|
+
if (legacy &&
|
|
221
|
+
typeof legacy === 'object' &&
|
|
222
|
+
typeof legacy.caps === 'string') {
|
|
136
223
|
fs.unlinkSync(legacyPath);
|
|
137
224
|
}
|
|
138
225
|
}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,12 +27,14 @@ import * as pathModule from 'path';
|
|
|
27
27
|
import { createRequire } from 'module';
|
|
28
28
|
import { spawn } from 'child_process';
|
|
29
29
|
import { ApiClient, unauthenticatedRequest } from './client.js';
|
|
30
|
+
import { classifyFileArg, awaitLocalFileReady, decideAfterWait, localFileNotReadyError, } from './localFiles.js';
|
|
30
31
|
import { setDebugEnabled, setOutputFormat, debug, info, error as logError, output, } from './logger.js';
|
|
31
|
-
import { loadConfigFile,
|
|
32
|
+
import { loadConfigFile, getConfigPath, loadToolsCache, normalizeBaseUrl, saveToolsCache, setConfigPathOverride, updateConfigFile, } from './config.js';
|
|
32
33
|
import { checkForUpdates } from './updater.js';
|
|
34
|
+
import { getSandboxRuntime } from './runtime.js';
|
|
33
35
|
import { registerDesignCommand } from './commands/design.js';
|
|
34
36
|
import { pickExistingFileOperand } from './commands/aidrive-upload.js';
|
|
35
|
-
import { parseLastSeenIndex, eventStdoutLine
|
|
37
|
+
import { parseLastSeenIndex, eventStdoutLine } from './commands/chat-events.js';
|
|
36
38
|
import { mediaItemsKeyFor, mediaSummaryLines } from './mediaSummary.js';
|
|
37
39
|
import { registerMeshCommand, getMeshInvocation, runMesh, } from './commands/mesh.js';
|
|
38
40
|
import { executeCloneUrl, normalizeCloneUrlForGit, } from './commands/sb-git-clone.js';
|
|
@@ -104,9 +106,13 @@ function getGlobalOptions() {
|
|
|
104
106
|
// API key priority: CLI > env > config file
|
|
105
107
|
const apiKey = opts.apiKey || process.env.GSK_API_KEY || fileConfig.api_key;
|
|
106
108
|
// Base URL priority: CLI > env > config file > default
|
|
107
|
-
const
|
|
109
|
+
const explicitBaseUrl = program.getOptionValueSource('baseUrl') === 'cli'
|
|
108
110
|
? opts.baseUrl
|
|
109
|
-
:
|
|
111
|
+
: undefined;
|
|
112
|
+
const baseUrl = normalizeBaseUrl(explicitBaseUrl ||
|
|
113
|
+
process.env.GSK_BASE_URL ||
|
|
114
|
+
fileConfig.base_url ||
|
|
115
|
+
DEFAULT_BASE_URL);
|
|
110
116
|
// Timeout priority: CLI > config file > default
|
|
111
117
|
const timeout = opts.timeout !== String(DEFAULT_TIMEOUT)
|
|
112
118
|
? parseInt(opts.timeout, 10)
|
|
@@ -338,9 +344,27 @@ function isLocalFilePath(value) {
|
|
|
338
344
|
fs.existsSync(value));
|
|
339
345
|
}
|
|
340
346
|
async function resolveFileArg(value, client) {
|
|
341
|
-
|
|
347
|
+
// Classify the RAW value: a leading '~' is positive local evidence and must
|
|
348
|
+
// hit classifyFileArg's relative-marker branch before any expansion.
|
|
349
|
+
const kind = classifyFileArg(value);
|
|
350
|
+
if (kind === 'remote' || kind === 'aidrive')
|
|
342
351
|
return value;
|
|
343
|
-
|
|
352
|
+
// fs never expands '~' — expand only for the filesystem operations below.
|
|
353
|
+
const localPath = expandHome(value);
|
|
354
|
+
// Tolerate the same-batch create-then-read race (a parallel sibling tool
|
|
355
|
+
// call may still be writing the file) before deciding what the arg is.
|
|
356
|
+
const readiness = await awaitLocalFileReady(localPath);
|
|
357
|
+
switch (decideAfterWait(kind, readiness)) {
|
|
358
|
+
case 'upload':
|
|
359
|
+
return await uploadLocalFile(localPath, client);
|
|
360
|
+
case 'error':
|
|
361
|
+
throw new Error(localFileNotReadyError(localPath, readiness));
|
|
362
|
+
case 'passthrough':
|
|
363
|
+
// No local evidence beyond the parent directory: let the backend try
|
|
364
|
+
// it as an AI Drive path (its failure mode is a per-URL actionable
|
|
365
|
+
// error, not a generic one).
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
344
368
|
}
|
|
345
369
|
/**
|
|
346
370
|
* Inline-base64 transport limit for email `attachments`. Anything larger
|
|
@@ -547,7 +571,9 @@ function registerToolCommand(parentProgram, tool, clientFactory, vdProjectIdDefa
|
|
|
547
571
|
const prefix = groupName + '_';
|
|
548
572
|
cmdName =
|
|
549
573
|
tool.cli.subcommand ||
|
|
550
|
-
(tool.name.startsWith(prefix)
|
|
574
|
+
(tool.name.startsWith(prefix)
|
|
575
|
+
? tool.name.slice(prefix.length)
|
|
576
|
+
: tool.name);
|
|
551
577
|
}
|
|
552
578
|
const cmd = targetProgram
|
|
553
579
|
.command(cmdName, cmdOpts?.hidden ? { hidden: true } : {})
|
|
@@ -1186,8 +1212,7 @@ function registerToolCommand(parentProgram, tool, clientFactory, vdProjectIdDefa
|
|
|
1186
1212
|
// web_search payloads are large and agent-consumed — indent-2 here
|
|
1187
1213
|
// is pure token overhead on every SAS/Claw search
|
|
1188
1214
|
output(result, {
|
|
1189
|
-
compact: tool.name === 'web_search' ||
|
|
1190
|
-
Boolean(mediaItemsKeyFor(tool.name)),
|
|
1215
|
+
compact: tool.name === 'web_search' || Boolean(mediaItemsKeyFor(tool.name)),
|
|
1191
1216
|
});
|
|
1192
1217
|
}
|
|
1193
1218
|
catch (err) {
|
|
@@ -1364,10 +1389,10 @@ program
|
|
|
1364
1389
|
const remainingSec = expires_in - elapsedSec;
|
|
1365
1390
|
const tokenResp = await unauthenticatedRequest(baseUrl, `/api/cli_auth/token?code=${encodeURIComponent(device_code)}`, 'GET');
|
|
1366
1391
|
if (tokenResp.status === 'approved' && tokenResp.api_key) {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1392
|
+
updateConfigFile({
|
|
1393
|
+
api_key: tokenResp.api_key,
|
|
1394
|
+
base_url: baseUrl,
|
|
1395
|
+
});
|
|
1371
1396
|
info('Login successful! API key saved.');
|
|
1372
1397
|
output({
|
|
1373
1398
|
status: 'ok',
|
|
@@ -1405,8 +1430,7 @@ program
|
|
|
1405
1430
|
info('Already logged out (no API key in config).');
|
|
1406
1431
|
return;
|
|
1407
1432
|
}
|
|
1408
|
-
|
|
1409
|
-
saveConfigFile(config);
|
|
1433
|
+
updateConfigFile({}, ['api_key']);
|
|
1410
1434
|
info('Logged out. API key removed.');
|
|
1411
1435
|
output({
|
|
1412
1436
|
status: 'ok',
|
|
@@ -1439,6 +1463,25 @@ program
|
|
|
1439
1463
|
process.exit(1);
|
|
1440
1464
|
}
|
|
1441
1465
|
});
|
|
1466
|
+
// Runtime - report the sandbox environment this CLI process runs in
|
|
1467
|
+
program
|
|
1468
|
+
.command('runtime')
|
|
1469
|
+
.description('Show the Genspark sandbox runtime this CLI is running in ' +
|
|
1470
|
+
'(reads the /opt/genspark template marker; all-null outside a sandbox)')
|
|
1471
|
+
.action(() => {
|
|
1472
|
+
const runtime = getSandboxRuntime();
|
|
1473
|
+
output({
|
|
1474
|
+
status: 'ok',
|
|
1475
|
+
message: 'success',
|
|
1476
|
+
data: {
|
|
1477
|
+
family: runtime.family,
|
|
1478
|
+
version: runtime.version,
|
|
1479
|
+
is_sb_box: runtime.isSbBox,
|
|
1480
|
+
is_super_agent_sandbox: runtime.isSuperAgentSandbox,
|
|
1481
|
+
is_genspark_sandbox: runtime.isGensparkSandbox,
|
|
1482
|
+
},
|
|
1483
|
+
});
|
|
1484
|
+
});
|
|
1442
1485
|
// Init OpenCode - generate opencode.json config
|
|
1443
1486
|
program
|
|
1444
1487
|
.command('init-opencode')
|
|
@@ -1652,6 +1695,13 @@ function _generateContextMd(projectRoot, relSkillsDir, skillDirs) {
|
|
|
1652
1695
|
|
|
1653
1696
|
Read [gsk-shared](${sharedSkill}) for authentication, global flags, and output conventions.
|
|
1654
1697
|
|
|
1698
|
+
## Connectors
|
|
1699
|
+
|
|
1700
|
+
For any third-party integration (Gmail, Slack, Notion, HubSpot, custom MCP
|
|
1701
|
+
servers, ...), start with [gsk-connector](${relSkillsDir}/gsk-connector/SKILL.md) —
|
|
1702
|
+
one fixed \`list\` → \`search\` → \`tools <id>\` → \`call <id>\` flow covers every
|
|
1703
|
+
connector instead of memorizing per-service commands below.
|
|
1704
|
+
|
|
1655
1705
|
## Available Skills
|
|
1656
1706
|
|
|
1657
1707
|
${skillList}
|
|
@@ -1892,12 +1942,16 @@ _groupCommands.set('chat', chatCmd);
|
|
|
1892
1942
|
chatCmd
|
|
1893
1943
|
.command('events <project_id>')
|
|
1894
1944
|
.description("Attach to the conversation's in-flight run and stream its events " +
|
|
1895
|
-
'live (one JSON line per event on stdout):
|
|
1896
|
-
'
|
|
1897
|
-
'
|
|
1898
|
-
'
|
|
1899
|
-
'
|
|
1900
|
-
|
|
1945
|
+
'live (one JSON line per event on stdout): the first line is a ' +
|
|
1946
|
+
'project_data snapshot event, buffered events since run start ' +
|
|
1947
|
+
'replay next, then live events follow until the run ends. Every ' +
|
|
1948
|
+
'event line carries an _event_index. Prints no_running_agent when ' +
|
|
1949
|
+
'the conversation is idle. Upstream segment ends during long runs ' +
|
|
1950
|
+
'are reattached automatically; after a real disconnect, reattach ' +
|
|
1951
|
+
'with --last-seen <highest _event_index already processed> to ' +
|
|
1952
|
+
'skip the replayed prefix.')
|
|
1953
|
+
.option('--last-seen <index>', 'resume cursor: only replay events with _event_index greater than ' +
|
|
1954
|
+
'this (take it from the last event line of the previous stream)')
|
|
1901
1955
|
.action(async (projectId, opts) => {
|
|
1902
1956
|
try {
|
|
1903
1957
|
const lastSeen = parseLastSeenIndex(opts.lastSeen);
|
|
@@ -1921,6 +1975,11 @@ chatCmd
|
|
|
1921
1975
|
else if (msg.heartbeat !== undefined) {
|
|
1922
1976
|
debug(` Heartbeat #${msg.heartbeat}`);
|
|
1923
1977
|
}
|
|
1978
|
+
else if (msg.debug && typeof msg.message === 'string') {
|
|
1979
|
+
// Server-side notices (e.g. transparent segment reattach)
|
|
1980
|
+
// are context, not payload — stderr, --debug only.
|
|
1981
|
+
debug(` ${msg.message}`);
|
|
1982
|
+
}
|
|
1924
1983
|
});
|
|
1925
1984
|
output(result);
|
|
1926
1985
|
if (result.status === 'error') {
|
|
@@ -1944,11 +2003,12 @@ async function main() {
|
|
|
1944
2003
|
if (meshArgs !== null) {
|
|
1945
2004
|
program.parseOptions(process.argv);
|
|
1946
2005
|
setDebugEnabled(getGlobalOptions().debug);
|
|
1947
|
-
// Forward an explicit `--base-url` flag only
|
|
1948
|
-
//
|
|
1949
|
-
// inside the mesh layer so it doesn't inherit gsk's localhost default.
|
|
2006
|
+
// Forward an explicit `--base-url` flag only; env/config/default resolution
|
|
2007
|
+
// happens inside the mesh layer.
|
|
1950
2008
|
const rawBase = program.opts().baseUrl;
|
|
1951
|
-
const baseUrlOverride = rawBase &&
|
|
2009
|
+
const baseUrlOverride = rawBase && program.getOptionValueSource('baseUrl') === 'cli'
|
|
2010
|
+
? normalizeBaseUrl(rawBase)
|
|
2011
|
+
: undefined;
|
|
1952
2012
|
await runMesh(meshArgs, baseUrlOverride);
|
|
1953
2013
|
return;
|
|
1954
2014
|
}
|