@codex-infinity/pi-infinity 0.52.4 → 0.60.2
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/CHANGELOG.md +387 -0
- package/README.md +97 -66
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +6 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +17 -6
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +42 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +346 -72
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +27 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts +6 -7
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +8 -107
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +6 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +3 -0
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +16 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +7 -3
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +5 -2
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +4 -3
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.js +11 -14
- package/dist/core/export-html/tool-renderer.d.ts +5 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +17 -4
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +37 -11
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +8 -4
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +77 -8
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +56 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +4 -11
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +4 -78
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +6 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +83 -37
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +3 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +22 -12
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +11 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +56 -16
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +6 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +122 -39
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-manager.d.ts +19 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +290 -57
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +43 -8
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +4 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +7 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +21 -15
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +59 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +3 -2
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +29 -8
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +4 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +43 -29
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +8 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +77 -69
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -0
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +6 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +116 -36
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +5 -2
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +9 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -23
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +15 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +5 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +5 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +5 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +158 -7
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +21 -2
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +127 -10
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +12 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +5 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +215 -71
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +5 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +49 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -11
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +9 -11
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/child-process.d.ts +11 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +78 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +94 -11
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +27 -16
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +158 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +5 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +6 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +66 -21
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/compaction.md +2 -0
- package/docs/custom-provider.md +57 -9
- package/docs/extensions.md +125 -12
- package/docs/keybindings.md +11 -1
- package/docs/models.md +44 -2
- package/docs/packages.md +9 -0
- package/docs/providers.md +10 -1
- package/docs/rpc.md +44 -7
- package/docs/sdk.md +2 -2
- package/docs/settings.md +11 -0
- package/docs/terminal-setup.md +39 -3
- package/docs/tmux.md +61 -0
- package/docs/tree.md +9 -0
- package/examples/extensions/README.md +2 -0
- package/examples/extensions/antigravity-image-gen.ts +8 -5
- package/examples/extensions/built-in-tool-renderer.ts +246 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +2 -2
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/overlay-qa-tests.ts +468 -1
- package/examples/extensions/preset.ts +2 -3
- package/examples/extensions/provider-payload.ts +14 -0
- package/examples/extensions/sandbox/index.ts +2 -3
- package/examples/extensions/subagent/agents.ts +2 -3
- package/examples/extensions/tool-override.ts +2 -3
- package/examples/extensions/with-deps/index.ts +1 -5
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +10 -7
|
@@ -7,6 +7,14 @@ import ignore from "ignore";
|
|
|
7
7
|
import { minimatch } from "minimatch";
|
|
8
8
|
import { CONFIG_DIR_NAME } from "../config.js";
|
|
9
9
|
import { parseGitUrl } from "../utils/git.js";
|
|
10
|
+
const NETWORK_TIMEOUT_MS = 10000;
|
|
11
|
+
const UPDATE_CHECK_CONCURRENCY = 4;
|
|
12
|
+
function isOfflineModeEnabled() {
|
|
13
|
+
const value = process.env.PI_OFFLINE;
|
|
14
|
+
if (!value)
|
|
15
|
+
return false;
|
|
16
|
+
return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
|
|
17
|
+
}
|
|
10
18
|
const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
|
|
11
19
|
const FILE_PATTERNS = {
|
|
12
20
|
extensions: /\.(ts|js)$/,
|
|
@@ -18,6 +26,9 @@ const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
|
|
|
18
26
|
function toPosixPath(p) {
|
|
19
27
|
return p.split(sep).join("/");
|
|
20
28
|
}
|
|
29
|
+
function getHomeDir() {
|
|
30
|
+
return process.env.HOME || homedir();
|
|
31
|
+
}
|
|
21
32
|
function prefixIgnorePattern(line, prefix) {
|
|
22
33
|
const trimmed = line.trim();
|
|
23
34
|
if (!trimmed)
|
|
@@ -376,43 +387,50 @@ function collectResourceFiles(dir, resourceType) {
|
|
|
376
387
|
return collectFiles(dir, FILE_PATTERNS[resourceType]);
|
|
377
388
|
}
|
|
378
389
|
function matchesAnyPattern(filePath, patterns, baseDir) {
|
|
379
|
-
const rel = relative(baseDir, filePath);
|
|
390
|
+
const rel = toPosixPath(relative(baseDir, filePath));
|
|
380
391
|
const name = basename(filePath);
|
|
392
|
+
const filePathPosix = toPosixPath(filePath);
|
|
381
393
|
const isSkillFile = name === "SKILL.md";
|
|
382
394
|
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
383
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
395
|
+
const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
|
|
384
396
|
const parentName = isSkillFile ? basename(parentDir) : undefined;
|
|
397
|
+
const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
|
|
385
398
|
return patterns.some((pattern) => {
|
|
386
|
-
|
|
399
|
+
const normalizedPattern = toPosixPath(pattern);
|
|
400
|
+
if (minimatch(rel, normalizedPattern) ||
|
|
401
|
+
minimatch(name, normalizedPattern) ||
|
|
402
|
+
minimatch(filePathPosix, normalizedPattern)) {
|
|
387
403
|
return true;
|
|
388
404
|
}
|
|
389
405
|
if (!isSkillFile)
|
|
390
406
|
return false;
|
|
391
|
-
return minimatch(parentRel,
|
|
407
|
+
return (minimatch(parentRel, normalizedPattern) ||
|
|
408
|
+
minimatch(parentName, normalizedPattern) ||
|
|
409
|
+
minimatch(parentDirPosix, normalizedPattern));
|
|
392
410
|
});
|
|
393
411
|
}
|
|
394
412
|
function normalizeExactPattern(pattern) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
return pattern;
|
|
413
|
+
const normalized = pattern.startsWith("./") || pattern.startsWith(".\\") ? pattern.slice(2) : pattern;
|
|
414
|
+
return toPosixPath(normalized);
|
|
399
415
|
}
|
|
400
416
|
function matchesAnyExactPattern(filePath, patterns, baseDir) {
|
|
401
417
|
if (patterns.length === 0)
|
|
402
418
|
return false;
|
|
403
|
-
const rel = relative(baseDir, filePath);
|
|
419
|
+
const rel = toPosixPath(relative(baseDir, filePath));
|
|
404
420
|
const name = basename(filePath);
|
|
421
|
+
const filePathPosix = toPosixPath(filePath);
|
|
405
422
|
const isSkillFile = name === "SKILL.md";
|
|
406
423
|
const parentDir = isSkillFile ? dirname(filePath) : undefined;
|
|
407
|
-
const parentRel = isSkillFile ? relative(baseDir, parentDir) : undefined;
|
|
424
|
+
const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
|
|
425
|
+
const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
|
|
408
426
|
return patterns.some((pattern) => {
|
|
409
427
|
const normalized = normalizeExactPattern(pattern);
|
|
410
|
-
if (normalized === rel || normalized ===
|
|
428
|
+
if (normalized === rel || normalized === filePathPosix) {
|
|
411
429
|
return true;
|
|
412
430
|
}
|
|
413
431
|
if (!isSkillFile)
|
|
414
432
|
return false;
|
|
415
|
-
return normalized === parentRel || normalized ===
|
|
433
|
+
return normalized === parentRel || normalized === parentDirPosix;
|
|
416
434
|
});
|
|
417
435
|
}
|
|
418
436
|
function getOverridePatterns(entries) {
|
|
@@ -493,6 +511,7 @@ export class DefaultPackageManager {
|
|
|
493
511
|
agentDir;
|
|
494
512
|
settingsManager;
|
|
495
513
|
globalNpmRoot;
|
|
514
|
+
globalNpmRootCommandKey;
|
|
496
515
|
progressCallback;
|
|
497
516
|
constructor(options) {
|
|
498
517
|
this.cwd = options.cwd;
|
|
@@ -573,14 +592,14 @@ export class DefaultPackageManager {
|
|
|
573
592
|
const accumulator = this.createAccumulator();
|
|
574
593
|
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
575
594
|
const projectSettings = this.settingsManager.getProjectSettings();
|
|
576
|
-
// Collect all packages with scope
|
|
595
|
+
// Collect all packages with scope (project first so cwd resources win collisions)
|
|
577
596
|
const allPackages = [];
|
|
578
|
-
for (const pkg of globalSettings.packages ?? []) {
|
|
579
|
-
allPackages.push({ pkg, scope: "user" });
|
|
580
|
-
}
|
|
581
597
|
for (const pkg of projectSettings.packages ?? []) {
|
|
582
598
|
allPackages.push({ pkg, scope: "project" });
|
|
583
599
|
}
|
|
600
|
+
for (const pkg of globalSettings.packages ?? []) {
|
|
601
|
+
allPackages.push({ pkg, scope: "user" });
|
|
602
|
+
}
|
|
584
603
|
// Dedupe: project scope wins over global for same package identity
|
|
585
604
|
const packageSources = this.dedupePackages(allPackages);
|
|
586
605
|
await this.resolvePackageSources(packageSources, accumulator, onMissing);
|
|
@@ -590,16 +609,16 @@ export class DefaultPackageManager {
|
|
|
590
609
|
const target = this.getTargetMap(accumulator, resourceType);
|
|
591
610
|
const globalEntries = (globalSettings[resourceType] ?? []);
|
|
592
611
|
const projectEntries = (projectSettings[resourceType] ?? []);
|
|
593
|
-
this.resolveLocalEntries(globalEntries, resourceType, target, {
|
|
594
|
-
source: "local",
|
|
595
|
-
scope: "user",
|
|
596
|
-
origin: "top-level",
|
|
597
|
-
}, globalBaseDir);
|
|
598
612
|
this.resolveLocalEntries(projectEntries, resourceType, target, {
|
|
599
613
|
source: "local",
|
|
600
614
|
scope: "project",
|
|
601
615
|
origin: "top-level",
|
|
602
616
|
}, projectBaseDir);
|
|
617
|
+
this.resolveLocalEntries(globalEntries, resourceType, target, {
|
|
618
|
+
source: "local",
|
|
619
|
+
scope: "user",
|
|
620
|
+
origin: "top-level",
|
|
621
|
+
}, globalBaseDir);
|
|
603
622
|
}
|
|
604
623
|
this.addAutoDiscoveredResources(accumulator, globalSettings, projectSettings, globalBaseDir, projectBaseDir);
|
|
605
624
|
return this.toResolvedPaths(accumulator);
|
|
@@ -669,6 +688,9 @@ export class DefaultPackageManager {
|
|
|
669
688
|
}
|
|
670
689
|
}
|
|
671
690
|
async updateSourceForScope(source, scope) {
|
|
691
|
+
if (isOfflineModeEnabled()) {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
672
694
|
const parsed = this.parseSource(source);
|
|
673
695
|
if (parsed.type === "npm") {
|
|
674
696
|
if (parsed.pinned)
|
|
@@ -687,6 +709,62 @@ export class DefaultPackageManager {
|
|
|
687
709
|
return;
|
|
688
710
|
}
|
|
689
711
|
}
|
|
712
|
+
async checkForAvailableUpdates() {
|
|
713
|
+
if (isOfflineModeEnabled()) {
|
|
714
|
+
return [];
|
|
715
|
+
}
|
|
716
|
+
const globalSettings = this.settingsManager.getGlobalSettings();
|
|
717
|
+
const projectSettings = this.settingsManager.getProjectSettings();
|
|
718
|
+
const allPackages = [];
|
|
719
|
+
for (const pkg of projectSettings.packages ?? []) {
|
|
720
|
+
allPackages.push({ pkg, scope: "project" });
|
|
721
|
+
}
|
|
722
|
+
for (const pkg of globalSettings.packages ?? []) {
|
|
723
|
+
allPackages.push({ pkg, scope: "user" });
|
|
724
|
+
}
|
|
725
|
+
const packageSources = this.dedupePackages(allPackages);
|
|
726
|
+
const checks = packageSources
|
|
727
|
+
.filter((entry) => entry.scope !== "temporary")
|
|
728
|
+
.map((entry) => async () => {
|
|
729
|
+
const source = typeof entry.pkg === "string" ? entry.pkg : entry.pkg.source;
|
|
730
|
+
const parsed = this.parseSource(source);
|
|
731
|
+
if (parsed.type === "local" || parsed.pinned) {
|
|
732
|
+
return undefined;
|
|
733
|
+
}
|
|
734
|
+
if (parsed.type === "npm") {
|
|
735
|
+
const installedPath = this.getNpmInstallPath(parsed, entry.scope);
|
|
736
|
+
if (!existsSync(installedPath)) {
|
|
737
|
+
return undefined;
|
|
738
|
+
}
|
|
739
|
+
const hasUpdate = await this.npmHasAvailableUpdate(parsed, installedPath);
|
|
740
|
+
if (!hasUpdate) {
|
|
741
|
+
return undefined;
|
|
742
|
+
}
|
|
743
|
+
return {
|
|
744
|
+
source,
|
|
745
|
+
displayName: parsed.name,
|
|
746
|
+
type: "npm",
|
|
747
|
+
scope: entry.scope,
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
const installedPath = this.getGitInstallPath(parsed, entry.scope);
|
|
751
|
+
if (!existsSync(installedPath)) {
|
|
752
|
+
return undefined;
|
|
753
|
+
}
|
|
754
|
+
const hasUpdate = await this.gitHasAvailableUpdate(installedPath);
|
|
755
|
+
if (!hasUpdate) {
|
|
756
|
+
return undefined;
|
|
757
|
+
}
|
|
758
|
+
return {
|
|
759
|
+
source,
|
|
760
|
+
displayName: `${parsed.host}/${parsed.path}`,
|
|
761
|
+
type: "git",
|
|
762
|
+
scope: entry.scope,
|
|
763
|
+
};
|
|
764
|
+
});
|
|
765
|
+
const results = await this.runWithConcurrency(checks, UPDATE_CHECK_CONCURRENCY);
|
|
766
|
+
return results.filter((result) => result !== undefined);
|
|
767
|
+
}
|
|
690
768
|
async resolvePackageSources(sources, accumulator, onMissing) {
|
|
691
769
|
for (const { pkg, scope } of sources) {
|
|
692
770
|
const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
|
|
@@ -699,6 +777,9 @@ export class DefaultPackageManager {
|
|
|
699
777
|
continue;
|
|
700
778
|
}
|
|
701
779
|
const installMissing = async () => {
|
|
780
|
+
if (isOfflineModeEnabled()) {
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
702
783
|
if (!onMissing) {
|
|
703
784
|
await this.installParsedSource(parsed, scope);
|
|
704
785
|
return true;
|
|
@@ -713,7 +794,8 @@ export class DefaultPackageManager {
|
|
|
713
794
|
};
|
|
714
795
|
if (parsed.type === "npm") {
|
|
715
796
|
const installedPath = this.getNpmInstallPath(parsed, scope);
|
|
716
|
-
const needsInstall = !existsSync(installedPath) ||
|
|
797
|
+
const needsInstall = !existsSync(installedPath) ||
|
|
798
|
+
(parsed.pinned && !(await this.installedNpmMatchesPinnedVersion(parsed, installedPath)));
|
|
717
799
|
if (needsInstall) {
|
|
718
800
|
const installed = await installMissing();
|
|
719
801
|
if (!installed)
|
|
@@ -730,7 +812,7 @@ export class DefaultPackageManager {
|
|
|
730
812
|
if (!installed)
|
|
731
813
|
continue;
|
|
732
814
|
}
|
|
733
|
-
else if (scope === "temporary" && !parsed.pinned) {
|
|
815
|
+
else if (scope === "temporary" && !parsed.pinned && !isOfflineModeEnabled()) {
|
|
734
816
|
await this.refreshTemporaryGitSource(parsed, sourceStr);
|
|
735
817
|
}
|
|
736
818
|
metadata.baseDir = installedPath;
|
|
@@ -839,27 +921,30 @@ export class DefaultPackageManager {
|
|
|
839
921
|
}
|
|
840
922
|
return { type: "local", path: source };
|
|
841
923
|
}
|
|
842
|
-
|
|
843
|
-
* Check if an npm package needs to be updated.
|
|
844
|
-
* - For unpinned packages: check if registry has a newer version
|
|
845
|
-
* - For pinned packages: check if installed version matches the pinned version
|
|
846
|
-
*/
|
|
847
|
-
async npmNeedsUpdate(source, installedPath) {
|
|
924
|
+
async installedNpmMatchesPinnedVersion(source, installedPath) {
|
|
848
925
|
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
849
|
-
if (!installedVersion)
|
|
850
|
-
return
|
|
926
|
+
if (!installedVersion) {
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
851
929
|
const { version: pinnedVersion } = this.parseNpmSpec(source.spec);
|
|
852
|
-
if (pinnedVersion) {
|
|
853
|
-
|
|
854
|
-
|
|
930
|
+
if (!pinnedVersion) {
|
|
931
|
+
return true;
|
|
932
|
+
}
|
|
933
|
+
return installedVersion === pinnedVersion;
|
|
934
|
+
}
|
|
935
|
+
async npmHasAvailableUpdate(source, installedPath) {
|
|
936
|
+
if (isOfflineModeEnabled()) {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
const installedVersion = this.getInstalledNpmVersion(installedPath);
|
|
940
|
+
if (!installedVersion) {
|
|
941
|
+
return false;
|
|
855
942
|
}
|
|
856
|
-
// Unpinned: check registry for latest version
|
|
857
943
|
try {
|
|
858
944
|
const latestVersion = await this.getLatestNpmVersion(source.name);
|
|
859
945
|
return latestVersion !== installedVersion;
|
|
860
946
|
}
|
|
861
947
|
catch {
|
|
862
|
-
// If we can't check registry, assume it's fine
|
|
863
948
|
return false;
|
|
864
949
|
}
|
|
865
950
|
}
|
|
@@ -877,12 +962,92 @@ export class DefaultPackageManager {
|
|
|
877
962
|
}
|
|
878
963
|
}
|
|
879
964
|
async getLatestNpmVersion(packageName) {
|
|
880
|
-
const response = await fetch(`https://registry.npmjs.org/${packageName}/latest
|
|
965
|
+
const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
|
|
966
|
+
signal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),
|
|
967
|
+
});
|
|
881
968
|
if (!response.ok)
|
|
882
969
|
throw new Error(`Failed to fetch npm registry: ${response.status}`);
|
|
883
970
|
const data = (await response.json());
|
|
884
971
|
return data.version;
|
|
885
972
|
}
|
|
973
|
+
async gitHasAvailableUpdate(installedPath) {
|
|
974
|
+
if (isOfflineModeEnabled()) {
|
|
975
|
+
return false;
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
const localHead = await this.runCommandCapture("git", ["rev-parse", "HEAD"], {
|
|
979
|
+
cwd: installedPath,
|
|
980
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
981
|
+
});
|
|
982
|
+
const remoteHead = await this.getRemoteGitHead(installedPath);
|
|
983
|
+
return localHead.trim() !== remoteHead.trim();
|
|
984
|
+
}
|
|
985
|
+
catch {
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
async getRemoteGitHead(installedPath) {
|
|
990
|
+
const upstreamRef = await this.getGitUpstreamRef(installedPath);
|
|
991
|
+
if (upstreamRef) {
|
|
992
|
+
const remoteHead = await this.runGitRemoteCommand(installedPath, ["ls-remote", "origin", upstreamRef]);
|
|
993
|
+
const match = remoteHead.match(/^([0-9a-f]{40})\s+/m);
|
|
994
|
+
if (match?.[1]) {
|
|
995
|
+
return match[1];
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
const remoteHead = await this.runGitRemoteCommand(installedPath, ["ls-remote", "origin", "HEAD"]);
|
|
999
|
+
const match = remoteHead.match(/^([0-9a-f]{40})\s+HEAD$/m);
|
|
1000
|
+
if (!match?.[1]) {
|
|
1001
|
+
throw new Error("Failed to determine remote HEAD");
|
|
1002
|
+
}
|
|
1003
|
+
return match[1];
|
|
1004
|
+
}
|
|
1005
|
+
async getGitUpstreamRef(installedPath) {
|
|
1006
|
+
try {
|
|
1007
|
+
const upstream = await this.runCommandCapture("git", ["rev-parse", "--abbrev-ref", "@{upstream}"], {
|
|
1008
|
+
cwd: installedPath,
|
|
1009
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1010
|
+
});
|
|
1011
|
+
const trimmed = upstream.trim();
|
|
1012
|
+
if (!trimmed.startsWith("origin/")) {
|
|
1013
|
+
return undefined;
|
|
1014
|
+
}
|
|
1015
|
+
const branch = trimmed.slice("origin/".length);
|
|
1016
|
+
return branch ? `refs/heads/${branch}` : undefined;
|
|
1017
|
+
}
|
|
1018
|
+
catch {
|
|
1019
|
+
return undefined;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
runGitRemoteCommand(installedPath, args) {
|
|
1023
|
+
return this.runCommandCapture("git", args, {
|
|
1024
|
+
cwd: installedPath,
|
|
1025
|
+
timeoutMs: NETWORK_TIMEOUT_MS,
|
|
1026
|
+
env: {
|
|
1027
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
1028
|
+
},
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
async runWithConcurrency(tasks, limit) {
|
|
1032
|
+
if (tasks.length === 0) {
|
|
1033
|
+
return [];
|
|
1034
|
+
}
|
|
1035
|
+
const results = new Array(tasks.length);
|
|
1036
|
+
let nextIndex = 0;
|
|
1037
|
+
const workerCount = Math.max(1, Math.min(limit, tasks.length));
|
|
1038
|
+
const worker = async () => {
|
|
1039
|
+
while (true) {
|
|
1040
|
+
const index = nextIndex;
|
|
1041
|
+
nextIndex += 1;
|
|
1042
|
+
if (index >= tasks.length) {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
results[index] = await tasks[index]();
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
1048
|
+
await Promise.all(Array.from({ length: workerCount }, () => worker()));
|
|
1049
|
+
return results;
|
|
1050
|
+
}
|
|
886
1051
|
/**
|
|
887
1052
|
* Get a unique identity for a package, ignoring version/ref.
|
|
888
1053
|
* Used to detect when the same package is in both global and project settings.
|
|
@@ -935,25 +1100,44 @@ export class DefaultPackageManager {
|
|
|
935
1100
|
const version = match[2];
|
|
936
1101
|
return { name, version };
|
|
937
1102
|
}
|
|
1103
|
+
getNpmCommand() {
|
|
1104
|
+
const configuredCommand = this.settingsManager.getNpmCommand();
|
|
1105
|
+
if (!configuredCommand || configuredCommand.length === 0) {
|
|
1106
|
+
return { command: "npm", args: [] };
|
|
1107
|
+
}
|
|
1108
|
+
const [command, ...args] = configuredCommand;
|
|
1109
|
+
if (!command) {
|
|
1110
|
+
throw new Error("Invalid npmCommand: first array entry must be a non-empty command");
|
|
1111
|
+
}
|
|
1112
|
+
return { command, args };
|
|
1113
|
+
}
|
|
1114
|
+
async runNpmCommand(args, options) {
|
|
1115
|
+
const npmCommand = this.getNpmCommand();
|
|
1116
|
+
await this.runCommand(npmCommand.command, [...npmCommand.args, ...args], options);
|
|
1117
|
+
}
|
|
1118
|
+
runNpmCommandSync(args) {
|
|
1119
|
+
const npmCommand = this.getNpmCommand();
|
|
1120
|
+
return this.runCommandSync(npmCommand.command, [...npmCommand.args, ...args]);
|
|
1121
|
+
}
|
|
938
1122
|
async installNpm(source, scope, temporary) {
|
|
939
1123
|
if (scope === "user" && !temporary) {
|
|
940
|
-
await this.
|
|
1124
|
+
await this.runNpmCommand(["install", "-g", source.spec]);
|
|
941
1125
|
return;
|
|
942
1126
|
}
|
|
943
1127
|
const installRoot = this.getNpmInstallRoot(scope, temporary);
|
|
944
1128
|
this.ensureNpmProject(installRoot);
|
|
945
|
-
await this.
|
|
1129
|
+
await this.runNpmCommand(["install", source.spec, "--prefix", installRoot]);
|
|
946
1130
|
}
|
|
947
1131
|
async uninstallNpm(source, scope) {
|
|
948
1132
|
if (scope === "user") {
|
|
949
|
-
await this.
|
|
1133
|
+
await this.runNpmCommand(["uninstall", "-g", source.name]);
|
|
950
1134
|
return;
|
|
951
1135
|
}
|
|
952
1136
|
const installRoot = this.getNpmInstallRoot(scope, false);
|
|
953
1137
|
if (!existsSync(installRoot)) {
|
|
954
1138
|
return;
|
|
955
1139
|
}
|
|
956
|
-
await this.
|
|
1140
|
+
await this.runNpmCommand(["uninstall", source.name, "--prefix", installRoot]);
|
|
957
1141
|
}
|
|
958
1142
|
async installGit(source, scope) {
|
|
959
1143
|
const targetDir = this.getGitInstallPath(source, scope);
|
|
@@ -971,7 +1155,7 @@ export class DefaultPackageManager {
|
|
|
971
1155
|
}
|
|
972
1156
|
const packageJsonPath = join(targetDir, "package.json");
|
|
973
1157
|
if (existsSync(packageJsonPath)) {
|
|
974
|
-
await this.
|
|
1158
|
+
await this.runNpmCommand(["install"], { cwd: targetDir });
|
|
975
1159
|
}
|
|
976
1160
|
}
|
|
977
1161
|
async updateGit(source, scope) {
|
|
@@ -994,10 +1178,13 @@ export class DefaultPackageManager {
|
|
|
994
1178
|
await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
|
|
995
1179
|
const packageJsonPath = join(targetDir, "package.json");
|
|
996
1180
|
if (existsSync(packageJsonPath)) {
|
|
997
|
-
await this.
|
|
1181
|
+
await this.runNpmCommand(["install"], { cwd: targetDir });
|
|
998
1182
|
}
|
|
999
1183
|
}
|
|
1000
1184
|
async refreshTemporaryGitSource(source, sourceStr) {
|
|
1185
|
+
if (isOfflineModeEnabled()) {
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1001
1188
|
try {
|
|
1002
1189
|
await this.withProgress("pull", sourceStr, `Refreshing ${sourceStr}...`, async () => {
|
|
1003
1190
|
await this.updateGit(source, "temporary");
|
|
@@ -1067,11 +1254,14 @@ export class DefaultPackageManager {
|
|
|
1067
1254
|
return join(this.getGlobalNpmRoot(), "..");
|
|
1068
1255
|
}
|
|
1069
1256
|
getGlobalNpmRoot() {
|
|
1070
|
-
|
|
1257
|
+
const npmCommand = this.getNpmCommand();
|
|
1258
|
+
const commandKey = [npmCommand.command, ...npmCommand.args].join("\0");
|
|
1259
|
+
if (this.globalNpmRoot && this.globalNpmRootCommandKey === commandKey) {
|
|
1071
1260
|
return this.globalNpmRoot;
|
|
1072
1261
|
}
|
|
1073
|
-
const result = this.
|
|
1262
|
+
const result = this.runNpmCommandSync(["root", "-g"]);
|
|
1074
1263
|
this.globalNpmRoot = result.trim();
|
|
1264
|
+
this.globalNpmRootCommandKey = commandKey;
|
|
1075
1265
|
return this.globalNpmRoot;
|
|
1076
1266
|
}
|
|
1077
1267
|
getNpmInstallPath(source, scope) {
|
|
@@ -1120,21 +1310,21 @@ export class DefaultPackageManager {
|
|
|
1120
1310
|
resolvePath(input) {
|
|
1121
1311
|
const trimmed = input.trim();
|
|
1122
1312
|
if (trimmed === "~")
|
|
1123
|
-
return
|
|
1313
|
+
return getHomeDir();
|
|
1124
1314
|
if (trimmed.startsWith("~/"))
|
|
1125
|
-
return join(
|
|
1315
|
+
return join(getHomeDir(), trimmed.slice(2));
|
|
1126
1316
|
if (trimmed.startsWith("~"))
|
|
1127
|
-
return join(
|
|
1317
|
+
return join(getHomeDir(), trimmed.slice(1));
|
|
1128
1318
|
return resolve(this.cwd, trimmed);
|
|
1129
1319
|
}
|
|
1130
1320
|
resolvePathFromBase(input, baseDir) {
|
|
1131
1321
|
const trimmed = input.trim();
|
|
1132
1322
|
if (trimmed === "~")
|
|
1133
|
-
return
|
|
1323
|
+
return getHomeDir();
|
|
1134
1324
|
if (trimmed.startsWith("~/"))
|
|
1135
|
-
return join(
|
|
1325
|
+
return join(getHomeDir(), trimmed.slice(2));
|
|
1136
1326
|
if (trimmed.startsWith("~"))
|
|
1137
|
-
return join(
|
|
1327
|
+
return join(getHomeDir(), trimmed.slice(1));
|
|
1138
1328
|
return resolve(baseDir, trimmed);
|
|
1139
1329
|
}
|
|
1140
1330
|
collectPackageResources(packageRoot, accumulator, filter, metadata) {
|
|
@@ -1308,8 +1498,8 @@ export class DefaultPackageManager {
|
|
|
1308
1498
|
prompts: join(projectBaseDir, "prompts"),
|
|
1309
1499
|
themes: join(projectBaseDir, "themes"),
|
|
1310
1500
|
};
|
|
1311
|
-
const userAgentsSkillsDir = join(
|
|
1312
|
-
const projectAgentsSkillDirs = collectAncestorAgentsSkillDirs(this.cwd);
|
|
1501
|
+
const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
|
|
1502
|
+
const projectAgentsSkillDirs = collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsSkillsDir));
|
|
1313
1503
|
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
1314
1504
|
const target = this.getTargetMap(accumulator, resourceType);
|
|
1315
1505
|
for (const path of paths) {
|
|
@@ -1317,10 +1507,6 @@ export class DefaultPackageManager {
|
|
|
1317
1507
|
this.addResource(target, path, metadata, enabled);
|
|
1318
1508
|
}
|
|
1319
1509
|
};
|
|
1320
|
-
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1321
|
-
addResources("skills", [...collectAutoSkillEntries(userDirs.skills), ...collectAutoSkillEntries(userAgentsSkillsDir)], userMetadata, userOverrides.skills, globalBaseDir);
|
|
1322
|
-
addResources("prompts", collectAutoPromptEntries(userDirs.prompts), userMetadata, userOverrides.prompts, globalBaseDir);
|
|
1323
|
-
addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
|
|
1324
1510
|
addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
|
|
1325
1511
|
addResources("skills", [
|
|
1326
1512
|
...collectAutoSkillEntries(projectDirs.skills),
|
|
@@ -1328,6 +1514,10 @@ export class DefaultPackageManager {
|
|
|
1328
1514
|
], projectMetadata, projectOverrides.skills, projectBaseDir);
|
|
1329
1515
|
addResources("prompts", collectAutoPromptEntries(projectDirs.prompts), projectMetadata, projectOverrides.prompts, projectBaseDir);
|
|
1330
1516
|
addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
|
|
1517
|
+
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1518
|
+
addResources("skills", [...collectAutoSkillEntries(userDirs.skills), ...collectAutoSkillEntries(userAgentsSkillsDir)], userMetadata, userOverrides.skills, globalBaseDir);
|
|
1519
|
+
addResources("prompts", collectAutoPromptEntries(userDirs.prompts), userMetadata, userOverrides.prompts, globalBaseDir);
|
|
1520
|
+
addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
|
|
1331
1521
|
}
|
|
1332
1522
|
collectFilesFromPaths(paths, resourceType) {
|
|
1333
1523
|
const files = [];
|
|
@@ -1393,6 +1583,49 @@ export class DefaultPackageManager {
|
|
|
1393
1583
|
themes: toResolved(accumulator.themes),
|
|
1394
1584
|
};
|
|
1395
1585
|
}
|
|
1586
|
+
runCommandCapture(command, args, options) {
|
|
1587
|
+
return new Promise((resolvePromise, reject) => {
|
|
1588
|
+
const child = spawn(command, args, {
|
|
1589
|
+
cwd: options?.cwd,
|
|
1590
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1591
|
+
shell: process.platform === "win32",
|
|
1592
|
+
env: options?.env ? { ...process.env, ...options.env } : process.env,
|
|
1593
|
+
});
|
|
1594
|
+
let stdout = "";
|
|
1595
|
+
let stderr = "";
|
|
1596
|
+
let timedOut = false;
|
|
1597
|
+
const timeout = typeof options?.timeoutMs === "number"
|
|
1598
|
+
? setTimeout(() => {
|
|
1599
|
+
timedOut = true;
|
|
1600
|
+
child.kill();
|
|
1601
|
+
}, options.timeoutMs)
|
|
1602
|
+
: undefined;
|
|
1603
|
+
child.stdout?.on("data", (data) => {
|
|
1604
|
+
stdout += data.toString();
|
|
1605
|
+
});
|
|
1606
|
+
child.stderr?.on("data", (data) => {
|
|
1607
|
+
stderr += data.toString();
|
|
1608
|
+
});
|
|
1609
|
+
child.on("error", (error) => {
|
|
1610
|
+
if (timeout)
|
|
1611
|
+
clearTimeout(timeout);
|
|
1612
|
+
reject(error);
|
|
1613
|
+
});
|
|
1614
|
+
child.on("exit", (code) => {
|
|
1615
|
+
if (timeout)
|
|
1616
|
+
clearTimeout(timeout);
|
|
1617
|
+
if (timedOut) {
|
|
1618
|
+
reject(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
if (code === 0) {
|
|
1622
|
+
resolvePromise(stdout.trim());
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
reject(new Error(`${command} ${args.join(" ")} failed with code ${code}: ${stderr || stdout}`));
|
|
1626
|
+
});
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1396
1629
|
runCommand(command, args, options) {
|
|
1397
1630
|
return new Promise((resolvePromise, reject) => {
|
|
1398
1631
|
const child = spawn(command, args, {
|