perchai-cli 2.4.18 → 2.4.19

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.
Files changed (2) hide show
  1. package/dist/perch.mjs +74 -23
  2. package/package.json +1 -1
package/dist/perch.mjs CHANGED
@@ -75900,7 +75900,6 @@ function isTurnAbortedError(error) {
75900
75900
  var TURN_STOPPED_BY_USER_MESSAGE;
75901
75901
  var init_turnAbort = __esm({
75902
75902
  "features/perchTerminal/runtime/turnAbort.ts"() {
75903
- "use strict";
75904
75903
  TURN_STOPPED_BY_USER_MESSAGE = "Turn stopped by user.";
75905
75904
  }
75906
75905
  });
@@ -76201,7 +76200,6 @@ function getToolDisplayName(toolName) {
76201
76200
  var NON_MODULE_TOOL_OWNERS, TOOL_RISK, TOOL_DISPLAY_NAMES;
76202
76201
  var init_catalog = __esm({
76203
76202
  "features/perchTerminal/runtime/toolSystem/catalog.ts"() {
76204
- "use strict";
76205
76203
  init_toolNames();
76206
76204
  NON_MODULE_TOOL_OWNERS = {
76207
76205
  [TOOL_NAMES.listSources]: "lane",
@@ -137811,12 +137809,17 @@ async function restartBashTerminal(request) {
137811
137809
  async function runBashTerminalCommand(request) {
137812
137810
  const bridge = getDesktopBridge();
137813
137811
  if (!bridge) return null;
137814
- return bridge.runBashTerminalCommand(request);
137812
+ return bridge.runBashTerminalCommand(stripBrowserOnlyAbortSignal(request));
137815
137813
  }
137816
137814
  async function runLocalBash(request) {
137817
137815
  const bridge = getDesktopBridge();
137818
137816
  if (!bridge) return null;
137819
- return bridge.runLocalBash(withPermissionMode(request, request));
137817
+ return bridge.runLocalBash(withPermissionMode(stripBrowserOnlyAbortSignal(request), request));
137818
+ }
137819
+ function stripBrowserOnlyAbortSignal(request) {
137820
+ if (typeof window === "undefined" || !("signal" in request)) return request;
137821
+ const { signal: _signal, ...rest2 } = request;
137822
+ return rest2;
137820
137823
  }
137821
137824
  async function readWorkspaceFile(request) {
137822
137825
  const bridge = getDesktopBridge();
@@ -213107,18 +213110,24 @@ var init_terminal = __esm({
213107
213110
  command,
213108
213111
  cwd: cwd2,
213109
213112
  timeoutMs,
213110
- fsAccessOverride: ctx.fsAccessOverride
213113
+ fsAccessOverride: ctx.fsAccessOverride,
213114
+ signal: ctx.cliLocalTools ? ctx.signal : void 0
213111
213115
  });
213112
213116
  }
213113
213117
  };
213114
213118
  runBashTerminalCommandTool = {
213115
213119
  name: TOOL_NAMES.runBashTerminalCommand,
213116
213120
  classification: { native: false },
213117
- handler: async (args) => {
213121
+ handler: async (args, ctx) => {
213118
213122
  const command = String(args.command ?? "");
213119
213123
  const cwd2 = args.cwd ? String(args.cwd) : void 0;
213120
213124
  const commandArgs = Array.isArray(args.args) ? args.args.map(String) : void 0;
213121
- return runBashTerminalCommand({ command, cwd: cwd2, args: commandArgs });
213125
+ return runBashTerminalCommand({
213126
+ command,
213127
+ cwd: cwd2,
213128
+ args: commandArgs,
213129
+ signal: ctx.cliLocalTools ? ctx.signal : void 0
213130
+ });
213122
213131
  }
213123
213132
  };
213124
213133
  terminalTools = [bashTool, runBashTerminalCommandTool];
@@ -213769,6 +213778,11 @@ var init_fixtureStore = __esm({
213769
213778
  function calendarTicker() {
213770
213779
  return process.env.PERCH_MARKET_CALENDAR_TICKER || "SPY";
213771
213780
  }
213781
+ function sourceRank(source) {
213782
+ if (source === "yahoo") return 3;
213783
+ if (source === "stooq") return 2;
213784
+ return 1;
213785
+ }
213772
213786
  function createSupabaseMarketStore(supabase) {
213773
213787
  return {
213774
213788
  async listInstruments() {
@@ -213786,13 +213800,13 @@ function createSupabaseMarketStore(supabase) {
213786
213800
  async getBars(ticker, opts) {
213787
213801
  const cutoff = endOfDayUtc(opts.upTo);
213788
213802
  const wanted = opts.lookbackBars ?? Number.MAX_SAFE_INTEGER;
213789
- const rows = [];
213790
- for (let page2 = 0; rows.length < wanted; page2++) {
213791
- const { data, error } = await supabase.from("perch_ai_market_bars").select("bar_date, open, high, low, close, adj_close, volume, known_at").eq("ticker", ticker).lte("bar_date", opts.upTo).lte("known_at", cutoff).order("bar_date", { ascending: false }).range(page2 * PAGE_SIZE, page2 * PAGE_SIZE + PAGE_SIZE - 1);
213803
+ const byDate = /* @__PURE__ */ new Map();
213804
+ for (let page2 = 0; byDate.size < wanted; page2++) {
213805
+ const { data, error } = await supabase.from("perch_ai_market_bars").select("bar_date, open, high, low, close, adj_close, volume, known_at, source").eq("ticker", ticker).lte("bar_date", opts.upTo).lte("known_at", cutoff).order("bar_date", { ascending: false }).order("known_at", { ascending: false }).range(page2 * PAGE_SIZE, page2 * PAGE_SIZE + PAGE_SIZE - 1);
213792
213806
  if (error) throw new Error(`market bars read failed: ${error.message}`);
213793
213807
  const batch = data ?? [];
213794
213808
  for (const row of batch) {
213795
- rows.push({
213809
+ const bar = {
213796
213810
  ticker,
213797
213811
  date: row.bar_date,
213798
213812
  open: row.open === null ? void 0 : Number(row.open),
@@ -213801,13 +213815,17 @@ function createSupabaseMarketStore(supabase) {
213801
213815
  close: Number(row.close),
213802
213816
  adjClose: row.adj_close === null ? Number(row.close) : Number(row.adj_close),
213803
213817
  volume: row.volume === null ? void 0 : Number(row.volume),
213804
- knownAt: row.known_at
213805
- });
213806
- if (rows.length >= wanted) break;
213818
+ knownAt: row.known_at,
213819
+ source: row.source ?? void 0
213820
+ };
213821
+ const existing = byDate.get(bar.date);
213822
+ if (!existing || sourceRank(bar.source) > sourceRank(existing.source)) {
213823
+ byDate.set(bar.date, bar);
213824
+ }
213807
213825
  }
213808
213826
  if (batch.length < PAGE_SIZE) break;
213809
213827
  }
213810
- return rows.reverse();
213828
+ return [...byDate.values()].sort((a, b2) => a.date > b2.date ? -1 : a.date < b2.date ? 1 : 0).slice(0, wanted).reverse().map(({ source: _source, ...bar }) => bar);
213811
213829
  },
213812
213830
  async getTradingDates(opts) {
213813
213831
  const dates = [];
@@ -226567,7 +226585,8 @@ function createCliNodeLocalBridge(input) {
226567
226585
  workspaceRoot: resolveRequestRoot(workspaceRoot, request.workspaceRoot),
226568
226586
  command: request.command,
226569
226587
  cwd: request.cwd,
226570
- timeoutMs: request.timeoutMs
226588
+ timeoutMs: request.timeoutMs,
226589
+ signal: request.signal
226571
226590
  }),
226572
226591
  runBashTerminalCommand: async (request) => {
226573
226592
  const startedAt = Date.now();
@@ -226575,7 +226594,8 @@ function createCliNodeLocalBridge(input) {
226575
226594
  const result2 = await runShellCommand({
226576
226595
  workspaceRoot,
226577
226596
  command: request.args?.length ? shellQuote([request.command, ...request.args]) : request.command,
226578
- cwd: request.cwd
226597
+ cwd: request.cwd,
226598
+ signal: request.signal
226579
226599
  });
226580
226600
  return {
226581
226601
  ok: result2.ok,
@@ -227063,15 +227083,28 @@ async function runShellCommand(input) {
227063
227083
  const child = spawn2(process.env.SHELL || "/bin/zsh", ["-lc", input.command], {
227064
227084
  cwd: cwd2,
227065
227085
  env: process.env,
227066
- stdio: ["ignore", "pipe", "pipe"]
227086
+ stdio: ["ignore", "pipe", "pipe"],
227087
+ detached: true
227067
227088
  });
227068
227089
  let stdout = "";
227069
227090
  let stderr = "";
227070
227091
  let timedOut = false;
227092
+ let aborted = false;
227093
+ let settled = false;
227094
+ const stopChild = (reason) => {
227095
+ if (reason === "abort") aborted = true;
227096
+ if (reason === "timeout") timedOut = true;
227097
+ terminateProcessGroup(child, "SIGTERM");
227098
+ setTimeout(() => {
227099
+ if (!settled) terminateProcessGroup(child, "SIGKILL");
227100
+ }, 1e3).unref?.();
227101
+ };
227071
227102
  const timer = setTimeout(() => {
227072
- timedOut = true;
227073
- child.kill("SIGTERM");
227103
+ stopChild("timeout");
227074
227104
  }, timeoutMs);
227105
+ const onAbort = () => stopChild("abort");
227106
+ if (input.signal?.aborted) onAbort();
227107
+ input.signal?.addEventListener("abort", onAbort, { once: true });
227075
227108
  child.stdout.on("data", (chunk2) => {
227076
227109
  stdout += String(chunk2);
227077
227110
  });
@@ -227079,7 +227112,9 @@ async function runShellCommand(input) {
227079
227112
  stderr += String(chunk2);
227080
227113
  });
227081
227114
  child.on("error", (error) => {
227115
+ settled = true;
227082
227116
  clearTimeout(timer);
227117
+ input.signal?.removeEventListener("abort", onAbort);
227083
227118
  resolve5({
227084
227119
  ok: false,
227085
227120
  stdout,
@@ -227095,10 +227130,12 @@ async function runShellCommand(input) {
227095
227130
  });
227096
227131
  });
227097
227132
  child.on("close", (code, signal) => {
227133
+ settled = true;
227098
227134
  clearTimeout(timer);
227135
+ input.signal?.removeEventListener("abort", onAbort);
227099
227136
  const capped = capOutput(stdout, stderr);
227100
227137
  resolve5({
227101
- ok: code === 0 && !timedOut,
227138
+ ok: code === 0 && !timedOut && !aborted,
227102
227139
  stdout: capped.stdout,
227103
227140
  stderr: capped.stderr,
227104
227141
  exitCode: code,
@@ -227109,11 +227146,25 @@ async function runShellCommand(input) {
227109
227146
  command: input.command,
227110
227147
  cwd: cwd2,
227111
227148
  executionHost: "electron_desktop",
227112
- ...timedOut ? { errorCode: "timed_out", errorMessage: `Command timed out after ${timeoutMs}ms.` } : {}
227149
+ ...timedOut ? { errorCode: "timed_out", errorMessage: `Command timed out after ${timeoutMs}ms.` } : {},
227150
+ ...aborted ? { errorCode: "aborted", errorMessage: "Command stopped by user." } : {}
227113
227151
  });
227114
227152
  });
227115
227153
  });
227116
227154
  }
227155
+ function terminateProcessGroup(child, signal) {
227156
+ if (child.pid) {
227157
+ try {
227158
+ process.kill(-child.pid, signal);
227159
+ return;
227160
+ } catch {
227161
+ }
227162
+ }
227163
+ try {
227164
+ child.kill(signal);
227165
+ } catch {
227166
+ }
227167
+ }
227117
227168
  function resolveReadPath(root2, inputPath) {
227118
227169
  const expanded = expandHome4(inputPath || ".");
227119
227170
  return path11.resolve(path11.isAbsolute(expanded) ? expanded : path11.join(root2, expanded));
@@ -284616,7 +284667,7 @@ Usage:
284616
284667
  perch login
284617
284668
  perch status
284618
284669
  perch logout
284619
- perch run "<task>" [--json] [--cwd <dir>] [--mode ask|agents|plan] [--persona saffron|quill]
284670
+ perch run "<task>" [--json] [--thread <id>] [--cwd <dir>] [--mode ask|agents|plan] [--persona saffron|quill]
284620
284671
  perch ap evidence <folder> [--json] [--out <dir>] [--timestamp <id>]
284621
284672
  perch ap packet <folder> [--json] [--out <dir>] [--timestamp <id>]
284622
284673
  perch test ap <folder> [--json] [--out <dir>] [--timestamp <id>] [--profile financial-lab-v2] [--expect key=value]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perchai-cli",
3
- "version": "2.4.18",
3
+ "version": "2.4.19",
4
4
  "description": "Perch AI command-line interface",
5
5
  "bin": {
6
6
  "perch": "bin/perch"