@cydm/pie 1.0.7 → 1.0.9
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 +10 -5
- package/dist/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/init/index.js +70 -68
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +10 -65
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/builtin/skills/browser-tools/SKILL.md +14 -14
- package/dist/chunks/{chunk-BHNULR7U.js → chunk-EJGQAAKS.js} +841 -433
- package/dist/chunks/chunk-NTYHFBUA.js +36 -0
- package/dist/chunks/{chunk-GDTN4UPJ.js → chunk-XHZP5EK4.js} +297 -9
- package/dist/cli.js +570 -488
- package/package.json +2 -2
- package/dist/builtin/skills/pie-unity-rpc/SKILL.md +0 -121
- package/dist/builtin/skills/pie-unity-rpc/pie-unity-rpc.js +0 -417
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
-
createCliHostCapabilities
|
|
5
|
-
|
|
4
|
+
createCliHostCapabilities,
|
|
5
|
+
createCliWebResearchHealthStore,
|
|
6
|
+
getAgentDir,
|
|
7
|
+
getBuiltinDir,
|
|
8
|
+
getConfigDir,
|
|
9
|
+
getCustomThemesDir,
|
|
10
|
+
getLogsDir,
|
|
11
|
+
getPackageDir,
|
|
12
|
+
getRuntimeLogPath,
|
|
13
|
+
getSessionsDir,
|
|
14
|
+
getSettingsPath,
|
|
15
|
+
getThemesDir,
|
|
16
|
+
migrateConfigFromAgentDir
|
|
17
|
+
} from "./chunks/chunk-XHZP5EK4.js";
|
|
6
18
|
import {
|
|
19
|
+
AGENTS_CONTEXT_FILE_NAME,
|
|
7
20
|
AgentSessionController,
|
|
8
21
|
BUILTIN_TOOL_CAPABILITY_METADATA,
|
|
9
22
|
SessionTraceSnapshotWriter,
|
|
10
23
|
abortExecutionState,
|
|
11
24
|
attachAgentEventsToSessionTrace,
|
|
12
25
|
buildExecutionReminder,
|
|
13
|
-
|
|
14
|
-
buildKnowledgeIndexSection,
|
|
26
|
+
buildProjectContextSection,
|
|
15
27
|
buildToolsPromptSection,
|
|
16
28
|
calculateTotalTokens,
|
|
17
29
|
continueExecutionState,
|
|
@@ -21,11 +33,9 @@ import {
|
|
|
21
33
|
createExecutionStateStore,
|
|
22
34
|
createPolicyEnforcedTools,
|
|
23
35
|
createReadFileUnderstandingHandler,
|
|
24
|
-
createReadResourceCapability,
|
|
25
|
-
createReadSkillCapability,
|
|
26
|
-
createResolveResourceCapability,
|
|
27
36
|
createSessionManager,
|
|
28
37
|
createSharedFileSystemTools,
|
|
38
|
+
createSharedWebSearchTool,
|
|
29
39
|
createTodoWidgetView,
|
|
30
40
|
evaluateTodoClosureAfterAbort,
|
|
31
41
|
evaluateTodoClosureAfterCompletedTurn,
|
|
@@ -35,13 +45,14 @@ import {
|
|
|
35
45
|
hasInteractionHandler,
|
|
36
46
|
maybeAdvanceTodoExecutionState,
|
|
37
47
|
modalityForReadFileUnderstandingKind,
|
|
48
|
+
pauseExecutionState,
|
|
38
49
|
registerInteractionHandler,
|
|
39
50
|
requestInteraction,
|
|
40
51
|
restoreExecutionState,
|
|
41
52
|
selectToolsForRuntimePolicy,
|
|
42
53
|
shouldPreserveExecutionStateForUserText,
|
|
43
54
|
supersedeExecutionState
|
|
44
|
-
} from "./chunks/chunk-
|
|
55
|
+
} from "./chunks/chunk-EJGQAAKS.js";
|
|
45
56
|
import {
|
|
46
57
|
Deref,
|
|
47
58
|
Errors,
|
|
@@ -76,6 +87,9 @@ import {
|
|
|
76
87
|
sortToolModelCandidatesByCapability,
|
|
77
88
|
type_exports
|
|
78
89
|
} from "./chunks/chunk-A5JSJAPK.js";
|
|
90
|
+
import {
|
|
91
|
+
resolveCliProjectRoot
|
|
92
|
+
} from "./chunks/chunk-NTYHFBUA.js";
|
|
79
93
|
import {
|
|
80
94
|
__commonJS,
|
|
81
95
|
__require,
|
|
@@ -1883,7 +1897,7 @@ var require_core = __commonJS({
|
|
|
1883
1897
|
return match && match.index === 0;
|
|
1884
1898
|
}
|
|
1885
1899
|
var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
|
|
1886
|
-
function
|
|
1900
|
+
function join19(regexps, separator = "|") {
|
|
1887
1901
|
let numCaptures = 0;
|
|
1888
1902
|
return regexps.map((regex) => {
|
|
1889
1903
|
numCaptures += 1;
|
|
@@ -2187,7 +2201,7 @@ var require_core = __commonJS({
|
|
|
2187
2201
|
this.exec = () => null;
|
|
2188
2202
|
}
|
|
2189
2203
|
const terminators = this.regexes.map((el) => el[1]);
|
|
2190
|
-
this.matcherRe = langRe(
|
|
2204
|
+
this.matcherRe = langRe(join19(terminators), true);
|
|
2191
2205
|
this.lastIndex = 0;
|
|
2192
2206
|
}
|
|
2193
2207
|
/** @param {string} s */
|
|
@@ -14049,7 +14063,7 @@ var require_http = __commonJS({
|
|
|
14049
14063
|
return joined;
|
|
14050
14064
|
}
|
|
14051
14065
|
function http(hljs) {
|
|
14052
|
-
const
|
|
14066
|
+
const VERSION = "HTTP/(2|1\\.[01])";
|
|
14053
14067
|
const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/;
|
|
14054
14068
|
const HEADER = {
|
|
14055
14069
|
className: "attribute",
|
|
@@ -14082,12 +14096,12 @@ var require_http = __commonJS({
|
|
|
14082
14096
|
contains: [
|
|
14083
14097
|
// response
|
|
14084
14098
|
{
|
|
14085
|
-
begin: "^(?=" +
|
|
14099
|
+
begin: "^(?=" + VERSION + " \\d{3})",
|
|
14086
14100
|
end: /$/,
|
|
14087
14101
|
contains: [
|
|
14088
14102
|
{
|
|
14089
14103
|
className: "meta",
|
|
14090
|
-
begin:
|
|
14104
|
+
begin: VERSION
|
|
14091
14105
|
},
|
|
14092
14106
|
{
|
|
14093
14107
|
className: "number",
|
|
@@ -14102,7 +14116,7 @@ var require_http = __commonJS({
|
|
|
14102
14116
|
},
|
|
14103
14117
|
// request
|
|
14104
14118
|
{
|
|
14105
|
-
begin: "(?=^[A-Z]+ (.*?) " +
|
|
14119
|
+
begin: "(?=^[A-Z]+ (.*?) " + VERSION + "$)",
|
|
14106
14120
|
end: /$/,
|
|
14107
14121
|
contains: [
|
|
14108
14122
|
{
|
|
@@ -14114,7 +14128,7 @@ var require_http = __commonJS({
|
|
|
14114
14128
|
},
|
|
14115
14129
|
{
|
|
14116
14130
|
className: "meta",
|
|
14117
|
-
begin:
|
|
14131
|
+
begin: VERSION
|
|
14118
14132
|
},
|
|
14119
14133
|
{
|
|
14120
14134
|
className: "keyword",
|
|
@@ -50554,7 +50568,7 @@ var ProcessTerminal = class {
|
|
|
50554
50568
|
const timeLeft = endTime - now;
|
|
50555
50569
|
if (timeLeft <= 0) break;
|
|
50556
50570
|
if (now - lastDataTime >= idleMs) break;
|
|
50557
|
-
await new Promise((
|
|
50571
|
+
await new Promise((resolve4) => setTimeout(resolve4, Math.min(idleMs, timeLeft)));
|
|
50558
50572
|
}
|
|
50559
50573
|
} finally {
|
|
50560
50574
|
process.stdin.removeListener("data", onData);
|
|
@@ -50629,120 +50643,8 @@ var ProcessTerminal = class {
|
|
|
50629
50643
|
};
|
|
50630
50644
|
|
|
50631
50645
|
// src/keybindings.ts
|
|
50632
|
-
import { existsSync
|
|
50633
|
-
import { join as
|
|
50634
|
-
|
|
50635
|
-
// src/config.ts
|
|
50636
|
-
import { existsSync, mkdirSync as mkdirSync2, readFileSync, renameSync } from "fs";
|
|
50637
|
-
import { homedir as homedir2 } from "os";
|
|
50638
|
-
import { dirname as dirname2, join as join2 } from "path";
|
|
50639
|
-
import { fileURLToPath } from "url";
|
|
50640
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
50641
|
-
var __dirname = dirname2(__filename);
|
|
50642
|
-
var isBunRuntime = !!process.versions.bun;
|
|
50643
|
-
function getPackageDir() {
|
|
50644
|
-
const envDir = process.env.PIE_PACKAGE_DIR;
|
|
50645
|
-
if (envDir) {
|
|
50646
|
-
if (envDir === "~") return homedir2();
|
|
50647
|
-
if (envDir.startsWith("~/")) return homedir2() + envDir.slice(1);
|
|
50648
|
-
return envDir;
|
|
50649
|
-
}
|
|
50650
|
-
let dir = __dirname;
|
|
50651
|
-
while (dir !== dirname2(dir)) {
|
|
50652
|
-
if (existsSync(join2(dir, "package.json"))) {
|
|
50653
|
-
return dir;
|
|
50654
|
-
}
|
|
50655
|
-
dir = dirname2(dir);
|
|
50656
|
-
}
|
|
50657
|
-
return __dirname;
|
|
50658
|
-
}
|
|
50659
|
-
function getThemesDir() {
|
|
50660
|
-
const packageDir = getPackageDir();
|
|
50661
|
-
const srcOrDist = existsSync(join2(packageDir, "src")) ? "src" : "dist";
|
|
50662
|
-
return join2(packageDir, srcOrDist, "theme");
|
|
50663
|
-
}
|
|
50664
|
-
function getBuiltinDir() {
|
|
50665
|
-
const packageDir = getPackageDir();
|
|
50666
|
-
const distBuiltinDir = join2(packageDir, "dist", "builtin");
|
|
50667
|
-
if (existsSync(distBuiltinDir)) {
|
|
50668
|
-
return distBuiltinDir;
|
|
50669
|
-
}
|
|
50670
|
-
return join2(packageDir, "builtin");
|
|
50671
|
-
}
|
|
50672
|
-
function getPackageJsonPath() {
|
|
50673
|
-
return join2(getPackageDir(), "package.json");
|
|
50674
|
-
}
|
|
50675
|
-
var pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
|
|
50676
|
-
var CONFIG_DIR_NAME = ".pie";
|
|
50677
|
-
var VERSION = pkg.version;
|
|
50678
|
-
var ENV_AGENT_DIR = "PIE_CODING_AGENT_DIR";
|
|
50679
|
-
function getConfigDir() {
|
|
50680
|
-
const envDir = process.env[ENV_AGENT_DIR];
|
|
50681
|
-
if (envDir) {
|
|
50682
|
-
if (envDir === "~") return homedir2();
|
|
50683
|
-
if (envDir.startsWith("~/")) return homedir2() + envDir.slice(1);
|
|
50684
|
-
return envDir;
|
|
50685
|
-
}
|
|
50686
|
-
return join2(homedir2(), CONFIG_DIR_NAME);
|
|
50687
|
-
}
|
|
50688
|
-
function getAgentDir() {
|
|
50689
|
-
return getConfigDir();
|
|
50690
|
-
}
|
|
50691
|
-
function getCustomThemesDir() {
|
|
50692
|
-
return join2(getConfigDir(), "themes");
|
|
50693
|
-
}
|
|
50694
|
-
function getSettingsPath() {
|
|
50695
|
-
return join2(getConfigDir(), "settings.json");
|
|
50696
|
-
}
|
|
50697
|
-
function getSessionsDir() {
|
|
50698
|
-
return join2(getConfigDir(), "sessions");
|
|
50699
|
-
}
|
|
50700
|
-
function getLogsDir() {
|
|
50701
|
-
return join2(getConfigDir(), "logs");
|
|
50702
|
-
}
|
|
50703
|
-
function getRuntimeLogPath() {
|
|
50704
|
-
return join2(getLogsDir(), "pie-cli.log");
|
|
50705
|
-
}
|
|
50706
|
-
function migrateConfigFromAgentDir() {
|
|
50707
|
-
const oldAgentDir = join2(homedir2(), CONFIG_DIR_NAME, "agent");
|
|
50708
|
-
const newConfigDir = getConfigDir();
|
|
50709
|
-
if (!existsSync(oldAgentDir)) {
|
|
50710
|
-
return;
|
|
50711
|
-
}
|
|
50712
|
-
if (!existsSync(newConfigDir)) {
|
|
50713
|
-
mkdirSync2(newConfigDir, { recursive: true });
|
|
50714
|
-
}
|
|
50715
|
-
const filesToMigrate = [
|
|
50716
|
-
"keybindings.json",
|
|
50717
|
-
"settings.json",
|
|
50718
|
-
"pie-debug.log"
|
|
50719
|
-
];
|
|
50720
|
-
for (const file of filesToMigrate) {
|
|
50721
|
-
const oldPath = join2(oldAgentDir, file);
|
|
50722
|
-
const newPath = file === "pie-debug.log" ? getRuntimeLogPath() : join2(newConfigDir, file);
|
|
50723
|
-
if (existsSync(oldPath) && !existsSync(newPath)) {
|
|
50724
|
-
try {
|
|
50725
|
-
if (file === "pie-debug.log") {
|
|
50726
|
-
mkdirSync2(getLogsDir(), { recursive: true });
|
|
50727
|
-
}
|
|
50728
|
-
renameSync(oldPath, newPath);
|
|
50729
|
-
console.log(`[Config] Migrated ${file} to ${newPath}`);
|
|
50730
|
-
} catch (e) {
|
|
50731
|
-
}
|
|
50732
|
-
}
|
|
50733
|
-
}
|
|
50734
|
-
const oldThemesDir = join2(oldAgentDir, "themes");
|
|
50735
|
-
const newThemesDir = getCustomThemesDir();
|
|
50736
|
-
if (existsSync(oldThemesDir) && !existsSync(newThemesDir)) {
|
|
50737
|
-
try {
|
|
50738
|
-
renameSync(oldThemesDir, newThemesDir);
|
|
50739
|
-
console.log(`[Config] Migrated themes to ${newThemesDir}`);
|
|
50740
|
-
} catch (e) {
|
|
50741
|
-
}
|
|
50742
|
-
}
|
|
50743
|
-
}
|
|
50744
|
-
|
|
50745
|
-
// src/keybindings.ts
|
|
50646
|
+
import { existsSync, readFileSync } from "fs";
|
|
50647
|
+
import { join as join2 } from "path";
|
|
50746
50648
|
var DEFAULT_APP_KEYBINDINGS = {
|
|
50747
50649
|
interrupt: "escape",
|
|
50748
50650
|
clear: "ctrl+c",
|
|
@@ -50804,7 +50706,7 @@ var KeybindingsManager = class _KeybindingsManager {
|
|
|
50804
50706
|
* Create from config file and set up editor keybindings.
|
|
50805
50707
|
*/
|
|
50806
50708
|
static create(agentDir = getAgentDir()) {
|
|
50807
|
-
const configPath =
|
|
50709
|
+
const configPath = join2(agentDir, "keybindings.json");
|
|
50808
50710
|
const config = _KeybindingsManager.loadFromFile(configPath);
|
|
50809
50711
|
const manager = new _KeybindingsManager(config);
|
|
50810
50712
|
const editorConfig = {};
|
|
@@ -50823,9 +50725,9 @@ var KeybindingsManager = class _KeybindingsManager {
|
|
|
50823
50725
|
return new _KeybindingsManager(config);
|
|
50824
50726
|
}
|
|
50825
50727
|
static loadFromFile(path26) {
|
|
50826
|
-
if (!
|
|
50728
|
+
if (!existsSync(path26)) return {};
|
|
50827
50729
|
try {
|
|
50828
|
-
return JSON.parse(
|
|
50730
|
+
return JSON.parse(readFileSync(path26, "utf-8"));
|
|
50829
50731
|
} catch {
|
|
50830
50732
|
return {};
|
|
50831
50733
|
}
|
|
@@ -50876,21 +50778,70 @@ var KeybindingsManager = class _KeybindingsManager {
|
|
|
50876
50778
|
// src/project-knowledge.ts
|
|
50877
50779
|
import fs3 from "node:fs";
|
|
50878
50780
|
import path2 from "node:path";
|
|
50879
|
-
function
|
|
50880
|
-
const
|
|
50881
|
-
|
|
50882
|
-
|
|
50883
|
-
|
|
50884
|
-
|
|
50885
|
-
|
|
50886
|
-
|
|
50887
|
-
|
|
50781
|
+
function collectAncestorAgentsFiles(cwd) {
|
|
50782
|
+
const resolvedCwd = path2.resolve(cwd || process.cwd());
|
|
50783
|
+
const projectRoot = resolveCliProjectRoot(resolvedCwd);
|
|
50784
|
+
const candidates = [];
|
|
50785
|
+
let current = resolvedCwd;
|
|
50786
|
+
while (true) {
|
|
50787
|
+
candidates.unshift(path2.join(current, AGENTS_CONTEXT_FILE_NAME));
|
|
50788
|
+
if (current === projectRoot) {
|
|
50789
|
+
break;
|
|
50790
|
+
}
|
|
50791
|
+
const parent = path2.dirname(current);
|
|
50792
|
+
if (parent === current) {
|
|
50793
|
+
break;
|
|
50794
|
+
}
|
|
50795
|
+
current = parent;
|
|
50796
|
+
}
|
|
50797
|
+
const files = [];
|
|
50798
|
+
for (const candidate of candidates) {
|
|
50799
|
+
if (!fs3.existsSync(candidate)) {
|
|
50800
|
+
continue;
|
|
50801
|
+
}
|
|
50802
|
+
try {
|
|
50803
|
+
files.push({
|
|
50804
|
+
path: path2.relative(resolvedCwd, candidate) || AGENTS_CONTEXT_FILE_NAME,
|
|
50805
|
+
content: fs3.readFileSync(candidate, "utf-8")
|
|
50806
|
+
});
|
|
50807
|
+
} catch {
|
|
50808
|
+
}
|
|
50809
|
+
}
|
|
50810
|
+
return files;
|
|
50811
|
+
}
|
|
50812
|
+
function buildCliProjectContextSection(cwd) {
|
|
50813
|
+
return buildProjectContextSection(collectAncestorAgentsFiles(cwd));
|
|
50814
|
+
}
|
|
50815
|
+
|
|
50816
|
+
// src/file-access-context.ts
|
|
50817
|
+
import * as path3 from "node:path";
|
|
50818
|
+
function uniqueNormalizedPaths(paths) {
|
|
50819
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50820
|
+
const result = [];
|
|
50821
|
+
for (const entry of paths) {
|
|
50822
|
+
const trimmed = String(entry || "").trim();
|
|
50823
|
+
if (!trimmed) continue;
|
|
50824
|
+
const normalized = path3.normalize(trimmed);
|
|
50825
|
+
if (seen.has(normalized)) continue;
|
|
50826
|
+
seen.add(normalized);
|
|
50827
|
+
result.push(normalized);
|
|
50888
50828
|
}
|
|
50829
|
+
return result;
|
|
50830
|
+
}
|
|
50831
|
+
function buildCliFileAccessOptions(params) {
|
|
50832
|
+
return {
|
|
50833
|
+
accessRoots: uniqueNormalizedPaths([
|
|
50834
|
+
resolveCliProjectRoot(params.cwd),
|
|
50835
|
+
params.configDir,
|
|
50836
|
+
...params.skills.map((skill) => skill.baseDir)
|
|
50837
|
+
]),
|
|
50838
|
+
allowlistedDirs: params.allowlistedDirs
|
|
50839
|
+
};
|
|
50889
50840
|
}
|
|
50890
50841
|
|
|
50891
50842
|
// src/theme/theme.ts
|
|
50892
50843
|
import * as fs4 from "node:fs";
|
|
50893
|
-
import * as
|
|
50844
|
+
import * as path4 from "node:path";
|
|
50894
50845
|
|
|
50895
50846
|
// ../../node_modules/@sinclair/typebox/build/esm/compiler/compiler.mjs
|
|
50896
50847
|
var TypeCheck = class {
|
|
@@ -51777,8 +51728,8 @@ var BUILTIN_THEMES;
|
|
|
51777
51728
|
function getBuiltinThemes() {
|
|
51778
51729
|
if (!BUILTIN_THEMES) {
|
|
51779
51730
|
const themesDir = getThemesDir();
|
|
51780
|
-
const darkPath =
|
|
51781
|
-
const lightPath =
|
|
51731
|
+
const darkPath = path4.join(themesDir, "dark.json");
|
|
51732
|
+
const lightPath = path4.join(themesDir, "light.json");
|
|
51782
51733
|
BUILTIN_THEMES = {
|
|
51783
51734
|
dark: JSON.parse(fs4.readFileSync(darkPath, "utf-8")),
|
|
51784
51735
|
light: JSON.parse(fs4.readFileSync(lightPath, "utf-8"))
|
|
@@ -51858,7 +51809,7 @@ function loadThemeJson(name) {
|
|
|
51858
51809
|
throw new Error(`Theme "${name}" does not have a source path for export`);
|
|
51859
51810
|
}
|
|
51860
51811
|
const customThemesDir = getCustomThemesDir();
|
|
51861
|
-
const themePath =
|
|
51812
|
+
const themePath = path4.join(customThemesDir, `${name}.json`);
|
|
51862
51813
|
if (!fs4.existsSync(themePath)) {
|
|
51863
51814
|
throw new Error(`Theme not found: ${name}`);
|
|
51864
51815
|
}
|
|
@@ -51975,7 +51926,7 @@ function startThemeWatcher() {
|
|
|
51975
51926
|
return;
|
|
51976
51927
|
}
|
|
51977
51928
|
const customThemesDir = getCustomThemesDir();
|
|
51978
|
-
const themeFile =
|
|
51929
|
+
const themeFile = path4.join(customThemesDir, `${currentThemeName}.json`);
|
|
51979
51930
|
if (!fs4.existsSync(themeFile)) {
|
|
51980
51931
|
return;
|
|
51981
51932
|
}
|
|
@@ -52165,36 +52116,7 @@ function getEditorTheme() {
|
|
|
52165
52116
|
|
|
52166
52117
|
// src/skills/loader.ts
|
|
52167
52118
|
import * as fs5 from "fs";
|
|
52168
|
-
import * as
|
|
52169
|
-
function inferResourceKind(resourcePath) {
|
|
52170
|
-
const lower = resourcePath.toLowerCase();
|
|
52171
|
-
if (lower.endsWith(".md")) return "document";
|
|
52172
|
-
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".sh") || lower.endsWith(".py")) return "script";
|
|
52173
|
-
return void 0;
|
|
52174
|
-
}
|
|
52175
|
-
function extractResourceRefs(content) {
|
|
52176
|
-
const refs = /* @__PURE__ */ new Map();
|
|
52177
|
-
const patterns = [
|
|
52178
|
-
/`((?:references|scripts|assets|examples)\/[^`\n]+)`/g,
|
|
52179
|
-
/\b((?:references|scripts|assets|examples)\/[A-Za-z0-9._/-]+)/g,
|
|
52180
|
-
/`(\.?\/[A-Za-z0-9._/-]+\.[A-Za-z0-9]+)`/g
|
|
52181
|
-
];
|
|
52182
|
-
for (const pattern of patterns) {
|
|
52183
|
-
for (const match of content.matchAll(pattern)) {
|
|
52184
|
-
const rawPath = String(match[1] || "").trim().replace(/\\/g, "/");
|
|
52185
|
-
if (!rawPath) continue;
|
|
52186
|
-
const normalizedPath = rawPath.replace(/^\.\/+/, "");
|
|
52187
|
-
if (!normalizedPath || normalizedPath.startsWith("/") || normalizedPath.includes("..")) continue;
|
|
52188
|
-
if (!refs.has(normalizedPath)) {
|
|
52189
|
-
refs.set(normalizedPath, {
|
|
52190
|
-
path: normalizedPath,
|
|
52191
|
-
kind: inferResourceKind(normalizedPath)
|
|
52192
|
-
});
|
|
52193
|
-
}
|
|
52194
|
-
}
|
|
52195
|
-
}
|
|
52196
|
-
return Array.from(refs.values());
|
|
52197
|
-
}
|
|
52119
|
+
import * as path5 from "path";
|
|
52198
52120
|
function parseSkillDescription(content) {
|
|
52199
52121
|
const frontmatterMatch = content.match(/^---\n[\s\S]*?description:\s*["']?(.+?)["']?(?:\n|$)/m);
|
|
52200
52122
|
if (frontmatterMatch) return frontmatterMatch[1].trim();
|
|
@@ -52218,9 +52140,9 @@ function loadSkillsFromDir(dir, source) {
|
|
|
52218
52140
|
const entries = fs5.readdirSync(dir, { withFileTypes: true });
|
|
52219
52141
|
for (const entry of entries) {
|
|
52220
52142
|
if (entry.name.startsWith(".")) continue;
|
|
52221
|
-
const fullPath =
|
|
52143
|
+
const fullPath = path5.join(dir, entry.name);
|
|
52222
52144
|
if (entry.isDirectory()) {
|
|
52223
|
-
const skillMdPath =
|
|
52145
|
+
const skillMdPath = path5.join(fullPath, "SKILL.md");
|
|
52224
52146
|
if (fs5.existsSync(skillMdPath)) {
|
|
52225
52147
|
try {
|
|
52226
52148
|
const content = fs5.readFileSync(skillMdPath, "utf-8");
|
|
@@ -52231,8 +52153,7 @@ function loadSkillsFromDir(dir, source) {
|
|
|
52231
52153
|
content,
|
|
52232
52154
|
filePath: skillMdPath,
|
|
52233
52155
|
source,
|
|
52234
|
-
baseDir: fullPath
|
|
52235
|
-
resourceRefs: extractResourceRefs(content)
|
|
52156
|
+
baseDir: fullPath
|
|
52236
52157
|
});
|
|
52237
52158
|
} catch (e) {
|
|
52238
52159
|
diagnostics.push({
|
|
@@ -52253,8 +52174,7 @@ function loadSkillsFromDir(dir, source) {
|
|
|
52253
52174
|
content,
|
|
52254
52175
|
filePath: fullPath,
|
|
52255
52176
|
source,
|
|
52256
|
-
baseDir: dir
|
|
52257
|
-
resourceRefs: extractResourceRefs(content)
|
|
52177
|
+
baseDir: dir
|
|
52258
52178
|
});
|
|
52259
52179
|
} catch (e) {
|
|
52260
52180
|
diagnostics.push({
|
|
@@ -52441,84 +52361,8 @@ function validateSkillName(name) {
|
|
|
52441
52361
|
return { valid: true };
|
|
52442
52362
|
}
|
|
52443
52363
|
|
|
52444
|
-
// src/skills/runtime.ts
|
|
52445
|
-
import * as fs6 from "node:fs";
|
|
52446
|
-
import * as path5 from "node:path";
|
|
52447
|
-
function resolveSkill(skills, name) {
|
|
52448
|
-
return skills.find((entry) => entry.name === name) ?? null;
|
|
52449
|
-
}
|
|
52450
|
-
function resolveSkillResource(skill, resourcePath) {
|
|
52451
|
-
const trimmed = String(resourcePath || "").trim().replace(/\\/g, "/");
|
|
52452
|
-
if (!trimmed || trimmed.startsWith("/") || /^[A-Za-z]:\//.test(trimmed)) {
|
|
52453
|
-
return null;
|
|
52454
|
-
}
|
|
52455
|
-
const segments = trimmed.split("/").filter(Boolean);
|
|
52456
|
-
if (segments.some((segment) => segment === "..")) {
|
|
52457
|
-
return null;
|
|
52458
|
-
}
|
|
52459
|
-
const absolutePath = path5.resolve(skill.baseDir, ...segments);
|
|
52460
|
-
const relativePath = path5.relative(skill.baseDir, absolutePath).replace(/\\/g, "/");
|
|
52461
|
-
if (relativePath.startsWith("../") || relativePath === "..") {
|
|
52462
|
-
return null;
|
|
52463
|
-
}
|
|
52464
|
-
return absolutePath;
|
|
52465
|
-
}
|
|
52466
|
-
function createCliReadSkillTool(skills) {
|
|
52467
|
-
return createReadSkillCapability({
|
|
52468
|
-
resolveSkill(name) {
|
|
52469
|
-
const skill = resolveSkill(skills, name);
|
|
52470
|
-
if (!skill) {
|
|
52471
|
-
return null;
|
|
52472
|
-
}
|
|
52473
|
-
return {
|
|
52474
|
-
name: skill.name,
|
|
52475
|
-
content: skill.content,
|
|
52476
|
-
resources: skill.resourceRefs
|
|
52477
|
-
};
|
|
52478
|
-
}
|
|
52479
|
-
}).tool;
|
|
52480
|
-
}
|
|
52481
|
-
function createCliReadResourceTool(skills) {
|
|
52482
|
-
return createReadResourceCapability({
|
|
52483
|
-
resolveResource(owner, resourcePath) {
|
|
52484
|
-
const skill = resolveSkill(skills, owner);
|
|
52485
|
-
if (!skill) {
|
|
52486
|
-
return null;
|
|
52487
|
-
}
|
|
52488
|
-
const absolutePath = resolveSkillResource(skill, resourcePath);
|
|
52489
|
-
if (!absolutePath || !fs6.existsSync(absolutePath) || !fs6.statSync(absolutePath).isFile()) {
|
|
52490
|
-
return null;
|
|
52491
|
-
}
|
|
52492
|
-
return {
|
|
52493
|
-
owner: skill.name,
|
|
52494
|
-
path: resourcePath.replace(/\\/g, "/").replace(/^\.\/+/, ""),
|
|
52495
|
-
content: fs6.readFileSync(absolutePath, "utf8")
|
|
52496
|
-
};
|
|
52497
|
-
}
|
|
52498
|
-
}).tool;
|
|
52499
|
-
}
|
|
52500
|
-
function createCliResolveResourceTool(skills) {
|
|
52501
|
-
return createResolveResourceCapability({
|
|
52502
|
-
resolveResource(owner, resourcePath) {
|
|
52503
|
-
const skill = resolveSkill(skills, owner);
|
|
52504
|
-
if (!skill) {
|
|
52505
|
-
return null;
|
|
52506
|
-
}
|
|
52507
|
-
const absolutePath = resolveSkillResource(skill, resourcePath);
|
|
52508
|
-
if (!absolutePath || !fs6.existsSync(absolutePath) || !fs6.statSync(absolutePath).isFile()) {
|
|
52509
|
-
return null;
|
|
52510
|
-
}
|
|
52511
|
-
return {
|
|
52512
|
-
owner: skill.name,
|
|
52513
|
-
path: resourcePath.replace(/\\/g, "/").replace(/^\.\/+/, ""),
|
|
52514
|
-
resolvedPath: absolutePath
|
|
52515
|
-
};
|
|
52516
|
-
}
|
|
52517
|
-
}).tool;
|
|
52518
|
-
}
|
|
52519
|
-
|
|
52520
52364
|
// src/debug/file-logger.ts
|
|
52521
|
-
import * as
|
|
52365
|
+
import * as fs6 from "fs";
|
|
52522
52366
|
import * as path6 from "path";
|
|
52523
52367
|
var FileLogger = class {
|
|
52524
52368
|
config = {
|
|
@@ -52560,8 +52404,8 @@ var FileLogger = class {
|
|
|
52560
52404
|
this.config.filePath = filePath;
|
|
52561
52405
|
}
|
|
52562
52406
|
const dir = path6.dirname(this.config.filePath);
|
|
52563
|
-
if (!
|
|
52564
|
-
|
|
52407
|
+
if (!fs6.existsSync(dir)) {
|
|
52408
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
52565
52409
|
}
|
|
52566
52410
|
this.log("file-logger", `File logging enabled: ${this.config.filePath}`);
|
|
52567
52411
|
}
|
|
@@ -52599,8 +52443,8 @@ var FileLogger = class {
|
|
|
52599
52443
|
this.buffer = [];
|
|
52600
52444
|
this.bufferIndex = 0;
|
|
52601
52445
|
this.totalLines = 0;
|
|
52602
|
-
if (
|
|
52603
|
-
|
|
52446
|
+
if (fs6.existsSync(this.config.filePath)) {
|
|
52447
|
+
fs6.writeFileSync(this.config.filePath, "");
|
|
52604
52448
|
}
|
|
52605
52449
|
}
|
|
52606
52450
|
/**
|
|
@@ -52641,8 +52485,8 @@ var FileLogger = class {
|
|
|
52641
52485
|
*/
|
|
52642
52486
|
getStats() {
|
|
52643
52487
|
let size = 0;
|
|
52644
|
-
if (
|
|
52645
|
-
const stats =
|
|
52488
|
+
if (fs6.existsSync(this.config.filePath)) {
|
|
52489
|
+
const stats = fs6.statSync(this.config.filePath);
|
|
52646
52490
|
size = stats.size;
|
|
52647
52491
|
}
|
|
52648
52492
|
return {
|
|
@@ -52656,11 +52500,11 @@ var FileLogger = class {
|
|
|
52656
52500
|
* Read last N lines from file (fallback when buffer is not enough)
|
|
52657
52501
|
*/
|
|
52658
52502
|
readLastLines(count) {
|
|
52659
|
-
if (!
|
|
52503
|
+
if (!fs6.existsSync(this.config.filePath)) {
|
|
52660
52504
|
return [];
|
|
52661
52505
|
}
|
|
52662
52506
|
try {
|
|
52663
|
-
const content =
|
|
52507
|
+
const content = fs6.readFileSync(this.config.filePath, "utf-8");
|
|
52664
52508
|
const lines = content.split("\n").filter(Boolean);
|
|
52665
52509
|
return lines.slice(-count);
|
|
52666
52510
|
} catch {
|
|
@@ -52678,10 +52522,10 @@ var FileLogger = class {
|
|
|
52678
52522
|
const entry = this.formatEntry(level, module, message, data);
|
|
52679
52523
|
try {
|
|
52680
52524
|
const dir = path6.dirname(this.config.filePath);
|
|
52681
|
-
if (!
|
|
52682
|
-
|
|
52525
|
+
if (!fs6.existsSync(dir)) {
|
|
52526
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
52683
52527
|
}
|
|
52684
|
-
|
|
52528
|
+
fs6.appendFileSync(this.config.filePath, entry + "\n");
|
|
52685
52529
|
} catch {
|
|
52686
52530
|
return;
|
|
52687
52531
|
}
|
|
@@ -52770,7 +52614,7 @@ function flushEarlyLogs() {
|
|
|
52770
52614
|
|
|
52771
52615
|
// src/capabilities/read-file-understanding.ts
|
|
52772
52616
|
import * as path15 from "node:path";
|
|
52773
|
-
import * as
|
|
52617
|
+
import * as fs14 from "node:fs/promises";
|
|
52774
52618
|
|
|
52775
52619
|
// src/core/provider-capabilities.ts
|
|
52776
52620
|
var PLATFORM_DISPLAY_NAMES = {
|
|
@@ -52796,7 +52640,7 @@ function getProviderDisplayName(platform2) {
|
|
|
52796
52640
|
}
|
|
52797
52641
|
|
|
52798
52642
|
// src/files/adapters/kimi-adapter.ts
|
|
52799
|
-
import * as
|
|
52643
|
+
import * as fs7 from "node:fs";
|
|
52800
52644
|
import * as path7 from "node:path";
|
|
52801
52645
|
|
|
52802
52646
|
// src/files/errors.ts
|
|
@@ -52937,14 +52781,14 @@ var KimiFileAdapter = class {
|
|
|
52937
52781
|
const fileName = options.sourceName || path7.basename(filePath);
|
|
52938
52782
|
const mimeType = options.mimeType || this.guessMimeType(fileName);
|
|
52939
52783
|
const purpose = this.detectPurpose(filePath, options.purpose, mimeType);
|
|
52940
|
-
const stats =
|
|
52784
|
+
const stats = fs7.statSync(filePath);
|
|
52941
52785
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
52942
52786
|
throw new FileManagerError(
|
|
52943
52787
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
52944
52788
|
`File size ${(stats.size / 1024 / 1024).toFixed(1)}MB exceeds Kimi limit of 100MB`
|
|
52945
52789
|
);
|
|
52946
52790
|
}
|
|
52947
|
-
const fileBuffer =
|
|
52791
|
+
const fileBuffer = fs7.readFileSync(filePath);
|
|
52948
52792
|
const file = new File([fileBuffer], fileName, { type: mimeType });
|
|
52949
52793
|
const formData = new FormData();
|
|
52950
52794
|
formData.append("file", file);
|
|
@@ -53158,7 +53002,7 @@ var KimiFileAdapter = class {
|
|
|
53158
53002
|
};
|
|
53159
53003
|
|
|
53160
53004
|
// src/files/adapters/gemini-adapter.ts
|
|
53161
|
-
import * as
|
|
53005
|
+
import * as fs8 from "node:fs";
|
|
53162
53006
|
import * as path8 from "node:path";
|
|
53163
53007
|
import { Readable } from "node:stream";
|
|
53164
53008
|
var GeminiFileAdapter = class {
|
|
@@ -53216,7 +53060,7 @@ var GeminiFileAdapter = class {
|
|
|
53216
53060
|
// Upload
|
|
53217
53061
|
// ============================================================================
|
|
53218
53062
|
async upload(filePath, options = {}) {
|
|
53219
|
-
const stats =
|
|
53063
|
+
const stats = fs8.statSync(filePath);
|
|
53220
53064
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
53221
53065
|
throw new FileManagerError(
|
|
53222
53066
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
@@ -53255,7 +53099,7 @@ var GeminiFileAdapter = class {
|
|
|
53255
53099
|
"No upload URL received"
|
|
53256
53100
|
);
|
|
53257
53101
|
}
|
|
53258
|
-
const fileStream = Readable.toWeb(
|
|
53102
|
+
const fileStream = Readable.toWeb(fs8.createReadStream(filePath));
|
|
53259
53103
|
const uploadResponse = await fetch(uploadUrl, {
|
|
53260
53104
|
method: "POST",
|
|
53261
53105
|
headers: {
|
|
@@ -53459,7 +53303,7 @@ var GeminiFileAdapter = class {
|
|
|
53459
53303
|
};
|
|
53460
53304
|
|
|
53461
53305
|
// src/files/adapters/openai-compatible-files-adapter.ts
|
|
53462
|
-
import * as
|
|
53306
|
+
import * as fs9 from "node:fs";
|
|
53463
53307
|
import * as path9 from "node:path";
|
|
53464
53308
|
var OpenAICompatibleFilesAdapter = class {
|
|
53465
53309
|
constructor(apiKey, baseUrl, extraHeaders = {}) {
|
|
@@ -53488,14 +53332,14 @@ var OpenAICompatibleFilesAdapter = class {
|
|
|
53488
53332
|
async upload(filePath, options = {}) {
|
|
53489
53333
|
const fileName = options.sourceName || path9.basename(filePath);
|
|
53490
53334
|
const mimeType = options.mimeType || guessMimeType(fileName);
|
|
53491
|
-
const stats =
|
|
53335
|
+
const stats = fs9.statSync(filePath);
|
|
53492
53336
|
if (stats.size > this.capabilities.maxFileSize) {
|
|
53493
53337
|
throw new FileManagerError(
|
|
53494
53338
|
"FILE_TOO_LARGE" /* FILE_TOO_LARGE */,
|
|
53495
53339
|
`File size ${(stats.size / 1024 / 1024).toFixed(1)}MB exceeds OpenAI-compatible Files limit of ${this.capabilities.maxFileSize / 1024 / 1024}MB`
|
|
53496
53340
|
);
|
|
53497
53341
|
}
|
|
53498
|
-
const file = new File([
|
|
53342
|
+
const file = new File([fs9.readFileSync(filePath)], fileName, { type: mimeType });
|
|
53499
53343
|
const formData = new FormData();
|
|
53500
53344
|
formData.append("file", file);
|
|
53501
53345
|
formData.append("purpose", options.purpose && options.purpose !== "auto" ? options.purpose : "file-extract");
|
|
@@ -53628,12 +53472,12 @@ function guessMimeType(filename) {
|
|
|
53628
53472
|
}
|
|
53629
53473
|
|
|
53630
53474
|
// src/files/file-manager.ts
|
|
53631
|
-
import * as
|
|
53475
|
+
import * as fs13 from "node:fs";
|
|
53632
53476
|
import * as path14 from "node:path";
|
|
53633
53477
|
import * as crypto2 from "node:crypto";
|
|
53634
53478
|
|
|
53635
53479
|
// src/files/file-cache.ts
|
|
53636
|
-
import * as
|
|
53480
|
+
import * as fs10 from "node:fs";
|
|
53637
53481
|
import * as path11 from "node:path";
|
|
53638
53482
|
import * as crypto from "node:crypto";
|
|
53639
53483
|
|
|
@@ -53730,6 +53574,17 @@ var DEFAULT_PIC_OPTIONS = {
|
|
|
53730
53574
|
|
|
53731
53575
|
// src/files/utils.ts
|
|
53732
53576
|
import * as path10 from "node:path";
|
|
53577
|
+
import { homedir as homedir2 } from "node:os";
|
|
53578
|
+
var WINDOWS_ABSOLUTE_PATH_RE = /^(?:[a-zA-Z]:[\\/]|[\\/]{2}[^\\/]+[\\/][^\\/]+)/;
|
|
53579
|
+
function isWindowsAbsolutePath(filePath) {
|
|
53580
|
+
return WINDOWS_ABSOLUTE_PATH_RE.test(filePath);
|
|
53581
|
+
}
|
|
53582
|
+
function getHomeDirectory() {
|
|
53583
|
+
return homedir2() || process.env.USERPROFILE || process.env.HOME || ".";
|
|
53584
|
+
}
|
|
53585
|
+
function looksLikeFilePath(inputPath) {
|
|
53586
|
+
return inputPath.startsWith("/") || inputPath.startsWith("~") || inputPath.startsWith("./") || inputPath.startsWith("../") || inputPath.startsWith(".\\") || inputPath.startsWith("..\\") || isWindowsAbsolutePath(inputPath);
|
|
53587
|
+
}
|
|
53733
53588
|
function formatBytes(bytes) {
|
|
53734
53589
|
if (bytes < 1024) return `${bytes}B`;
|
|
53735
53590
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
@@ -53739,7 +53594,10 @@ function formatBytes(bytes) {
|
|
|
53739
53594
|
}
|
|
53740
53595
|
function resolvePath(inputPath) {
|
|
53741
53596
|
if (inputPath.startsWith("~")) {
|
|
53742
|
-
return path10.join(
|
|
53597
|
+
return path10.join(getHomeDirectory(), inputPath.slice(1));
|
|
53598
|
+
}
|
|
53599
|
+
if (isWindowsAbsolutePath(inputPath)) {
|
|
53600
|
+
return inputPath;
|
|
53743
53601
|
}
|
|
53744
53602
|
if (!path10.isAbsolute(inputPath)) {
|
|
53745
53603
|
return path10.resolve(process.cwd(), inputPath);
|
|
@@ -53780,22 +53638,22 @@ var FileCache = class _FileCache {
|
|
|
53780
53638
|
// Directory Management
|
|
53781
53639
|
// ============================================================================
|
|
53782
53640
|
ensureDirectories() {
|
|
53783
|
-
if (!
|
|
53784
|
-
|
|
53641
|
+
if (!fs10.existsSync(this.baseDir)) {
|
|
53642
|
+
fs10.mkdirSync(this.baseDir, { recursive: true });
|
|
53785
53643
|
}
|
|
53786
|
-
if (!
|
|
53787
|
-
|
|
53644
|
+
if (!fs10.existsSync(this.dataDir)) {
|
|
53645
|
+
fs10.mkdirSync(this.dataDir, { recursive: true });
|
|
53788
53646
|
}
|
|
53789
53647
|
}
|
|
53790
53648
|
// ============================================================================
|
|
53791
53649
|
// Index Management
|
|
53792
53650
|
// ============================================================================
|
|
53793
53651
|
loadIndex() {
|
|
53794
|
-
if (!
|
|
53652
|
+
if (!fs10.existsSync(this.indexPath)) {
|
|
53795
53653
|
return { version: CACHE_VERSION, files: {}, pathHints: {} };
|
|
53796
53654
|
}
|
|
53797
53655
|
try {
|
|
53798
|
-
const data = JSON.parse(
|
|
53656
|
+
const data = JSON.parse(fs10.readFileSync(this.indexPath, "utf-8"));
|
|
53799
53657
|
if (data.version !== CACHE_VERSION) {
|
|
53800
53658
|
cacheLogger.warn(`Index version mismatch: ${data.version} vs ${CACHE_VERSION}`);
|
|
53801
53659
|
}
|
|
@@ -53811,7 +53669,7 @@ var FileCache = class _FileCache {
|
|
|
53811
53669
|
}
|
|
53812
53670
|
saveIndex() {
|
|
53813
53671
|
try {
|
|
53814
|
-
|
|
53672
|
+
fs10.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
|
|
53815
53673
|
} catch (err) {
|
|
53816
53674
|
cacheLogger.error(" Failed to save index:", err);
|
|
53817
53675
|
throw err;
|
|
@@ -53821,11 +53679,11 @@ var FileCache = class _FileCache {
|
|
|
53821
53679
|
// Hash Computation
|
|
53822
53680
|
// ============================================================================
|
|
53823
53681
|
async computeHash(filePath) {
|
|
53824
|
-
return new Promise((
|
|
53682
|
+
return new Promise((resolve4, reject) => {
|
|
53825
53683
|
const hash = crypto.createHash("sha256");
|
|
53826
|
-
const stream =
|
|
53684
|
+
const stream = fs10.createReadStream(filePath);
|
|
53827
53685
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
53828
|
-
stream.on("end", () =>
|
|
53686
|
+
stream.on("end", () => resolve4(hash.digest("hex")));
|
|
53829
53687
|
stream.on("error", reject);
|
|
53830
53688
|
});
|
|
53831
53689
|
}
|
|
@@ -53838,8 +53696,8 @@ var FileCache = class _FileCache {
|
|
|
53838
53696
|
getStoragePath(hash) {
|
|
53839
53697
|
const subdir = hash.slice(0, 2);
|
|
53840
53698
|
const fullDir = path11.join(this.dataDir, subdir);
|
|
53841
|
-
if (!
|
|
53842
|
-
|
|
53699
|
+
if (!fs10.existsSync(fullDir)) {
|
|
53700
|
+
fs10.mkdirSync(fullDir, { recursive: true });
|
|
53843
53701
|
}
|
|
53844
53702
|
return path11.join(fullDir, hash);
|
|
53845
53703
|
}
|
|
@@ -53851,11 +53709,11 @@ var FileCache = class _FileCache {
|
|
|
53851
53709
|
const hash = await this.computeHash(sourcePath);
|
|
53852
53710
|
const storagePath = this.getStoragePath(hash);
|
|
53853
53711
|
this.rememberPathHint(sourcePath, hash, name);
|
|
53854
|
-
if (
|
|
53712
|
+
if (fs10.existsSync(storagePath)) {
|
|
53855
53713
|
return { hash, localPath: storagePath };
|
|
53856
53714
|
}
|
|
53857
|
-
|
|
53858
|
-
const stat2 =
|
|
53715
|
+
fs10.copyFileSync(sourcePath, storagePath);
|
|
53716
|
+
const stat2 = fs10.statSync(storagePath);
|
|
53859
53717
|
this.index.files[hash] = {
|
|
53860
53718
|
hash,
|
|
53861
53719
|
name,
|
|
@@ -53872,10 +53730,10 @@ var FileCache = class _FileCache {
|
|
|
53872
53730
|
async storeBuffer(data, name, mimeType) {
|
|
53873
53731
|
const hash = this.computeHashSync(data);
|
|
53874
53732
|
const storagePath = this.getStoragePath(hash);
|
|
53875
|
-
if (
|
|
53733
|
+
if (fs10.existsSync(storagePath)) {
|
|
53876
53734
|
return { hash, localPath: storagePath };
|
|
53877
53735
|
}
|
|
53878
|
-
|
|
53736
|
+
fs10.writeFileSync(storagePath, data);
|
|
53879
53737
|
this.index.files[hash] = {
|
|
53880
53738
|
hash,
|
|
53881
53739
|
name,
|
|
@@ -53947,7 +53805,7 @@ var FileCache = class _FileCache {
|
|
|
53947
53805
|
getPathHint(filePath) {
|
|
53948
53806
|
try {
|
|
53949
53807
|
const resolvedPath = this.getResolvedHintPath(filePath);
|
|
53950
|
-
const stat2 =
|
|
53808
|
+
const stat2 = fs10.statSync(resolvedPath);
|
|
53951
53809
|
if (!stat2.isFile()) return void 0;
|
|
53952
53810
|
const normalizedMtimeMs = this.normalizeHintMtimeMs(stat2.mtimeMs);
|
|
53953
53811
|
const key = this.getPathHintKey(resolvedPath);
|
|
@@ -53977,7 +53835,7 @@ var FileCache = class _FileCache {
|
|
|
53977
53835
|
rememberPathHint(filePath, hash, name) {
|
|
53978
53836
|
try {
|
|
53979
53837
|
const resolvedPath = this.getResolvedHintPath(filePath);
|
|
53980
|
-
const stat2 =
|
|
53838
|
+
const stat2 = fs10.statSync(resolvedPath);
|
|
53981
53839
|
if (!stat2.isFile()) return;
|
|
53982
53840
|
const entry = this.index.files[hash];
|
|
53983
53841
|
const normalizedMtimeMs = this.normalizeHintMtimeMs(stat2.mtimeMs);
|
|
@@ -54036,8 +53894,8 @@ var FileCache = class _FileCache {
|
|
|
54036
53894
|
entry = entry || this.index.files[hash];
|
|
54037
53895
|
if (!entry) return;
|
|
54038
53896
|
const localPath = path11.join(this.dataDir, entry.localPath);
|
|
54039
|
-
if (
|
|
54040
|
-
|
|
53897
|
+
if (fs10.existsSync(localPath)) {
|
|
53898
|
+
fs10.unlinkSync(localPath);
|
|
54041
53899
|
}
|
|
54042
53900
|
delete this.index.files[hash];
|
|
54043
53901
|
if (this.index.pathHints) {
|
|
@@ -54052,8 +53910,8 @@ var FileCache = class _FileCache {
|
|
|
54052
53910
|
clear() {
|
|
54053
53911
|
for (const entry of Object.values(this.index.files)) {
|
|
54054
53912
|
const localPath = path11.join(this.dataDir, entry.localPath);
|
|
54055
|
-
if (
|
|
54056
|
-
|
|
53913
|
+
if (fs10.existsSync(localPath)) {
|
|
53914
|
+
fs10.unlinkSync(localPath);
|
|
54057
53915
|
}
|
|
54058
53916
|
}
|
|
54059
53917
|
this.index = { version: CACHE_VERSION, files: {}, pathHints: {} };
|
|
@@ -54141,7 +53999,7 @@ var FileCache = class _FileCache {
|
|
|
54141
53999
|
getResolvedHintPath(filePath) {
|
|
54142
54000
|
const resolvedPath = resolvePath(filePath);
|
|
54143
54001
|
try {
|
|
54144
|
-
return
|
|
54002
|
+
return fs10.realpathSync.native ? fs10.realpathSync.native(resolvedPath) : fs10.realpathSync(resolvedPath);
|
|
54145
54003
|
} catch {
|
|
54146
54004
|
return resolvedPath;
|
|
54147
54005
|
}
|
|
@@ -54149,7 +54007,7 @@ var FileCache = class _FileCache {
|
|
|
54149
54007
|
};
|
|
54150
54008
|
|
|
54151
54009
|
// src/files/session-file-manager.ts
|
|
54152
|
-
import * as
|
|
54010
|
+
import * as fs11 from "node:fs";
|
|
54153
54011
|
import * as path12 from "node:path";
|
|
54154
54012
|
var INITIAL_REFRESH_BACKOFF_MS = 6e4;
|
|
54155
54013
|
var MAX_REFRESH_BACKOFF_MS = 60 * 60 * 1e3;
|
|
@@ -54174,15 +54032,15 @@ var SessionFileManager = class {
|
|
|
54174
54032
|
// Directory Management
|
|
54175
54033
|
// ============================================================================
|
|
54176
54034
|
ensureDirectories() {
|
|
54177
|
-
if (!
|
|
54178
|
-
|
|
54035
|
+
if (!fs11.existsSync(this.sessionsDir)) {
|
|
54036
|
+
fs11.mkdirSync(this.sessionsDir, { recursive: true });
|
|
54179
54037
|
}
|
|
54180
54038
|
}
|
|
54181
54039
|
// ============================================================================
|
|
54182
54040
|
// State Management
|
|
54183
54041
|
// ============================================================================
|
|
54184
54042
|
loadState() {
|
|
54185
|
-
if (!
|
|
54043
|
+
if (!fs11.existsSync(this.statePath)) {
|
|
54186
54044
|
return {
|
|
54187
54045
|
sessionId: this.sessionId,
|
|
54188
54046
|
lastSyncedAt: 0,
|
|
@@ -54190,7 +54048,7 @@ var SessionFileManager = class {
|
|
|
54190
54048
|
};
|
|
54191
54049
|
}
|
|
54192
54050
|
try {
|
|
54193
|
-
return JSON.parse(
|
|
54051
|
+
return JSON.parse(fs11.readFileSync(this.statePath, "utf-8"));
|
|
54194
54052
|
} catch (err) {
|
|
54195
54053
|
sessionLogger.error(" Failed to load state:", err);
|
|
54196
54054
|
return {
|
|
@@ -54203,12 +54061,12 @@ var SessionFileManager = class {
|
|
|
54203
54061
|
saveState() {
|
|
54204
54062
|
try {
|
|
54205
54063
|
if (Object.keys(this.state.files).length === 0) {
|
|
54206
|
-
if (
|
|
54207
|
-
|
|
54064
|
+
if (fs11.existsSync(this.statePath)) {
|
|
54065
|
+
fs11.unlinkSync(this.statePath);
|
|
54208
54066
|
}
|
|
54209
54067
|
return;
|
|
54210
54068
|
}
|
|
54211
|
-
|
|
54069
|
+
fs11.writeFileSync(this.statePath, JSON.stringify(this.state, null, 2));
|
|
54212
54070
|
} catch (err) {
|
|
54213
54071
|
sessionLogger.error(" Failed to save state:", err);
|
|
54214
54072
|
}
|
|
@@ -54354,7 +54212,7 @@ var SessionFileManager = class {
|
|
|
54354
54212
|
return { success: false, coolingDown: true };
|
|
54355
54213
|
}
|
|
54356
54214
|
const localPath = this.fileCache.getLocalPath(entry.hash);
|
|
54357
|
-
if (!localPath || !
|
|
54215
|
+
if (!localPath || !fs11.existsSync(localPath)) {
|
|
54358
54216
|
sessionLogger.warn(`Local file not found for ${fileId}`);
|
|
54359
54217
|
entry.status = "expired";
|
|
54360
54218
|
entry.error = "Local file missing";
|
|
@@ -54505,15 +54363,15 @@ var SessionFileManager = class {
|
|
|
54505
54363
|
// Static Utilities
|
|
54506
54364
|
// ============================================================================
|
|
54507
54365
|
static cleanupOldSessions(sessionsDir, maxAge = 30 * 24 * 60 * 60 * 1e3) {
|
|
54508
|
-
if (!
|
|
54366
|
+
if (!fs11.existsSync(sessionsDir)) return;
|
|
54509
54367
|
const now = Date.now();
|
|
54510
|
-
const files =
|
|
54368
|
+
const files = fs11.readdirSync(sessionsDir);
|
|
54511
54369
|
for (const file of files) {
|
|
54512
54370
|
if (!file.endsWith(".json")) continue;
|
|
54513
54371
|
const filePath = path12.join(sessionsDir, file);
|
|
54514
|
-
const stat2 =
|
|
54372
|
+
const stat2 = fs11.statSync(filePath);
|
|
54515
54373
|
if (now - stat2.mtime.getTime() > maxAge) {
|
|
54516
|
-
|
|
54374
|
+
fs11.unlinkSync(filePath);
|
|
54517
54375
|
sessionLogger.debug(`Cleaned up old session: ${file}`);
|
|
54518
54376
|
}
|
|
54519
54377
|
}
|
|
@@ -54521,7 +54379,7 @@ var SessionFileManager = class {
|
|
|
54521
54379
|
};
|
|
54522
54380
|
|
|
54523
54381
|
// src/files/ffmpeg-processor.ts
|
|
54524
|
-
import * as
|
|
54382
|
+
import * as fs12 from "node:fs";
|
|
54525
54383
|
import * as path13 from "node:path";
|
|
54526
54384
|
import { spawn } from "node:child_process";
|
|
54527
54385
|
var FFmpegProcessor = class {
|
|
@@ -54535,17 +54393,17 @@ var FFmpegProcessor = class {
|
|
|
54535
54393
|
// Detection
|
|
54536
54394
|
// ============================================================================
|
|
54537
54395
|
async checkAvailability() {
|
|
54538
|
-
return new Promise((
|
|
54396
|
+
return new Promise((resolve4) => {
|
|
54539
54397
|
const proc = spawn(this.ffmpegPath, ["-version"]);
|
|
54540
|
-
proc.on("error", () =>
|
|
54541
|
-
proc.on("exit", (code) =>
|
|
54398
|
+
proc.on("error", () => resolve4(false));
|
|
54399
|
+
proc.on("exit", (code) => resolve4(code === 0));
|
|
54542
54400
|
});
|
|
54543
54401
|
}
|
|
54544
54402
|
// ============================================================================
|
|
54545
54403
|
// Video Analysis
|
|
54546
54404
|
// ============================================================================
|
|
54547
54405
|
async analyzeVideo(videoPath) {
|
|
54548
|
-
return new Promise((
|
|
54406
|
+
return new Promise((resolve4, reject) => {
|
|
54549
54407
|
const args = [
|
|
54550
54408
|
"-v",
|
|
54551
54409
|
"error",
|
|
@@ -54574,7 +54432,7 @@ var FFmpegProcessor = class {
|
|
|
54574
54432
|
}
|
|
54575
54433
|
try {
|
|
54576
54434
|
const info = this.parseProbeOutput(stdout, videoPath);
|
|
54577
|
-
|
|
54435
|
+
resolve4(info);
|
|
54578
54436
|
} catch (err) {
|
|
54579
54437
|
reject(err);
|
|
54580
54438
|
}
|
|
@@ -54657,7 +54515,7 @@ var FFmpegProcessor = class {
|
|
|
54657
54515
|
onProgress?.(percent);
|
|
54658
54516
|
}
|
|
54659
54517
|
});
|
|
54660
|
-
const outputStat =
|
|
54518
|
+
const outputStat = fs12.statSync(outputPath);
|
|
54661
54519
|
return {
|
|
54662
54520
|
type: "video",
|
|
54663
54521
|
output: outputPath,
|
|
@@ -54689,7 +54547,7 @@ var FFmpegProcessor = class {
|
|
|
54689
54547
|
async extractKeyframes(inputPath, outputDir, info, opts, onProgress) {
|
|
54690
54548
|
const interval = Math.floor(info.duration / opts.keyframeCount);
|
|
54691
54549
|
const framesDir = path13.join(outputDir, `keyframes_${Date.now()}`);
|
|
54692
|
-
|
|
54550
|
+
fs12.mkdirSync(framesDir, { recursive: true });
|
|
54693
54551
|
const outputPattern = path13.join(framesDir, "frame_%03d.jpg");
|
|
54694
54552
|
const args = [
|
|
54695
54553
|
"-i",
|
|
@@ -54708,10 +54566,10 @@ var FFmpegProcessor = class {
|
|
|
54708
54566
|
onProgress?.(percent);
|
|
54709
54567
|
}
|
|
54710
54568
|
});
|
|
54711
|
-
let frames =
|
|
54569
|
+
let frames = fs12.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path13.join(framesDir, f));
|
|
54712
54570
|
if (frames.length < opts.keyframeCount / 2) {
|
|
54713
|
-
|
|
54714
|
-
|
|
54571
|
+
fs12.rmSync(framesDir, { recursive: true, force: true });
|
|
54572
|
+
fs12.mkdirSync(framesDir, { recursive: true });
|
|
54715
54573
|
const uniformArgs = [
|
|
54716
54574
|
"-i",
|
|
54717
54575
|
inputPath,
|
|
@@ -54727,10 +54585,10 @@ var FFmpegProcessor = class {
|
|
|
54727
54585
|
onProgress?.(percent);
|
|
54728
54586
|
}
|
|
54729
54587
|
});
|
|
54730
|
-
frames =
|
|
54588
|
+
frames = fs12.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path13.join(framesDir, f));
|
|
54731
54589
|
}
|
|
54732
54590
|
const totalOutputSize = frames.reduce(
|
|
54733
|
-
(sum, f) => sum +
|
|
54591
|
+
(sum, f) => sum + fs12.statSync(f).size,
|
|
54734
54592
|
0
|
|
54735
54593
|
);
|
|
54736
54594
|
return {
|
|
@@ -54769,7 +54627,7 @@ var FFmpegProcessor = class {
|
|
|
54769
54627
|
// FFmpeg Execution
|
|
54770
54628
|
// ============================================================================
|
|
54771
54629
|
runFFmpeg(args) {
|
|
54772
|
-
return new Promise((
|
|
54630
|
+
return new Promise((resolve4, reject) => {
|
|
54773
54631
|
const proc = spawn(this.ffmpegPath, args);
|
|
54774
54632
|
let stderr = "";
|
|
54775
54633
|
proc.stderr.on("data", (data) => {
|
|
@@ -54784,7 +54642,7 @@ var FFmpegProcessor = class {
|
|
|
54784
54642
|
)
|
|
54785
54643
|
);
|
|
54786
54644
|
} else {
|
|
54787
|
-
|
|
54645
|
+
resolve4();
|
|
54788
54646
|
}
|
|
54789
54647
|
});
|
|
54790
54648
|
proc.on("error", (err) => {
|
|
@@ -54801,7 +54659,7 @@ var FFmpegProcessor = class {
|
|
|
54801
54659
|
// Progress Monitoring (for future use)
|
|
54802
54660
|
// ============================================================================
|
|
54803
54661
|
async runWithProgress(args, onProgress) {
|
|
54804
|
-
return new Promise((
|
|
54662
|
+
return new Promise((resolve4, reject) => {
|
|
54805
54663
|
const progressArgs = [
|
|
54806
54664
|
...args,
|
|
54807
54665
|
"-progress",
|
|
@@ -54831,7 +54689,7 @@ var FFmpegProcessor = class {
|
|
|
54831
54689
|
)
|
|
54832
54690
|
);
|
|
54833
54691
|
} else {
|
|
54834
|
-
|
|
54692
|
+
resolve4();
|
|
54835
54693
|
}
|
|
54836
54694
|
});
|
|
54837
54695
|
});
|
|
@@ -54950,8 +54808,8 @@ var FileManager = class {
|
|
|
54950
54808
|
directoryListingCache = /* @__PURE__ */ new Map();
|
|
54951
54809
|
authFingerprint;
|
|
54952
54810
|
ensureDirectories() {
|
|
54953
|
-
if (!
|
|
54954
|
-
|
|
54811
|
+
if (!fs13.existsSync(this.tempDir)) {
|
|
54812
|
+
fs13.mkdirSync(this.tempDir, { recursive: true });
|
|
54955
54813
|
}
|
|
54956
54814
|
}
|
|
54957
54815
|
// ============================================================================
|
|
@@ -54982,7 +54840,7 @@ var FileManager = class {
|
|
|
54982
54840
|
async stageLocal(filePath, options = {}) {
|
|
54983
54841
|
const resolvedPath = resolvePath(filePath);
|
|
54984
54842
|
const sourceName = options.sourceName || path14.basename(resolvedPath);
|
|
54985
|
-
if (!
|
|
54843
|
+
if (!fs13.existsSync(resolvedPath)) {
|
|
54986
54844
|
throw new FileManagerError(
|
|
54987
54845
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
54988
54846
|
`File not found: ${filePath}`
|
|
@@ -54997,7 +54855,7 @@ var FileManager = class {
|
|
|
54997
54855
|
this.fileCache.rememberPathHint(resolvedPath, hash, sourceName);
|
|
54998
54856
|
this.invalidateDirectoryListingCacheForPath(resolvedPath);
|
|
54999
54857
|
const entry = this.fileCache.getByHash(hash);
|
|
55000
|
-
const size = entry?.size ??
|
|
54858
|
+
const size = entry?.size ?? fs13.statSync(resolvedPath).size;
|
|
55001
54859
|
return {
|
|
55002
54860
|
success: true,
|
|
55003
54861
|
hash,
|
|
@@ -55012,7 +54870,7 @@ var FileManager = class {
|
|
|
55012
54870
|
async upload(filePath, options = {}) {
|
|
55013
54871
|
const resolvedPath = resolvePath(filePath);
|
|
55014
54872
|
const sourceName = options.sourceName || path14.basename(resolvedPath);
|
|
55015
|
-
if (!
|
|
54873
|
+
if (!fs13.existsSync(resolvedPath)) {
|
|
55016
54874
|
throw new FileManagerError(
|
|
55017
54875
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
55018
54876
|
`File not found: ${filePath}`
|
|
@@ -55093,7 +54951,7 @@ var FileManager = class {
|
|
|
55093
54951
|
// ============================================================================
|
|
55094
54952
|
async uploadPic(filePath, options = {}) {
|
|
55095
54953
|
const resolvedPath = resolvePath(filePath);
|
|
55096
|
-
if (!
|
|
54954
|
+
if (!fs13.existsSync(resolvedPath)) {
|
|
55097
54955
|
throw new FileManagerError(
|
|
55098
54956
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
55099
54957
|
`File not found: ${filePath}`
|
|
@@ -55123,7 +54981,7 @@ var FileManager = class {
|
|
|
55123
54981
|
this.fileCache.rememberPathHint(resolvedPath, result.hash, path14.basename(resolvedPath));
|
|
55124
54982
|
this.invalidateDirectoryListingCacheForPath(resolvedPath);
|
|
55125
54983
|
try {
|
|
55126
|
-
|
|
54984
|
+
fs13.unlinkSync(optimizedPath);
|
|
55127
54985
|
} catch {
|
|
55128
54986
|
}
|
|
55129
54987
|
return result;
|
|
@@ -55133,7 +54991,7 @@ var FileManager = class {
|
|
|
55133
54991
|
// ============================================================================
|
|
55134
54992
|
async uploadVideo(filePath, options = {}) {
|
|
55135
54993
|
const resolvedPath = resolvePath(filePath);
|
|
55136
|
-
if (!
|
|
54994
|
+
if (!fs13.existsSync(resolvedPath)) {
|
|
55137
54995
|
throw new FileManagerError(
|
|
55138
54996
|
"LOCAL_FILE_MISSING" /* LOCAL_FILE_MISSING */,
|
|
55139
54997
|
`File not found: ${filePath}`
|
|
@@ -55527,13 +55385,13 @@ var FileManager = class {
|
|
|
55527
55385
|
cleanupTempFiles(output) {
|
|
55528
55386
|
try {
|
|
55529
55387
|
if (typeof output === "string") {
|
|
55530
|
-
if (
|
|
55531
|
-
|
|
55388
|
+
if (fs13.existsSync(output)) {
|
|
55389
|
+
fs13.unlinkSync(output);
|
|
55532
55390
|
}
|
|
55533
55391
|
} else {
|
|
55534
55392
|
for (const file of output) {
|
|
55535
|
-
if (
|
|
55536
|
-
|
|
55393
|
+
if (fs13.existsSync(file)) {
|
|
55394
|
+
fs13.unlinkSync(file);
|
|
55537
55395
|
}
|
|
55538
55396
|
}
|
|
55539
55397
|
}
|
|
@@ -55565,7 +55423,7 @@ var FileManager = class {
|
|
|
55565
55423
|
}];
|
|
55566
55424
|
}
|
|
55567
55425
|
const localPath = this.fileCache.getLocalPath(entry.hash);
|
|
55568
|
-
if (localPath &&
|
|
55426
|
+
if (localPath && fs13.existsSync(localPath)) {
|
|
55569
55427
|
return [{
|
|
55570
55428
|
fileId,
|
|
55571
55429
|
name: cacheEntry.name,
|
|
@@ -55662,7 +55520,7 @@ var FileManager = class {
|
|
|
55662
55520
|
directories: []
|
|
55663
55521
|
};
|
|
55664
55522
|
try {
|
|
55665
|
-
const entries =
|
|
55523
|
+
const entries = fs13.readdirSync(resolvedDir, { withFileTypes: true });
|
|
55666
55524
|
for (const entry of entries) {
|
|
55667
55525
|
if (!entry.name || entry.name.startsWith(".")) {
|
|
55668
55526
|
continue;
|
|
@@ -55676,7 +55534,7 @@ var FileManager = class {
|
|
|
55676
55534
|
let isFile = entry.isFile();
|
|
55677
55535
|
if (entry.isSymbolicLink()) {
|
|
55678
55536
|
try {
|
|
55679
|
-
const targetStat =
|
|
55537
|
+
const targetStat = fs13.statSync(fullPath);
|
|
55680
55538
|
isDirectory = targetStat.isDirectory();
|
|
55681
55539
|
isFile = targetStat.isFile();
|
|
55682
55540
|
} catch {
|
|
@@ -55694,7 +55552,7 @@ var FileManager = class {
|
|
|
55694
55552
|
if (!type) {
|
|
55695
55553
|
continue;
|
|
55696
55554
|
}
|
|
55697
|
-
const stat2 =
|
|
55555
|
+
const stat2 = fs13.statSync(fullPath);
|
|
55698
55556
|
listing.files.push({
|
|
55699
55557
|
name: entry.name,
|
|
55700
55558
|
path: fullPath,
|
|
@@ -55793,7 +55651,7 @@ function isInlineMediaRequest(request) {
|
|
|
55793
55651
|
return request.kind === "image" || request.kind === "video";
|
|
55794
55652
|
}
|
|
55795
55653
|
async function prepareInlineMediaContent(params) {
|
|
55796
|
-
const stat2 = await
|
|
55654
|
+
const stat2 = await fs14.stat(params.request.absolutePath);
|
|
55797
55655
|
const limitMb = getCapabilityLimitMb(params.model, params.request.kind);
|
|
55798
55656
|
const limitBytes = limitMb * 1024 * 1024;
|
|
55799
55657
|
if (stat2.size > limitBytes) {
|
|
@@ -55801,7 +55659,7 @@ async function prepareInlineMediaContent(params) {
|
|
|
55801
55659
|
`${params.request.kind} understanding for ${params.model.provider}/${params.model.id} supports inline files up to ${limitMb}MB; ${path15.basename(params.request.displayPath)} is ${(stat2.size / 1024 / 1024).toFixed(1)}MB. Configure a model with a file upload adapter, or compress/trim the file before reading it.`
|
|
55802
55660
|
);
|
|
55803
55661
|
}
|
|
55804
|
-
const data = await
|
|
55662
|
+
const data = await fs14.readFile(params.request.absolutePath, "base64");
|
|
55805
55663
|
const content = params.request.kind === "video" ? [{ type: "video", data, mimeType: params.request.mimeType }] : [{ type: "image", data, mimeType: params.request.mimeType }];
|
|
55806
55664
|
return {
|
|
55807
55665
|
content,
|
|
@@ -55821,7 +55679,7 @@ async function waitForReady(params) {
|
|
|
55821
55679
|
if (status.status === "error" || status.status === "expired") {
|
|
55822
55680
|
throw new Error(`Uploaded file is not ready: ${status.status}${status.error ? ` (${status.error})` : ""}`);
|
|
55823
55681
|
}
|
|
55824
|
-
await new Promise((
|
|
55682
|
+
await new Promise((resolve4) => setTimeout(resolve4, 1500));
|
|
55825
55683
|
}
|
|
55826
55684
|
throw new Error("Timed out waiting for uploaded file to become ready");
|
|
55827
55685
|
}
|
|
@@ -55957,7 +55815,7 @@ var ExecutionStateManager = class {
|
|
|
55957
55815
|
case "aborted":
|
|
55958
55816
|
return "Todo run aborted. Cleared the remaining todo list.";
|
|
55959
55817
|
case "failed_turn":
|
|
55960
|
-
return "Todo run failed during the latest turn.
|
|
55818
|
+
return "Todo run failed during the latest turn. Preserved the todo list and paused automatic continuation.";
|
|
55961
55819
|
case "max_attempts":
|
|
55962
55820
|
return "Todo run reached the maximum follow-up attempts and was cleared as failed.";
|
|
55963
55821
|
case "stagnated":
|
|
@@ -56075,6 +55933,18 @@ var ExecutionStateManager = class {
|
|
|
56075
55933
|
return { changed: false };
|
|
56076
55934
|
}
|
|
56077
55935
|
const decision = evaluateTodoClosureAfterFailedTurn(previous.loop);
|
|
55936
|
+
if (decision.action === "pause_failed") {
|
|
55937
|
+
const paused = pauseExecutionState({
|
|
55938
|
+
...previous,
|
|
55939
|
+
loop: decision.loop
|
|
55940
|
+
}, this.summarizeFailure(decision.reason));
|
|
55941
|
+
this.store.replace(paused);
|
|
55942
|
+
return {
|
|
55943
|
+
changed: true,
|
|
55944
|
+
terminalStatus: "paused",
|
|
55945
|
+
terminalSummary: paused.failureSummary || void 0
|
|
55946
|
+
};
|
|
55947
|
+
}
|
|
56078
55948
|
if (decision.action === "clear_failed") {
|
|
56079
55949
|
this.clearWithSummary(this.summarizeFailure(decision.reason));
|
|
56080
55950
|
return {
|
|
@@ -56086,6 +55956,14 @@ var ExecutionStateManager = class {
|
|
|
56086
55956
|
}
|
|
56087
55957
|
return { changed: false };
|
|
56088
55958
|
}
|
|
55959
|
+
resumePausedTodo() {
|
|
55960
|
+
const previous = this.store.read();
|
|
55961
|
+
if (previous.mode !== "todo" || previous.lifecycle !== "paused" || previous.steps.length === 0) {
|
|
55962
|
+
return { changed: false };
|
|
55963
|
+
}
|
|
55964
|
+
const next = this.store.replace(continueExecutionState(previous));
|
|
55965
|
+
return { changed: !this.unchanged(previous, next) };
|
|
55966
|
+
}
|
|
56089
55967
|
markAwaitingContinuationStalled() {
|
|
56090
55968
|
const previous = this.store.read();
|
|
56091
55969
|
if (previous.mode !== "todo" || !previous.awaitingContinuation) {
|
|
@@ -56123,7 +56001,7 @@ var ExecutionStateManager = class {
|
|
|
56123
56001
|
return null;
|
|
56124
56002
|
}
|
|
56125
56003
|
if (shouldPreserveExecutionStateForUserText(text)) {
|
|
56126
|
-
if (state.lifecycle === "aborted") {
|
|
56004
|
+
if (state.lifecycle === "paused" || state.lifecycle === "aborted") {
|
|
56127
56005
|
this.store.replace(continueExecutionState(state));
|
|
56128
56006
|
return "continued";
|
|
56129
56007
|
}
|
|
@@ -56151,7 +56029,7 @@ var ExecutionStateManager = class {
|
|
|
56151
56029
|
};
|
|
56152
56030
|
|
|
56153
56031
|
// src/session-trace.ts
|
|
56154
|
-
import * as
|
|
56032
|
+
import * as fs15 from "node:fs";
|
|
56155
56033
|
import * as path16 from "node:path";
|
|
56156
56034
|
var SessionTraceWriter = class extends SessionTraceSnapshotWriter {
|
|
56157
56035
|
constructor(sessionsDir, sessionManager) {
|
|
@@ -56159,9 +56037,9 @@ var SessionTraceWriter = class extends SessionTraceSnapshotWriter {
|
|
|
56159
56037
|
getSessionId: () => sessionManager.getActiveSessionId(),
|
|
56160
56038
|
loadTrace: (sessionId) => {
|
|
56161
56039
|
const tracePath = path16.join(sessionsDir, `${sessionId}.trace.json`);
|
|
56162
|
-
if (!
|
|
56040
|
+
if (!fs15.existsSync(tracePath)) return null;
|
|
56163
56041
|
try {
|
|
56164
|
-
return JSON.parse(
|
|
56042
|
+
return JSON.parse(fs15.readFileSync(tracePath, "utf8"));
|
|
56165
56043
|
} catch {
|
|
56166
56044
|
return null;
|
|
56167
56045
|
}
|
|
@@ -56169,8 +56047,8 @@ var SessionTraceWriter = class extends SessionTraceSnapshotWriter {
|
|
|
56169
56047
|
saveTrace: (trace) => {
|
|
56170
56048
|
const tracePath = path16.join(sessionsDir, `${trace.sessionId}.trace.json`);
|
|
56171
56049
|
const tempPath = `${tracePath}.tmp`;
|
|
56172
|
-
|
|
56173
|
-
|
|
56050
|
+
fs15.writeFileSync(tempPath, JSON.stringify(trace, null, 2), "utf8");
|
|
56051
|
+
fs15.renameSync(tempPath, tracePath);
|
|
56174
56052
|
}
|
|
56175
56053
|
});
|
|
56176
56054
|
this.sessionsDir = sessionsDir;
|
|
@@ -56777,7 +56655,7 @@ async function handleCacheTest(host) {
|
|
|
56777
56655
|
host.chatContainer.addChild(new Text(theme.fg("dim", ` ${summarizeUsage(result1.usage)}`), 1, 0));
|
|
56778
56656
|
host.chatContainer.addChild(new Text(theme.fg("dim", " Waiting 2s before replaying identical request..."), 1, 0));
|
|
56779
56657
|
host.ui.requestRender();
|
|
56780
|
-
await new Promise((
|
|
56658
|
+
await new Promise((resolve4) => setTimeout(resolve4, 2e3));
|
|
56781
56659
|
host.chatContainer.addChild(new Text(theme.fg("accent", "Request 2/2: replaying identical request..."), 1, 0));
|
|
56782
56660
|
host.ui.requestRender();
|
|
56783
56661
|
result2 = await completeSimple(model, context, options);
|
|
@@ -58860,7 +58738,7 @@ async function handleForkCommand(host) {
|
|
|
58860
58738
|
}
|
|
58861
58739
|
|
|
58862
58740
|
// src/commands/interactive-skill-commands.ts
|
|
58863
|
-
import * as
|
|
58741
|
+
import * as fs16 from "fs";
|
|
58864
58742
|
import * as os3 from "os";
|
|
58865
58743
|
import * as path17 from "path";
|
|
58866
58744
|
|
|
@@ -59204,7 +59082,7 @@ function expandSkillCommand(host, text) {
|
|
|
59204
59082
|
const skill = host.skills.find((s) => s.name === skillName);
|
|
59205
59083
|
if (!skill) return text;
|
|
59206
59084
|
try {
|
|
59207
|
-
const content =
|
|
59085
|
+
const content = fs16.readFileSync(skill.filePath, "utf-8");
|
|
59208
59086
|
const body = host.stripFrontmatter(content).trim();
|
|
59209
59087
|
const skillBlock = `<skill name="${skill.name}" location="${skill.filePath}">
|
|
59210
59088
|
References are relative to ${skill.baseDir}.
|
|
@@ -59274,13 +59152,13 @@ async function handleSkillsCreate(host, args) {
|
|
|
59274
59152
|
const skillDir = path17.join(skillsDir, name);
|
|
59275
59153
|
const skillFile = path17.join(skillDir, "SKILL.md");
|
|
59276
59154
|
console.error(`[SkillsCreate] Creating at: ${skillFile}`);
|
|
59277
|
-
if (
|
|
59155
|
+
if (fs16.existsSync(skillDir)) {
|
|
59278
59156
|
host.showError(`Skill "${name}" already exists at ${skillDir}`);
|
|
59279
59157
|
return;
|
|
59280
59158
|
}
|
|
59281
|
-
|
|
59159
|
+
fs16.mkdirSync(skillDir, { recursive: true });
|
|
59282
59160
|
const template = createSkillTemplate(name, description);
|
|
59283
|
-
|
|
59161
|
+
fs16.writeFileSync(skillFile, template, "utf-8");
|
|
59284
59162
|
console.error(`[SkillsCreate] Successfully created skill`);
|
|
59285
59163
|
host.chatContainer.addChild(new Spacer(1));
|
|
59286
59164
|
host.chatContainer.addChild(new Text(theme.fg("accent", `\u2713 Created skill: ${name}`), 1, 0));
|
|
@@ -60024,6 +59902,29 @@ async function handleCompactCommand(host) {
|
|
|
60024
59902
|
}
|
|
60025
59903
|
}
|
|
60026
59904
|
|
|
59905
|
+
// src/runtime/footer-lifecycle.ts
|
|
59906
|
+
function messageRole(event) {
|
|
59907
|
+
return String(event.message.role);
|
|
59908
|
+
}
|
|
59909
|
+
function formatFooterLifecycleEvent(event) {
|
|
59910
|
+
switch (event.type) {
|
|
59911
|
+
case "message_start":
|
|
59912
|
+
return `message_start(${messageRole(event)})`;
|
|
59913
|
+
case "message_end":
|
|
59914
|
+
return `message_end(${messageRole(event)})`;
|
|
59915
|
+
case "message_update":
|
|
59916
|
+
return event.message.role === "assistant" ? event.assistantMessageEvent.type : "message_update";
|
|
59917
|
+
case "tool_execution_start":
|
|
59918
|
+
return `tool_execution_start(${event.toolName})`;
|
|
59919
|
+
case "tool_execution_update":
|
|
59920
|
+
return `tool_execution_update(${event.toolName})`;
|
|
59921
|
+
case "tool_execution_end":
|
|
59922
|
+
return `tool_execution_end(${event.toolName})`;
|
|
59923
|
+
default:
|
|
59924
|
+
return event.type;
|
|
59925
|
+
}
|
|
59926
|
+
}
|
|
59927
|
+
|
|
60027
59928
|
// src/runtime/interactive-runtime-events.ts
|
|
60028
59929
|
function bindInteractiveRuntimeEvents(host) {
|
|
60029
59930
|
host.agent.subscribe((event) => {
|
|
@@ -60046,7 +59947,7 @@ function bindInteractiveRuntimeEvents(host) {
|
|
|
60046
59947
|
break;
|
|
60047
59948
|
case "message_end":
|
|
60048
59949
|
if (process.env.PIE_DEBUG_FOOTER) {
|
|
60049
|
-
console.error(`[Footer Debug]
|
|
59950
|
+
console.error(`[Footer Debug] ${formatFooterLifecycleEvent(event)}`);
|
|
60050
59951
|
}
|
|
60051
59952
|
host.logDebug("message:end", { stopReason: event.message.role === "assistant" ? event.message.stopReason : void 0 });
|
|
60052
59953
|
handleMessageEnd(host, event);
|
|
@@ -60248,7 +60149,7 @@ function handleMessageStart(host, event) {
|
|
|
60248
60149
|
host.chatContainer.addChild(host.streamingComponent);
|
|
60249
60150
|
host.sessionTrace.updateAssistantMessage(event.message);
|
|
60250
60151
|
}
|
|
60251
|
-
host.footer.setState({ lifecycleEvent:
|
|
60152
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60252
60153
|
host.emitExtensionEvent({ type: "message:start", message: event.message });
|
|
60253
60154
|
host.safeRequestRender();
|
|
60254
60155
|
}
|
|
@@ -60259,7 +60160,7 @@ function handleMessageUpdate(host, event) {
|
|
|
60259
60160
|
host.pendingRender = true;
|
|
60260
60161
|
return;
|
|
60261
60162
|
}
|
|
60262
|
-
host.footer.setState({ lifecycleEvent:
|
|
60163
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60263
60164
|
const message = event.message;
|
|
60264
60165
|
let textContent = "";
|
|
60265
60166
|
let thinkingContent = "";
|
|
@@ -60333,7 +60234,7 @@ function handleToolStart(host, event) {
|
|
|
60333
60234
|
if (toolComponent) {
|
|
60334
60235
|
}
|
|
60335
60236
|
}
|
|
60336
|
-
host.footer.setState({ lifecycleEvent:
|
|
60237
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60337
60238
|
host.emitExtensionEvent({
|
|
60338
60239
|
type: "tool:execution:start",
|
|
60339
60240
|
toolCallId: event.toolCallId,
|
|
@@ -60358,7 +60259,7 @@ function handleToolUpdate(host, event) {
|
|
|
60358
60259
|
host.ui.requestRender();
|
|
60359
60260
|
}
|
|
60360
60261
|
}
|
|
60361
|
-
host.footer.setState({ lifecycleEvent:
|
|
60262
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60362
60263
|
host.emitExtensionEvent({
|
|
60363
60264
|
type: "tool:execution:update",
|
|
60364
60265
|
toolCallId: event.toolCallId,
|
|
@@ -60391,7 +60292,7 @@ function handleToolEnd(host, event) {
|
|
|
60391
60292
|
void host.refreshTodoWidget();
|
|
60392
60293
|
}
|
|
60393
60294
|
}
|
|
60394
|
-
host.footer.setState({ lifecycleEvent:
|
|
60295
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60395
60296
|
host.emitExtensionEvent({
|
|
60396
60297
|
type: "tool:execution:end",
|
|
60397
60298
|
toolCallId: event.toolCallId,
|
|
@@ -60403,7 +60304,7 @@ function handleToolEnd(host, event) {
|
|
|
60403
60304
|
}
|
|
60404
60305
|
function handleMessageEnd(host, event) {
|
|
60405
60306
|
host.streamingComponent = void 0;
|
|
60406
|
-
host.footer.setState({ lifecycleEvent:
|
|
60307
|
+
host.footer.setState({ lifecycleEvent: formatFooterLifecycleEvent(event) });
|
|
60407
60308
|
host.emitExtensionEvent({ type: "message:end", message: event.message });
|
|
60408
60309
|
host.safeRequestRender();
|
|
60409
60310
|
}
|
|
@@ -60668,7 +60569,7 @@ function setupInteractiveEditorSubmitHandler(host) {
|
|
|
60668
60569
|
host.chatContainer.addChild(userMsg);
|
|
60669
60570
|
host.editor.setText("");
|
|
60670
60571
|
host.ui.requestRender();
|
|
60671
|
-
await new Promise((
|
|
60572
|
+
await new Promise((resolve4) => setImmediate(resolve4));
|
|
60672
60573
|
let finalContent = messageContent;
|
|
60673
60574
|
const reminderPrefix = host.executionReminder;
|
|
60674
60575
|
const combinedPrefix = [reminderPrefix].filter((value) => Boolean(value)).join("");
|
|
@@ -60704,7 +60605,7 @@ function setupInteractiveEditorSubmitHandler(host) {
|
|
|
60704
60605
|
}
|
|
60705
60606
|
|
|
60706
60607
|
// src/input/interactive-file-pipeline.ts
|
|
60707
|
-
import * as
|
|
60608
|
+
import * as fs19 from "fs";
|
|
60708
60609
|
import * as path20 from "path";
|
|
60709
60610
|
|
|
60710
60611
|
// src/components/file-picker.ts
|
|
@@ -60926,7 +60827,7 @@ var FilePickerComponent = class extends Container {
|
|
|
60926
60827
|
};
|
|
60927
60828
|
|
|
60928
60829
|
// src/files/commands/file-commands.ts
|
|
60929
|
-
import * as
|
|
60830
|
+
import * as fs17 from "node:fs";
|
|
60930
60831
|
import * as path18 from "node:path";
|
|
60931
60832
|
var FileCommands = class {
|
|
60932
60833
|
context;
|
|
@@ -60943,7 +60844,7 @@ var FileCommands = class {
|
|
|
60943
60844
|
return;
|
|
60944
60845
|
}
|
|
60945
60846
|
const filePath = resolvePath(parsed.path);
|
|
60946
|
-
if (!
|
|
60847
|
+
if (!fs17.existsSync(filePath)) {
|
|
60947
60848
|
this.context.showError(`File not found: ${parsed.path}`);
|
|
60948
60849
|
return;
|
|
60949
60850
|
}
|
|
@@ -60982,7 +60883,7 @@ var FileCommands = class {
|
|
|
60982
60883
|
return;
|
|
60983
60884
|
}
|
|
60984
60885
|
const resolvedPath = resolvePath(filePath);
|
|
60985
|
-
if (!
|
|
60886
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
60986
60887
|
this.context.showError(`File not found: ${filePath}`);
|
|
60987
60888
|
return;
|
|
60988
60889
|
}
|
|
@@ -61013,7 +60914,7 @@ var FileCommands = class {
|
|
|
61013
60914
|
return;
|
|
61014
60915
|
}
|
|
61015
60916
|
const resolvedPath = resolvePath(parsed.path);
|
|
61016
|
-
if (!
|
|
60917
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
61017
60918
|
this.context.showError(`File not found: ${parsed.path}`);
|
|
61018
60919
|
return;
|
|
61019
60920
|
}
|
|
@@ -61491,7 +61392,7 @@ var FileStatusMonitor = class {
|
|
|
61491
61392
|
};
|
|
61492
61393
|
|
|
61493
61394
|
// src/files/mention/mention-handler.ts
|
|
61494
|
-
import * as
|
|
61395
|
+
import * as fs18 from "node:fs";
|
|
61495
61396
|
import * as path19 from "node:path";
|
|
61496
61397
|
var MentionHandler = class {
|
|
61497
61398
|
fileManager;
|
|
@@ -61861,8 +61762,8 @@ var MentionHandler = class {
|
|
|
61861
61762
|
}
|
|
61862
61763
|
if (this.isPath(query)) {
|
|
61863
61764
|
const resolvedPath = resolvePath(query);
|
|
61864
|
-
if (
|
|
61865
|
-
const stats =
|
|
61765
|
+
if (fs18.existsSync(resolvedPath)) {
|
|
61766
|
+
const stats = fs18.statSync(resolvedPath);
|
|
61866
61767
|
if (stats.isFile()) {
|
|
61867
61768
|
const type = FileCache.getFileTypeFromName(resolvedPath);
|
|
61868
61769
|
const name = path19.basename(resolvedPath);
|
|
@@ -61886,7 +61787,7 @@ var MentionHandler = class {
|
|
|
61886
61787
|
return void 0;
|
|
61887
61788
|
}
|
|
61888
61789
|
const queryPath = this.isPath(query) ? resolvePath(query) : void 0;
|
|
61889
|
-
const filter = queryPath ?
|
|
61790
|
+
const filter = queryPath ? fs18.existsSync(queryPath) && fs18.statSync(queryPath).isDirectory() ? "" : path19.basename(queryPath) : query;
|
|
61890
61791
|
const entries = this.fileManager.listPathEntries(currentDir, filter);
|
|
61891
61792
|
const options = [];
|
|
61892
61793
|
const homeDir = process.env.HOME || "";
|
|
@@ -61927,7 +61828,7 @@ var MentionHandler = class {
|
|
|
61927
61828
|
getBrowserDirectory(query = this.currentQuery) {
|
|
61928
61829
|
if (this.isPath(query)) {
|
|
61929
61830
|
const resolvedPath = resolvePath(query);
|
|
61930
|
-
if (
|
|
61831
|
+
if (fs18.existsSync(resolvedPath) && fs18.statSync(resolvedPath).isDirectory()) {
|
|
61931
61832
|
return resolvedPath;
|
|
61932
61833
|
}
|
|
61933
61834
|
return path19.dirname(resolvedPath);
|
|
@@ -62004,7 +61905,7 @@ var MentionHandler = class {
|
|
|
62004
61905
|
this.pendingStatusMessages.delete(key);
|
|
62005
61906
|
}
|
|
62006
61907
|
isPath(query) {
|
|
62007
|
-
return
|
|
61908
|
+
return looksLikeFilePath(query);
|
|
62008
61909
|
}
|
|
62009
61910
|
};
|
|
62010
61911
|
|
|
@@ -62291,13 +62192,13 @@ function convertPreparedAttachmentItems(items) {
|
|
|
62291
62192
|
break;
|
|
62292
62193
|
case "image": {
|
|
62293
62194
|
if (!item.data && !item.path) return void 0;
|
|
62294
|
-
const data = item.data ??
|
|
62195
|
+
const data = item.data ?? fs19.readFileSync(item.path, "base64");
|
|
62295
62196
|
converted.push({ type: "image", data, mimeType: item.mimeType });
|
|
62296
62197
|
break;
|
|
62297
62198
|
}
|
|
62298
62199
|
case "video": {
|
|
62299
62200
|
if (!item.data && !item.path) return void 0;
|
|
62300
|
-
const data = item.data ??
|
|
62201
|
+
const data = item.data ?? fs19.readFileSync(item.path, "base64");
|
|
62301
62202
|
converted.push({ type: "video", data, mimeType: item.mimeType });
|
|
62302
62203
|
break;
|
|
62303
62204
|
}
|
|
@@ -62688,6 +62589,7 @@ function buildCodingAgentGuidelinesSection(tools = []) {
|
|
|
62688
62589
|
const hasGrep = toolNames.has("grep_text");
|
|
62689
62590
|
const hasFind = toolNames.has("find_files");
|
|
62690
62591
|
const hasBash = toolNames.has("bash");
|
|
62592
|
+
const hasWebResearch = toolNames.has("web_research");
|
|
62691
62593
|
const hasWebSearch = toolNames.has("web_search");
|
|
62692
62594
|
const hasWebFetch = toolNames.has("web_fetch");
|
|
62693
62595
|
const hasCodeIntel = toolNames.has("code_intel");
|
|
@@ -62702,11 +62604,17 @@ function buildCodingAgentGuidelinesSection(tools = []) {
|
|
|
62702
62604
|
if (hasGrep || hasFind || hasList) {
|
|
62703
62605
|
guidelines.push("Prefer grep_text, find_files, and list_dir for workspace exploration when they are sufficient.");
|
|
62704
62606
|
}
|
|
62705
|
-
if (
|
|
62607
|
+
if (hasWebResearch) {
|
|
62608
|
+
guidelines.push("Use web_research for general public web research, current information, official docs, news, releases, issues, or webpage summaries; it searches, fetches, and returns cited sources.");
|
|
62609
|
+
guidelines.push("When web_research returns fetched sources that answer the request, synthesize the answer from that pack instead of calling web_search or web_fetch again.");
|
|
62610
|
+
}
|
|
62611
|
+
if (hasWebSearch && !hasWebResearch) {
|
|
62706
62612
|
guidelines.push("Use web_search for public web research and grep_text/find_files/list_dir for local workspace search.");
|
|
62707
62613
|
}
|
|
62708
|
-
if (hasWebFetch) {
|
|
62614
|
+
if (hasWebFetch && !hasWebResearch) {
|
|
62709
62615
|
guidelines.push("After web_search identifies a public source, use web_fetch to read the chosen URL before relying on it; also use web_fetch for user-supplied URLs.");
|
|
62616
|
+
} else if (hasWebResearch && hasWebSearch && hasWebFetch) {
|
|
62617
|
+
guidelines.push("Use web_search and web_fetch directly only when you need low-level control over exact queries or URLs.");
|
|
62710
62618
|
}
|
|
62711
62619
|
if (hasCodeIntel) {
|
|
62712
62620
|
guidelines.push("Use code_intel for JS/TS diagnostics, definitions, references, symbols, or hover when type or symbol information matters before editing.");
|
|
@@ -63537,8 +63445,21 @@ function createInteractiveAgentSessionController(host) {
|
|
|
63537
63445
|
} else if (event.type === "retry_start") {
|
|
63538
63446
|
host.showStatus(`Retrying request (attempt ${event.attempt}/${event.maxRetries})...`);
|
|
63539
63447
|
} else if (event.type === "retry_succeeded") {
|
|
63448
|
+
const outcome = host.executionState.resumePausedTodo();
|
|
63449
|
+
if (outcome.changed) {
|
|
63450
|
+
host.sessionTrace.noteRuntimeEvent("todo_resumed_after_retry", {
|
|
63451
|
+
lifecycle: host.executionState.read().lifecycle,
|
|
63452
|
+
currentStepId: host.executionState.read().currentStepId
|
|
63453
|
+
});
|
|
63454
|
+
host.persistExecutionState();
|
|
63455
|
+
void host.refreshTodoWidget();
|
|
63456
|
+
}
|
|
63540
63457
|
host.showStatus("Retry succeeded");
|
|
63541
63458
|
} else if (event.type === "retry_exhausted") {
|
|
63459
|
+
const state = host.executionState.read();
|
|
63460
|
+
if (state.mode === "todo" && state.lifecycle === "paused" && state.steps.length > 0) {
|
|
63461
|
+
host.showStatus("Todo list preserved. Send 'continue' when you want to resume it.");
|
|
63462
|
+
}
|
|
63542
63463
|
host.showError(`Request failed after ${event.maxRetries} retries: ${event.errorMessage}`);
|
|
63543
63464
|
} else if (event.type === "runtime_guard_triggered") {
|
|
63544
63465
|
host.sessionTrace.noteStalled("runtime_guard_triggered", {
|
|
@@ -63770,7 +63691,7 @@ async function handleDirectBash(host, command) {
|
|
|
63770
63691
|
}
|
|
63771
63692
|
host.ui.requestRender();
|
|
63772
63693
|
});
|
|
63773
|
-
return new Promise((
|
|
63694
|
+
return new Promise((resolve4) => {
|
|
63774
63695
|
child.on("close", (code) => {
|
|
63775
63696
|
if (code !== 0) {
|
|
63776
63697
|
outputContainer.addChild(new Spacer(1));
|
|
@@ -63778,7 +63699,7 @@ async function handleDirectBash(host, command) {
|
|
|
63778
63699
|
}
|
|
63779
63700
|
host.chatContainer.addChild(new Spacer(1));
|
|
63780
63701
|
host.ui.requestRender();
|
|
63781
|
-
|
|
63702
|
+
resolve4();
|
|
63782
63703
|
});
|
|
63783
63704
|
});
|
|
63784
63705
|
}
|
|
@@ -63854,11 +63775,11 @@ function installInteractiveInteractionHandler(host) {
|
|
|
63854
63775
|
if (!("timeoutMs" in request) || !request.timeoutMs || request.timeoutMs <= 0) {
|
|
63855
63776
|
return { value: await promise, timedOut: false };
|
|
63856
63777
|
}
|
|
63857
|
-
return await new Promise((
|
|
63858
|
-
const timer = setTimeout(() =>
|
|
63778
|
+
return await new Promise((resolve4, reject) => {
|
|
63779
|
+
const timer = setTimeout(() => resolve4({ timedOut: true }), request.timeoutMs);
|
|
63859
63780
|
promise.then((value) => {
|
|
63860
63781
|
clearTimeout(timer);
|
|
63861
|
-
|
|
63782
|
+
resolve4({ value, timedOut: false });
|
|
63862
63783
|
}).catch((error) => {
|
|
63863
63784
|
clearTimeout(timer);
|
|
63864
63785
|
reject(error);
|
|
@@ -63958,15 +63879,15 @@ function showExtensionNotification(host, message, type = "info") {
|
|
|
63958
63879
|
host.ui.requestRender();
|
|
63959
63880
|
}
|
|
63960
63881
|
function showExtensionSelector(host, title, options, opts) {
|
|
63961
|
-
return new Promise((
|
|
63882
|
+
return new Promise((resolve4) => {
|
|
63962
63883
|
host.showStatus(`Waiting for selection: ${title}`);
|
|
63963
63884
|
if (opts?.signal?.aborted) {
|
|
63964
|
-
|
|
63885
|
+
resolve4(void 0);
|
|
63965
63886
|
return;
|
|
63966
63887
|
}
|
|
63967
63888
|
const onAbort = () => {
|
|
63968
63889
|
host.restoreEditor();
|
|
63969
|
-
|
|
63890
|
+
resolve4(void 0);
|
|
63970
63891
|
};
|
|
63971
63892
|
opts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
63972
63893
|
const selector = new ExtensionSelectorComponent(
|
|
@@ -63975,12 +63896,12 @@ function showExtensionSelector(host, title, options, opts) {
|
|
|
63975
63896
|
(option) => {
|
|
63976
63897
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
63977
63898
|
host.restoreEditor();
|
|
63978
|
-
|
|
63899
|
+
resolve4(option);
|
|
63979
63900
|
},
|
|
63980
63901
|
() => {
|
|
63981
63902
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
63982
63903
|
host.restoreEditor();
|
|
63983
|
-
|
|
63904
|
+
resolve4(void 0);
|
|
63984
63905
|
}
|
|
63985
63906
|
);
|
|
63986
63907
|
host.editorContainer.clear();
|
|
@@ -63996,15 +63917,15 @@ ${message}`, ["Yes", "No"], opts);
|
|
|
63996
63917
|
return result === "Yes";
|
|
63997
63918
|
}
|
|
63998
63919
|
function showExtensionInput(host, title, placeholder, opts) {
|
|
63999
|
-
return new Promise((
|
|
63920
|
+
return new Promise((resolve4) => {
|
|
64000
63921
|
host.showStatus(`Waiting for input: ${title}`);
|
|
64001
63922
|
if (opts?.signal?.aborted) {
|
|
64002
|
-
|
|
63923
|
+
resolve4(void 0);
|
|
64003
63924
|
return;
|
|
64004
63925
|
}
|
|
64005
63926
|
const onAbort = () => {
|
|
64006
63927
|
host.restoreEditor();
|
|
64007
|
-
|
|
63928
|
+
resolve4(void 0);
|
|
64008
63929
|
};
|
|
64009
63930
|
opts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
64010
63931
|
const input = new ExtensionInputComponent(
|
|
@@ -64013,12 +63934,12 @@ function showExtensionInput(host, title, placeholder, opts) {
|
|
|
64013
63934
|
(value) => {
|
|
64014
63935
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
64015
63936
|
host.restoreEditor();
|
|
64016
|
-
|
|
63937
|
+
resolve4(value);
|
|
64017
63938
|
},
|
|
64018
63939
|
() => {
|
|
64019
63940
|
opts?.signal?.removeEventListener("abort", onAbort);
|
|
64020
63941
|
host.restoreEditor();
|
|
64021
|
-
|
|
63942
|
+
resolve4(void 0);
|
|
64022
63943
|
}
|
|
64023
63944
|
);
|
|
64024
63945
|
host.editorContainer.clear();
|
|
@@ -64029,7 +63950,7 @@ function showExtensionInput(host, title, placeholder, opts) {
|
|
|
64029
63950
|
});
|
|
64030
63951
|
}
|
|
64031
63952
|
function showExtensionEditor(host, title, prefill) {
|
|
64032
|
-
return new Promise((
|
|
63953
|
+
return new Promise((resolve4) => {
|
|
64033
63954
|
host.showStatus(`Waiting for input: ${title}`);
|
|
64034
63955
|
const container = new Container();
|
|
64035
63956
|
container.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
|
|
@@ -64051,12 +63972,12 @@ function showExtensionEditor(host, title, prefill) {
|
|
|
64051
63972
|
preview: value.slice(0, 120)
|
|
64052
63973
|
});
|
|
64053
63974
|
host.restoreEditor();
|
|
64054
|
-
|
|
63975
|
+
resolve4(value);
|
|
64055
63976
|
};
|
|
64056
63977
|
editor.onEscape = () => {
|
|
64057
63978
|
host.logDebug("extension:editor:cancel", { title });
|
|
64058
63979
|
host.restoreEditor();
|
|
64059
|
-
|
|
63980
|
+
resolve4(void 0);
|
|
64060
63981
|
};
|
|
64061
63982
|
container.addChild(editor);
|
|
64062
63983
|
container.addChild(new Spacer(1));
|
|
@@ -64070,14 +63991,14 @@ function showExtensionEditor(host, title, prefill) {
|
|
|
64070
63991
|
}
|
|
64071
63992
|
function showExtensionCustom(host, factory, options) {
|
|
64072
63993
|
const savedText = host.editor.getText();
|
|
64073
|
-
return new Promise((
|
|
63994
|
+
return new Promise((resolve4, reject) => {
|
|
64074
63995
|
let closed = false;
|
|
64075
63996
|
const close = (result) => {
|
|
64076
63997
|
if (closed) return;
|
|
64077
63998
|
closed = true;
|
|
64078
63999
|
host.restoreEditor();
|
|
64079
64000
|
host.editor.setText(savedText);
|
|
64080
|
-
|
|
64001
|
+
resolve4(result);
|
|
64081
64002
|
};
|
|
64082
64003
|
Promise.resolve(factory(host.ui, theme, close)).then((component) => {
|
|
64083
64004
|
if (closed) return;
|
|
@@ -64151,7 +64072,7 @@ var AttachmentResolver = class {
|
|
|
64151
64072
|
};
|
|
64152
64073
|
|
|
64153
64074
|
// src/extensions/loader.ts
|
|
64154
|
-
import * as
|
|
64075
|
+
import * as fs20 from "node:fs";
|
|
64155
64076
|
import * as os4 from "os";
|
|
64156
64077
|
import * as path21 from "path";
|
|
64157
64078
|
import { pathToFileURL } from "node:url";
|
|
@@ -64335,7 +64256,7 @@ function normalizeExtensionImportPath(extensionPath) {
|
|
|
64335
64256
|
}
|
|
64336
64257
|
async function loadExtension(extensionPath, cwd, uiContext, abortFn, isIdleFn, hasUI, actions) {
|
|
64337
64258
|
const resolvedPath = resolvePath2(extensionPath, cwd);
|
|
64338
|
-
if (!
|
|
64259
|
+
if (!fs20.existsSync(resolvedPath)) {
|
|
64339
64260
|
return { extension: null, error: `Extension not found: ${extensionPath}` };
|
|
64340
64261
|
}
|
|
64341
64262
|
try {
|
|
@@ -64356,12 +64277,12 @@ async function loadExtension(extensionPath, cwd, uiContext, abortFn, isIdleFn, h
|
|
|
64356
64277
|
}
|
|
64357
64278
|
}
|
|
64358
64279
|
function discoverExtensionsInDir(dir) {
|
|
64359
|
-
if (!
|
|
64280
|
+
if (!fs20.existsSync(dir)) {
|
|
64360
64281
|
return [];
|
|
64361
64282
|
}
|
|
64362
64283
|
const discovered = [];
|
|
64363
64284
|
try {
|
|
64364
|
-
const entries =
|
|
64285
|
+
const entries = fs20.readdirSync(dir, { withFileTypes: true });
|
|
64365
64286
|
for (const entry of entries) {
|
|
64366
64287
|
const entryPath = path21.join(dir, entry.name);
|
|
64367
64288
|
if (entry.isFile() && (entry.name.endsWith(".cjs") || entry.name.endsWith(".js") || entry.name.endsWith(".ts"))) {
|
|
@@ -64370,16 +64291,16 @@ function discoverExtensionsInDir(dir) {
|
|
|
64370
64291
|
}
|
|
64371
64292
|
if (entry.isDirectory()) {
|
|
64372
64293
|
const packageJsonPath = path21.join(entryPath, "package.json");
|
|
64373
|
-
if (
|
|
64294
|
+
if (fs20.existsSync(packageJsonPath)) {
|
|
64374
64295
|
try {
|
|
64375
|
-
const
|
|
64376
|
-
const manifest =
|
|
64296
|
+
const pkg = JSON.parse(fs20.readFileSync(packageJsonPath, "utf-8"));
|
|
64297
|
+
const manifest = pkg.pie;
|
|
64377
64298
|
if (manifest?.main) {
|
|
64378
64299
|
const mainPath = path21.resolve(entryPath, manifest.main);
|
|
64379
|
-
if (
|
|
64300
|
+
if (fs20.existsSync(mainPath)) {
|
|
64380
64301
|
discovered.push({
|
|
64381
64302
|
entryPath: mainPath,
|
|
64382
|
-
manifestName: manifest.name ||
|
|
64303
|
+
manifestName: manifest.name || pkg.name
|
|
64383
64304
|
});
|
|
64384
64305
|
continue;
|
|
64385
64306
|
}
|
|
@@ -64388,17 +64309,17 @@ function discoverExtensionsInDir(dir) {
|
|
|
64388
64309
|
}
|
|
64389
64310
|
}
|
|
64390
64311
|
const indexCjs = path21.join(entryPath, "index.cjs");
|
|
64391
|
-
if (
|
|
64312
|
+
if (fs20.existsSync(indexCjs)) {
|
|
64392
64313
|
discovered.push({ entryPath: indexCjs });
|
|
64393
64314
|
continue;
|
|
64394
64315
|
}
|
|
64395
64316
|
const indexJs = path21.join(entryPath, "index.js");
|
|
64396
|
-
if (
|
|
64317
|
+
if (fs20.existsSync(indexJs)) {
|
|
64397
64318
|
discovered.push({ entryPath: indexJs });
|
|
64398
64319
|
continue;
|
|
64399
64320
|
}
|
|
64400
64321
|
const indexTs = path21.join(entryPath, "index.ts");
|
|
64401
|
-
if (
|
|
64322
|
+
if (fs20.existsSync(indexTs)) {
|
|
64402
64323
|
discovered.push({ entryPath: indexTs });
|
|
64403
64324
|
continue;
|
|
64404
64325
|
}
|
|
@@ -64447,11 +64368,11 @@ async function loadExtensions(configuredPaths, cwd, uiContext, abortFn, isIdleFn
|
|
|
64447
64368
|
}
|
|
64448
64369
|
for (const p of configuredPaths) {
|
|
64449
64370
|
const resolved = resolvePath2(p, cwd);
|
|
64450
|
-
if (!
|
|
64371
|
+
if (!fs20.existsSync(resolved)) {
|
|
64451
64372
|
errors.push({ path: p, error: `Extension path not found: ${p}` });
|
|
64452
64373
|
continue;
|
|
64453
64374
|
}
|
|
64454
|
-
if (!
|
|
64375
|
+
if (!fs20.statSync(resolved).isDirectory()) {
|
|
64455
64376
|
errors.push({ path: p, error: `Extension path must be a directory: ${p}` });
|
|
64456
64377
|
continue;
|
|
64457
64378
|
}
|
|
@@ -65200,7 +65121,7 @@ var InteractiveMode = class {
|
|
|
65200
65121
|
this.skills = options.skills;
|
|
65201
65122
|
this.originalTools = [...options.tools];
|
|
65202
65123
|
this.skillsSection = formatSkillsForPrompt(options.skills);
|
|
65203
|
-
this.knowledgeSection =
|
|
65124
|
+
this.knowledgeSection = buildCliProjectContextSection(options.cwd);
|
|
65204
65125
|
}
|
|
65205
65126
|
options;
|
|
65206
65127
|
get runtimeEventHost() {
|
|
@@ -65241,10 +65162,15 @@ var InteractiveMode = class {
|
|
|
65241
65162
|
}
|
|
65242
65163
|
rebuildSkillAwareTools(sourceTools) {
|
|
65243
65164
|
const preservedTools = sourceTools.filter(
|
|
65244
|
-
(tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name)
|
|
65165
|
+
(tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name)
|
|
65245
65166
|
);
|
|
65246
65167
|
const fileSystemToolOptions = (allowlistedDirs) => ({
|
|
65247
|
-
|
|
65168
|
+
...buildCliFileAccessOptions({
|
|
65169
|
+
cwd: this.options.cwd,
|
|
65170
|
+
configDir: this.options.configDir,
|
|
65171
|
+
skills: this.skills,
|
|
65172
|
+
allowlistedDirs
|
|
65173
|
+
}),
|
|
65248
65174
|
configDir: this.options.configDir,
|
|
65249
65175
|
getAgentModel: () => this.options.model,
|
|
65250
65176
|
getSessionId: () => this.sessionManager.getActiveSessionId() || void 0,
|
|
@@ -65257,9 +65183,6 @@ var InteractiveMode = class {
|
|
|
65257
65183
|
});
|
|
65258
65184
|
const normalFsTools = createCliFileSystemTools(this.options.cwd, fileSystemToolOptions([this.options.configDir]));
|
|
65259
65185
|
const currentFsTools = this.yoloMode ? createCliFileSystemTools(this.options.cwd, fileSystemToolOptions(["/"])) : normalFsTools;
|
|
65260
|
-
const readSkillTool = createCliReadSkillTool(this.skills);
|
|
65261
|
-
const readResourceTool = createCliReadResourceTool(this.skills);
|
|
65262
|
-
const resolveResourceTool = createCliResolveResourceTool(this.skills);
|
|
65263
65186
|
const getPolicyContext = () => ({
|
|
65264
65187
|
mode: this.planModeEnabled ? "plan" : "normal",
|
|
65265
65188
|
yoloMode: this.yoloMode,
|
|
@@ -65267,11 +65190,11 @@ var InteractiveMode = class {
|
|
|
65267
65190
|
});
|
|
65268
65191
|
return {
|
|
65269
65192
|
currentTools: createPolicyEnforcedTools(
|
|
65270
|
-
[...currentFsTools,
|
|
65193
|
+
[...currentFsTools, ...preservedTools],
|
|
65271
65194
|
{ getContext: getPolicyContext }
|
|
65272
65195
|
),
|
|
65273
65196
|
originalTools: createPolicyEnforcedTools(
|
|
65274
|
-
[...normalFsTools,
|
|
65197
|
+
[...normalFsTools, ...preservedTools],
|
|
65275
65198
|
{ getContext: getPolicyContext }
|
|
65276
65199
|
)
|
|
65277
65200
|
};
|
|
@@ -65765,8 +65688,8 @@ function parseCliInvocation(args) {
|
|
|
65765
65688
|
}
|
|
65766
65689
|
|
|
65767
65690
|
// src/cli.ts
|
|
65768
|
-
import { mkdirSync as
|
|
65769
|
-
import * as
|
|
65691
|
+
import { mkdirSync as mkdirSync11, existsSync as existsSync17 } from "fs";
|
|
65692
|
+
import * as fs25 from "fs";
|
|
65770
65693
|
import * as path25 from "path";
|
|
65771
65694
|
|
|
65772
65695
|
// src/logging/runtime-logger.ts
|
|
@@ -65904,7 +65827,7 @@ var AuthStorage = class {
|
|
|
65904
65827
|
};
|
|
65905
65828
|
|
|
65906
65829
|
// src/core/settings-manager.ts
|
|
65907
|
-
import * as
|
|
65830
|
+
import * as fs21 from "fs";
|
|
65908
65831
|
var SettingsManager = class {
|
|
65909
65832
|
settingsPath;
|
|
65910
65833
|
legacyConfigPath;
|
|
@@ -65918,9 +65841,9 @@ var SettingsManager = class {
|
|
|
65918
65841
|
this.legacyConfig = this.loadLegacyConfigFile();
|
|
65919
65842
|
}
|
|
65920
65843
|
readJson(filePath) {
|
|
65921
|
-
if (!
|
|
65844
|
+
if (!fs21.existsSync(filePath)) return null;
|
|
65922
65845
|
try {
|
|
65923
|
-
return JSON.parse(
|
|
65846
|
+
return JSON.parse(fs21.readFileSync(filePath, "utf-8"));
|
|
65924
65847
|
} catch {
|
|
65925
65848
|
return null;
|
|
65926
65849
|
}
|
|
@@ -65932,15 +65855,15 @@ var SettingsManager = class {
|
|
|
65932
65855
|
return this.readJson(this.legacyConfigPath) || {};
|
|
65933
65856
|
}
|
|
65934
65857
|
ensureDir() {
|
|
65935
|
-
|
|
65858
|
+
fs21.mkdirSync(getConfigDir(), { recursive: true });
|
|
65936
65859
|
}
|
|
65937
65860
|
writeSettings() {
|
|
65938
65861
|
this.ensureDir();
|
|
65939
|
-
|
|
65862
|
+
fs21.writeFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2));
|
|
65940
65863
|
}
|
|
65941
65864
|
writeLegacyConfig() {
|
|
65942
65865
|
this.ensureDir();
|
|
65943
|
-
|
|
65866
|
+
fs21.writeFileSync(this.legacyConfigPath, JSON.stringify(this.legacyConfig, null, 2));
|
|
65944
65867
|
}
|
|
65945
65868
|
getLegacyApiKey() {
|
|
65946
65869
|
return this.legacyConfig.apiKey;
|
|
@@ -65992,7 +65915,7 @@ var SettingsManager = class {
|
|
|
65992
65915
|
};
|
|
65993
65916
|
|
|
65994
65917
|
// src/core/model-registry.ts
|
|
65995
|
-
import * as
|
|
65918
|
+
import * as fs22 from "fs";
|
|
65996
65919
|
import * as path22 from "path";
|
|
65997
65920
|
function validateProfileConfig(profileId, profileConfig) {
|
|
65998
65921
|
const missing = [];
|
|
@@ -66055,11 +65978,11 @@ var ModelRegistry = class {
|
|
|
66055
65978
|
this.modelOrder = [];
|
|
66056
65979
|
this.configDefaults = void 0;
|
|
66057
65980
|
this.usingExternalProviders = false;
|
|
66058
|
-
if (!
|
|
65981
|
+
if (!fs22.existsSync(this.modelsPath)) {
|
|
66059
65982
|
return;
|
|
66060
65983
|
}
|
|
66061
65984
|
try {
|
|
66062
|
-
const raw = JSON.parse(
|
|
65985
|
+
const raw = JSON.parse(fs22.readFileSync(this.modelsPath, "utf-8"));
|
|
66063
65986
|
if (raw && typeof raw === "object" && "providers" in raw) {
|
|
66064
65987
|
throw new Error('Legacy models.json format is no longer supported. Use top-level "profiles".');
|
|
66065
65988
|
}
|
|
@@ -66308,11 +66231,12 @@ var ModelRegistry = class {
|
|
|
66308
66231
|
// src/doctor.ts
|
|
66309
66232
|
import { spawnSync } from "node:child_process";
|
|
66310
66233
|
import { createRequire } from "node:module";
|
|
66311
|
-
import * as
|
|
66234
|
+
import * as fs23 from "node:fs";
|
|
66312
66235
|
import * as os5 from "node:os";
|
|
66313
66236
|
import * as path23 from "node:path";
|
|
66314
66237
|
import { delimiter } from "node:path";
|
|
66315
66238
|
var require2 = createRequire(import.meta.url);
|
|
66239
|
+
var UNITY_INSTANCE_MAX_AGE_SEC = 120;
|
|
66316
66240
|
function checkStatus(checks) {
|
|
66317
66241
|
return {
|
|
66318
66242
|
pass: checks.filter((check) => check.status === "pass").length,
|
|
@@ -66344,19 +66268,19 @@ function checkShell() {
|
|
|
66344
66268
|
}
|
|
66345
66269
|
function canWriteDirectory(dir) {
|
|
66346
66270
|
try {
|
|
66347
|
-
|
|
66271
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
66348
66272
|
const probe = path23.join(dir, `.pie-doctor-${process.pid}-${Date.now()}`);
|
|
66349
|
-
|
|
66350
|
-
|
|
66273
|
+
fs23.writeFileSync(probe, "ok", "utf8");
|
|
66274
|
+
fs23.rmSync(probe, { force: true });
|
|
66351
66275
|
return { ok: true };
|
|
66352
66276
|
} catch (error) {
|
|
66353
66277
|
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
66354
66278
|
}
|
|
66355
66279
|
}
|
|
66356
66280
|
function isExecutable(candidate) {
|
|
66357
|
-
if (!candidate || !
|
|
66281
|
+
if (!candidate || !fs23.existsSync(candidate)) return false;
|
|
66358
66282
|
try {
|
|
66359
|
-
|
|
66283
|
+
fs23.accessSync(candidate, fs23.constants.X_OK);
|
|
66360
66284
|
return true;
|
|
66361
66285
|
} catch {
|
|
66362
66286
|
return os5.platform() === "win32";
|
|
@@ -66434,7 +66358,7 @@ function checkPlaywrightBrowser() {
|
|
|
66434
66358
|
} catch {
|
|
66435
66359
|
executablePath = void 0;
|
|
66436
66360
|
}
|
|
66437
|
-
if (executablePath &&
|
|
66361
|
+
if (executablePath && fs23.existsSync(executablePath)) {
|
|
66438
66362
|
return {
|
|
66439
66363
|
id: "playwright_browser",
|
|
66440
66364
|
label: "Playwright browser",
|
|
@@ -66452,37 +66376,98 @@ function checkPlaywrightBrowser() {
|
|
|
66452
66376
|
details: { expectedExecutablePath: executablePath, skillWrapper }
|
|
66453
66377
|
};
|
|
66454
66378
|
}
|
|
66379
|
+
function isRecord2(value) {
|
|
66380
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
66381
|
+
}
|
|
66382
|
+
function hasRequiredUnityIdentityFields(instance) {
|
|
66383
|
+
return typeof instance.instanceId === "string" && instance.instanceId.trim().length > 0 && typeof instance.projectPath === "string" && instance.projectPath.trim().length > 0 && Number(instance.port || 0) > 0 && Number(instance.pid || 0) > 0 && Number(instance.lastSeenUnix || 0) > 0;
|
|
66384
|
+
}
|
|
66385
|
+
function isProcessAlive(pid) {
|
|
66386
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
66387
|
+
try {
|
|
66388
|
+
process.kill(pid, 0);
|
|
66389
|
+
return true;
|
|
66390
|
+
} catch (error) {
|
|
66391
|
+
return error?.code === "EPERM";
|
|
66392
|
+
}
|
|
66393
|
+
}
|
|
66394
|
+
function isLiveUnityInstance(instance, nowUnix = Math.floor(Date.now() / 1e3)) {
|
|
66395
|
+
if (!hasRequiredUnityIdentityFields(instance)) return false;
|
|
66396
|
+
const lastSeenUnix = Number(instance.lastSeenUnix || 0);
|
|
66397
|
+
if (nowUnix - lastSeenUnix > UNITY_INSTANCE_MAX_AGE_SEC) return false;
|
|
66398
|
+
return isProcessAlive(Number(instance.pid || 0));
|
|
66399
|
+
}
|
|
66455
66400
|
function checkUnityRegistry() {
|
|
66456
|
-
const
|
|
66457
|
-
if (!
|
|
66401
|
+
const registryDir = path23.join(os5.homedir(), ".pie-unity", "instances");
|
|
66402
|
+
if (!fs23.existsSync(registryDir)) {
|
|
66458
66403
|
return {
|
|
66459
66404
|
id: "unity_bridge",
|
|
66460
66405
|
label: "Unity bridge",
|
|
66461
66406
|
status: "warn",
|
|
66462
|
-
message: "No pie-unity registry found. This is fine unless you plan to control Unity from Pie.",
|
|
66463
|
-
details: {
|
|
66407
|
+
message: "No pie-unity instance registry directory found. This is fine unless you plan to control Unity from Pie.",
|
|
66408
|
+
details: { registryDir }
|
|
66464
66409
|
};
|
|
66465
66410
|
}
|
|
66466
66411
|
try {
|
|
66467
|
-
const
|
|
66468
|
-
const
|
|
66412
|
+
const nowUnix = Math.floor(Date.now() / 1e3);
|
|
66413
|
+
const files = fs23.readdirSync(registryDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => path23.join(registryDir, entry.name));
|
|
66414
|
+
let malformedFiles = 0;
|
|
66415
|
+
let invalidFiles = 0;
|
|
66416
|
+
const liveInstances = files.map((filePath) => {
|
|
66417
|
+
try {
|
|
66418
|
+
const parsed = JSON.parse(fs23.readFileSync(filePath, "utf8").replace(/^\uFEFF/, ""));
|
|
66419
|
+
if (!isRecord2(parsed)) {
|
|
66420
|
+
invalidFiles += 1;
|
|
66421
|
+
return null;
|
|
66422
|
+
}
|
|
66423
|
+
if (!isLiveUnityInstance(parsed, nowUnix)) {
|
|
66424
|
+
invalidFiles += 1;
|
|
66425
|
+
return null;
|
|
66426
|
+
}
|
|
66427
|
+
return parsed;
|
|
66428
|
+
} catch {
|
|
66429
|
+
malformedFiles += 1;
|
|
66430
|
+
return null;
|
|
66431
|
+
}
|
|
66432
|
+
}).filter((item) => Boolean(item));
|
|
66469
66433
|
return {
|
|
66470
66434
|
id: "unity_bridge",
|
|
66471
66435
|
label: "Unity bridge",
|
|
66472
|
-
status:
|
|
66473
|
-
message:
|
|
66474
|
-
details: {
|
|
66436
|
+
status: liveInstances.length > 0 ? "pass" : "warn",
|
|
66437
|
+
message: liveInstances.length > 0 ? `Found ${liveInstances.length} live pie-unity instance(s).` : "pie-unity instance registry directory exists but has no live readable instances.",
|
|
66438
|
+
details: {
|
|
66439
|
+
registryDir,
|
|
66440
|
+
liveInstances: liveInstances.length,
|
|
66441
|
+
totalFiles: files.length,
|
|
66442
|
+
malformedFiles,
|
|
66443
|
+
invalidOrStaleFiles: invalidFiles
|
|
66444
|
+
}
|
|
66475
66445
|
};
|
|
66476
66446
|
} catch (error) {
|
|
66477
66447
|
return {
|
|
66478
66448
|
id: "unity_bridge",
|
|
66479
66449
|
label: "Unity bridge",
|
|
66480
66450
|
status: "warn",
|
|
66481
|
-
message: `Could not read pie-unity registry: ${error instanceof Error ? error.message : String(error)}`,
|
|
66482
|
-
details: {
|
|
66451
|
+
message: `Could not read pie-unity instance registry directory: ${error instanceof Error ? error.message : String(error)}`,
|
|
66452
|
+
details: { registryDir }
|
|
66483
66453
|
};
|
|
66484
66454
|
}
|
|
66485
66455
|
}
|
|
66456
|
+
function checkPieUnityRpcSkill() {
|
|
66457
|
+
return {
|
|
66458
|
+
id: "pie_unity_rpc_skill",
|
|
66459
|
+
label: "Pie Unity RPC skill",
|
|
66460
|
+
status: "pass",
|
|
66461
|
+
message: "pie-unity-rpc is package-contained. Use the helper from the current Unity project's resolved com.pie.agent package.",
|
|
66462
|
+
details: {
|
|
66463
|
+
lookupOrder: [
|
|
66464
|
+
"Packages/com.pie.agent/Skills/pie-unity-rpc",
|
|
66465
|
+
"Library/PackageCache/com.pie.agent@*/Skills/pie-unity-rpc",
|
|
66466
|
+
"Library/PackageCache/com.pie.agent*/Skills/pie-unity-rpc"
|
|
66467
|
+
]
|
|
66468
|
+
}
|
|
66469
|
+
};
|
|
66470
|
+
}
|
|
66486
66471
|
async function runDoctor() {
|
|
66487
66472
|
const checks = [];
|
|
66488
66473
|
const settings = new SettingsManager();
|
|
@@ -66506,7 +66491,7 @@ async function runDoctor() {
|
|
|
66506
66491
|
let lockPath;
|
|
66507
66492
|
while (dir !== path23.dirname(dir)) {
|
|
66508
66493
|
const candidate = path23.join(dir, "package-lock.json");
|
|
66509
|
-
if (
|
|
66494
|
+
if (fs23.existsSync(candidate)) {
|
|
66510
66495
|
lockPath = candidate;
|
|
66511
66496
|
break;
|
|
66512
66497
|
}
|
|
@@ -66571,6 +66556,26 @@ async function runDoctor() {
|
|
|
66571
66556
|
preferredWebSearchCapability: webSearchCandidates[0]?.model?.webSearch?.type
|
|
66572
66557
|
}
|
|
66573
66558
|
});
|
|
66559
|
+
const webResearchHealth = createCliWebResearchHealthStore(getConfigDir()).loadProviderHealth();
|
|
66560
|
+
checks.push({
|
|
66561
|
+
id: "web_research_health",
|
|
66562
|
+
label: "Web research provider health",
|
|
66563
|
+
status: webResearchHealth.length > 0 ? "pass" : "warn",
|
|
66564
|
+
message: webResearchHealth.length > 0 ? `Loaded health for ${webResearchHealth.length} web research route(s).` : "No web research provider health has been recorded yet. Run verify:web or use web_research once to populate route quality data.",
|
|
66565
|
+
details: {
|
|
66566
|
+
routes: webResearchHealth.slice(0, 8).map((entry) => ({
|
|
66567
|
+
routeKey: entry.routeKey,
|
|
66568
|
+
attempts: entry.attempts,
|
|
66569
|
+
successRate: entry.attempts ? entry.successes / entry.attempts : 0,
|
|
66570
|
+
lowQualityRate: entry.attempts ? entry.lowQuality / entry.attempts : 0,
|
|
66571
|
+
rateLimited: entry.rateLimited,
|
|
66572
|
+
timeouts: entry.timeouts,
|
|
66573
|
+
averageLatencyMs: entry.attempts ? Math.round(entry.totalDurationMs / entry.attempts) : 0,
|
|
66574
|
+
averageSourceCount: entry.attempts ? entry.totalSources / entry.attempts : 0,
|
|
66575
|
+
updatedAt: entry.updatedAt
|
|
66576
|
+
}))
|
|
66577
|
+
}
|
|
66578
|
+
});
|
|
66574
66579
|
checks.push({
|
|
66575
66580
|
id: "tool_model_routes",
|
|
66576
66581
|
label: "Tool model routes",
|
|
@@ -66596,6 +66601,7 @@ async function runDoctor() {
|
|
|
66596
66601
|
checks.push(checkPlaywrightCli());
|
|
66597
66602
|
checks.push(checkPlaywrightBrowser());
|
|
66598
66603
|
checks.push(checkUnityRegistry());
|
|
66604
|
+
checks.push(checkPieUnityRpcSkill());
|
|
66599
66605
|
const runtimeLog = getRuntimeLogPath();
|
|
66600
66606
|
checks.push({
|
|
66601
66607
|
id: "runtime_log",
|
|
@@ -66652,7 +66658,7 @@ Disable or narrow capabilities:
|
|
|
66652
66658
|
}
|
|
66653
66659
|
|
|
66654
66660
|
// src/commands/models-config.ts
|
|
66655
|
-
import * as
|
|
66661
|
+
import * as fs24 from "node:fs";
|
|
66656
66662
|
import * as path24 from "node:path";
|
|
66657
66663
|
function getDefaultModelsPath() {
|
|
66658
66664
|
return path24.join(getConfigDir(), "models.json");
|
|
@@ -66758,16 +66764,16 @@ function initModelsConfig(options = {}) {
|
|
|
66758
66764
|
if (options.stdout) {
|
|
66759
66765
|
return { path: targetPath, content, wrote: false };
|
|
66760
66766
|
}
|
|
66761
|
-
if (
|
|
66767
|
+
if (fs24.existsSync(targetPath) && !options.force) {
|
|
66762
66768
|
throw new Error(`models.json already exists: ${targetPath}. Use --force to overwrite, or --stdout to print the template.`);
|
|
66763
66769
|
}
|
|
66764
|
-
|
|
66765
|
-
|
|
66770
|
+
fs24.mkdirSync(path24.dirname(targetPath), { recursive: true });
|
|
66771
|
+
fs24.writeFileSync(targetPath, content, "utf8");
|
|
66766
66772
|
return { path: targetPath, content, wrote: true };
|
|
66767
66773
|
}
|
|
66768
66774
|
function validateModelsConfig(options = {}) {
|
|
66769
66775
|
const modelsPath = resolveModelsPath(options.path);
|
|
66770
|
-
if (!
|
|
66776
|
+
if (!fs24.existsSync(modelsPath)) {
|
|
66771
66777
|
return {
|
|
66772
66778
|
ok: false,
|
|
66773
66779
|
path: modelsPath,
|
|
@@ -66822,6 +66828,73 @@ function validateModelsConfig(options = {}) {
|
|
|
66822
66828
|
toolModelRoutes
|
|
66823
66829
|
};
|
|
66824
66830
|
}
|
|
66831
|
+
async function probeModelsConfig(options) {
|
|
66832
|
+
const registry = new ModelRegistry(new AuthStorage(), resolveModelsPath(options.path));
|
|
66833
|
+
const loadError = registry.getLoadError();
|
|
66834
|
+
if (loadError) {
|
|
66835
|
+
return {
|
|
66836
|
+
purpose: options.probe,
|
|
66837
|
+
status: "failed",
|
|
66838
|
+
attempts: [],
|
|
66839
|
+
message: `Cannot probe invalid models.json: ${loadError}`
|
|
66840
|
+
};
|
|
66841
|
+
}
|
|
66842
|
+
if (options.probe !== "web_search") {
|
|
66843
|
+
return {
|
|
66844
|
+
purpose: options.probe,
|
|
66845
|
+
status: "skipped",
|
|
66846
|
+
attempts: [],
|
|
66847
|
+
message: `Unsupported probe: ${options.probe}`
|
|
66848
|
+
};
|
|
66849
|
+
}
|
|
66850
|
+
const candidates = registry.resolveToolModelCandidates("web_search").filter((route) => route.model);
|
|
66851
|
+
if (candidates.length === 0) {
|
|
66852
|
+
return {
|
|
66853
|
+
purpose: options.probe,
|
|
66854
|
+
status: "failed",
|
|
66855
|
+
attempts: [],
|
|
66856
|
+
message: "No configured model declares webSearch capability."
|
|
66857
|
+
};
|
|
66858
|
+
}
|
|
66859
|
+
const attempts = [];
|
|
66860
|
+
for (const candidate of candidates.slice(0, 3)) {
|
|
66861
|
+
const route = `${candidate.model?.provider}/${candidate.model?.id}:${candidate.model?.webSearch?.type}:${candidate.routeSource}`;
|
|
66862
|
+
const tool = createSharedWebSearchTool({
|
|
66863
|
+
getModel: () => candidate.model,
|
|
66864
|
+
getApiKey: () => candidate.apiKey,
|
|
66865
|
+
getMode: () => "live",
|
|
66866
|
+
resolveToolModelCandidates: () => [candidate]
|
|
66867
|
+
});
|
|
66868
|
+
try {
|
|
66869
|
+
const result = await tool.execute("models_probe_web_search", { query: "Pie web search capability probe current official source" });
|
|
66870
|
+
const details = result.details;
|
|
66871
|
+
attempts.push({
|
|
66872
|
+
route,
|
|
66873
|
+
status: result.isError ? "failed" : "passed",
|
|
66874
|
+
sourceCount: Number(details?.sourceCount || 0),
|
|
66875
|
+
failureCategory: details?.failureCategory,
|
|
66876
|
+
durationSeconds: details?.durationSeconds,
|
|
66877
|
+
message: result.content.find((item) => item.type === "text")?.text?.slice(0, 240)
|
|
66878
|
+
});
|
|
66879
|
+
if (!result.isError && Number(details?.sourceCount || 0) > 0) break;
|
|
66880
|
+
} catch (error) {
|
|
66881
|
+
attempts.push({
|
|
66882
|
+
route,
|
|
66883
|
+
status: "failed",
|
|
66884
|
+
sourceCount: 0,
|
|
66885
|
+
failureCategory: "provider_compat",
|
|
66886
|
+
message: error instanceof Error ? error.message : String(error)
|
|
66887
|
+
});
|
|
66888
|
+
}
|
|
66889
|
+
}
|
|
66890
|
+
const passed = attempts.some((attempt) => attempt.status === "passed" && attempt.sourceCount > 0);
|
|
66891
|
+
return {
|
|
66892
|
+
purpose: options.probe,
|
|
66893
|
+
status: passed ? "passed" : "failed",
|
|
66894
|
+
attempts,
|
|
66895
|
+
message: passed ? `web_search probe passed using ${attempts.find((attempt) => attempt.status === "passed")?.route}.` : "web_search probe failed for all configured candidate routes."
|
|
66896
|
+
};
|
|
66897
|
+
}
|
|
66825
66898
|
function parseModelsCommandArgs(args) {
|
|
66826
66899
|
const parsed = { force: false, stdout: false };
|
|
66827
66900
|
for (let i = 0; i < args.length; i += 1) {
|
|
@@ -66830,6 +66903,12 @@ function parseModelsCommandArgs(args) {
|
|
|
66830
66903
|
parsed.force = true;
|
|
66831
66904
|
} else if (arg === "--stdout") {
|
|
66832
66905
|
parsed.stdout = true;
|
|
66906
|
+
} else if (arg === "--probe" && args[i + 1]) {
|
|
66907
|
+
parsed.probe = args[i + 1] === "web_search" ? "web_search" : void 0;
|
|
66908
|
+
i += 1;
|
|
66909
|
+
} else if (arg.startsWith("--probe=")) {
|
|
66910
|
+
const value = arg.slice("--probe=".length);
|
|
66911
|
+
parsed.probe = value === "web_search" ? "web_search" : void 0;
|
|
66833
66912
|
} else if (arg === "--path" && args[i + 1]) {
|
|
66834
66913
|
parsed.path = args[i + 1];
|
|
66835
66914
|
i += 1;
|
|
@@ -66846,8 +66925,8 @@ var logError = (msg, err) => {
|
|
|
66846
66925
|
const logPath = getRuntimeLogPath();
|
|
66847
66926
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
66848
66927
|
const stack = err instanceof Error ? err.stack || "" : "";
|
|
66849
|
-
|
|
66850
|
-
|
|
66928
|
+
fs25.mkdirSync(path25.dirname(logPath), { recursive: true });
|
|
66929
|
+
fs25.appendFileSync(logPath, `[${timestamp}] ${msg}
|
|
66851
66930
|
${stack}
|
|
66852
66931
|
|
|
66853
66932
|
`);
|
|
@@ -66860,8 +66939,8 @@ var SKILLS_DIR = path25.join(CONFIG_DIR, "skills");
|
|
|
66860
66939
|
var BUILTIN_DIR = getBuiltinDir();
|
|
66861
66940
|
var BUILTIN_SKILLS_DIR = path25.join(BUILTIN_DIR, "skills");
|
|
66862
66941
|
var BUILTIN_EXTENSIONS_DIR = path25.join(BUILTIN_DIR, "extensions");
|
|
66863
|
-
if (!
|
|
66864
|
-
|
|
66942
|
+
if (!existsSync17(SKILLS_DIR)) {
|
|
66943
|
+
mkdirSync11(SKILLS_DIR, { recursive: true });
|
|
66865
66944
|
}
|
|
66866
66945
|
function maskApiKey2(key) {
|
|
66867
66946
|
if (key.length <= 6) return "***";
|
|
@@ -66916,7 +66995,7 @@ async function runDoctorCommand(args) {
|
|
|
66916
66995
|
process.exitCode = 1;
|
|
66917
66996
|
}
|
|
66918
66997
|
}
|
|
66919
|
-
function runModelsCommand(args) {
|
|
66998
|
+
async function runModelsCommand(args) {
|
|
66920
66999
|
const subcommand = args[0] || "help";
|
|
66921
67000
|
const parsed = parseModelsCommandArgs(args.slice(1));
|
|
66922
67001
|
if (subcommand === "init") {
|
|
@@ -66958,11 +67037,19 @@ function runModelsCommand(args) {
|
|
|
66958
67037
|
if (result.toolModelRoutes && result.toolModelRoutes.length > 0) {
|
|
66959
67038
|
console.log(`Tool model routes: ${result.toolModelRoutes.join(", ")}`);
|
|
66960
67039
|
}
|
|
67040
|
+
if (parsed.probe) {
|
|
67041
|
+
const probe = await probeModelsConfig({ path: parsed.path, probe: parsed.probe });
|
|
67042
|
+
console.log(`Probe ${probe.purpose}: ${probe.message}`);
|
|
67043
|
+
for (const attempt of probe.attempts) {
|
|
67044
|
+
console.log(`- ${attempt.status} ${attempt.route} sources=${attempt.sourceCount}${attempt.failureCategory ? ` failure=${attempt.failureCategory}` : ""}`);
|
|
67045
|
+
}
|
|
67046
|
+
if (probe.status === "failed") process.exitCode = 1;
|
|
67047
|
+
}
|
|
66961
67048
|
return;
|
|
66962
67049
|
}
|
|
66963
67050
|
console.log(`Usage:
|
|
66964
67051
|
pie models init [--path <path>] [--force] [--stdout]
|
|
66965
|
-
pie models validate [--path <path>]`);
|
|
67052
|
+
pie models validate [--path <path>] [--probe web_search]`);
|
|
66966
67053
|
}
|
|
66967
67054
|
function createNoOpExtensionUIContext() {
|
|
66968
67055
|
return {
|
|
@@ -67174,24 +67261,19 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
67174
67261
|
getApiKey: () => interactiveOptions?.apiKey ?? apiKey,
|
|
67175
67262
|
getWebSearchMode: () => settingsManager.getWebSearchMode(),
|
|
67176
67263
|
resolveToolModel: (purpose) => modelRegistry.resolveToolModel(purpose, interactiveOptions?.model ?? model),
|
|
67177
|
-
resolveToolModelCandidates: (purpose) => modelRegistry.resolveToolModelCandidates(purpose, interactiveOptions?.model ?? model)
|
|
67264
|
+
resolveToolModelCandidates: (purpose) => modelRegistry.resolveToolModelCandidates(purpose, interactiveOptions?.model ?? model),
|
|
67265
|
+
configDir: CONFIG_DIR
|
|
67178
67266
|
});
|
|
67179
67267
|
const fileSystemToolOptions = {
|
|
67180
|
-
allowlistedDirs: [CONFIG_DIR],
|
|
67268
|
+
...buildCliFileAccessOptions({ cwd, configDir: CONFIG_DIR, skills, allowlistedDirs: [CONFIG_DIR] }),
|
|
67181
67269
|
configDir: CONFIG_DIR,
|
|
67182
67270
|
getAgentModel: () => interactiveOptions?.model ?? model,
|
|
67183
67271
|
getSessionId: () => sessionManager.getActiveSessionId() || void 0,
|
|
67184
67272
|
resolveToolModel: (purpose) => modelRegistry.resolveToolModel(purpose, interactiveOptions?.model ?? model),
|
|
67185
67273
|
getPolicyContext: () => ({ mode: "normal", confirmationPolicy: "allow" })
|
|
67186
67274
|
};
|
|
67187
|
-
const readSkillTool = createCliReadSkillTool(skills);
|
|
67188
|
-
const readResourceTool = createCliReadResourceTool(skills);
|
|
67189
|
-
const resolveResourceTool = createCliResolveResourceTool(skills);
|
|
67190
67275
|
const tools = createPolicyEnforcedTools([
|
|
67191
67276
|
...createCliFileSystemTools(cwd, fileSystemToolOptions),
|
|
67192
|
-
readSkillTool,
|
|
67193
|
-
readResourceTool,
|
|
67194
|
-
resolveResourceTool,
|
|
67195
67277
|
...cliHostCapabilities.tools
|
|
67196
67278
|
], {
|
|
67197
67279
|
getContext: () => ({ mode: "normal", confirmationPolicy: "allow" })
|
|
@@ -67201,7 +67283,7 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
67201
67283
|
console.log(`[CLI] ${diag.message}`);
|
|
67202
67284
|
}
|
|
67203
67285
|
const skillsSection = formatSkillsForPrompt(skills);
|
|
67204
|
-
const knowledgeSection =
|
|
67286
|
+
const knowledgeSection = buildCliProjectContextSection(cwd);
|
|
67205
67287
|
if (initialPrompt) {
|
|
67206
67288
|
if (initialModel.unconfigured) {
|
|
67207
67289
|
const errorText = initialModel.warning || "No models are configured. Add one in ~/.pie/models.json before sending messages.";
|
|
@@ -67353,9 +67435,9 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
67353
67435
|
flushEarlyLogs();
|
|
67354
67436
|
if (testCommand) {
|
|
67355
67437
|
console.log(`[TEST] Auto-executing command: ${testCommand}`);
|
|
67356
|
-
await new Promise((
|
|
67438
|
+
await new Promise((resolve4) => setTimeout(resolve4, 500));
|
|
67357
67439
|
await interactive.executeCommand(testCommand);
|
|
67358
|
-
await new Promise((
|
|
67440
|
+
await new Promise((resolve4) => setTimeout(resolve4, 2e3));
|
|
67359
67441
|
console.log("[TEST] Command executed, exiting...");
|
|
67360
67442
|
process.exit(0);
|
|
67361
67443
|
return;
|
|
@@ -67378,7 +67460,7 @@ async function main() {
|
|
|
67378
67460
|
}
|
|
67379
67461
|
if (args[0] === "models") {
|
|
67380
67462
|
try {
|
|
67381
|
-
runModelsCommand(args.slice(1));
|
|
67463
|
+
await runModelsCommand(args.slice(1));
|
|
67382
67464
|
} catch (error) {
|
|
67383
67465
|
console.error(error instanceof Error ? error.message : String(error));
|
|
67384
67466
|
process.exitCode = 1;
|