@namzu/cli 2.6.0 → 3.0.0

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 (56) hide show
  1. package/dist/commands/doctor.d.ts.map +1 -1
  2. package/dist/commands/doctor.js +15 -4
  3. package/dist/commands/doctor.js.map +1 -1
  4. package/dist/commands/run-flags.d.ts +23 -0
  5. package/dist/commands/run-flags.d.ts.map +1 -1
  6. package/dist/commands/run-flags.js +39 -0
  7. package/dist/commands/run-flags.js.map +1 -1
  8. package/dist/commands/run-stream.d.ts.map +1 -1
  9. package/dist/commands/run-stream.js +12 -6
  10. package/dist/commands/run-stream.js.map +1 -1
  11. package/dist/commands/run.d.ts.map +1 -1
  12. package/dist/commands/run.js +12 -6
  13. package/dist/commands/run.js.map +1 -1
  14. package/dist/doctor/checks/chain.d.ts +32 -0
  15. package/dist/doctor/checks/chain.d.ts.map +1 -0
  16. package/dist/doctor/checks/chain.js +118 -0
  17. package/dist/doctor/checks/chain.js.map +1 -0
  18. package/dist/doctor/checks/index.d.ts +2 -1
  19. package/dist/doctor/checks/index.d.ts.map +1 -1
  20. package/dist/doctor/checks/index.js +6 -1
  21. package/dist/doctor/checks/index.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/integrations/providers/chain-capabilities.d.ts +80 -0
  27. package/dist/integrations/providers/chain-capabilities.d.ts.map +1 -0
  28. package/dist/integrations/providers/chain-capabilities.js +207 -0
  29. package/dist/integrations/providers/chain-capabilities.js.map +1 -0
  30. package/dist/integrations/providers/index.d.ts +2 -1
  31. package/dist/integrations/providers/index.d.ts.map +1 -1
  32. package/dist/integrations/providers/index.js +2 -1
  33. package/dist/integrations/providers/index.js.map +1 -1
  34. package/dist/integrations/providers/preferences.d.ts +84 -15
  35. package/dist/integrations/providers/preferences.d.ts.map +1 -1
  36. package/dist/integrations/providers/preferences.js +180 -25
  37. package/dist/integrations/providers/preferences.js.map +1 -1
  38. package/dist/tui/App.d.ts.map +1 -1
  39. package/dist/tui/App.js +69 -13
  40. package/dist/tui/App.js.map +1 -1
  41. package/dist/tui/PermissionOverlay.d.ts.map +1 -1
  42. package/dist/tui/PermissionOverlay.js +1 -1
  43. package/dist/tui/PermissionOverlay.js.map +1 -1
  44. package/dist/tui/agent.d.ts +12 -0
  45. package/dist/tui/agent.d.ts.map +1 -1
  46. package/dist/tui/agent.js +70 -10
  47. package/dist/tui/agent.js.map +1 -1
  48. package/dist/tui/bottom-spacer.d.ts +72 -0
  49. package/dist/tui/bottom-spacer.d.ts.map +1 -0
  50. package/dist/tui/bottom-spacer.js +83 -0
  51. package/dist/tui/bottom-spacer.js.map +1 -0
  52. package/dist/tui/permission-timing.d.ts +35 -0
  53. package/dist/tui/permission-timing.d.ts.map +1 -0
  54. package/dist/tui/permission-timing.js +39 -0
  55. package/dist/tui/permission-timing.js.map +1 -0
  56. package/package.json +4 -4
@@ -0,0 +1,83 @@
1
+ /**
2
+ * How many blank rows to put above the composer so it sits at the bottom.
3
+ *
4
+ * ## The narrow defect
5
+ *
6
+ * Ink writes the transcript to native scrollback via `<Static>` and re-renders
7
+ * the live region — activity, composer, status bar — beneath it. Once the
8
+ * output exceeds the viewport the terminal has scrolled, and the composer is
9
+ * already at the bottom. The complaint is entirely the case before that: five
10
+ * lines on a forty-row terminal leaves the composer at row six with blank space
11
+ * under it, and the operator's eye has to find it.
12
+ *
13
+ * So this does not try to pin the composer always. It pads only while the
14
+ * transcript is unambiguously shorter than the viewport, and returns 0 the
15
+ * moment that stops being knowable. After that, the terminal does it.
16
+ *
17
+ * ## Why a rough estimate is safe here, and would not be in general
18
+ *
19
+ * The rendered height of a transcript is not knowable from this side: ink does
20
+ * not report it, and wrapping depends on ANSI, wide glyphs and markdown that
21
+ * this module does not model. That is exactly why the whole-session version of
22
+ * this idea is a bad one.
23
+ *
24
+ * It is safe in the short case because the error is **asymmetric**:
25
+ *
26
+ * - Overestimate the content ⇒ pad less, or not at all ⇒ the composer floats,
27
+ * which is precisely today's behaviour. No worse than not doing this.
28
+ * - Underestimate the content ⇒ pad too much ⇒ the composer is pushed off the
29
+ * bottom, which is worse than today.
30
+ *
31
+ * So every uncertainty is resolved toward *more* content and *less* padding:
32
+ * `estimateRenderedLines` counts a minimum, {@link SAFETY_ROWS} is subtracted
33
+ * on top, and anything unknown returns 0. Being wrong costs the feature, never
34
+ * the usability.
35
+ */
36
+ /**
37
+ * Rows held back from the calculation.
38
+ *
39
+ * Absorbs what the estimate cannot see — a wrapped line the width maths missed,
40
+ * a wide glyph, a markdown block that renders taller than its source. Six is
41
+ * chosen to be visibly generous rather than tuned: the cost of it being too
42
+ * large is a small gap under the composer on a nearly-empty screen, and the
43
+ * cost of it being too small is a composer pushed out of view.
44
+ */
45
+ export const SAFETY_ROWS = 6;
46
+ /**
47
+ * A deliberate UNDER-count of how tall the transcript will render.
48
+ *
49
+ * Under, not over, because it is subtracted from the space available: counting
50
+ * low leaves more apparent room, and the safety margin plus the guard below are
51
+ * what stop that becoming padding. Each entry is at least one row, and a long
52
+ * entry is divided by the width to approximate wrapping.
53
+ */
54
+ export function estimateRenderedLines(transcript, columns) {
55
+ const width = Math.max(20, columns ?? 80);
56
+ let total = 0;
57
+ for (const entry of transcript) {
58
+ for (const line of entry.split('\n')) {
59
+ total += Math.max(1, Math.ceil(line.length / width));
60
+ }
61
+ }
62
+ return total;
63
+ }
64
+ /**
65
+ * Blank rows to insert above the composer, or 0 to leave the layout alone.
66
+ *
67
+ * Returns 0 whenever the answer could be wrong: no TTY, an implausible height,
68
+ * or a transcript long enough that the terminal has plausibly begun to scroll.
69
+ */
70
+ export function bottomSpacerRows(input) {
71
+ const { rows, columns, transcript, liveRows } = input;
72
+ // Not a terminal, or a height too small to reason about. A pipe has no
73
+ // bottom to pin to.
74
+ if (rows === undefined || !Number.isFinite(rows) || rows < 12)
75
+ return 0;
76
+ const used = estimateRenderedLines(transcript, columns) + liveRows + SAFETY_ROWS;
77
+ // The transcript is at or past the viewport: the terminal is scrolling and
78
+ // the composer is already where it should be. Padding now would push it off.
79
+ if (used >= rows)
80
+ return 0;
81
+ return rows - used;
82
+ }
83
+ //# sourceMappingURL=bottom-spacer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bottom-spacer.js","sourceRoot":"","sources":["../../src/tui/bottom-spacer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAA;AAa5B;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,UAA6B,EAC7B,OAA2B;IAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA;IACzC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAA;QACrD,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAErD,uEAAuE;IACvE,oBAAoB;IACpB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,QAAQ,GAAG,WAAW,CAAA;IAEhF,2EAA2E;IAC3E,6EAA6E;IAC7E,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IAE1B,OAAO,IAAI,GAAG,IAAI,CAAA;AACnB,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * When an approving keystroke at the permission prompt counts as a decision.
3
+ *
4
+ * The prompt takes the screen on the agent's schedule, not the operator's. The
5
+ * composer stays live while a turn runs and the docs encourage typing a
6
+ * follow-up there, so the moment the agent asks to run a tool the overlay
7
+ * replaces a composer someone's hands are already in. A keystroke begun before
8
+ * that swap was aimed at the composer behind it, and must not be read as
9
+ * consent for a tool call nobody has had time to read.
10
+ *
11
+ * So approval is deferred for a beat after the prompt opens. Refusal is NOT:
12
+ * rejecting a call the operator wanted costs them a retry, while approving one
13
+ * they never saw cannot be taken back, and a guard that hesitates in both
14
+ * directions would make the safe key feel broken to buy nothing.
15
+ */
16
+ /**
17
+ * How long after the prompt opens an approving key is ignored.
18
+ *
19
+ * Long enough to swallow a keystroke already in flight, short enough that
20
+ * someone who read the prompt and reached for `y` never waits on it. A fast
21
+ * typist runs near 100ms between characters, so this covers roughly three
22
+ * characters of overshoot.
23
+ */
24
+ export declare const APPROVAL_SETTLE_MS = 350;
25
+ /**
26
+ * Whether an approving keypress arriving `now` should decide the prompt that
27
+ * opened at `openedAt`.
28
+ *
29
+ * `null` — no recorded open — is refused rather than allowed. The value exists
30
+ * only while a prompt is up, so its absence means the caller cannot establish
31
+ * that the operator has seen anything, and the fail-safe reading of "I cannot
32
+ * establish this" is not consent.
33
+ */
34
+ export declare function approvalIsDeliberate(openedAt: number | null, now: number): boolean;
35
+ //# sourceMappingURL=permission-timing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-timing.d.ts","sourceRoot":"","sources":["../../src/tui/permission-timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * When an approving keystroke at the permission prompt counts as a decision.
3
+ *
4
+ * The prompt takes the screen on the agent's schedule, not the operator's. The
5
+ * composer stays live while a turn runs and the docs encourage typing a
6
+ * follow-up there, so the moment the agent asks to run a tool the overlay
7
+ * replaces a composer someone's hands are already in. A keystroke begun before
8
+ * that swap was aimed at the composer behind it, and must not be read as
9
+ * consent for a tool call nobody has had time to read.
10
+ *
11
+ * So approval is deferred for a beat after the prompt opens. Refusal is NOT:
12
+ * rejecting a call the operator wanted costs them a retry, while approving one
13
+ * they never saw cannot be taken back, and a guard that hesitates in both
14
+ * directions would make the safe key feel broken to buy nothing.
15
+ */
16
+ /**
17
+ * How long after the prompt opens an approving key is ignored.
18
+ *
19
+ * Long enough to swallow a keystroke already in flight, short enough that
20
+ * someone who read the prompt and reached for `y` never waits on it. A fast
21
+ * typist runs near 100ms between characters, so this covers roughly three
22
+ * characters of overshoot.
23
+ */
24
+ export const APPROVAL_SETTLE_MS = 350;
25
+ /**
26
+ * Whether an approving keypress arriving `now` should decide the prompt that
27
+ * opened at `openedAt`.
28
+ *
29
+ * `null` — no recorded open — is refused rather than allowed. The value exists
30
+ * only while a prompt is up, so its absence means the caller cannot establish
31
+ * that the operator has seen anything, and the fail-safe reading of "I cannot
32
+ * establish this" is not consent.
33
+ */
34
+ export function approvalIsDeliberate(openedAt, now) {
35
+ if (openedAt === null)
36
+ return false;
37
+ return now - openedAt >= APPROVAL_SETTLE_MS;
38
+ }
39
+ //# sourceMappingURL=permission-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-timing.js","sourceRoot":"","sources":["../../src/tui/permission-timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAuB,EAAE,GAAW;IACxE,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IACnC,OAAO,GAAG,GAAG,QAAQ,IAAI,kBAAkB,CAAA;AAC5C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namzu/cli",
3
- "version": "2.6.0",
3
+ "version": "3.0.0",
4
4
  "description": "Operator CLI for the Namzu agent platform — namzu doctor + future commands. Dual-purpose: standalone bin (`namzu doctor`) and library (`import { runDoctor } from '@namzu/cli'`).",
5
5
  "keywords": [
6
6
  "namzu",
@@ -45,10 +45,10 @@
45
45
  "react": "^19.2.6",
46
46
  "yaml": "^2.9.0",
47
47
  "@namzu/anthropic": "3.1.1",
48
- "@namzu/openai": "1.1.1",
49
- "@namzu/openrouter": "2.0.1",
50
48
  "@namzu/ollama": "2.0.1",
51
- "@namzu/sdk": "^15.1.0"
49
+ "@namzu/openrouter": "2.0.1",
50
+ "@namzu/openai": "1.1.1",
51
+ "@namzu/sdk": "^16.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@biomejs/biome": "^1.9.4",