@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/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
- } from "./chunks/chunk-GDTN4UPJ.js";
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
- buildKnowledgeIndexEntry,
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-BHNULR7U.js";
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 join20(regexps, separator = "|") {
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(join20(terminators), true);
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 VERSION2 = "HTTP/(2|1\\.[01])";
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: "^(?=" + VERSION2 + " \\d{3})",
14099
+ begin: "^(?=" + VERSION + " \\d{3})",
14086
14100
  end: /$/,
14087
14101
  contains: [
14088
14102
  {
14089
14103
  className: "meta",
14090
- begin: VERSION2
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]+ (.*?) " + VERSION2 + "$)",
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: VERSION2
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((resolve6) => setTimeout(resolve6, Math.min(idleMs, timeLeft)));
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 as existsSync2, readFileSync as readFileSync2 } from "fs";
50633
- import { join as join3 } from "path";
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 = join3(agentDir, "keybindings.json");
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 (!existsSync2(path26)) return {};
50728
+ if (!existsSync(path26)) return {};
50827
50729
  try {
50828
- return JSON.parse(readFileSync2(path26, "utf-8"));
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 buildCliKnowledgeIndexSection(cwd) {
50880
- const agentsPath = path2.join(cwd, ".pie", "agents.md");
50881
- if (!fs3.existsSync(agentsPath)) return "";
50882
- try {
50883
- const content = fs3.readFileSync(agentsPath, "utf-8");
50884
- const entry = buildKnowledgeIndexEntry(".pie/agents.md", content);
50885
- return buildKnowledgeIndexSection(entry ? [entry] : []);
50886
- } catch {
50887
- return "";
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 path3 from "node:path";
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 = path3.join(themesDir, "dark.json");
51781
- const lightPath = path3.join(themesDir, "light.json");
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 = path3.join(customThemesDir, `${name}.json`);
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 = path3.join(customThemesDir, `${currentThemeName}.json`);
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 path4 from "path";
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 = path4.join(dir, entry.name);
52143
+ const fullPath = path5.join(dir, entry.name);
52222
52144
  if (entry.isDirectory()) {
52223
- const skillMdPath = path4.join(fullPath, "SKILL.md");
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 fs7 from "fs";
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 (!fs7.existsSync(dir)) {
52564
- fs7.mkdirSync(dir, { recursive: true });
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 (fs7.existsSync(this.config.filePath)) {
52603
- fs7.writeFileSync(this.config.filePath, "");
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 (fs7.existsSync(this.config.filePath)) {
52645
- const stats = fs7.statSync(this.config.filePath);
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 (!fs7.existsSync(this.config.filePath)) {
52503
+ if (!fs6.existsSync(this.config.filePath)) {
52660
52504
  return [];
52661
52505
  }
52662
52506
  try {
52663
- const content = fs7.readFileSync(this.config.filePath, "utf-8");
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 (!fs7.existsSync(dir)) {
52682
- fs7.mkdirSync(dir, { recursive: true });
52525
+ if (!fs6.existsSync(dir)) {
52526
+ fs6.mkdirSync(dir, { recursive: true });
52683
52527
  }
52684
- fs7.appendFileSync(this.config.filePath, entry + "\n");
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 fs15 from "node:fs/promises";
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 fs8 from "node:fs";
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 = fs8.statSync(filePath);
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 = fs8.readFileSync(filePath);
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 fs9 from "node:fs";
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 = fs9.statSync(filePath);
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(fs9.createReadStream(filePath));
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 fs10 from "node:fs";
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 = fs10.statSync(filePath);
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([fs10.readFileSync(filePath)], fileName, { type: mimeType });
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 fs14 from "node:fs";
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 fs11 from "node:fs";
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(process.env.HOME || ".", inputPath.slice(1));
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 (!fs11.existsSync(this.baseDir)) {
53784
- fs11.mkdirSync(this.baseDir, { recursive: true });
53641
+ if (!fs10.existsSync(this.baseDir)) {
53642
+ fs10.mkdirSync(this.baseDir, { recursive: true });
53785
53643
  }
53786
- if (!fs11.existsSync(this.dataDir)) {
53787
- fs11.mkdirSync(this.dataDir, { recursive: true });
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 (!fs11.existsSync(this.indexPath)) {
53652
+ if (!fs10.existsSync(this.indexPath)) {
53795
53653
  return { version: CACHE_VERSION, files: {}, pathHints: {} };
53796
53654
  }
53797
53655
  try {
53798
- const data = JSON.parse(fs11.readFileSync(this.indexPath, "utf-8"));
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
- fs11.writeFileSync(this.indexPath, JSON.stringify(this.index, null, 2));
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((resolve6, reject) => {
53682
+ return new Promise((resolve4, reject) => {
53825
53683
  const hash = crypto.createHash("sha256");
53826
- const stream = fs11.createReadStream(filePath);
53684
+ const stream = fs10.createReadStream(filePath);
53827
53685
  stream.on("data", (chunk) => hash.update(chunk));
53828
- stream.on("end", () => resolve6(hash.digest("hex")));
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 (!fs11.existsSync(fullDir)) {
53842
- fs11.mkdirSync(fullDir, { recursive: true });
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 (fs11.existsSync(storagePath)) {
53712
+ if (fs10.existsSync(storagePath)) {
53855
53713
  return { hash, localPath: storagePath };
53856
53714
  }
53857
- fs11.copyFileSync(sourcePath, storagePath);
53858
- const stat2 = fs11.statSync(storagePath);
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 (fs11.existsSync(storagePath)) {
53733
+ if (fs10.existsSync(storagePath)) {
53876
53734
  return { hash, localPath: storagePath };
53877
53735
  }
53878
- fs11.writeFileSync(storagePath, data);
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 = fs11.statSync(resolvedPath);
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 = fs11.statSync(resolvedPath);
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 (fs11.existsSync(localPath)) {
54040
- fs11.unlinkSync(localPath);
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 (fs11.existsSync(localPath)) {
54056
- fs11.unlinkSync(localPath);
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 fs11.realpathSync.native ? fs11.realpathSync.native(resolvedPath) : fs11.realpathSync(resolvedPath);
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 fs12 from "node:fs";
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 (!fs12.existsSync(this.sessionsDir)) {
54178
- fs12.mkdirSync(this.sessionsDir, { recursive: true });
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 (!fs12.existsSync(this.statePath)) {
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(fs12.readFileSync(this.statePath, "utf-8"));
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 (fs12.existsSync(this.statePath)) {
54207
- fs12.unlinkSync(this.statePath);
54064
+ if (fs11.existsSync(this.statePath)) {
54065
+ fs11.unlinkSync(this.statePath);
54208
54066
  }
54209
54067
  return;
54210
54068
  }
54211
- fs12.writeFileSync(this.statePath, JSON.stringify(this.state, null, 2));
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 || !fs12.existsSync(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 (!fs12.existsSync(sessionsDir)) return;
54366
+ if (!fs11.existsSync(sessionsDir)) return;
54509
54367
  const now = Date.now();
54510
- const files = fs12.readdirSync(sessionsDir);
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 = fs12.statSync(filePath);
54372
+ const stat2 = fs11.statSync(filePath);
54515
54373
  if (now - stat2.mtime.getTime() > maxAge) {
54516
- fs12.unlinkSync(filePath);
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 fs13 from "node:fs";
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((resolve6) => {
54396
+ return new Promise((resolve4) => {
54539
54397
  const proc = spawn(this.ffmpegPath, ["-version"]);
54540
- proc.on("error", () => resolve6(false));
54541
- proc.on("exit", (code) => resolve6(code === 0));
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((resolve6, reject) => {
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
- resolve6(info);
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 = fs13.statSync(outputPath);
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
- fs13.mkdirSync(framesDir, { recursive: true });
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 = fs13.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path13.join(framesDir, f));
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
- fs13.rmSync(framesDir, { recursive: true, force: true });
54714
- fs13.mkdirSync(framesDir, { recursive: true });
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 = fs13.readdirSync(framesDir).filter((f) => f.endsWith(".jpg")).sort().map((f) => path13.join(framesDir, f));
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 + fs13.statSync(f).size,
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((resolve6, reject) => {
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
- resolve6();
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((resolve6, reject) => {
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
- resolve6();
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 (!fs14.existsSync(this.tempDir)) {
54954
- fs14.mkdirSync(this.tempDir, { recursive: true });
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 (!fs14.existsSync(resolvedPath)) {
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 ?? fs14.statSync(resolvedPath).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 (!fs14.existsSync(resolvedPath)) {
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 (!fs14.existsSync(resolvedPath)) {
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
- fs14.unlinkSync(optimizedPath);
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 (!fs14.existsSync(resolvedPath)) {
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 (fs14.existsSync(output)) {
55531
- fs14.unlinkSync(output);
55388
+ if (fs13.existsSync(output)) {
55389
+ fs13.unlinkSync(output);
55532
55390
  }
55533
55391
  } else {
55534
55392
  for (const file of output) {
55535
- if (fs14.existsSync(file)) {
55536
- fs14.unlinkSync(file);
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 && fs14.existsSync(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 = fs14.readdirSync(resolvedDir, { withFileTypes: true });
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 = fs14.statSync(fullPath);
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 = fs14.statSync(fullPath);
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 fs15.stat(params.request.absolutePath);
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 fs15.readFile(params.request.absolutePath, "base64");
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((resolve6) => setTimeout(resolve6, 1500));
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. Cleared the remaining todo list.";
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 fs16 from "node:fs";
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 (!fs16.existsSync(tracePath)) return null;
56040
+ if (!fs15.existsSync(tracePath)) return null;
56163
56041
  try {
56164
- return JSON.parse(fs16.readFileSync(tracePath, "utf8"));
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
- fs16.writeFileSync(tempPath, JSON.stringify(trace, null, 2), "utf8");
56173
- fs16.renameSync(tempPath, tracePath);
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((resolve6) => setTimeout(resolve6, 2e3));
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 fs17 from "fs";
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 = fs17.readFileSync(skill.filePath, "utf-8");
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 (fs17.existsSync(skillDir)) {
59155
+ if (fs16.existsSync(skillDir)) {
59278
59156
  host.showError(`Skill "${name}" already exists at ${skillDir}`);
59279
59157
  return;
59280
59158
  }
59281
- fs17.mkdirSync(skillDir, { recursive: true });
59159
+ fs16.mkdirSync(skillDir, { recursive: true });
59282
59160
  const template = createSkillTemplate(name, description);
59283
- fs17.writeFileSync(skillFile, template, "utf-8");
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] message_end fired, setting status: ready`);
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: "message_start" });
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: "message_update" });
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: "tool_execution_start" });
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: "tool_execution_update" });
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: "tool_execution_end" });
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: "message_end" });
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((resolve6) => setImmediate(resolve6));
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 fs20 from "fs";
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 fs18 from "node:fs";
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 (!fs18.existsSync(filePath)) {
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 (!fs18.existsSync(resolvedPath)) {
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 (!fs18.existsSync(resolvedPath)) {
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 fs19 from "node:fs";
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 (fs19.existsSync(resolvedPath)) {
61865
- const stats = fs19.statSync(resolvedPath);
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 ? fs19.existsSync(queryPath) && fs19.statSync(queryPath).isDirectory() ? "" : path19.basename(queryPath) : query;
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 (fs19.existsSync(resolvedPath) && fs19.statSync(resolvedPath).isDirectory()) {
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 query.startsWith("/") || query.startsWith("~") || query.startsWith("./") || query.startsWith("../");
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 ?? fs20.readFileSync(item.path, "base64");
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 ?? fs20.readFileSync(item.path, "base64");
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 (hasWebSearch) {
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((resolve6) => {
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
- resolve6();
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((resolve6, reject) => {
63858
- const timer = setTimeout(() => resolve6({ timedOut: true }), request.timeoutMs);
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
- resolve6({ value, timedOut: false });
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((resolve6) => {
63882
+ return new Promise((resolve4) => {
63962
63883
  host.showStatus(`Waiting for selection: ${title}`);
63963
63884
  if (opts?.signal?.aborted) {
63964
- resolve6(void 0);
63885
+ resolve4(void 0);
63965
63886
  return;
63966
63887
  }
63967
63888
  const onAbort = () => {
63968
63889
  host.restoreEditor();
63969
- resolve6(void 0);
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
- resolve6(option);
63899
+ resolve4(option);
63979
63900
  },
63980
63901
  () => {
63981
63902
  opts?.signal?.removeEventListener("abort", onAbort);
63982
63903
  host.restoreEditor();
63983
- resolve6(void 0);
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((resolve6) => {
63920
+ return new Promise((resolve4) => {
64000
63921
  host.showStatus(`Waiting for input: ${title}`);
64001
63922
  if (opts?.signal?.aborted) {
64002
- resolve6(void 0);
63923
+ resolve4(void 0);
64003
63924
  return;
64004
63925
  }
64005
63926
  const onAbort = () => {
64006
63927
  host.restoreEditor();
64007
- resolve6(void 0);
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
- resolve6(value);
63937
+ resolve4(value);
64017
63938
  },
64018
63939
  () => {
64019
63940
  opts?.signal?.removeEventListener("abort", onAbort);
64020
63941
  host.restoreEditor();
64021
- resolve6(void 0);
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((resolve6) => {
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
- resolve6(value);
63975
+ resolve4(value);
64055
63976
  };
64056
63977
  editor.onEscape = () => {
64057
63978
  host.logDebug("extension:editor:cancel", { title });
64058
63979
  host.restoreEditor();
64059
- resolve6(void 0);
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((resolve6, reject) => {
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
- resolve6(result);
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 fs21 from "node:fs";
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 (!fs21.existsSync(resolvedPath)) {
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 (!fs21.existsSync(dir)) {
64280
+ if (!fs20.existsSync(dir)) {
64360
64281
  return [];
64361
64282
  }
64362
64283
  const discovered = [];
64363
64284
  try {
64364
- const entries = fs21.readdirSync(dir, { withFileTypes: true });
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 (fs21.existsSync(packageJsonPath)) {
64294
+ if (fs20.existsSync(packageJsonPath)) {
64374
64295
  try {
64375
- const pkg2 = JSON.parse(fs21.readFileSync(packageJsonPath, "utf-8"));
64376
- const manifest = pkg2.pie;
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 (fs21.existsSync(mainPath)) {
64300
+ if (fs20.existsSync(mainPath)) {
64380
64301
  discovered.push({
64381
64302
  entryPath: mainPath,
64382
- manifestName: manifest.name || pkg2.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 (fs21.existsSync(indexCjs)) {
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 (fs21.existsSync(indexJs)) {
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 (fs21.existsSync(indexTs)) {
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 (!fs21.existsSync(resolved)) {
64371
+ if (!fs20.existsSync(resolved)) {
64451
64372
  errors.push({ path: p, error: `Extension path not found: ${p}` });
64452
64373
  continue;
64453
64374
  }
64454
- if (!fs21.statSync(resolved).isDirectory()) {
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 = buildCliKnowledgeIndexSection(options.cwd);
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) && tool.name !== "read_skill" && tool.name !== "read_resource" && tool.name !== "resolve_resource"
65165
+ (tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name)
65245
65166
  );
65246
65167
  const fileSystemToolOptions = (allowlistedDirs) => ({
65247
- allowlistedDirs,
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, readSkillTool, readResourceTool, resolveResourceTool, ...preservedTools],
65193
+ [...currentFsTools, ...preservedTools],
65271
65194
  { getContext: getPolicyContext }
65272
65195
  ),
65273
65196
  originalTools: createPolicyEnforcedTools(
65274
- [...normalFsTools, readSkillTool, readResourceTool, resolveResourceTool, ...preservedTools],
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 mkdirSync12, existsSync as existsSync19 } from "fs";
65769
- import * as fs26 from "fs";
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 fs22 from "fs";
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 (!fs22.existsSync(filePath)) return null;
65844
+ if (!fs21.existsSync(filePath)) return null;
65922
65845
  try {
65923
- return JSON.parse(fs22.readFileSync(filePath, "utf-8"));
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
- fs22.mkdirSync(getConfigDir(), { recursive: true });
65858
+ fs21.mkdirSync(getConfigDir(), { recursive: true });
65936
65859
  }
65937
65860
  writeSettings() {
65938
65861
  this.ensureDir();
65939
- fs22.writeFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2));
65862
+ fs21.writeFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2));
65940
65863
  }
65941
65864
  writeLegacyConfig() {
65942
65865
  this.ensureDir();
65943
- fs22.writeFileSync(this.legacyConfigPath, JSON.stringify(this.legacyConfig, null, 2));
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 fs23 from "fs";
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 (!fs23.existsSync(this.modelsPath)) {
65981
+ if (!fs22.existsSync(this.modelsPath)) {
66059
65982
  return;
66060
65983
  }
66061
65984
  try {
66062
- const raw = JSON.parse(fs23.readFileSync(this.modelsPath, "utf-8"));
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 fs24 from "node:fs";
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
- fs24.mkdirSync(dir, { recursive: true });
66271
+ fs23.mkdirSync(dir, { recursive: true });
66348
66272
  const probe = path23.join(dir, `.pie-doctor-${process.pid}-${Date.now()}`);
66349
- fs24.writeFileSync(probe, "ok", "utf8");
66350
- fs24.rmSync(probe, { force: true });
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 || !fs24.existsSync(candidate)) return false;
66281
+ if (!candidate || !fs23.existsSync(candidate)) return false;
66358
66282
  try {
66359
- fs24.accessSync(candidate, fs24.constants.X_OK);
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 && fs24.existsSync(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 registryPath = path23.join(os5.homedir(), ".pie-unity", "registry.json");
66457
- if (!fs24.existsSync(registryPath)) {
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: { registryPath }
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 raw = JSON.parse(fs24.readFileSync(registryPath, "utf8"));
66468
- const instances = Array.isArray(raw?.instances) ? raw.instances : [];
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: instances.length > 0 ? "pass" : "warn",
66473
- message: instances.length > 0 ? `Found ${instances.length} registered pie-unity instance(s).` : "pie-unity registry exists but has no instances.",
66474
- details: { registryPath, instances: instances.length }
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: { registryPath }
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 (fs24.existsSync(candidate)) {
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 fs25 from "node:fs";
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 (fs25.existsSync(targetPath) && !options.force) {
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
- fs25.mkdirSync(path24.dirname(targetPath), { recursive: true });
66765
- fs25.writeFileSync(targetPath, content, "utf8");
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 (!fs25.existsSync(modelsPath)) {
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
- fs26.mkdirSync(path25.dirname(logPath), { recursive: true });
66850
- fs26.appendFileSync(logPath, `[${timestamp}] ${msg}
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 (!existsSync19(SKILLS_DIR)) {
66864
- mkdirSync12(SKILLS_DIR, { recursive: true });
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 = buildCliKnowledgeIndexSection(cwd);
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((resolve6) => setTimeout(resolve6, 500));
67438
+ await new Promise((resolve4) => setTimeout(resolve4, 500));
67357
67439
  await interactive.executeCommand(testCommand);
67358
- await new Promise((resolve6) => setTimeout(resolve6, 2e3));
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;