@hasna/loops 0.3.30 → 0.3.32

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/index.js CHANGED
@@ -2245,9 +2245,10 @@ class Store {
2245
2245
 
2246
2246
  // src/cli/index.ts
2247
2247
  import { createHash as createHash2, randomUUID } from "crypto";
2248
- import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync2, realpathSync, writeFileSync as writeFileSync3 } from "fs";
2248
+ import { closeSync, existsSync as existsSync4, mkdirSync as mkdirSync5, mkdtempSync, openSync as openSync2, readFileSync as readFileSync2, realpathSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2249
2249
  import { spawnSync as spawnSync5 } from "child_process";
2250
2250
  import { join as join4, resolve as resolve2 } from "path";
2251
+ import { tmpdir } from "os";
2251
2252
  import { Database as Database2 } from "bun:sqlite";
2252
2253
  import { Command } from "commander";
2253
2254
 
@@ -5253,7 +5254,7 @@ function buildScriptInventoryReport(store, opts = {}) {
5253
5254
  // package.json
5254
5255
  var package_default = {
5255
5256
  name: "@hasna/loops",
5256
- version: "0.3.30",
5257
+ version: "0.3.32",
5257
5258
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5258
5259
  type: "module",
5259
5260
  main: "dist/index.js",
@@ -6211,7 +6212,7 @@ function runLocalCommand(command, args, opts = {}) {
6211
6212
  input: opts.input,
6212
6213
  encoding: "utf8",
6213
6214
  timeout: opts.timeoutMs ?? 30000,
6214
- maxBuffer: 8 * 1024 * 1024,
6215
+ maxBuffer: opts.maxBuffer ?? 8 * 1024 * 1024,
6215
6216
  env: process.env
6216
6217
  });
6217
6218
  return {
@@ -6222,6 +6223,35 @@ function runLocalCommand(command, args, opts = {}) {
6222
6223
  error: result.error ? String(result.error.message || result.error) : ""
6223
6224
  };
6224
6225
  }
6226
+ function runLocalCommandWithStdoutFile(command, args, opts = {}) {
6227
+ const tempDir = mkdtempSync(join4(tmpdir(), "loops-command-output-"));
6228
+ const stdoutPath = join4(tempDir, "stdout");
6229
+ const stdoutFd = openSync2(stdoutPath, "w");
6230
+ let result;
6231
+ try {
6232
+ result = spawnSync5(command, args, {
6233
+ input: opts.input,
6234
+ encoding: "utf8",
6235
+ timeout: opts.timeoutMs ?? 30000,
6236
+ maxBuffer: opts.maxBuffer ?? 8 * 1024 * 1024,
6237
+ env: process.env,
6238
+ stdio: ["pipe", stdoutFd, "pipe"]
6239
+ });
6240
+ } finally {
6241
+ closeSync(stdoutFd);
6242
+ }
6243
+ try {
6244
+ return {
6245
+ ok: result.status === 0,
6246
+ status: result.status,
6247
+ stdout: readFileSync2(stdoutPath, "utf8"),
6248
+ stderr: typeof result.stderr === "string" ? result.stderr : result.stderr?.toString() || "",
6249
+ error: result.error ? String(result.error.message || result.error) : ""
6250
+ };
6251
+ } finally {
6252
+ rmSync2(tempDir, { recursive: true, force: true });
6253
+ }
6254
+ }
6225
6255
  function ensureTodosTaskList(project, slug, name, description) {
6226
6256
  runLocalCommand("todos", ["--project", project, "task-lists", "--add", name, "--slug", slug, "-d", description]);
6227
6257
  const list = runLocalCommand("todos", ["--project", project, "--json", "task-lists"]);
@@ -6901,10 +6931,16 @@ function taskDrainEvent(task) {
6901
6931
  function loadReadyTodosTasks(opts, scanLimit) {
6902
6932
  const todosProject = opts.todosProject ?? defaultLoopsProject();
6903
6933
  const args = ["--project", todosProject, "--json", "ready", "--limit", String(scanLimit)];
6904
- const result = runLocalCommand("todos", args, { timeoutMs: 60000 });
6934
+ const result = runLocalCommandWithStdoutFile("todos", args, { timeoutMs: 60000, maxBuffer: 64 * 1024 * 1024 });
6905
6935
  if (!result.ok)
6906
6936
  throw new Error(result.stderr || result.error || "todos ready failed");
6907
- const parsed = JSON.parse(result.stdout || "[]");
6937
+ let parsed;
6938
+ try {
6939
+ parsed = JSON.parse(result.stdout || "[]");
6940
+ } catch (error) {
6941
+ const message = error instanceof Error ? error.message : String(error);
6942
+ throw new Error(`failed to parse todos ready --json output (${result.stdout.length} bytes): ${message}`);
6943
+ }
6908
6944
  if (!Array.isArray(parsed))
6909
6945
  throw new Error("todos ready --json returned a non-array value");
6910
6946
  return parsed;
@@ -4574,7 +4574,7 @@ function enableStartup(result) {
4574
4574
  // package.json
4575
4575
  var package_default = {
4576
4576
  name: "@hasna/loops",
4577
- version: "0.3.30",
4577
+ version: "0.3.32",
4578
4578
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
4579
4579
  type: "module",
4580
4580
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/loops",
3
- "version": "0.3.30",
3
+ "version": "0.3.32",
4
4
  "description": "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",