@qoder-ai/qoder-agent-sdk 1.0.20 → 1.0.22
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 +20 -14
- package/dist/core/brand.d.ts +4 -0
- package/dist/core/process-transport.d.ts +2 -0
- package/dist/core/runtime-launch-options.d.ts +2 -0
- package/dist/global/plugins.d.ts +8 -2
- package/dist/index.d.ts +7 -4
- package/dist/index.js +30 -27
- package/dist/protocol/control.d.ts +53 -79
- package/dist/protocol/index.d.ts +1 -1
- package/dist/protocol/index.js +1 -1
- package/dist/protocol/messages.d.ts +19 -0
- package/dist/query/index.d.ts +2 -0
- package/dist/query/startup.d.ts +11 -0
- package/dist/runtime-manifest.json +6 -6
- package/dist/settings/resolve-settings.d.ts +2 -0
- package/dist/types/messages.d.ts +3 -1
- package/dist/types/model-policy-provider.d.ts +10 -0
- package/dist/types/options.d.ts +19 -0
- package/dist/types/plugins.d.ts +52 -0
- package/dist/types/session.d.ts +5 -0
- package/dist/types/settings.d.ts +14 -1
- package/package.json +2 -2
- package/scripts/postinstall.cjs +154 -24
package/scripts/postinstall.cjs
CHANGED
|
@@ -30,7 +30,6 @@ const CN_DEV_DOWNLOAD_BASE_URL = 'https://static.qoder.com.cn/qoder-cli-cn/dev/r
|
|
|
30
30
|
const PACKAGE_JSON = require('../package.json');
|
|
31
31
|
const LOG_PREFIX = `[${PACKAGE_JSON.name ?? '@qoder-ai/qoder-agent-sdk'}]`;
|
|
32
32
|
const WORKER_RUNTIME_ENTRY_NAMES = ['qoder-worker-runtime.obf.mjs', 'qoder-worker-runtime.mjs'];
|
|
33
|
-
const REQUIRED_WORKER_RUNTIME_ASSETS = [path.join('vendor', 'ripgrep', 'x64-win32', 'rg.exe')];
|
|
34
33
|
|
|
35
34
|
function isTruthy(value) {
|
|
36
35
|
return value === '1' || value === 'true';
|
|
@@ -143,6 +142,7 @@ function normalizePlatformOverride(value) {
|
|
|
143
142
|
'linux-x64',
|
|
144
143
|
'linux-x64-baseline',
|
|
145
144
|
'linux-x64-musl',
|
|
145
|
+
'openharmony-arm64',
|
|
146
146
|
'windows-arm64',
|
|
147
147
|
'windows-x64',
|
|
148
148
|
]);
|
|
@@ -182,6 +182,15 @@ function getPlatformTarget() {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
// HarmonyOS reports process.platform === 'openharmony'. Only aarch64 is
|
|
186
|
+
// produced; the artifact is qodercli-openharmony-arm64.tar.gz.
|
|
187
|
+
if (process.platform === 'openharmony') {
|
|
188
|
+
if (process.arch !== 'arm64') {
|
|
189
|
+
throw new Error(`Unsupported OpenHarmony architecture: ${process.arch}`);
|
|
190
|
+
}
|
|
191
|
+
return 'openharmony-arm64';
|
|
192
|
+
}
|
|
193
|
+
|
|
185
194
|
throw new Error(`Unsupported platform: ${process.platform}/${process.arch}`);
|
|
186
195
|
}
|
|
187
196
|
|
|
@@ -199,8 +208,36 @@ function getDownloadUrl() {
|
|
|
199
208
|
return `${baseUrl}/${getArtifactName()}`;
|
|
200
209
|
}
|
|
201
210
|
|
|
202
|
-
function
|
|
203
|
-
|
|
211
|
+
function getWorkerRuntimeTarget(target = getPlatformTarget()) {
|
|
212
|
+
const [platform, arch] = target.split('-');
|
|
213
|
+
if (platform === 'darwin') return `darwin-${arch}`;
|
|
214
|
+
if (platform === 'linux') return `linux-${arch}`;
|
|
215
|
+
if (platform === 'windows') return `win32-${arch}`;
|
|
216
|
+
throw new Error(
|
|
217
|
+
`Worker runtime platform artifacts do not support ${target}. Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64, windows-arm64, windows-x64`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function getWorkerRuntimeArtifactName(site = getCliSite(), target = getPlatformTarget()) {
|
|
222
|
+
const workerTarget = getWorkerRuntimeTarget(target);
|
|
223
|
+
return `${getCliArtifactPrefix(site)}-worker-runtime-${workerTarget}.tgz`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function getWorkerRuntimeArtifactNameTemplate(site = getCliSite()) {
|
|
227
|
+
return `${getCliArtifactPrefix(site)}-worker-runtime-{target}.tgz`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function getWorkerRuntimeRequiredAssets(target = getPlatformTarget()) {
|
|
231
|
+
const workerTarget = getWorkerRuntimeTarget(target);
|
|
232
|
+
const [platform, arch] = workerTarget.split('-');
|
|
233
|
+
return [
|
|
234
|
+
path.join(
|
|
235
|
+
'vendor',
|
|
236
|
+
'ripgrep',
|
|
237
|
+
`${arch}-${platform}`,
|
|
238
|
+
platform === 'win32' ? 'rg.exe' : 'rg',
|
|
239
|
+
),
|
|
240
|
+
];
|
|
204
241
|
}
|
|
205
242
|
|
|
206
243
|
function hasWorkerRuntimeDownloadSiteOverride() {
|
|
@@ -221,6 +258,14 @@ function getManifestWorkerRuntimeDownloadUrl(manifest = readRuntimeManifest()) {
|
|
|
221
258
|
return url ?? null;
|
|
222
259
|
}
|
|
223
260
|
|
|
261
|
+
function getManifestWorkerRuntimeDownloadUrlTemplate(manifest = readRuntimeManifest()) {
|
|
262
|
+
const workerRuntime = getManifestWorkerRuntime(manifest);
|
|
263
|
+
if (!workerRuntime || workerRuntime.packaged === true) return null;
|
|
264
|
+
return typeof workerRuntime.urlTemplate === 'string' && workerRuntime.urlTemplate.length > 0
|
|
265
|
+
? workerRuntime.urlTemplate
|
|
266
|
+
: null;
|
|
267
|
+
}
|
|
268
|
+
|
|
224
269
|
function getManifestWorkerRuntimeSha256(manifest = readRuntimeManifest()) {
|
|
225
270
|
const workerRuntime = getManifestWorkerRuntime(manifest);
|
|
226
271
|
if (!workerRuntime || workerRuntime.packaged === true) return null;
|
|
@@ -236,30 +281,39 @@ function getManifestWorkerRuntimeSha256(manifest = readRuntimeManifest()) {
|
|
|
236
281
|
return checksum ? checksum.trim().toLowerCase() : null;
|
|
237
282
|
}
|
|
238
283
|
|
|
284
|
+
function getWorkerRuntimeDownloadUrlTemplate() {
|
|
285
|
+
const version = getCliVersion();
|
|
286
|
+
const baseUrl = normalizeDownloadBaseUrl(getWorkerRuntimeDownloadBaseUrl(version), version);
|
|
287
|
+
return `${baseUrl}/${getWorkerRuntimeArtifactNameTemplate()}`;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function getWorkerRuntimeDefaultDownloadUrl() {
|
|
291
|
+
return getWorkerRuntimeDownloadUrlTemplate().replace(
|
|
292
|
+
'{target}',
|
|
293
|
+
getWorkerRuntimeTarget(),
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
239
297
|
function getWorkerRuntimeDownloadUrl() {
|
|
240
298
|
if (process.env.QODER_WORKER_RUNTIME_URL) {
|
|
241
299
|
return process.env.QODER_WORKER_RUNTIME_URL;
|
|
242
300
|
}
|
|
243
301
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
302
|
+
if (!hasWorkerRuntimeDownloadSiteOverride()) {
|
|
303
|
+
const template = getManifestWorkerRuntimeDownloadUrlTemplate();
|
|
304
|
+
if (template) {
|
|
305
|
+
return template.replace('{target}', getWorkerRuntimeTarget());
|
|
306
|
+
}
|
|
307
|
+
const manifestUrl = getManifestWorkerRuntimeDownloadUrl();
|
|
308
|
+
if (manifestUrl) return manifestUrl;
|
|
249
309
|
}
|
|
250
310
|
|
|
251
|
-
|
|
252
|
-
const baseUrl = normalizeDownloadBaseUrl(getWorkerRuntimeDownloadBaseUrl(version), version);
|
|
253
|
-
return `${baseUrl}/${getWorkerRuntimeArtifactName()}`;
|
|
311
|
+
return getWorkerRuntimeDefaultDownloadUrl();
|
|
254
312
|
}
|
|
255
313
|
|
|
256
314
|
function getWorkerRuntimeExpectedSha256(url = getWorkerRuntimeDownloadUrl()) {
|
|
257
315
|
const manifestUrl = getManifestWorkerRuntimeDownloadUrl();
|
|
258
|
-
|
|
259
|
-
return getManifestWorkerRuntimeSha256();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return null;
|
|
316
|
+
return manifestUrl === url ? getManifestWorkerRuntimeSha256() : null;
|
|
263
317
|
}
|
|
264
318
|
|
|
265
319
|
function getBundledDir() {
|
|
@@ -365,6 +419,15 @@ function isPackagedWorkerRuntimeCompatibleWithSite(site = getCliSite()) {
|
|
|
365
419
|
runtimeInfo.build && typeof runtimeInfo.build === 'object' ? runtimeInfo.build : {};
|
|
366
420
|
const actualProductName = buildInfo.productName;
|
|
367
421
|
const actualSite = buildInfo.site;
|
|
422
|
+
const expectedVersion = getCliVersion();
|
|
423
|
+
|
|
424
|
+
if (runtimeInfo.version !== expectedVersion) {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (runtimeInfo.profile !== 'platform' || runtimeInfo.target !== getWorkerRuntimeTarget()) {
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
368
431
|
|
|
369
432
|
if (
|
|
370
433
|
typeof actualProductName === 'string' &&
|
|
@@ -452,8 +515,10 @@ async function downloadFile(url, destPath) {
|
|
|
452
515
|
console.log(`${LOG_PREFIX} Downloading: ${url}`);
|
|
453
516
|
const response = await requestUrl(url);
|
|
454
517
|
if (response.statusCode !== 200) {
|
|
518
|
+
const error = new Error(`Download failed: HTTP ${response.statusCode}`);
|
|
519
|
+
error.statusCode = response.statusCode;
|
|
455
520
|
response.resume();
|
|
456
|
-
throw
|
|
521
|
+
throw error;
|
|
457
522
|
}
|
|
458
523
|
|
|
459
524
|
await new Promise((resolve, reject) => {
|
|
@@ -496,6 +561,7 @@ async function downloadWithRetry(url, destPath, maxRetries = 2) {
|
|
|
496
561
|
lastError = error;
|
|
497
562
|
console.error(`${LOG_PREFIX} Download failed: ${error.message}`);
|
|
498
563
|
fs.rmSync(destPath, { force: true });
|
|
564
|
+
if (error.statusCode === 404) break;
|
|
499
565
|
}
|
|
500
566
|
}
|
|
501
567
|
throw lastError;
|
|
@@ -699,7 +765,7 @@ function assertWorkerRuntimeComplete(runtimeDir, sourceDescription) {
|
|
|
699
765
|
throw new Error(`Worker runtime entry missing in ${sourceDescription}: ${runtimePath}`);
|
|
700
766
|
}
|
|
701
767
|
|
|
702
|
-
const missingAssets =
|
|
768
|
+
const missingAssets = getWorkerRuntimeRequiredAssets().filter(
|
|
703
769
|
(assetPath) => !fs.existsSync(path.join(runtimeDir, assetPath)),
|
|
704
770
|
);
|
|
705
771
|
if (missingAssets.length > 0) {
|
|
@@ -715,7 +781,49 @@ function assertWorkerRuntimeComplete(runtimeDir, sourceDescription) {
|
|
|
715
781
|
return runtimePath;
|
|
716
782
|
}
|
|
717
783
|
|
|
718
|
-
function
|
|
784
|
+
function assertWorkerRuntimeIdentity(runtimeDir) {
|
|
785
|
+
const runtimeInfoPath = path.join(runtimeDir, 'runtime-info.json');
|
|
786
|
+
if (!fs.existsSync(runtimeInfoPath)) {
|
|
787
|
+
throw new Error(`Downloaded Worker runtime is missing identity metadata: ${runtimeInfoPath}`);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
let runtimeInfo;
|
|
791
|
+
try {
|
|
792
|
+
runtimeInfo = JSON.parse(fs.readFileSync(runtimeInfoPath, 'utf8'));
|
|
793
|
+
} catch (error) {
|
|
794
|
+
throw new Error(`Downloaded Worker runtime has invalid identity metadata: ${error.message}`);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
const expectedTarget = getWorkerRuntimeTarget();
|
|
798
|
+
const expectedSite = getCliSite();
|
|
799
|
+
const expectedProductName = getCliArtifactPrefix(expectedSite);
|
|
800
|
+
const expectedVersion = getCliVersion();
|
|
801
|
+
const mismatches = [];
|
|
802
|
+
|
|
803
|
+
if (runtimeInfo.profile !== 'platform') {
|
|
804
|
+
mismatches.push(`profile=${String(runtimeInfo.profile)} (expected platform)`);
|
|
805
|
+
}
|
|
806
|
+
if (runtimeInfo.target !== expectedTarget) {
|
|
807
|
+
mismatches.push(`target=${String(runtimeInfo.target)} (expected ${expectedTarget})`);
|
|
808
|
+
}
|
|
809
|
+
if (runtimeInfo.version !== expectedVersion) {
|
|
810
|
+
mismatches.push(`version=${String(runtimeInfo.version)} (expected ${expectedVersion})`);
|
|
811
|
+
}
|
|
812
|
+
if (runtimeInfo.build?.site !== expectedSite) {
|
|
813
|
+
mismatches.push(`site=${String(runtimeInfo.build?.site)} (expected ${expectedSite})`);
|
|
814
|
+
}
|
|
815
|
+
if (runtimeInfo.build?.productName !== expectedProductName) {
|
|
816
|
+
mismatches.push(
|
|
817
|
+
`productName=${String(runtimeInfo.build?.productName)} (expected ${expectedProductName})`,
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (mismatches.length > 0) {
|
|
822
|
+
throw new Error(`Downloaded Worker runtime identity mismatch: ${mismatches.join(', ')}`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
function installExtractedWorkerRuntime(extractDir, workerDir, options = {}) {
|
|
719
827
|
const contentRoot = findWorkerRuntimeRoot(extractDir);
|
|
720
828
|
if (!contentRoot) {
|
|
721
829
|
throw new Error(
|
|
@@ -723,6 +831,9 @@ function installExtractedWorkerRuntime(extractDir, workerDir) {
|
|
|
723
831
|
);
|
|
724
832
|
}
|
|
725
833
|
assertWorkerRuntimeComplete(contentRoot, contentRoot);
|
|
834
|
+
if (options.validateIdentity === true) {
|
|
835
|
+
assertWorkerRuntimeIdentity(contentRoot);
|
|
836
|
+
}
|
|
726
837
|
|
|
727
838
|
fs.rmSync(workerDir, { recursive: true, force: true });
|
|
728
839
|
copyDirContents(contentRoot, workerDir);
|
|
@@ -734,24 +845,36 @@ function installExtractedWorkerRuntime(extractDir, workerDir) {
|
|
|
734
845
|
return runtimePath;
|
|
735
846
|
}
|
|
736
847
|
|
|
737
|
-
async function
|
|
738
|
-
const url = getWorkerRuntimeDownloadUrl();
|
|
739
|
-
const expectedSha256 = getWorkerRuntimeExpectedSha256(url);
|
|
848
|
+
async function downloadAndInstallWorkerRuntime(workerDir, options = {}) {
|
|
849
|
+
const url = options.urlOverride ?? getWorkerRuntimeDownloadUrl();
|
|
850
|
+
const expectedSha256 = options.urlOverride ? null : getWorkerRuntimeExpectedSha256(url);
|
|
740
851
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'qoder-worker-runtime-'));
|
|
741
852
|
const archivePath = path.join(tempDir, path.basename(new URL(url).pathname));
|
|
742
853
|
const extractDir = path.join(tempDir, 'extract');
|
|
743
854
|
|
|
744
855
|
try {
|
|
856
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
745
857
|
await downloadWithRetry(url, archivePath);
|
|
746
858
|
await verifyChecksum(url, archivePath, expectedSha256);
|
|
747
|
-
fs.mkdirSync(extractDir, { recursive: true });
|
|
748
859
|
await extractArchive(archivePath, extractDir);
|
|
749
|
-
return
|
|
860
|
+
return {
|
|
861
|
+
runtimePath: installExtractedWorkerRuntime(extractDir, workerDir, {
|
|
862
|
+
validateIdentity: true,
|
|
863
|
+
}),
|
|
864
|
+
url,
|
|
865
|
+
};
|
|
750
866
|
} finally {
|
|
751
867
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
752
868
|
}
|
|
753
869
|
}
|
|
754
870
|
|
|
871
|
+
async function installWorkerRuntimeFromDownload() {
|
|
872
|
+
const installed = await downloadAndInstallWorkerRuntime(
|
|
873
|
+
getPackagedWorkerRuntimeDir(),
|
|
874
|
+
);
|
|
875
|
+
return installed.runtimePath;
|
|
876
|
+
}
|
|
877
|
+
|
|
755
878
|
async function main() {
|
|
756
879
|
if (isTruthy(process.env.QODER_SKIP_DOWNLOAD)) {
|
|
757
880
|
console.log(`${LOG_PREFIX} QODER_SKIP_DOWNLOAD is set, skipping runtime downloads.`);
|
|
@@ -839,6 +962,8 @@ if (require.main === module) {
|
|
|
839
962
|
}
|
|
840
963
|
|
|
841
964
|
module.exports = {
|
|
965
|
+
assertWorkerRuntimeIdentity,
|
|
966
|
+
downloadAndInstallWorkerRuntime,
|
|
842
967
|
downloadWithRetry,
|
|
843
968
|
extractArchive,
|
|
844
969
|
getTarExtractInvocation,
|
|
@@ -860,8 +985,13 @@ module.exports = {
|
|
|
860
985
|
getDefaultRuntimeTransport,
|
|
861
986
|
getWorkerRuntimeExpectedSha256,
|
|
862
987
|
getWorkerRuntimeArtifactName,
|
|
988
|
+
getWorkerRuntimeArtifactNameTemplate,
|
|
863
989
|
getWorkerRuntimeDownloadBaseUrl,
|
|
864
990
|
getWorkerRuntimeDownloadUrl,
|
|
991
|
+
getWorkerRuntimeDownloadUrlTemplate,
|
|
992
|
+
getWorkerRuntimeRequiredAssets,
|
|
993
|
+
getWorkerRuntimeTarget,
|
|
994
|
+
getManifestWorkerRuntimeDownloadUrlTemplate,
|
|
865
995
|
hasPackagedWorkerRuntime,
|
|
866
996
|
installExtractedContents,
|
|
867
997
|
installExtractedWorkerRuntime,
|