indusagi 0.13.8 → 0.13.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/swarm.js CHANGED
@@ -4781,7 +4781,7 @@ var ToolRegistry = class {
4781
4781
 
4782
4782
  // src/capabilities/backends/node-backends.ts
4783
4783
  import { promises as fsp } from "node:fs";
4784
- import { spawn as childSpawn } from "node:child_process";
4784
+ import { spawn as childSpawn, spawnSync } from "node:child_process";
4785
4785
  var NodeFs = class {
4786
4786
  async readFile(path, encoding) {
4787
4787
  if (encoding === void 0) {
@@ -4841,6 +4841,21 @@ function joinChunks(chunks) {
4841
4841
  function asSignal(signal) {
4842
4842
  return signal;
4843
4843
  }
4844
+ function killProcessTree(child, signal = "SIGTERM") {
4845
+ if (child.pid === void 0) return;
4846
+ if (process.platform === "win32") {
4847
+ spawnSync("taskkill", ["/F", "/T", "/PID", String(child.pid)], {
4848
+ stdio: "ignore",
4849
+ windowsHide: true
4850
+ });
4851
+ return;
4852
+ }
4853
+ try {
4854
+ process.kill(-child.pid, signal);
4855
+ } catch {
4856
+ child.kill(signal);
4857
+ }
4858
+ }
4844
4859
  var NodeShell = class {
4845
4860
  exec(command, options) {
4846
4861
  if (typeof command !== "string" || command.length === 0) {
@@ -4851,21 +4866,30 @@ var NodeShell = class {
4851
4866
  return new Promise((resolve, reject) => {
4852
4867
  const child = childSpawn(command, {
4853
4868
  shell: true,
4869
+ detached: process.platform !== "win32",
4854
4870
  cwd: options?.cwd,
4855
- env: options?.env ? { ...process.env, ...options.env } : process.env,
4856
- signal: options?.signal
4871
+ env: options?.env ? { ...process.env, ...options.env } : process.env
4857
4872
  });
4858
4873
  const out = [];
4859
4874
  const err = [];
4860
4875
  let settled2 = false;
4861
4876
  let timedOut = false;
4877
+ let aborted = false;
4862
4878
  let timer;
4879
+ const abortSignal = options?.signal;
4880
+ const onAbort = () => {
4881
+ aborted = true;
4882
+ killProcessTree(child);
4883
+ };
4863
4884
  const finish = (fn) => {
4864
4885
  if (settled2) return;
4865
4886
  settled2 = true;
4866
4887
  if (timer !== void 0) clearTimeout(timer);
4888
+ abortSignal?.removeEventListener("abort", onAbort);
4867
4889
  fn();
4868
4890
  };
4891
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
4892
+ if (abortSignal?.aborted) onAbort();
4869
4893
  child.stdout?.on("data", (chunk) => out.push(chunk));
4870
4894
  child.stderr?.on("data", (chunk) => err.push(chunk));
4871
4895
  if (options?.input !== void 0 && child.stdin) {
@@ -4878,7 +4902,7 @@ var NodeShell = class {
4878
4902
  if (limit !== void 0 && limit > 0) {
4879
4903
  timer = setTimeout(() => {
4880
4904
  timedOut = true;
4881
- child.kill("SIGTERM");
4905
+ killProcessTree(child);
4882
4906
  }, limit);
4883
4907
  }
4884
4908
  child.on("error", (cause) => {
@@ -4894,6 +4918,10 @@ var NodeShell = class {
4894
4918
  );
4895
4919
  return;
4896
4920
  }
4921
+ if (aborted) {
4922
+ reject(new Error("The command was aborted and stopped."));
4923
+ return;
4924
+ }
4897
4925
  resolve({
4898
4926
  stdout: joinChunks(out),
4899
4927
  stderr: joinChunks(err),
@@ -4911,11 +4939,11 @@ var NodeShell = class {
4911
4939
  }
4912
4940
  const child = childSpawn(command, {
4913
4941
  shell: true,
4942
+ detached: process.platform !== "win32",
4914
4943
  cwd: options?.cwd,
4915
- env: options?.env ? { ...process.env, ...options.env } : process.env,
4916
- signal: options?.signal
4944
+ env: options?.env ? { ...process.env, ...options.env } : process.env
4917
4945
  });
4918
- return new NodeShellHandle(child);
4946
+ return new NodeShellHandle(child, options?.signal);
4919
4947
  }
4920
4948
  };
4921
4949
  var NodeShellHandle = class {
@@ -4924,27 +4952,33 @@ var NodeShellHandle = class {
4924
4952
  exited = false;
4925
4953
  exitCode = null;
4926
4954
  exitSignal = null;
4927
- constructor(child) {
4955
+ abortSignal;
4956
+ onAbort = () => this.kill();
4957
+ constructor(child, abortSignal) {
4928
4958
  this.child = child;
4959
+ this.abortSignal = abortSignal;
4929
4960
  child.once(
4930
4961
  "close",
4931
4962
  (code, signal) => {
4932
4963
  this.exited = true;
4933
4964
  this.exitCode = code;
4934
4965
  this.exitSignal = asSignal(signal);
4966
+ this.abortSignal?.removeEventListener("abort", this.onAbort);
4935
4967
  for (const listener of [...this.listeners]) {
4936
4968
  listener(this.exitCode, this.exitSignal);
4937
4969
  }
4938
4970
  this.listeners.clear();
4939
4971
  }
4940
4972
  );
4973
+ this.abortSignal?.addEventListener("abort", this.onAbort, { once: true });
4974
+ if (this.abortSignal?.aborted) this.onAbort();
4941
4975
  }
4942
4976
  get pid() {
4943
4977
  return this.child.pid;
4944
4978
  }
4945
4979
  kill(signal) {
4946
4980
  if (this.exited) return;
4947
- this.child.kill(signal ?? "SIGTERM");
4981
+ killProcessTree(this.child, signal);
4948
4982
  }
4949
4983
  onExit(listener) {
4950
4984
  if (this.exited) {
@@ -6375,9 +6409,6 @@ function readInput2(raw) {
6375
6409
  }
6376
6410
  return { action, command, id };
6377
6411
  }
6378
- function shellQuote(value) {
6379
- return `'${value.replace(/'/g, `'\\''`)}'`;
6380
- }
6381
6412
  async function drainCapture(ctx, path, alreadyRead) {
6382
6413
  let full;
6383
6414
  try {
@@ -6413,7 +6444,7 @@ async function startJob(ctx, command) {
6413
6444
  await ctx.fs.mkdir(scratchDir, { recursive: true });
6414
6445
  await ctx.fs.writeFile(outPath, "", "utf8");
6415
6446
  await ctx.fs.writeFile(errPath, "", "utf8");
6416
- const wrapped = `( ${command} ) >${shellQuote(outPath)} 2>${shellQuote(errPath)}`;
6447
+ const wrapped = `( ${command} ) >${SCRATCH_DIR}/${id}.out 2>${SCRATCH_DIR}/${id}.err`;
6417
6448
  const handle = ctx.shell.spawn(wrapped, { cwd: ctx.cwd });
6418
6449
  const entry = {
6419
6450
  id,
@@ -6493,7 +6524,7 @@ async function pollJob(ctx, id) {
6493
6524
  hadNewOutput: out.fresh.length > 0 || err.fresh.length > 0
6494
6525
  });
6495
6526
  }
6496
- function stopJob(id) {
6527
+ async function stopJob(id) {
6497
6528
  const entry = table.remove(id);
6498
6529
  if (entry === void 0) {
6499
6530
  return asText2(
@@ -6501,14 +6532,24 @@ function stopJob(id) {
6501
6532
  true
6502
6533
  );
6503
6534
  }
6504
- entry.unsubscribe();
6505
6535
  const wasRunning = entry.state === "running";
6506
6536
  if (wasRunning) {
6507
- try {
6508
- entry.handle.kill();
6509
- } catch {
6510
- }
6537
+ await new Promise((resolve) => {
6538
+ let unsubscribeExit = () => {
6539
+ };
6540
+ unsubscribeExit = entry.handle.onExit(() => {
6541
+ unsubscribeExit();
6542
+ resolve();
6543
+ });
6544
+ try {
6545
+ entry.handle.kill();
6546
+ } catch {
6547
+ unsubscribeExit();
6548
+ resolve();
6549
+ }
6550
+ });
6511
6551
  }
6552
+ entry.unsubscribe();
6512
6553
  return asJson({
6513
6554
  action: "stop",
6514
6555
  id: entry.id,
@@ -5,6 +5,7 @@
5
5
  * OAuth callback server, so it is meant for CLI use and will not work in a browser.
6
6
  */
7
7
  import type { OAuthCredentials, OAuthPrompt, OAuthProviderInterface } from "./types.js";
8
+ export declare function resolveOpenAICodexClientId(configured?: string | undefined): string;
8
9
  /**
9
10
  * Drive the ChatGPT (Codex) OAuth sign-in end to end.
10
11
  *
@@ -4637,6 +4637,74 @@ export declare const MODELS: {
4637
4637
  contextWindow: number;
4638
4638
  maxTokens: number;
4639
4639
  };
4640
+ readonly "gpt-5.6-sol": {
4641
+ id: string;
4642
+ name: string;
4643
+ api: "openai-responses";
4644
+ provider: string;
4645
+ baseUrl: string;
4646
+ reasoning: true;
4647
+ input: ("text" | "image")[];
4648
+ cost: {
4649
+ input: number;
4650
+ output: number;
4651
+ cacheRead: number;
4652
+ cacheWrite: number;
4653
+ };
4654
+ contextWindow: number;
4655
+ maxTokens: number;
4656
+ };
4657
+ readonly "gpt-5.6-terra": {
4658
+ id: string;
4659
+ name: string;
4660
+ api: "openai-responses";
4661
+ provider: string;
4662
+ baseUrl: string;
4663
+ reasoning: true;
4664
+ input: ("text" | "image")[];
4665
+ cost: {
4666
+ input: number;
4667
+ output: number;
4668
+ cacheRead: number;
4669
+ cacheWrite: number;
4670
+ };
4671
+ contextWindow: number;
4672
+ maxTokens: number;
4673
+ };
4674
+ readonly "gpt-5.6-luna": {
4675
+ id: string;
4676
+ name: string;
4677
+ api: "openai-responses";
4678
+ provider: string;
4679
+ baseUrl: string;
4680
+ reasoning: true;
4681
+ input: ("text" | "image")[];
4682
+ cost: {
4683
+ input: number;
4684
+ output: number;
4685
+ cacheRead: number;
4686
+ cacheWrite: number;
4687
+ };
4688
+ contextWindow: number;
4689
+ maxTokens: number;
4690
+ };
4691
+ readonly "gpt-5.6": {
4692
+ id: string;
4693
+ name: string;
4694
+ api: "openai-responses";
4695
+ provider: string;
4696
+ baseUrl: string;
4697
+ reasoning: true;
4698
+ input: ("text" | "image")[];
4699
+ cost: {
4700
+ input: number;
4701
+ output: number;
4702
+ cacheRead: number;
4703
+ cacheWrite: number;
4704
+ };
4705
+ contextWindow: number;
4706
+ maxTokens: number;
4707
+ };
4640
4708
  readonly o1: {
4641
4709
  id: string;
4642
4710
  name: string;
@@ -4962,6 +5030,74 @@ export declare const MODELS: {
4962
5030
  contextWindow: number;
4963
5031
  maxTokens: number;
4964
5032
  };
5033
+ readonly "gpt-5.6-sol": {
5034
+ id: string;
5035
+ name: string;
5036
+ api: "openai-codex-responses";
5037
+ provider: string;
5038
+ baseUrl: string;
5039
+ reasoning: true;
5040
+ input: ("text" | "image")[];
5041
+ cost: {
5042
+ input: number;
5043
+ output: number;
5044
+ cacheRead: number;
5045
+ cacheWrite: number;
5046
+ };
5047
+ contextWindow: number;
5048
+ maxTokens: number;
5049
+ };
5050
+ readonly "gpt-5.6-terra": {
5051
+ id: string;
5052
+ name: string;
5053
+ api: "openai-codex-responses";
5054
+ provider: string;
5055
+ baseUrl: string;
5056
+ reasoning: true;
5057
+ input: ("text" | "image")[];
5058
+ cost: {
5059
+ input: number;
5060
+ output: number;
5061
+ cacheRead: number;
5062
+ cacheWrite: number;
5063
+ };
5064
+ contextWindow: number;
5065
+ maxTokens: number;
5066
+ };
5067
+ readonly "gpt-5.6-luna": {
5068
+ id: string;
5069
+ name: string;
5070
+ api: "openai-codex-responses";
5071
+ provider: string;
5072
+ baseUrl: string;
5073
+ reasoning: true;
5074
+ input: ("text" | "image")[];
5075
+ cost: {
5076
+ input: number;
5077
+ output: number;
5078
+ cacheRead: number;
5079
+ cacheWrite: number;
5080
+ };
5081
+ contextWindow: number;
5082
+ maxTokens: number;
5083
+ };
5084
+ readonly "gpt-5.6": {
5085
+ id: string;
5086
+ name: string;
5087
+ api: "openai-codex-responses";
5088
+ provider: string;
5089
+ baseUrl: string;
5090
+ reasoning: true;
5091
+ input: ("text" | "image")[];
5092
+ cost: {
5093
+ input: number;
5094
+ output: number;
5095
+ cacheRead: number;
5096
+ cacheWrite: number;
5097
+ };
5098
+ contextWindow: number;
5099
+ maxTokens: number;
5100
+ };
4965
5101
  };
4966
5102
  readonly opencode: {
4967
5103
  readonly "big-pickle": {
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indusagi",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "description": "Indusagi — a terminal-first AI coding agent framework. Clean-room implementation.",
5
5
  "author": "Varun Israni",
6
6
  "license": "AGPL-3.0",