@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
package/dist/bin/gd-cli.js
CHANGED
|
@@ -27,7 +27,8 @@ try {
|
|
|
27
27
|
signal: controller.signal,
|
|
28
28
|
telemetry: runtime.telemetry,
|
|
29
29
|
telemetrySink: runtime.telemetrySink,
|
|
30
|
-
updateNotification: runtime.updateNotification
|
|
30
|
+
updateNotification: runtime.updateNotification,
|
|
31
|
+
product: runtime.product
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
catch (error) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { insmindProduct } from "../src/product/config.js";
|
|
3
|
+
import { localeOption } from "../src/product/locale.js";
|
|
4
|
+
const controller = new AbortController();
|
|
5
|
+
const interrupt = () => controller.abort(new Error("SIGINT"));
|
|
6
|
+
process.once("SIGINT", interrupt);
|
|
7
|
+
let runtime;
|
|
8
|
+
let mapCliError;
|
|
9
|
+
let redact;
|
|
10
|
+
try {
|
|
11
|
+
const [cliModule, runtimeModule, errorsModule, redactModule] = await Promise.all([
|
|
12
|
+
import("../src/bootstrap/create-cli.js"),
|
|
13
|
+
import("../src/bootstrap/create-runtime.js"),
|
|
14
|
+
import("../src/cli/errors.js"),
|
|
15
|
+
import("../src/platform/redact.js")
|
|
16
|
+
]);
|
|
17
|
+
mapCliError = errorsModule.mapCliError;
|
|
18
|
+
redact = redactModule.redact;
|
|
19
|
+
const selectedLocale = localeOption(process.argv.slice(2));
|
|
20
|
+
runtime = runtimeModule.createProductionRuntime({
|
|
21
|
+
product: insmindProduct,
|
|
22
|
+
...(selectedLocale === undefined ? {} : { locale: selectedLocale })
|
|
23
|
+
});
|
|
24
|
+
const program = cliModule.createCli(runtime, { signal: controller.signal });
|
|
25
|
+
process.exitCode = await cliModule.executeCli({
|
|
26
|
+
program,
|
|
27
|
+
argv: process.argv.slice(2),
|
|
28
|
+
presenter: runtime.presenter,
|
|
29
|
+
signal: controller.signal,
|
|
30
|
+
telemetry: runtime.telemetry,
|
|
31
|
+
telemetrySink: runtime.telemetrySink,
|
|
32
|
+
updateNotification: runtime.updateNotification,
|
|
33
|
+
product: runtime.product
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (mapCliError === undefined || redact === undefined) {
|
|
38
|
+
process.stderr.write("INTERNAL_ERROR: CLI failed to start.\n");
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const outcome = redact(mapCliError(error, { aborted: controller.signal.aborted, product: insmindProduct }));
|
|
43
|
+
if (runtime) {
|
|
44
|
+
runtime.presenter.error(outcome, { json: process.argv.includes("--json") });
|
|
45
|
+
}
|
|
46
|
+
else if (outcome.kind === "interrupted") {
|
|
47
|
+
process.stderr.write("Cancelled.\n");
|
|
48
|
+
}
|
|
49
|
+
else if (process.argv.includes("--json")) {
|
|
50
|
+
process.stderr.write(`${JSON.stringify({ error: outcome.failure })}\n`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
process.stderr.write(`${outcome.failure.code}: ${outcome.failure.message}\n`);
|
|
54
|
+
}
|
|
55
|
+
process.exitCode = outcome.exitCode;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
process.removeListener("SIGINT", interrupt);
|
|
60
|
+
}
|
package/dist/bin/postinstall.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
|
-
import { resolve } from "node:path";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
3
|
import { loadBundledSkills } from "../src/features/skill/bundled-skills.js";
|
|
4
4
|
import { syncBundledSkills } from "../src/features/skill/installer.js";
|
|
5
|
+
import { markWorkBuddyInstallation, readInstallationOwner } from "../src/platform/installation-owner.js";
|
|
5
6
|
export function isSupportedGlobalLifecycle(env) {
|
|
6
7
|
const userAgent = env.npm_config_user_agent ?? "";
|
|
7
8
|
if (env.npm_config_global === "true") {
|
|
@@ -11,7 +12,7 @@ export function isSupportedGlobalLifecycle(env) {
|
|
|
11
12
|
return userAgent.startsWith("pnpm/")
|
|
12
13
|
&& env.npm_command === "add"
|
|
13
14
|
&& env.npm_lifecycle_event === "postinstall"
|
|
14
|
-
&& env.npm_package_name === "@gaoding/cli"
|
|
15
|
+
&& (env.npm_package_name === "@gaoding/cli" || env.npm_package_name === "@insmind/cli")
|
|
15
16
|
&& /\/v\d+\/[0-9a-f]+-[0-9a-f]+-[0-9a-f]{16}$/u.test(initialDirectory);
|
|
16
17
|
}
|
|
17
18
|
export async function runPostinstall(options = {}) {
|
|
@@ -19,8 +20,31 @@ export async function runPostinstall(options = {}) {
|
|
|
19
20
|
if (!isSupportedGlobalLifecycle(env))
|
|
20
21
|
return;
|
|
21
22
|
const writeError = options.writeError ?? ((text) => process.stderr.write(text));
|
|
23
|
+
let skills;
|
|
24
|
+
try {
|
|
25
|
+
skills = (options.loadSkills ?? loadBundledSkills)(options.startFile ?? fileURLToPath(import.meta.url));
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (env.GD_CLI_INSTALL_OWNER === "workbuddy") {
|
|
29
|
+
throw new Error("无法确认当前安装的 package。");
|
|
30
|
+
}
|
|
31
|
+
writeError(`警告: ${oneLineMessage(error)}\n`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const primarySkill = skills.find((skill) => skill.skill === "gd-cli");
|
|
35
|
+
if (!primarySkill)
|
|
36
|
+
throw new Error("Bundled gd-cli Skill is missing.");
|
|
37
|
+
const packageRoot = dirname(dirname(primarySkill.sourceDirectory));
|
|
38
|
+
if (env.GD_CLI_INSTALL_OWNER === "workbuddy") {
|
|
39
|
+
markWorkBuddyInstallation(packageRoot);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const owner = readInstallationOwner(packageRoot);
|
|
43
|
+
if (owner === "workbuddy")
|
|
44
|
+
return;
|
|
45
|
+
if (owner === "invalid")
|
|
46
|
+
throw new Error("无法确认当前安装的托管信息。");
|
|
22
47
|
try {
|
|
23
|
-
const skills = (options.loadSkills ?? loadBundledSkills)(options.startFile ?? fileURLToPath(import.meta.url));
|
|
24
48
|
await (options.syncSkills ?? syncBundledSkills)(skills, {
|
|
25
49
|
env,
|
|
26
50
|
...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {})
|
|
@@ -38,5 +62,8 @@ const entryPath = process.argv[1];
|
|
|
38
62
|
const isDirectEntry = entryPath !== undefined
|
|
39
63
|
&& resolve(entryPath) === fileURLToPath(import.meta.url);
|
|
40
64
|
if (isDirectEntry || process.env.npm_lifecycle_event === "postinstall") {
|
|
41
|
-
void runPostinstall()
|
|
65
|
+
void runPostinstall().catch((error) => {
|
|
66
|
+
process.stderr.write(`${oneLineMessage(error)}\n`);
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
});
|
|
42
69
|
}
|
|
@@ -9,12 +9,13 @@ import { registerModelCommands } from "../cli/model-commands.js";
|
|
|
9
9
|
import { registerEditorCommands } from "../cli/editor-commands.js";
|
|
10
10
|
import { registerDamCommands } from "../cli/dam-commands.js";
|
|
11
11
|
import { registerUpdateCommand } from "../cli/update-command.js";
|
|
12
|
+
import { registerCreditsCommand } from "../cli/credits-command.js";
|
|
12
13
|
import { redact } from "../platform/redact.js";
|
|
13
14
|
export { assertAllLeafCommandsBound, bindAction } from "../cli/action-binding.js";
|
|
14
15
|
export function createCli(runtime, options) {
|
|
15
16
|
const program = new Command()
|
|
16
|
-
.name(
|
|
17
|
-
.description(
|
|
17
|
+
.name(runtime.product.commandName)
|
|
18
|
+
.description(runtime.product.description)
|
|
18
19
|
.version(runtime.version)
|
|
19
20
|
.helpCommand(false)
|
|
20
21
|
.showHelpAfterError(false)
|
|
@@ -25,6 +26,9 @@ export function createCli(runtime, options) {
|
|
|
25
26
|
writeOut: runtime.io.writeOut,
|
|
26
27
|
writeErr: () => undefined
|
|
27
28
|
});
|
|
29
|
+
if (runtime.product.id === "insmind") {
|
|
30
|
+
program.option("--locale <locale>", "locale for service-owned business descriptions");
|
|
31
|
+
}
|
|
28
32
|
configureActionEnvironment(program, {
|
|
29
33
|
policies: runtime.accessPolicies,
|
|
30
34
|
signal: options.signal,
|
|
@@ -32,7 +36,10 @@ export function createCli(runtime, options) {
|
|
|
32
36
|
updateNotification: runtime.updateNotification
|
|
33
37
|
});
|
|
34
38
|
registerAuthCommands(program, runtime);
|
|
35
|
-
|
|
39
|
+
if (runtime.product.exposesOrganizations)
|
|
40
|
+
registerOrgCommands(program, runtime);
|
|
41
|
+
else
|
|
42
|
+
registerCreditsCommand(program, runtime);
|
|
36
43
|
registerAgentCommands(program, runtime);
|
|
37
44
|
registerToolCommands(program, runtime);
|
|
38
45
|
registerModelCommands(program, runtime);
|
|
@@ -68,7 +75,10 @@ export async function executeCli(options) {
|
|
|
68
75
|
// The original Commander error is mapped and presented below.
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
|
-
const outcome = redact(mapCliError(error, {
|
|
78
|
+
const outcome = redact(mapCliError(error, {
|
|
79
|
+
aborted: options.signal.aborted,
|
|
80
|
+
...(options.product ? { product: options.product } : {})
|
|
81
|
+
}));
|
|
72
82
|
const telemetryError = classifyTelemetryError(error);
|
|
73
83
|
const traceId = options.telemetry.selected
|
|
74
84
|
? options.telemetry.traceId
|
|
@@ -25,6 +25,7 @@ import { createToolApiAdapter } from "../features/tool/tool-api-adapter.js";
|
|
|
25
25
|
import { createToolUseCases } from "../features/tool/use-cases.js";
|
|
26
26
|
import { createOrgUseCases } from "../features/org/use-cases.js";
|
|
27
27
|
import { createOrgService } from "../features/org/org-service.js";
|
|
28
|
+
import { createCreditsUseCases } from "../features/credits/use-cases.js";
|
|
28
29
|
import { createBrowserOpener } from "../platform/open-browser.js";
|
|
29
30
|
import { createSignedHttpTransport } from "../platform/signed-http-transport.js";
|
|
30
31
|
import { createJsonInputReader } from "../platform/json-input.js";
|
|
@@ -37,22 +38,36 @@ import { createUpdateNotificationService } from "../features/update/update-notif
|
|
|
37
38
|
import { classifyTelemetryError } from "../cli/errors.js";
|
|
38
39
|
import { createTelemetryInvocation } from "../telemetry/invocation.js";
|
|
39
40
|
import { createSlsTelemetrySink } from "../telemetry/sls-sink.js";
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
toolApi: new URL("https://gdcli.gaoding.com/api"),
|
|
45
|
-
damApi: new URL("https://gdcli.gaoding.com/api"),
|
|
46
|
-
ssoApi: new URL("https://www.gaoding.com/api/sso"),
|
|
47
|
-
authPageOrigin: new URL("https://www.gaoding.art")
|
|
48
|
-
};
|
|
41
|
+
import { gaodingProduct } from "../product/config.js";
|
|
42
|
+
import { resolveProductLocale, systemLocale } from "../product/locale.js";
|
|
43
|
+
import { withAgentBillingUnit, withToolBillingUnit } from "../product/billing.js";
|
|
44
|
+
import { readInstallationOwner } from "../platform/installation-owner.js";
|
|
49
45
|
export function createProductionRuntime(options = {}) {
|
|
46
|
+
const product = options.product ?? gaodingProduct;
|
|
50
47
|
const bundledSkills = loadBundledSkills(fileURLToPath(import.meta.url));
|
|
51
|
-
const primarySkill = bundledSkills.find((skill) => skill.skill ===
|
|
48
|
+
const primarySkill = bundledSkills.find((skill) => skill.skill === product.skillName);
|
|
52
49
|
if (!primarySkill)
|
|
53
|
-
throw new Error(
|
|
54
|
-
const
|
|
50
|
+
throw new Error(`Bundled ${product.skillName} Skill is missing.`);
|
|
51
|
+
const packageRoot = dirname(dirname(primarySkill.sourceDirectory));
|
|
52
|
+
const installationOwner = readInstallationOwner(packageRoot);
|
|
53
|
+
const endpoints = options.endpoints ?? product.endpoints;
|
|
55
54
|
const fetch = options.fetch ?? globalThis.fetch;
|
|
55
|
+
const env = options.env ?? process.env;
|
|
56
|
+
const environmentLocale = product.localeEnvironmentVariable
|
|
57
|
+
? env[product.localeEnvironmentVariable]
|
|
58
|
+
: undefined;
|
|
59
|
+
const localSystemLocale = systemLocale();
|
|
60
|
+
const locale = resolveProductLocale({
|
|
61
|
+
...(options.locale === undefined ? {} : { explicit: options.locale }),
|
|
62
|
+
...(environmentLocale === undefined ? {} : { environment: environmentLocale }),
|
|
63
|
+
...(localSystemLocale === undefined ? {} : { system: localSystemLocale })
|
|
64
|
+
});
|
|
65
|
+
const businessHeaders = product.id === "insmind" ? {
|
|
66
|
+
"X-Locale": locale.locale,
|
|
67
|
+
"X-Language": locale.language,
|
|
68
|
+
"X-Market": locale.market,
|
|
69
|
+
"X-Legal-Region": locale.legalRegion
|
|
70
|
+
} : undefined;
|
|
56
71
|
const now = options.now ?? (() => new Date());
|
|
57
72
|
const telemetry = createTelemetryInvocation({
|
|
58
73
|
cliVersion: primarySkill.version,
|
|
@@ -66,7 +81,10 @@ export function createProductionRuntime(options = {}) {
|
|
|
66
81
|
},
|
|
67
82
|
classifyError: classifyTelemetryError
|
|
68
83
|
});
|
|
69
|
-
const telemetrySink = createSlsTelemetrySink({
|
|
84
|
+
const telemetrySink = createSlsTelemetrySink({
|
|
85
|
+
fetch,
|
|
86
|
+
trackingUrl: product.telemetryUrl
|
|
87
|
+
});
|
|
70
88
|
const rawIo = options.io ?? {
|
|
71
89
|
input: process.stdin,
|
|
72
90
|
stdout: process.stdout,
|
|
@@ -81,41 +99,55 @@ export function createProductionRuntime(options = {}) {
|
|
|
81
99
|
stderrTerminal: rawIo.stderrTerminal ?? hasTerminal(rawIo.stderr)
|
|
82
100
|
};
|
|
83
101
|
const store = createLocalCredentialStore({
|
|
84
|
-
...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {})
|
|
102
|
+
...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {}),
|
|
103
|
+
stateDirectory: product.stateDirectory
|
|
85
104
|
});
|
|
86
105
|
const orgTransport = createSignedHttpTransport({
|
|
87
106
|
baseUrl: endpoints.orgApi,
|
|
88
107
|
fetch,
|
|
89
108
|
now,
|
|
90
|
-
traceparent: () => telemetry.traceparent()
|
|
109
|
+
traceparent: () => telemetry.traceparent(),
|
|
110
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
111
|
+
});
|
|
112
|
+
const creditsTransport = createSignedHttpTransport({
|
|
113
|
+
baseUrl: endpoints.creditsApi,
|
|
114
|
+
fetch,
|
|
115
|
+
now,
|
|
116
|
+
traceparent: () => telemetry.traceparent(),
|
|
117
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
91
118
|
});
|
|
92
119
|
const agentTransport = createSignedHttpTransport({
|
|
93
120
|
baseUrl: endpoints.agentApi,
|
|
94
121
|
fetch,
|
|
95
122
|
now,
|
|
96
|
-
traceparent: () => telemetry.traceparent()
|
|
123
|
+
traceparent: () => telemetry.traceparent(),
|
|
124
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
97
125
|
});
|
|
98
126
|
const mnsTransport = createSignedHttpTransport({
|
|
99
127
|
baseUrl: endpoints.mnsApi,
|
|
100
128
|
fetch,
|
|
101
129
|
now,
|
|
102
|
-
traceparent: () => telemetry.traceparent()
|
|
130
|
+
traceparent: () => telemetry.traceparent(),
|
|
131
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
103
132
|
});
|
|
104
133
|
const toolTransport = createSignedHttpTransport({
|
|
105
134
|
baseUrl: endpoints.toolApi,
|
|
106
135
|
fetch,
|
|
107
136
|
now,
|
|
108
|
-
traceparent: () => telemetry.traceparent()
|
|
137
|
+
traceparent: () => telemetry.traceparent(),
|
|
138
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
109
139
|
});
|
|
110
140
|
const damTransport = createSignedHttpTransport({
|
|
111
141
|
baseUrl: endpoints.damApi,
|
|
112
142
|
fetch,
|
|
113
143
|
now,
|
|
114
144
|
channelId: "32",
|
|
115
|
-
traceparent: () => telemetry.traceparent()
|
|
145
|
+
traceparent: () => telemetry.traceparent(),
|
|
146
|
+
...(businessHeaders ? { businessHeaders } : {})
|
|
116
147
|
});
|
|
117
148
|
const sso = createSsoService({
|
|
118
149
|
ssoApi: endpoints.ssoApi,
|
|
150
|
+
clientId: product.deviceClientId,
|
|
119
151
|
fetch,
|
|
120
152
|
now
|
|
121
153
|
});
|
|
@@ -123,13 +155,18 @@ export function createProductionRuntime(options = {}) {
|
|
|
123
155
|
store,
|
|
124
156
|
org: createOrgService({ transport: orgTransport }),
|
|
125
157
|
sso,
|
|
126
|
-
telemetry
|
|
158
|
+
telemetry,
|
|
159
|
+
...(product.exposesOrganizations
|
|
160
|
+
? {}
|
|
161
|
+
: { singleOrganizationName: product.displayName })
|
|
127
162
|
});
|
|
128
163
|
const auth = createAuthUseCases({
|
|
129
164
|
store,
|
|
130
165
|
sso,
|
|
131
166
|
organizationBinder: org,
|
|
132
167
|
authPageOrigin: endpoints.authPageOrigin,
|
|
168
|
+
commandName: product.commandName,
|
|
169
|
+
requireOrganization: !product.exposesOrganizations,
|
|
133
170
|
now,
|
|
134
171
|
telemetry,
|
|
135
172
|
sleep: async (milliseconds, signal) => {
|
|
@@ -137,6 +174,10 @@ export function createProductionRuntime(options = {}) {
|
|
|
137
174
|
}
|
|
138
175
|
});
|
|
139
176
|
const storage = options.objectStorage ?? createObjectStorageUploader({ fetch, now });
|
|
177
|
+
const credits = createCreditsUseCases({
|
|
178
|
+
transport: creditsTransport,
|
|
179
|
+
billingUnit: product.billingUnit
|
|
180
|
+
});
|
|
140
181
|
const storageUpload = createDamStorageUploader({
|
|
141
182
|
transport: damTransport,
|
|
142
183
|
storage
|
|
@@ -144,10 +185,13 @@ export function createProductionRuntime(options = {}) {
|
|
|
144
185
|
const transientUploader = createDamTransientUploader({ storageUpload });
|
|
145
186
|
const presenter = createPresenter({
|
|
146
187
|
writeOut: io.writeOut,
|
|
147
|
-
writeError: io.writeError
|
|
188
|
+
writeError: io.writeError,
|
|
189
|
+
product
|
|
148
190
|
});
|
|
149
191
|
const browser = createBrowserOpener();
|
|
150
|
-
const validators = createContractValidators(
|
|
192
|
+
const validators = createContractValidators({
|
|
193
|
+
organizations: product.exposesOrganizations
|
|
194
|
+
});
|
|
151
195
|
const modelCatalog = createMnsCatalogAdapter({ transport: mnsTransport });
|
|
152
196
|
const damApi = createDamApiAdapter({ transport: damTransport });
|
|
153
197
|
const damRepositories = createDamRepositoryCatalog({ transport: damTransport });
|
|
@@ -190,7 +234,7 @@ export function createProductionRuntime(options = {}) {
|
|
|
190
234
|
},
|
|
191
235
|
telemetry
|
|
192
236
|
});
|
|
193
|
-
const agent = createAgentUseCases({
|
|
237
|
+
const agent = withAgentBillingUnit(createAgentUseCases({
|
|
194
238
|
catalog: modelCatalog,
|
|
195
239
|
uploader: transientUploader,
|
|
196
240
|
completion: createCreativeAgentAdapter({
|
|
@@ -200,24 +244,29 @@ export function createProductionRuntime(options = {}) {
|
|
|
200
244
|
}),
|
|
201
245
|
warn: (message) => { presenter.warning(message); },
|
|
202
246
|
telemetry
|
|
203
|
-
});
|
|
204
|
-
const tool = createToolUseCases({
|
|
247
|
+
}), product.billingUnit);
|
|
248
|
+
const tool = withToolBillingUnit(createToolUseCases({
|
|
205
249
|
catalog: modelCatalog,
|
|
250
|
+
tools: product.tools,
|
|
206
251
|
execution: createToolApiAdapter({ transport: toolTransport, telemetry }),
|
|
207
252
|
uploader: transientUploader,
|
|
208
253
|
warn: (message) => { presenter.warning(message); },
|
|
209
254
|
telemetry
|
|
210
|
-
});
|
|
255
|
+
}), product.billingUnit);
|
|
211
256
|
const editor = createEditorUseCases({
|
|
212
257
|
session: createEditorSession({
|
|
213
258
|
store: createEditorSessionStateStore({
|
|
214
259
|
...(options.homeDirectory === undefined
|
|
215
260
|
? {}
|
|
216
|
-
: { homeDirectory: options.homeDirectory })
|
|
261
|
+
: { homeDirectory: options.homeDirectory }),
|
|
262
|
+
stateDirectory: product.stateDirectory
|
|
217
263
|
}),
|
|
218
264
|
browser,
|
|
219
|
-
defaultCreateUrl:
|
|
220
|
-
workUrl:
|
|
265
|
+
defaultCreateUrl: product.defaultEditorCreateUrl,
|
|
266
|
+
workUrl: product.editorWorkUrl,
|
|
267
|
+
commandName: product.commandName,
|
|
268
|
+
restrictTargets: product.restrictEditorTargets,
|
|
269
|
+
stateDirectory: product.stateDirectory,
|
|
221
270
|
...(options.homeDirectory === undefined
|
|
222
271
|
? {}
|
|
223
272
|
: { homeDirectory: options.homeDirectory })
|
|
@@ -233,13 +282,18 @@ export function createProductionRuntime(options = {}) {
|
|
|
233
282
|
});
|
|
234
283
|
const update = {
|
|
235
284
|
run(signal) {
|
|
236
|
-
const packageRoot = dirname(dirname(primarySkill.sourceDirectory));
|
|
237
285
|
return createUpdateService({
|
|
238
286
|
currentVersion: primarySkill.version,
|
|
239
287
|
packageRoot,
|
|
240
288
|
bundledSkills,
|
|
241
289
|
fetch,
|
|
242
290
|
telemetry,
|
|
291
|
+
...(product.id === "insmind" ? {
|
|
292
|
+
packageName: product.npmPackage,
|
|
293
|
+
commandName: product.commandName,
|
|
294
|
+
registryUrl: `https://registry.npmjs.org/${encodeURIComponent(product.npmPackage)}`
|
|
295
|
+
} : {}),
|
|
296
|
+
installationOwner,
|
|
243
297
|
...(process.argv[1] ? { binaryPath: process.argv[1] } : {}),
|
|
244
298
|
...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {})
|
|
245
299
|
}).run(signal);
|
|
@@ -249,11 +303,18 @@ export function createProductionRuntime(options = {}) {
|
|
|
249
303
|
currentVersion: primarySkill.version,
|
|
250
304
|
fetch,
|
|
251
305
|
now,
|
|
306
|
+
installationOwner,
|
|
252
307
|
...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {}),
|
|
253
308
|
...(options.env ? { env: options.env } : {}),
|
|
254
|
-
notify: (message) => { presenter.notice(message); }
|
|
309
|
+
notify: (message) => { presenter.notice(message); },
|
|
310
|
+
...(product.id === "insmind" ? {
|
|
311
|
+
stateDirectoryName: product.stateDirectory,
|
|
312
|
+
registryUrl: `https://registry.npmjs.org/${encodeURIComponent(product.npmPackage)}`,
|
|
313
|
+
commandName: product.commandName
|
|
314
|
+
} : {})
|
|
255
315
|
});
|
|
256
316
|
return {
|
|
317
|
+
product,
|
|
257
318
|
version: primarySkill.version,
|
|
258
319
|
telemetry,
|
|
259
320
|
telemetrySink,
|
|
@@ -268,6 +329,7 @@ export function createProductionRuntime(options = {}) {
|
|
|
268
329
|
editor,
|
|
269
330
|
dam,
|
|
270
331
|
tool,
|
|
332
|
+
credits,
|
|
271
333
|
update,
|
|
272
334
|
updateNotification,
|
|
273
335
|
jsonInput: createJsonInputReader({
|
|
@@ -35,8 +35,6 @@ const editorDisconnectOutputSchema = contractSchema("editor.disconnect", "output
|
|
|
35
35
|
const editorSaveOutputSchema = contractSchema("editor.save", "output");
|
|
36
36
|
const editorScreenshotOutputSchema = contractSchema("editor.screenshot", "output");
|
|
37
37
|
const editorSnapshotOutputSchema = contractSchema("editor.snapshot", "output");
|
|
38
|
-
const orgCurrentSchema = contractSchema("org.current", "output");
|
|
39
|
-
const orgListSchema = contractSchema("org.list", "output");
|
|
40
38
|
const modelGetInputSchema = contractSchema("model.get", "input");
|
|
41
39
|
const modelGetOutputSchema = contractSchema("model.get", "output");
|
|
42
40
|
const modelListInputSchema = contractSchema("model.list", "input");
|
|
@@ -56,7 +54,7 @@ export class OutputContractError extends Error {
|
|
|
56
54
|
this.name = "OutputContractError";
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
|
-
export function createContractValidators() {
|
|
57
|
+
export function createContractValidators(options = {}) {
|
|
60
58
|
const ajv = new Ajv2020({ allErrors: true, strict: true });
|
|
61
59
|
const addFormats = addFormatsImport;
|
|
62
60
|
addFormats(ajv);
|
|
@@ -94,8 +92,13 @@ export function createContractValidators() {
|
|
|
94
92
|
const editorApplyOutput = ajv.compile(editorApplyOutputSchema);
|
|
95
93
|
const editorScreenshotOutput = ajv.compile(editorScreenshotOutputSchema);
|
|
96
94
|
const editorSaveOutput = ajv.compile(editorSaveOutputSchema);
|
|
97
|
-
const
|
|
98
|
-
const
|
|
95
|
+
const organizations = options.organizations !== false;
|
|
96
|
+
const orgList = organizations
|
|
97
|
+
? ajv.compile(contractSchema("org.list", "output"))
|
|
98
|
+
: unavailableValidator;
|
|
99
|
+
const orgCurrent = organizations
|
|
100
|
+
? ajv.compile(contractSchema("org.current", "output"))
|
|
101
|
+
: unavailableValidator;
|
|
99
102
|
const toolListOutput = ajv.compile(toolListOutputSchema);
|
|
100
103
|
const modelListInput = ajv.compile(modelListInputSchema);
|
|
101
104
|
const modelListOutput = ajv.compile(modelListOutputSchema);
|
|
@@ -149,6 +152,7 @@ export function createContractValidators() {
|
|
|
149
152
|
toolCallOutput: assertion(toolCallOutput, OutputContractError)
|
|
150
153
|
};
|
|
151
154
|
}
|
|
155
|
+
const unavailableValidator = Object.assign(() => false, { errors: null, schema: false, schemaEnv: undefined });
|
|
152
156
|
function assertion(validate, ErrorType) {
|
|
153
157
|
return (value) => {
|
|
154
158
|
if (!validate(value))
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { contractSchema } from "../contracts/schema.js";
|
|
2
2
|
import { bindPreparedAction } from "./action-binding.js";
|
|
3
3
|
import { CliUsageError } from "./errors.js";
|
|
4
|
+
import { productText as text } from "../product/text.js";
|
|
4
5
|
const agentSendInputSchema = contractSchema("agent.send", "input");
|
|
5
6
|
export function registerAgentCommands(program, runtime) {
|
|
6
7
|
const agent = program.command("agent")
|
|
7
|
-
.description("稿定 Agent")
|
|
8
|
+
.description(text(runtime.product, "稿定 Agent", "insMind Agent"))
|
|
8
9
|
.helpCommand(false);
|
|
9
10
|
const send = agent.command("send")
|
|
10
|
-
.description("发送结构化创作消息")
|
|
11
|
-
.option("--schema", "输出输入 Schema")
|
|
12
|
-
.option("--input <file|->", "从文件或标准输入读取 JSON")
|
|
11
|
+
.description(text(runtime.product, "发送结构化创作消息", "Send a structured creation message"))
|
|
12
|
+
.option("--schema", text(runtime.product, "输出输入 Schema", "output the input Schema"))
|
|
13
|
+
.option("--input <file|->", text(runtime.product, "从文件或标准输入读取 JSON", "read JSON from a file or stdin"))
|
|
13
14
|
.allowExcessArguments(false);
|
|
14
15
|
bindPreparedAction(send, "organization", async (signal) => {
|
|
15
16
|
signal.throwIfAborted();
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { bindAction } from "./action-binding.js";
|
|
2
|
-
import {
|
|
2
|
+
import { authStatusViewFor } from "./presenter.js";
|
|
3
|
+
import { productText as text } from "../product/text.js";
|
|
3
4
|
export function registerAuthCommands(program, runtime) {
|
|
4
5
|
const auth = program.command("auth")
|
|
5
|
-
.description("登录与本机凭证")
|
|
6
|
+
.description(text(runtime.product, "登录与本机凭证", "Authentication and local credentials"))
|
|
6
7
|
.helpCommand(false);
|
|
7
8
|
const login = leaf(auth.command("login"))
|
|
8
|
-
.description("登录稿定")
|
|
9
|
-
.option("--no-browser", "不自动打开浏览器");
|
|
9
|
+
.description(text(runtime.product, "登录稿定", "Sign in to insMind"))
|
|
10
|
+
.option("--no-browser", text(runtime.product, "不自动打开浏览器", "do not open a browser automatically"));
|
|
10
11
|
bindAction(login, "none", async (_context, signal) => {
|
|
11
12
|
const noBrowser = login.opts().browser === false;
|
|
12
13
|
runtime.telemetry.annotate({ parameters: { noBrowser } });
|
|
@@ -23,30 +24,32 @@ export function registerAuthCommands(program, runtime) {
|
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
await runtime.telemetry.stage("output", async () => {
|
|
26
|
-
runtime.presenter.success(result.status === "already_logged_in"
|
|
27
|
+
runtime.presenter.success(result.status === "already_logged_in"
|
|
28
|
+
? text(runtime.product, "已登录。", "Already signed in.")
|
|
29
|
+
: text(runtime.product, "登录成功。", "Signed in successfully."));
|
|
27
30
|
if (result.status === "already_logged_in" && !result.organizationSelected) {
|
|
28
31
|
runtime.presenter.warning("尚未选择组织,请执行 gd-cli org switch。");
|
|
29
32
|
}
|
|
30
33
|
});
|
|
31
34
|
}, { operation: "auth.login" });
|
|
32
35
|
const status = leaf(auth.command("status"))
|
|
33
|
-
.description("查看登录状态")
|
|
34
|
-
.option("--json", "输出 JSON");
|
|
36
|
+
.description(text(runtime.product, "查看登录状态", "Show authentication status"))
|
|
37
|
+
.option("--json", text(runtime.product, "输出 JSON", "output JSON"));
|
|
35
38
|
bindAction(status, "none", async () => {
|
|
36
39
|
const result = await runtime.auth.status({ now: runtime.now() });
|
|
37
40
|
await runtime.telemetry.stage("output", async () => {
|
|
38
41
|
runtime.validators.authStatus(result);
|
|
39
42
|
runtime.presenter.result(result, {
|
|
40
43
|
json: status.opts().json === true,
|
|
41
|
-
view:
|
|
44
|
+
view: authStatusViewFor(runtime.product)
|
|
42
45
|
});
|
|
43
46
|
});
|
|
44
47
|
}, { operation: "auth.status" });
|
|
45
|
-
const logout = leaf(auth.command("logout")).description("退出登录");
|
|
48
|
+
const logout = leaf(auth.command("logout")).description(text(runtime.product, "退出登录", "Sign out"));
|
|
46
49
|
bindAction(logout, "none", async () => {
|
|
47
50
|
await runtime.auth.logout();
|
|
48
51
|
await runtime.telemetry.stage("output", async () => {
|
|
49
|
-
runtime.presenter.success("已退出登录。");
|
|
52
|
+
runtime.presenter.success(text(runtime.product, "已退出登录。", "Signed out."));
|
|
50
53
|
});
|
|
51
54
|
}, { operation: "auth.logout" });
|
|
52
55
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { bindAction } from "./action-binding.js";
|
|
2
|
+
export function registerCreditsCommand(program, runtime) {
|
|
3
|
+
const credits = program.command("credits")
|
|
4
|
+
.description("Show the current insMind credits balance")
|
|
5
|
+
.option("--json", "output JSON")
|
|
6
|
+
.allowExcessArguments(false);
|
|
7
|
+
bindAction(credits, "organization", async (context, signal) => {
|
|
8
|
+
const result = await runtime.credits.get({
|
|
9
|
+
credential: context.state.credential,
|
|
10
|
+
organizationId: context.state.organization.id,
|
|
11
|
+
signal
|
|
12
|
+
});
|
|
13
|
+
await runtime.telemetry.stage("output", async () => {
|
|
14
|
+
runtime.presenter.result(result, {
|
|
15
|
+
json: credits.opts().json === true,
|
|
16
|
+
view: (value) => {
|
|
17
|
+
const balance = value;
|
|
18
|
+
return `${balance.credits.available} insMind credits available`;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}, { operation: "credits.get" });
|
|
23
|
+
}
|