indusagi-coding-agent 0.2.9 → 0.2.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.11]
4
+
5
+ ### Fixed
6
+ - **Fatal startup visibility**: uncaught boot failures now print their actual message and exit with status `1` instead of producing an empty failure log.
7
+
8
+ ## [0.2.10]
9
+
10
+ ### Fixed
11
+ - **OpenAI browser sign-in**: consumes `indusagi@0.13.10`, whose callback server falls back from port `1455` to the registered port `1457` when needed.
12
+ - **OAuth recovery input**: labels the manual field accurately so users can paste either an authorization code or the complete redirect URL.
13
+ - **Version display**: startup banner and `--version` now match package version `0.2.10`.
14
+
3
15
  ## [0.2.6]
4
16
 
5
17
  ### Fixed
package/dist/entry.js CHANGED
@@ -18,7 +18,7 @@ var BRAND = Object.freeze({
18
18
  envShareViewer: "INDUSAGI_SHARE_VIEWER_URL",
19
19
  shareViewerUrl: "https://buildwithindusagi.ai/session/"
20
20
  });
21
- var VERSION = "0.2.7";
21
+ var VERSION = "0.2.11";
22
22
 
23
23
  // src/launch/credentials.ts
24
24
  import { createInterface as createInterface2 } from "node:readline/promises";
@@ -12860,7 +12860,7 @@ function seedOAuthState(providerId, providerName, mode) {
12860
12860
  providerId,
12861
12861
  providerName,
12862
12862
  mode,
12863
- inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code",
12863
+ inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code or redirect URL",
12864
12864
  inputValue: "",
12865
12865
  accountId: "default",
12866
12866
  accountName: "Default"
@@ -12909,8 +12909,8 @@ function OAuthFlowDialog(props) {
12909
12909
  onManualCodeInput: () => new Promise((resolve9) => {
12910
12910
  pending.current = resolve9;
12911
12911
  safeMerge({
12912
- prompt: { message: "Paste the authorization code:" },
12913
- inputLabel: "Authorization code",
12912
+ prompt: { message: "Paste the authorization code or complete redirect URL:" },
12913
+ inputLabel: "Authorization code or redirect URL",
12914
12914
  inputValue: ""
12915
12915
  });
12916
12916
  }),
@@ -16812,13 +16812,26 @@ function isProgramEntry() {
16812
16812
  return false;
16813
16813
  }
16814
16814
  }
16815
+ async function resolveBoot(result) {
16816
+ try {
16817
+ return await result;
16818
+ } catch (error) {
16819
+ const message = error instanceof Error ? error.message : String(error);
16820
+ process.stderr.write(`${BRAND.name}: ${message}
16821
+ `);
16822
+ return 1;
16823
+ }
16824
+ }
16815
16825
  process.title = BRAND.binNames[0];
16816
16826
  installMcpNoiseFilter();
16817
16827
  if (isProgramEntry()) {
16818
16828
  ensureHeapHeadroom();
16819
- void boot(processArgv.slice(2)).then((code) => {
16829
+ void resolveBoot(boot(processArgv.slice(2))).then((code) => {
16820
16830
  process.exitCode = code;
16821
16831
  process.stdout.write("", () => process.exit(code));
16822
16832
  setTimeout(() => process.exit(code), 1e3).unref();
16823
16833
  });
16824
16834
  }
16835
+ export {
16836
+ resolveBoot
16837
+ };
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ var BRAND = Object.freeze({
50
50
  envShareViewer: "INDUSAGI_SHARE_VIEWER_URL",
51
51
  shareViewerUrl: "https://buildwithindusagi.ai/session/"
52
52
  });
53
- var VERSION = "0.2.7";
53
+ var VERSION = "0.2.11";
54
54
 
55
55
  // src/launch/credentials.ts
56
56
  import { createInterface as createInterface2 } from "node:readline/promises";
@@ -11857,7 +11857,7 @@ function seedOAuthState(providerId, providerName, mode) {
11857
11857
  providerId,
11858
11858
  providerName,
11859
11859
  mode,
11860
- inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code",
11860
+ inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code or redirect URL",
11861
11861
  inputValue: "",
11862
11862
  accountId: "default",
11863
11863
  accountName: "Default"
@@ -11906,8 +11906,8 @@ function OAuthFlowDialog(props) {
11906
11906
  onManualCodeInput: () => new Promise((resolve9) => {
11907
11907
  pending.current = resolve9;
11908
11908
  safeMerge({
11909
- prompt: { message: "Paste the authorization code:" },
11910
- inputLabel: "Authorization code",
11909
+ prompt: { message: "Paste the authorization code or complete redirect URL:" },
11910
+ inputLabel: "Authorization code or redirect URL",
11911
11911
  inputValue: ""
11912
11912
  });
11913
11913
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indusagi-coding-agent",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Indusagi coding agent — a terminal-first AI coding agent, built from scratch on the indusagi framework.",
5
5
  "author": "Varun Israni",
6
6
  "license": "AGPL-3.0",
@@ -59,7 +59,7 @@
59
59
  "@sinclair/typebox": "^0.34.49",
60
60
  "chalk": "^5.6.2",
61
61
  "highlight.js": "^11.11.1",
62
- "indusagi": "^0.13.9",
62
+ "indusagi": "^0.13.10",
63
63
  "ink": "^5.2.1",
64
64
  "jiti": "^2.7.0",
65
65
  "marked": "^18.0.4",
@@ -126,7 +126,7 @@ function seedOAuthState(providerId: string, providerName: string, mode: string)
126
126
  providerId,
127
127
  providerName,
128
128
  mode,
129
- inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code",
129
+ inputLabel: mode === "apiKey" ? `${providerName} API key` : "Authorization code or redirect URL",
130
130
  inputValue: "",
131
131
  accountId: "default",
132
132
  accountName: "Default"
@@ -182,8 +182,8 @@ function OAuthFlowDialog(props: OverlayGroupProps & { providerId: string; mode:
182
182
  new Promise<string>((resolve) => {
183
183
  pending.current = resolve;
184
184
  safeMerge({
185
- prompt: { message: "Paste the authorization code:" },
186
- inputLabel: "Authorization code",
185
+ prompt: { message: "Paste the authorization code or complete redirect URL:" },
186
+ inputLabel: "Authorization code or redirect URL",
187
187
  inputValue: ""
188
188
  });
189
189
  }),
@@ -0,0 +1,17 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { resolveBoot } from "./entry.js";
3
+
4
+ describe("resolveBoot", () => {
5
+ afterEach(() => vi.restoreAllMocks());
6
+
7
+ it("prints fatal boot errors and returns a failing exit code", async () => {
8
+ const stderr = vi.spyOn(process.stderr, "write").mockReturnValue(true);
9
+
10
+ await expect(resolveBoot(Promise.reject(new Error("startup failed")))).resolves.toBe(1);
11
+ expect(stderr).toHaveBeenCalledWith("indusagi: startup failed\n");
12
+ });
13
+
14
+ it("preserves successful exit codes", async () => {
15
+ await expect(resolveBoot(Promise.resolve(0))).resolves.toBe(0);
16
+ });
17
+ });
package/src/entry.ts CHANGED
@@ -43,11 +43,21 @@ function isProgramEntry(): boolean {
43
43
  }
44
44
  }
45
45
 
46
+ export async function resolveBoot(result: Promise<number>): Promise<number> {
47
+ try {
48
+ return await result;
49
+ } catch (error) {
50
+ const message = error instanceof Error ? error.message : String(error);
51
+ process.stderr.write(`${BRAND.name}: ${message}\n`);
52
+ return 1;
53
+ }
54
+ }
55
+
46
56
  process.title = BRAND.binNames[0];
47
57
  installMcpNoiseFilter();
48
58
  if (isProgramEntry()) {
49
59
  ensureHeapHeadroom();
50
- void boot(processArgv.slice(2)).then((code) => {
60
+ void resolveBoot(boot(processArgv.slice(2))).then((code) => {
51
61
  process.exitCode = code;
52
62
  process.stdout.write("", () => process.exit(code));
53
63
  setTimeout(() => process.exit(code), 1e3).unref();
@@ -26,4 +26,4 @@ export const BRAND: Brand = Object.freeze({
26
26
  /**
27
27
  * The product version — printed by `--version` and shown on the startup banner.
28
28
  */
29
- export const VERSION = "0.2.7";
29
+ export const VERSION = "0.2.11";