@gaoding/cli 1.0.0 → 1.2.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/bin/gd-cli.js +2 -1
- package/dist/bin/insmind-cli.js +60 -0
- package/dist/bin/postinstall.js +31 -4
- package/dist/src/bootstrap/create-cli.js +14 -4
- package/dist/src/bootstrap/create-runtime.js +93 -31
- package/dist/src/bootstrap/validators.js +9 -5
- package/dist/src/cli/agent-commands.js +5 -4
- package/dist/src/cli/auth-commands.js +13 -10
- package/dist/src/cli/credits-command.js +23 -0
- package/dist/src/cli/dam-commands.js +70 -69
- package/dist/src/cli/editor-commands.js +12 -11
- package/dist/src/cli/errors.js +49 -9
- package/dist/src/cli/model-commands.js +6 -5
- package/dist/src/cli/presenter.js +24 -6
- package/dist/src/cli/tool-commands.js +7 -6
- package/dist/src/cli/update-command.js +4 -3
- package/dist/src/features/auth/credential-store.js +1 -1
- package/dist/src/features/auth/sso-service.js +3 -1
- package/dist/src/features/auth/use-cases.js +38 -12
- package/dist/src/features/credits/use-cases.js +52 -0
- package/dist/src/features/dam/storage-upload.js +1 -1
- package/dist/src/features/editor/bridge-process.js +11 -4
- package/dist/src/features/editor/session-state.js +1 -1
- package/dist/src/features/editor/session.js +14 -8
- package/dist/src/features/org/use-cases.js +7 -0
- package/dist/src/features/skill/bundled-skills.js +13 -5
- package/dist/src/features/tool/catalog.js +13 -13
- package/dist/src/features/tool/use-cases.js +3 -3
- package/dist/src/features/update/latest-version.js +2 -2
- package/dist/src/features/update/update-notification.js +12 -3
- package/dist/src/features/update/update-service.js +64 -21
- package/dist/src/platform/installation-owner.js +81 -0
- package/dist/src/platform/signed-http-transport.js +1 -0
- package/dist/src/product/billing.js +45 -0
- package/dist/src/product/config.js +83 -0
- package/dist/src/product/locale.js +38 -0
- package/dist/src/product/text.js +3 -0
- package/dist/src/telemetry/sls-sink.js +1 -2
- package/package.json +5 -5
- package/skills/gd-cli/references/update.md +2 -0
|
@@ -4,6 +4,7 @@ import { resolve } from "node:path";
|
|
|
4
4
|
import { gt } from "semver";
|
|
5
5
|
import { syncBundledSkills, verifyBundledSkills } from "../skill/installer.js";
|
|
6
6
|
import { fetchLatestVersion } from "./latest-version.js";
|
|
7
|
+
import { readInstallationOwner } from "../../platform/installation-owner.js";
|
|
7
8
|
export class UpdateError extends Error {
|
|
8
9
|
code;
|
|
9
10
|
nextSteps;
|
|
@@ -21,6 +22,8 @@ export function detectInstallSource(input) {
|
|
|
21
22
|
const cwd = normalizePath(resolve(input.cwd));
|
|
22
23
|
const userAgent = input.env.npm_config_user_agent ?? "";
|
|
23
24
|
const npmExecPath = normalizePath(input.env.npm_execpath ?? "");
|
|
25
|
+
const packageName = input.packageName ?? "@gaoding/cli";
|
|
26
|
+
const encodedPackage = packageName.replace("/", "+").replace("@", "@");
|
|
24
27
|
if (userAgent.startsWith("yarn/") || npmExecPath.includes("/yarn/")) {
|
|
25
28
|
return unsupported("Yarn 安装不支持自动更新");
|
|
26
29
|
}
|
|
@@ -34,16 +37,15 @@ export function detectInstallSource(input) {
|
|
|
34
37
|
if (!isWithin(realBinaryPath, packageRoot)) {
|
|
35
38
|
return unsupported("CLI binary 与 package 不匹配");
|
|
36
39
|
}
|
|
37
|
-
if (
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.test(binaryPath)) {
|
|
40
|
+
if (packageRoot.includes(`/global/`) && packageRoot.includes(`/.pnpm/${encodedPackage}@`)
|
|
41
|
+
|| packageRoot.includes(`/node_modules/${packageName}`)
|
|
42
|
+
&& /\/v\d+\/[0-9a-f]+-[0-9a-f]+-[0-9a-f]{16}\//u.test(packageRoot)
|
|
43
|
+
|| binaryPath.includes(`/node_modules/${packageName}/dist/bin/${input.binaryName ?? "gd-cli"}.js`)
|
|
44
|
+
&& /\/v\d+\/[0-9a-f]+-[0-9a-f]+-[0-9a-f]{16}\//u.test(binaryPath)) {
|
|
43
45
|
return { kind: "global", manager: "pnpm", packageRoot: input.packageRoot };
|
|
44
46
|
}
|
|
45
|
-
if (packageRoot.endsWith(
|
|
46
|
-
|| packageRoot.endsWith(
|
|
47
|
+
if (packageRoot.endsWith(`/lib/node_modules/${packageName}`)
|
|
48
|
+
|| packageRoot.endsWith(`/npm/node_modules/${packageName}`)) {
|
|
47
49
|
return { kind: "global", manager: "npm", packageRoot: input.packageRoot };
|
|
48
50
|
}
|
|
49
51
|
return unsupported("无法确认 npm 或 pnpm 全局安装");
|
|
@@ -54,19 +56,46 @@ export function createUpdateService(options) {
|
|
|
54
56
|
const syncSkills = options.syncSkills ?? syncBundledSkills;
|
|
55
57
|
const verifySkills = options.verifySkills ?? verifyBundledSkills;
|
|
56
58
|
const env = options.env ?? process.env;
|
|
59
|
+
const packageName = options.packageName ?? "@gaoding/cli";
|
|
60
|
+
const commandName = options.commandName ?? "gd-cli";
|
|
61
|
+
const insmind = packageName === "@insmind/cli";
|
|
57
62
|
return {
|
|
58
63
|
async run(signal) {
|
|
59
64
|
signal.throwIfAborted();
|
|
65
|
+
const owner = options.installationOwner
|
|
66
|
+
?? readInstallationOwner(options.packageRoot);
|
|
67
|
+
if (owner === "workbuddy") {
|
|
68
|
+
throw new UpdateError("UPDATE_FAILED", insmind
|
|
69
|
+
? "This insMind CLI installation is managed by WorkBuddy."
|
|
70
|
+
: "此 gd-cli 由 WorkBuddy 连接器管理。", [insmind
|
|
71
|
+
? "Update the insMind connector in WorkBuddy."
|
|
72
|
+
: "请在 WorkBuddy 中更新「稿定」连接器。"]);
|
|
73
|
+
}
|
|
74
|
+
if (owner === "invalid") {
|
|
75
|
+
throw new UpdateError("UPDATE_FAILED", insmind
|
|
76
|
+
? "The current installation ownership metadata is invalid."
|
|
77
|
+
: "无法确认当前安装的托管信息。", [insmind
|
|
78
|
+
? "Reinstall insmind-cli through its original installation channel."
|
|
79
|
+
: "请通过原安装渠道重新安装 gd-cli。"]);
|
|
80
|
+
}
|
|
60
81
|
const latest = await options.telemetry.stage("registry", async () => {
|
|
61
82
|
try {
|
|
62
|
-
const result = await fetchLatestVersion({
|
|
83
|
+
const result = await fetchLatestVersion({
|
|
84
|
+
fetch: fetchPackage,
|
|
85
|
+
signal,
|
|
86
|
+
...(options.registryUrl ? { registryUrl: options.registryUrl } : {})
|
|
87
|
+
});
|
|
63
88
|
if (result.status !== "modified")
|
|
64
89
|
throw new Error("Registry response not modified");
|
|
65
90
|
return result.version;
|
|
66
91
|
}
|
|
67
92
|
catch (error) {
|
|
68
93
|
rethrowAbort(signal);
|
|
69
|
-
throw new UpdateError("UPDATE_FAILED",
|
|
94
|
+
throw new UpdateError("UPDATE_FAILED", options.commandName === undefined
|
|
95
|
+
? "无法获取 @gaoding/cli 最新版本。"
|
|
96
|
+
: `Unable to get the latest ${packageName} version.`, [options.commandName === undefined
|
|
97
|
+
? "请稍后重新执行 gd-cli update。"
|
|
98
|
+
: `Run ${commandName} update again later.`]);
|
|
70
99
|
}
|
|
71
100
|
});
|
|
72
101
|
signal.throwIfAborted();
|
|
@@ -81,7 +110,11 @@ export function createUpdateService(options) {
|
|
|
81
110
|
}
|
|
82
111
|
catch (error) {
|
|
83
112
|
rethrowAbort(signal);
|
|
84
|
-
throw new UpdateError("UPDATE_FAILED",
|
|
113
|
+
throw new UpdateError("UPDATE_FAILED", insmind
|
|
114
|
+
? `${commandName} ${options.currentVersion} is current, but Agent Skill synchronization failed.`
|
|
115
|
+
: `gd-cli ${options.currentVersion} 无需更新,但 Agent Skill 同步失败。`, [insmind
|
|
116
|
+
? `Resolve the conflict and run ${commandName} update again.`
|
|
117
|
+
: "请解决冲突后重新执行 gd-cli update。"]);
|
|
85
118
|
}
|
|
86
119
|
});
|
|
87
120
|
return { version: options.currentVersion, updated: false };
|
|
@@ -92,23 +125,29 @@ export function createUpdateService(options) {
|
|
|
92
125
|
realBinaryPath: safeRealpath(binaryPath),
|
|
93
126
|
packageRoot: options.packageRoot,
|
|
94
127
|
cwd: options.cwd ?? process.cwd(),
|
|
95
|
-
env
|
|
128
|
+
env,
|
|
129
|
+
packageName,
|
|
130
|
+
binaryName: commandName
|
|
96
131
|
});
|
|
97
|
-
const nextSteps = manualCommands(latest);
|
|
132
|
+
const nextSteps = manualCommands(latest, packageName);
|
|
98
133
|
if (source.kind === "unsupported") {
|
|
99
|
-
throw new UpdateError("UPDATE_FAILED",
|
|
134
|
+
throw new UpdateError("UPDATE_FAILED", insmind
|
|
135
|
+
? "The current installation method does not support automatic updates."
|
|
136
|
+
: `当前安装方式不支持自动更新:${source.reason}。`, nextSteps);
|
|
100
137
|
}
|
|
101
138
|
const command = source.manager;
|
|
102
139
|
const args = source.manager === "npm"
|
|
103
|
-
? ["install", "--global",
|
|
104
|
-
: ["add", "--global",
|
|
140
|
+
? ["install", "--global", `--allow-scripts=${packageName}`, `${packageName}@${latest}`]
|
|
141
|
+
: ["add", "--global", `--allow-build=${packageName}`, `${packageName}@${latest}`];
|
|
105
142
|
await options.telemetry.stage("install", async () => {
|
|
106
143
|
try {
|
|
107
144
|
await runProcess(command, args, signal);
|
|
108
145
|
}
|
|
109
146
|
catch (error) {
|
|
110
147
|
rethrowAbort(signal);
|
|
111
|
-
throw new UpdateError("UPDATE_FAILED",
|
|
148
|
+
throw new UpdateError("UPDATE_FAILED", insmind
|
|
149
|
+
? `Failed to update ${commandName} to ${latest}.`
|
|
150
|
+
: `gd-cli 更新到 ${latest} 失败。`, nextSteps);
|
|
112
151
|
}
|
|
113
152
|
});
|
|
114
153
|
signal.throwIfAborted();
|
|
@@ -122,7 +161,11 @@ export function createUpdateService(options) {
|
|
|
122
161
|
}
|
|
123
162
|
catch (error) {
|
|
124
163
|
rethrowAbort(signal);
|
|
125
|
-
throw new UpdateError("UPDATE_PARTIAL",
|
|
164
|
+
throw new UpdateError("UPDATE_PARTIAL", insmind
|
|
165
|
+
? `${commandName} was updated to ${latest}, but Agent Skill verification failed.`
|
|
166
|
+
: `gd-cli 已更新到 ${latest},但 Agent Skill 验收失败。`, [insmind
|
|
167
|
+
? `Run ${commandName} update again.`
|
|
168
|
+
: "请重新执行 gd-cli update。"]);
|
|
126
169
|
}
|
|
127
170
|
});
|
|
128
171
|
return { version: latest, updated: true };
|
|
@@ -149,10 +192,10 @@ function spawnProcess(command, args, signal) {
|
|
|
149
192
|
});
|
|
150
193
|
});
|
|
151
194
|
}
|
|
152
|
-
function manualCommands(version) {
|
|
195
|
+
function manualCommands(version, packageName = "@gaoding/cli") {
|
|
153
196
|
return [
|
|
154
|
-
`npm install --global --allow-scripts
|
|
155
|
-
`pnpm add --global --allow-build
|
|
197
|
+
`npm install --global --allow-scripts=${packageName} ${packageName}@${version}`,
|
|
198
|
+
`pnpm add --global --allow-build=${packageName} ${packageName}@${version}`
|
|
156
199
|
];
|
|
157
200
|
}
|
|
158
201
|
function containsTemporaryRunner(path) {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { closeSync, linkSync, lstatSync, openSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const markerFilename = ".gd-cli-installation.json";
|
|
5
|
+
export function readInstallationOwner(packageRoot) {
|
|
6
|
+
const path = join(packageRoot, markerFilename);
|
|
7
|
+
try {
|
|
8
|
+
if (!lstatSync(path).isFile())
|
|
9
|
+
return "invalid";
|
|
10
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
11
|
+
if (!isRecord(value))
|
|
12
|
+
return "invalid";
|
|
13
|
+
const keys = Object.keys(value);
|
|
14
|
+
return keys.length === 1 && keys[0] === "owner" && value.owner === "workbuddy"
|
|
15
|
+
? "workbuddy"
|
|
16
|
+
: "invalid";
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return isMissing(error) ? "user" : "invalid";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function markWorkBuddyInstallation(packageRoot) {
|
|
23
|
+
const packageMetadata = parsePackageMetadata(packageRoot);
|
|
24
|
+
if (packageMetadata.name !== "@gaoding/cli") {
|
|
25
|
+
throw new Error("无法确认当前安装的 package。");
|
|
26
|
+
}
|
|
27
|
+
const markerPath = join(packageRoot, markerFilename);
|
|
28
|
+
const current = readInstallationOwner(packageRoot);
|
|
29
|
+
if (current === "workbuddy")
|
|
30
|
+
return;
|
|
31
|
+
if (current === "invalid")
|
|
32
|
+
throw new Error("无法确认当前安装的托管信息。");
|
|
33
|
+
const temporaryPath = join(packageRoot, `.${markerFilename}.${randomUUID()}.tmp`);
|
|
34
|
+
let descriptor;
|
|
35
|
+
try {
|
|
36
|
+
descriptor = openSync(temporaryPath, "wx", 0o600);
|
|
37
|
+
writeFileSync(descriptor, `${JSON.stringify({ owner: "workbuddy" }, null, 2)}\n`, "utf8");
|
|
38
|
+
closeSync(descriptor);
|
|
39
|
+
descriptor = undefined;
|
|
40
|
+
linkSync(temporaryPath, markerPath);
|
|
41
|
+
unlinkSync(temporaryPath);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (descriptor !== undefined) {
|
|
45
|
+
try {
|
|
46
|
+
closeSync(descriptor);
|
|
47
|
+
}
|
|
48
|
+
catch { /* best effort */ }
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
unlinkSync(temporaryPath);
|
|
52
|
+
}
|
|
53
|
+
catch { /* best effort */ }
|
|
54
|
+
if (isExists(error)) {
|
|
55
|
+
if (readInstallationOwner(packageRoot) === "workbuddy")
|
|
56
|
+
return;
|
|
57
|
+
throw new Error("无法确认当前安装的托管信息。");
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function parsePackageMetadata(packageRoot) {
|
|
63
|
+
try {
|
|
64
|
+
const value = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8"));
|
|
65
|
+
if (!isRecord(value))
|
|
66
|
+
throw new Error("invalid package metadata");
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error("无法确认当前安装的 package。");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isRecord(value) {
|
|
74
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75
|
+
}
|
|
76
|
+
function isMissing(error) {
|
|
77
|
+
return isRecord(error) && error.code === "ENOENT";
|
|
78
|
+
}
|
|
79
|
+
function isExists(error) {
|
|
80
|
+
return isRecord(error) && error.code === "EEXIST";
|
|
81
|
+
}
|
|
@@ -51,6 +51,7 @@ export function createSignedHttpTransport(options) {
|
|
|
51
51
|
url.search = query;
|
|
52
52
|
const timestamp = Math.floor(options.now().getTime() / 1000);
|
|
53
53
|
const headers = {
|
|
54
|
+
...options.businessHeaders,
|
|
54
55
|
Accept: accept,
|
|
55
56
|
"X-AccessKey": request.credential.accessKey,
|
|
56
57
|
"X-Signature": signRequest({
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function withAgentBillingUnit(source, unit) {
|
|
2
|
+
if (unit === "gaodou")
|
|
3
|
+
return source;
|
|
4
|
+
return {
|
|
5
|
+
async send(input) {
|
|
6
|
+
const output = await source.send(input);
|
|
7
|
+
return {
|
|
8
|
+
...output,
|
|
9
|
+
usage: {
|
|
10
|
+
...output.usage,
|
|
11
|
+
cost: { ...output.usage.cost, unit },
|
|
12
|
+
items: output.usage.items.map((item) => ({
|
|
13
|
+
...item,
|
|
14
|
+
cost: { ...item.cost, unit }
|
|
15
|
+
}))
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function withToolBillingUnit(source, unit) {
|
|
22
|
+
if (unit === "gaodou")
|
|
23
|
+
return source;
|
|
24
|
+
const model = (value) => (value.cost ? { ...value, cost: { ...value.cost, unit } } : value);
|
|
25
|
+
return {
|
|
26
|
+
listTools: (input) => source.listTools(input),
|
|
27
|
+
async listModels(input) {
|
|
28
|
+
const output = await source.listModels(input);
|
|
29
|
+
return { ...output, models: output.models.map(model) };
|
|
30
|
+
},
|
|
31
|
+
async getModel(input) {
|
|
32
|
+
return model(await source.getModel(input));
|
|
33
|
+
},
|
|
34
|
+
getArgumentsSchema: (input) => source.getArgumentsSchema(input),
|
|
35
|
+
async call(input) {
|
|
36
|
+
const output = await source.call(input);
|
|
37
|
+
return {
|
|
38
|
+
...output,
|
|
39
|
+
usage: output.usage.cost
|
|
40
|
+
? { ...output.usage, cost: { ...output.usage.cost, unit } }
|
|
41
|
+
: output.usage
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { defaultToolDefinitions } from "../features/tool/catalog.js";
|
|
2
|
+
function freezeProduct(config) {
|
|
3
|
+
Object.freeze(config.endpoints);
|
|
4
|
+
for (const tool of config.tools)
|
|
5
|
+
Object.freeze(tool);
|
|
6
|
+
Object.freeze(config.tools);
|
|
7
|
+
return Object.freeze(config);
|
|
8
|
+
}
|
|
9
|
+
const gaodingApi = new URL("https://gdcli.gaoding.com/api");
|
|
10
|
+
export const gaodingProduct = freezeProduct({
|
|
11
|
+
id: "gaoding",
|
|
12
|
+
displayName: "GaoDing",
|
|
13
|
+
commandName: "gd-cli",
|
|
14
|
+
description: "稿定命令行工具",
|
|
15
|
+
npmPackage: "@gaoding/cli",
|
|
16
|
+
skillName: "gd-cli",
|
|
17
|
+
stateDirectory: ".gd",
|
|
18
|
+
billingUnit: "gaodou",
|
|
19
|
+
deviceClientId: "gdhub-cli",
|
|
20
|
+
pricingUrl: new URL("https://www.gaoding.art/pricing"),
|
|
21
|
+
telemetryUrl: new URL("https://gaoding-log-ai-gpu.cn-hangzhou.log.aliyuncs.com/logstores/gd-cli/track?APIVersion=0.6.0"),
|
|
22
|
+
defaultEditorCreateUrl: new URL("https://www.gaoding.art/editor/canvas?mode=create&type=board"),
|
|
23
|
+
editorWorkUrl: new URL("https://www.gaoding.art/editor/canvas"),
|
|
24
|
+
restrictEditorTargets: false,
|
|
25
|
+
endpoints: {
|
|
26
|
+
orgApi: gaodingApi,
|
|
27
|
+
creditsApi: gaodingApi,
|
|
28
|
+
agentApi: gaodingApi,
|
|
29
|
+
mnsApi: gaodingApi,
|
|
30
|
+
toolApi: gaodingApi,
|
|
31
|
+
damApi: gaodingApi,
|
|
32
|
+
ssoApi: new URL("https://www.gaoding.com/api/sso"),
|
|
33
|
+
authPageOrigin: new URL("https://www.gaoding.art")
|
|
34
|
+
},
|
|
35
|
+
exposesOrganizations: true,
|
|
36
|
+
tools: defaultToolDefinitions
|
|
37
|
+
});
|
|
38
|
+
const insmindApi = new URL("https://gdcli.insmind.com/api");
|
|
39
|
+
export const insmindProduct = freezeProduct({
|
|
40
|
+
id: "insmind",
|
|
41
|
+
displayName: "insMind",
|
|
42
|
+
commandName: "insmind-cli",
|
|
43
|
+
description: "insMind command-line interface",
|
|
44
|
+
npmPackage: "@insmind/cli",
|
|
45
|
+
skillName: "insmind-cli",
|
|
46
|
+
stateDirectory: ".insmind",
|
|
47
|
+
billingUnit: "credit",
|
|
48
|
+
deviceClientId: "gdhub-cli",
|
|
49
|
+
pricingUrl: new URL("https://www.insmind.com/pricing"),
|
|
50
|
+
telemetryUrl: new URL("https://gaoding-log-ai-gpu-use.us-east-1.log.aliyuncs.com/logstores/gd-cli/track?APIVersion=0.6.0"),
|
|
51
|
+
defaultEditorCreateUrl: new URL("https://www.insmind.com/editor/canvas?mode=create&type=board"),
|
|
52
|
+
editorWorkUrl: new URL("https://www.insmind.com/editor/canvas"),
|
|
53
|
+
restrictEditorTargets: true,
|
|
54
|
+
endpoints: {
|
|
55
|
+
orgApi: insmindApi,
|
|
56
|
+
creditsApi: insmindApi,
|
|
57
|
+
agentApi: insmindApi,
|
|
58
|
+
mnsApi: insmindApi,
|
|
59
|
+
toolApi: insmindApi,
|
|
60
|
+
damApi: insmindApi,
|
|
61
|
+
ssoApi: new URL("https://www.insmind.com/api/sso"),
|
|
62
|
+
authPageOrigin: new URL("https://www.insmind.com")
|
|
63
|
+
},
|
|
64
|
+
exposesOrganizations: false,
|
|
65
|
+
localeEnvironmentVariable: "INSMIND_CLI_LOCALE",
|
|
66
|
+
tools: [
|
|
67
|
+
{
|
|
68
|
+
name: "image.generate",
|
|
69
|
+
title: "Image generation and editing",
|
|
70
|
+
description: "Generate or edit images with published image models using text and optional reference images."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "video.generate",
|
|
74
|
+
title: "Video generation",
|
|
75
|
+
description: "Generate videos with published video models using text and optional images, video, or audio."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "text.generate",
|
|
79
|
+
title: "Text generation",
|
|
80
|
+
description: "Generate text with published text models using text and optional images."
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const SUPPORTED_LOCALES = [
|
|
2
|
+
"de-DE", "en-US", "es-ES", "fr-FR", "id-ID", "it-IT", "ja-JP", "ko-KR",
|
|
3
|
+
"nl-NL", "pl-PL", "pt-BR", "ru-RU", "th-TH", "tr-TR", "vi-VN", "zh-CN", "zh-TW"
|
|
4
|
+
];
|
|
5
|
+
export function localeOption(argv) {
|
|
6
|
+
const index = argv.indexOf("--locale");
|
|
7
|
+
if (index >= 0)
|
|
8
|
+
return argv[index + 1];
|
|
9
|
+
return argv.find((value) => value.startsWith("--locale="))?.slice("--locale=".length);
|
|
10
|
+
}
|
|
11
|
+
export function resolveProductLocale(options) {
|
|
12
|
+
const requested = options.explicit ?? options.environment ?? options.system ?? "en-US";
|
|
13
|
+
let canonical;
|
|
14
|
+
try {
|
|
15
|
+
canonical = Intl.getCanonicalLocales(requested.replace(/_/gu, "-"))[0] ?? "en-US";
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
canonical = "en-US";
|
|
19
|
+
}
|
|
20
|
+
const exact = SUPPORTED_LOCALES.find((value) => value.toLowerCase() === canonical.toLowerCase());
|
|
21
|
+
const language = canonical.split("-")[0]?.toLowerCase() ?? "en";
|
|
22
|
+
const matched = exact ?? SUPPORTED_LOCALES.find((value) => value.toLowerCase().startsWith(`${language}-`)) ?? "en-US";
|
|
23
|
+
const [normalizedLanguage, region = "US"] = matched.split("-");
|
|
24
|
+
return {
|
|
25
|
+
locale: matched,
|
|
26
|
+
language: normalizedLanguage,
|
|
27
|
+
market: region,
|
|
28
|
+
legalRegion: region
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function systemLocale() {
|
|
32
|
+
try {
|
|
33
|
+
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const trackingUrl = new URL("https://gaoding-log-ai-gpu.cn-hangzhou.log.aliyuncs.com/logstores/gd-cli/track?APIVersion=0.6.0");
|
|
2
1
|
const TIMEOUT_MS = 2_000;
|
|
3
2
|
export function createSlsTelemetrySink(options) {
|
|
4
3
|
return {
|
|
@@ -6,7 +5,7 @@ export function createSlsTelemetrySink(options) {
|
|
|
6
5
|
if (events.length === 0)
|
|
7
6
|
return;
|
|
8
7
|
try {
|
|
9
|
-
await options.fetch(trackingUrl, {
|
|
8
|
+
await options.fetch(options.trackingUrl, {
|
|
10
9
|
method: "POST",
|
|
11
10
|
headers: { "Content-Type": "application/json" },
|
|
12
11
|
body: JSON.stringify({ __logs__: events.map(wireEvent) }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaoding/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Gaoding command-line interface for agents and people.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"open": "11.0.0",
|
|
42
42
|
"qrcode": "1.5.4",
|
|
43
43
|
"semver": "7.8.5",
|
|
44
|
-
"sharp": "0.35.
|
|
44
|
+
"sharp": "0.35.4",
|
|
45
45
|
"ws": "8.21.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"vitest": "4.1.10"
|
|
56
56
|
},
|
|
57
57
|
"gaodingRelease": {
|
|
58
|
-
"sourceCommit": "
|
|
59
|
-
"pipelineId": "
|
|
60
|
-
"pipelineUrl": "https://git.intra.gaoding.com/gtt/gaoding-cli/-/pipelines/
|
|
58
|
+
"sourceCommit": "b0fd52f34b217c15a54dfb8d6af44c0a5659c752",
|
|
59
|
+
"pipelineId": "180065",
|
|
60
|
+
"pipelineUrl": "https://git.intra.gaoding.com/gtt/gaoding-cli/-/pipelines/180065"
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -10,4 +10,6 @@ gd-cli update
|
|
|
10
10
|
|
|
11
11
|
正常使用 CLI 时,版本可用性最多每小时检查一次;存在新版本时,同一本地自然日最多在 stderr 提醒一次。看到提示后执行 `gd-cli update`。自动检查不会更新 CLI,也不会检查或修复 Agent Skill;`CI=true` 时跳过。
|
|
12
12
|
|
|
13
|
+
如果 `gd-cli update` 提示当前安装由 WorkBuddy 连接器管理,请在 WorkBuddy 中更新「稿定」连接器。不要尝试绕过该安装渠道单独升级 CLI 或同步 Agent Skill;连接器会一起管理并验收匹配版本的 CLI 与 Skill。
|
|
14
|
+
|
|
13
15
|
命令不接收参数或 `--json`。不支持自动更新的安装来源会给出明确的 npm、pnpm 全局安装命令。若 CLI 已更新但 Agent Skill 验收失败,保留已更新版本,按 stderr 的下一步修复后重新执行 `gd-cli update`。
|