@dsh-workbench/adapter-supply 1.1.3 → 1.1.5
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/installed-module.d.ts +2 -0
- package/dist/installed-module.js +64 -9
- package/dist/plugin-tools.d.ts +1 -2
- package/dist/plugin-tools.js +6 -24
- package/dist/plugin-units.js +9 -1
- package/package.json +3 -3
|
@@ -25,6 +25,7 @@ export interface ProfileModule {
|
|
|
25
25
|
readonly version: string;
|
|
26
26
|
readonly registry?: string;
|
|
27
27
|
readonly local?: boolean;
|
|
28
|
+
readonly fromRegistry?: boolean;
|
|
28
29
|
}
|
|
29
30
|
export declare function profileManifestOf(profileDir: string | null): Readonly<Record<string, unknown>> | undefined;
|
|
30
31
|
export declare function profileModules(profileDir: string | null): readonly ProfileModule[];
|
|
@@ -39,6 +40,7 @@ export declare function declaredPluginCommands(profileDir: string | null): Reado
|
|
|
39
40
|
export declare function readInstalledModule(profileDir: string | null, pkg: string): InstalledModule;
|
|
40
41
|
export declare function isPackedArtifactSpec(spec: string): boolean;
|
|
41
42
|
export declare function isLocalDependencySpec(spec: string): boolean;
|
|
43
|
+
export declare function isRegistryDependencySpec(spec: string): boolean;
|
|
42
44
|
export interface ProfilePackage {
|
|
43
45
|
readonly pkg: string;
|
|
44
46
|
readonly version: string;
|
package/dist/installed-module.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { declarationProblemsOf, readDeclaration } from '@dsh-workbench/shared/host';
|
|
3
|
+
import { declarationProblemsOf, packageSourceOf, readDeclaration, scopeOf } from '@dsh-workbench/shared/host';
|
|
4
4
|
const PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
5
5
|
function asRecord(value) {
|
|
6
6
|
return typeof value === 'object' && value !== null ? value : undefined;
|
|
@@ -39,14 +39,17 @@ export function profileModules(profileDir) {
|
|
|
39
39
|
const found = [];
|
|
40
40
|
for (const pkg of names) {
|
|
41
41
|
const read = readInstalledModule(profileDir, pkg);
|
|
42
|
-
if (read.kind === 'module')
|
|
42
|
+
if (read.kind === 'module') {
|
|
43
|
+
const spec = asText(dependencies[read.pkg]);
|
|
43
44
|
found.push({
|
|
44
45
|
pkg: read.pkg,
|
|
45
46
|
unit: read.unit,
|
|
46
47
|
version: read.version,
|
|
47
48
|
...(read.registry === undefined ? {} : { registry: read.registry }),
|
|
48
|
-
local: isLocalDependencySpec(
|
|
49
|
+
local: isLocalDependencySpec(spec),
|
|
50
|
+
fromRegistry: isRegistryDependencySpec(spec),
|
|
49
51
|
});
|
|
52
|
+
}
|
|
50
53
|
}
|
|
51
54
|
return found;
|
|
52
55
|
}
|
|
@@ -87,6 +90,51 @@ function registryFromLockfile(profileDir, pkg) {
|
|
|
87
90
|
return undefined;
|
|
88
91
|
return tarball.slice(0, cut);
|
|
89
92
|
}
|
|
93
|
+
function unquoted(value) {
|
|
94
|
+
const quote = value.charAt(0);
|
|
95
|
+
if (value.length >= 2 && (quote === '"' || quote === "'") && value.endsWith(quote)) {
|
|
96
|
+
return value.slice(1, -1).trim();
|
|
97
|
+
}
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
function registryFromNpmrc(profileDir, pkg) {
|
|
101
|
+
let text;
|
|
102
|
+
try {
|
|
103
|
+
text = fs.readFileSync(path.join(profileDir, '.npmrc'), 'utf8');
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const scope = scopeOf(pkg);
|
|
109
|
+
let fallback;
|
|
110
|
+
for (const line of text.split('\n')) {
|
|
111
|
+
const trimmed = line.trim();
|
|
112
|
+
if (trimmed === '' || trimmed.startsWith('#') || trimmed.startsWith(';'))
|
|
113
|
+
continue;
|
|
114
|
+
const separator = trimmed.indexOf('=');
|
|
115
|
+
if (separator <= 0)
|
|
116
|
+
continue;
|
|
117
|
+
const key = trimmed.slice(0, separator).trim();
|
|
118
|
+
const value = unquoted(trimmed.slice(separator + 1).trim());
|
|
119
|
+
if (value === '')
|
|
120
|
+
continue;
|
|
121
|
+
if (scope !== null && key === `${scope}:registry`)
|
|
122
|
+
return value;
|
|
123
|
+
if (key === 'registry')
|
|
124
|
+
fallback = value;
|
|
125
|
+
}
|
|
126
|
+
return fallback;
|
|
127
|
+
}
|
|
128
|
+
function registryOf(profileDir, pkg, manifest) {
|
|
129
|
+
const declared = asText(asRecord(manifest.publishConfig)?.registry);
|
|
130
|
+
if (declared !== '')
|
|
131
|
+
return declared;
|
|
132
|
+
const recorded = packageSourceOf(profileDir, pkg);
|
|
133
|
+
if (recorded !== undefined)
|
|
134
|
+
return recorded.registry;
|
|
135
|
+
const locked = registryFromLockfile(profileDir, pkg);
|
|
136
|
+
return locked === undefined ? registryFromNpmrc(profileDir, pkg) : locked;
|
|
137
|
+
}
|
|
90
138
|
export function moduleDeclarationOf(profileDir, pkg) {
|
|
91
139
|
if (profileDir === null || !isPackageName(pkg))
|
|
92
140
|
return undefined;
|
|
@@ -144,14 +192,13 @@ export function readInstalledModule(profileDir, pkg) {
|
|
|
144
192
|
const unit = declared === undefined ? '' : asText(declared.unit);
|
|
145
193
|
if (unit === '')
|
|
146
194
|
return { kind: 'not-module', pkg };
|
|
147
|
-
const
|
|
148
|
-
const registry = declaredRegistry === '' ? registryFromLockfile(profileDir, pkg) : declaredRegistry;
|
|
195
|
+
const registry = registryOf(profileDir, pkg, record);
|
|
149
196
|
return {
|
|
150
197
|
kind: 'module',
|
|
151
198
|
pkg,
|
|
152
199
|
unit,
|
|
153
200
|
version: asText(record.version),
|
|
154
|
-
...(registry ===
|
|
201
|
+
...(registry === undefined ? {} : { registry }),
|
|
155
202
|
};
|
|
156
203
|
}
|
|
157
204
|
const PACKED_ARTIFACT = /\.(?:tgz|tar\.gz|tar)$/i;
|
|
@@ -170,6 +217,15 @@ export function isLocalDependencySpec(spec) {
|
|
|
170
217
|
trimmed.startsWith('../') ||
|
|
171
218
|
trimmed.startsWith('/'));
|
|
172
219
|
}
|
|
220
|
+
const NON_REGISTRY_SPEC = /^(?:git\+|git:|github:|gitlab:|bitbucket:|https?:|ssh:|workspace:)/i;
|
|
221
|
+
export function isRegistryDependencySpec(spec) {
|
|
222
|
+
const trimmed = spec.trim();
|
|
223
|
+
if (trimmed === '')
|
|
224
|
+
return true;
|
|
225
|
+
if (isLocalDependencySpec(trimmed) || isPackedArtifactSpec(trimmed))
|
|
226
|
+
return false;
|
|
227
|
+
return !NON_REGISTRY_SPEC.test(trimmed);
|
|
228
|
+
}
|
|
173
229
|
export function readProfilePackage(profileDir, pkg) {
|
|
174
230
|
if (profileDir === null || !isPackageName(pkg))
|
|
175
231
|
return undefined;
|
|
@@ -186,14 +242,13 @@ export function readProfilePackage(profileDir, pkg) {
|
|
|
186
242
|
const version = asText(record.version);
|
|
187
243
|
if (version === '')
|
|
188
244
|
return undefined;
|
|
189
|
-
const
|
|
190
|
-
const registry = declaredRegistry === '' ? registryFromLockfile(profileDir, pkg) : declaredRegistry;
|
|
245
|
+
const registry = registryOf(profileDir, pkg, record);
|
|
191
246
|
const dependencies = asRecord(profileManifestOf(profileDir)?.dependencies) ?? {};
|
|
192
247
|
const local = isLocalDependencySpec(asText(dependencies[pkg]));
|
|
193
248
|
return {
|
|
194
249
|
pkg,
|
|
195
250
|
version,
|
|
196
|
-
...(registry ===
|
|
251
|
+
...(registry === undefined ? {} : { registry }),
|
|
197
252
|
...(local ? { local: true } : {}),
|
|
198
253
|
};
|
|
199
254
|
}
|
package/dist/plugin-tools.d.ts
CHANGED
|
@@ -10,6 +10,5 @@ export declare function pluginToolDescription(command: PluginCommand): string;
|
|
|
10
10
|
export declare function pluginToolWrites(command: PluginCommand): boolean;
|
|
11
11
|
export declare function pluginToolSession(command: PluginCommand): OpencliSession;
|
|
12
12
|
export declare function pluginToolArgv(command: PluginCommand, raw: unknown): string[];
|
|
13
|
-
export declare function
|
|
14
|
-
export declare function pluginApprovalQuestion(command: PluginCommand, raw: unknown): ApprovalDetail;
|
|
13
|
+
export declare function pluginApprovalQuestion(command: PluginCommand): ApprovalDetail;
|
|
15
14
|
export declare function pluginApprovalFor(command: PluginCommand): ApprovalPolicy;
|
package/dist/plugin-tools.js
CHANGED
|
@@ -8,8 +8,6 @@ const SCHEMA_TYPE = {
|
|
|
8
8
|
boolean: 'boolean',
|
|
9
9
|
string: 'string',
|
|
10
10
|
};
|
|
11
|
-
const KEY_ARG_LIMIT = 3;
|
|
12
|
-
const NO_KEY_ARGS = '没有带参数';
|
|
13
11
|
export const RUN_CODE_TOOL = 'run_code';
|
|
14
12
|
export const PLUGIN_PROMPT_BUDGET = 4_000;
|
|
15
13
|
export function pluginToolName(plugin, command) {
|
|
@@ -93,35 +91,18 @@ export function pluginToolArgv(command, raw) {
|
|
|
93
91
|
}
|
|
94
92
|
return argv;
|
|
95
93
|
}
|
|
96
|
-
export function
|
|
97
|
-
const values = valuesOf(raw);
|
|
98
|
-
const ordered = [...command.args.filter((arg) => arg.required), ...command.args.filter((arg) => !arg.required)];
|
|
99
|
-
const parts = [];
|
|
100
|
-
for (const arg of ordered) {
|
|
101
|
-
const value = values[arg.name];
|
|
102
|
-
if (value === undefined || value === null || value === '')
|
|
103
|
-
continue;
|
|
104
|
-
parts.push(`${arg.name}=${String(value)}`);
|
|
105
|
-
if (parts.length === KEY_ARG_LIMIT)
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
return parts.length === 0 ? NO_KEY_ARGS : parts.join('、');
|
|
109
|
-
}
|
|
110
|
-
export function pluginApprovalQuestion(command, raw) {
|
|
111
|
-
const key = pluginKeyArgs(command, raw);
|
|
112
|
-
const zhKey = key === NO_KEY_ARGS ? '这次没带参数' : key;
|
|
113
|
-
const enKey = key === NO_KEY_ARGS ? 'no arguments' : key;
|
|
94
|
+
export function pluginApprovalQuestion(command) {
|
|
114
95
|
return {
|
|
115
|
-
zh: `agent 想执行工作台 [${command.plugin}] opencli 插件的 [${command.name}]
|
|
116
|
-
en: `The agent wants to run the [${command.name}] command of the workbench opencli plugin [${command.plugin}]
|
|
96
|
+
zh: `agent 想执行工作台 [${command.plugin}] opencli 插件的 [${command.name}] 命令,允许吗?`,
|
|
97
|
+
en: `The agent wants to run the [${command.name}] command of the workbench opencli plugin [${command.plugin}]. Allow?`,
|
|
117
98
|
};
|
|
118
99
|
}
|
|
119
100
|
export function pluginApprovalFor(command) {
|
|
120
101
|
const denied = command.access === 'read';
|
|
121
|
-
return (
|
|
102
|
+
return () => {
|
|
122
103
|
if (denied)
|
|
123
104
|
return { kind: 'read' };
|
|
124
|
-
const question = pluginApprovalQuestion(command
|
|
105
|
+
const question = pluginApprovalQuestion(command);
|
|
125
106
|
return {
|
|
126
107
|
kind: 'ask',
|
|
127
108
|
reason: command.access === 'write'
|
|
@@ -129,6 +110,7 @@ export function pluginApprovalFor(command) {
|
|
|
129
110
|
: `${command.plugin} ${command.name} 没有拿到 access(fail-safe:按写处理)`,
|
|
130
111
|
question,
|
|
131
112
|
fallback: question,
|
|
113
|
+
noteInDetail: true,
|
|
132
114
|
};
|
|
133
115
|
};
|
|
134
116
|
}
|
package/dist/plugin-units.js
CHANGED
|
@@ -99,7 +99,15 @@ function faceOf(unit, opencliFor, note) {
|
|
|
99
99
|
title: { zh: unit.plugin, en: unit.plugin },
|
|
100
100
|
titleKey: unitTitleKey(unit.id),
|
|
101
101
|
card: null,
|
|
102
|
-
tools: unit.tools.map((tool) => ({
|
|
102
|
+
tools: unit.tools.map((tool) => ({
|
|
103
|
+
name: tool.name,
|
|
104
|
+
writes: pluginToolWrites(tool.command),
|
|
105
|
+
opencli: {
|
|
106
|
+
plugin: unit.plugin,
|
|
107
|
+
command: tool.command.name,
|
|
108
|
+
args: tool.command.args.map((arg) => arg.name),
|
|
109
|
+
},
|
|
110
|
+
})),
|
|
103
111
|
host: { inject: [] },
|
|
104
112
|
};
|
|
105
113
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/adapter-supply",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Workbench supply adapter package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"directory": "packages/adapter-supply"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@dsh-workbench/adapter-runtime": "1.1.
|
|
26
|
-
"@dsh-workbench/shared": "1.1.
|
|
25
|
+
"@dsh-workbench/adapter-runtime": "1.1.5",
|
|
26
|
+
"@dsh-workbench/shared": "1.1.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^24.19.0",
|