codebase-cli 2.0.0-pre.4 → 2.0.0-pre.41

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 (111) hide show
  1. package/dist/agent/agent.js +43 -15
  2. package/dist/agent/agent.js.map +1 -1
  3. package/dist/agent/config.js +61 -20
  4. package/dist/agent/config.js.map +1 -1
  5. package/dist/agent/events.bench.js +84 -0
  6. package/dist/agent/events.bench.js.map +1 -0
  7. package/dist/agent/prompt-suggestion.js +141 -0
  8. package/dist/agent/prompt-suggestion.js.map +1 -0
  9. package/dist/agent/system-prompt.js +15 -0
  10. package/dist/agent/system-prompt.js.map +1 -1
  11. package/dist/app-server/protocol.js +7 -0
  12. package/dist/app-server/protocol.js.map +1 -0
  13. package/dist/app-server/server.js +241 -0
  14. package/dist/app-server/server.js.map +1 -0
  15. package/dist/auth/cli.js +1 -1
  16. package/dist/auth/cli.js.map +1 -1
  17. package/dist/auth/credentials.js +33 -2
  18. package/dist/auth/credentials.js.map +1 -1
  19. package/dist/auth/flow.js +145 -24
  20. package/dist/auth/flow.js.map +1 -1
  21. package/dist/auth/token-manager.js +122 -0
  22. package/dist/auth/token-manager.js.map +1 -0
  23. package/dist/cli.js +56 -1
  24. package/dist/cli.js.map +1 -1
  25. package/dist/commands/builtins.js +160 -14
  26. package/dist/commands/builtins.js.map +1 -1
  27. package/dist/commands/registry.js +46 -1
  28. package/dist/commands/registry.js.map +1 -1
  29. package/dist/compaction/monitor.js +38 -0
  30. package/dist/compaction/monitor.js.map +1 -0
  31. package/dist/config/types.js.map +1 -1
  32. package/dist/glue/client.js +12 -2
  33. package/dist/glue/client.js.map +1 -1
  34. package/dist/hooks/manager.js +8 -2
  35. package/dist/hooks/manager.js.map +1 -1
  36. package/dist/memory/store.js +2 -3
  37. package/dist/memory/store.js.map +1 -1
  38. package/dist/plan/run-flow.js +89 -0
  39. package/dist/plan/run-flow.js.map +1 -0
  40. package/dist/projects/cli.js +92 -0
  41. package/dist/projects/cli.js.map +1 -0
  42. package/dist/projects/client.js +120 -0
  43. package/dist/projects/client.js.map +1 -0
  44. package/dist/projects/types.js +2 -0
  45. package/dist/projects/types.js.map +1 -0
  46. package/dist/skills/platform-loader.js +133 -38
  47. package/dist/skills/platform-loader.js.map +1 -1
  48. package/dist/tools/__test__/mock-tool-context.js +31 -0
  49. package/dist/tools/__test__/mock-tool-context.js.map +1 -0
  50. package/dist/tools/file-state-cache.js.map +1 -1
  51. package/dist/tools/read-file.js +7 -2
  52. package/dist/tools/read-file.js.map +1 -1
  53. package/dist/ui/App.js +109 -110
  54. package/dist/ui/App.js.map +1 -1
  55. package/dist/ui/CompactionBanner.js +23 -0
  56. package/dist/ui/CompactionBanner.js.map +1 -0
  57. package/dist/ui/FirstRunSetup.js +66 -14
  58. package/dist/ui/FirstRunSetup.js.map +1 -1
  59. package/dist/ui/Input.js +370 -20
  60. package/dist/ui/Input.js.map +1 -1
  61. package/dist/ui/Markdown.js +286 -0
  62. package/dist/ui/Markdown.js.map +1 -0
  63. package/dist/ui/Message.js +110 -48
  64. package/dist/ui/Message.js.map +1 -1
  65. package/dist/ui/MessageList.js +100 -3
  66. package/dist/ui/MessageList.js.map +1 -1
  67. package/dist/ui/Permission.js +43 -20
  68. package/dist/ui/Permission.js.map +1 -1
  69. package/dist/ui/PixelC.js +25 -0
  70. package/dist/ui/PixelC.js.map +1 -0
  71. package/dist/ui/Status.js +267 -7
  72. package/dist/ui/Status.js.map +1 -1
  73. package/dist/ui/Throbber.js +11 -7
  74. package/dist/ui/Throbber.js.map +1 -1
  75. package/dist/ui/Welcome.js +59 -0
  76. package/dist/ui/Welcome.js.map +1 -0
  77. package/dist/ui/attachments.js +68 -0
  78. package/dist/ui/attachments.js.map +1 -0
  79. package/dist/ui/debug-input.js +44 -0
  80. package/dist/ui/debug-input.js.map +1 -0
  81. package/dist/ui/diff-summary.js +171 -0
  82. package/dist/ui/diff-summary.js.map +1 -0
  83. package/dist/ui/highlight.js +324 -0
  84. package/dist/ui/highlight.js.map +1 -0
  85. package/dist/ui/history-store.js +60 -0
  86. package/dist/ui/history-store.js.map +1 -0
  87. package/dist/ui/input-state.js +125 -1
  88. package/dist/ui/input-state.js.map +1 -1
  89. package/dist/ui/path-complete.js +102 -0
  90. package/dist/ui/path-complete.js.map +1 -0
  91. package/dist/ui/paths.js +41 -0
  92. package/dist/ui/paths.js.map +1 -0
  93. package/dist/ui/shell-escape.js +42 -0
  94. package/dist/ui/shell-escape.js.map +1 -0
  95. package/dist/ui/terminal-restore.js +83 -0
  96. package/dist/ui/terminal-restore.js.map +1 -0
  97. package/dist/ui/terminal-title.js +21 -0
  98. package/dist/ui/terminal-title.js.map +1 -0
  99. package/dist/ui/tool-call-line.js +83 -0
  100. package/dist/ui/tool-call-line.js.map +1 -0
  101. package/dist/ui/tool-labels.js +194 -0
  102. package/dist/ui/tool-labels.js.map +1 -0
  103. package/dist/ui/truncated-output.js +42 -0
  104. package/dist/ui/truncated-output.js.map +1 -0
  105. package/dist/ui/use-coalesced-agent-events.js +70 -0
  106. package/dist/ui/use-coalesced-agent-events.js.map +1 -0
  107. package/dist/ui/use-prompt-suggestion.js +52 -0
  108. package/dist/ui/use-prompt-suggestion.js.map +1 -0
  109. package/dist/ui/wrapped-lines.js +18 -0
  110. package/dist/ui/wrapped-lines.js.map +1 -0
  111. package/package.json +6 -1
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { WrappedLines } from "./wrapped-lines.js";
4
+ const DEFAULT_MAX_TOOL_OUTPUT_LINES = 12;
5
+ /**
6
+ * Per-tool display caps. Search-style tools (grep, find, glob) produce
7
+ * many matches, most of which the user doesn't need to read inline —
8
+ * the model still sees the full result. Default is 12 lines.
9
+ */
10
+ export const TOOL_OUTPUT_LIMITS = {
11
+ grep: 6,
12
+ search_files: 6,
13
+ glob: 8,
14
+ find: 8,
15
+ list_files: 10,
16
+ };
17
+ /**
18
+ * Truncate tool output past the per-tool limit into "head + (N hidden)
19
+ * + tail" — long shell or grep output otherwise dominates the
20
+ * transcript and pushes context off-screen. The agent still gets the
21
+ * full output; this is purely a display trim. Errors are NEVER
22
+ * truncated since the user needs to see exactly what blew up.
23
+ */
24
+ export function TruncatedOutput({ text, width, keyPrefix, color, toolName, }) {
25
+ const max = toolName && TOOL_OUTPUT_LIMITS[toolName] !== undefined
26
+ ? TOOL_OUTPUT_LIMITS[toolName]
27
+ : DEFAULT_MAX_TOOL_OUTPUT_LINES;
28
+ // Reserve at least 1 head + 1 tail line so the user can see the
29
+ // shape of the truncation; rest is head-weighted (where the
30
+ // interesting content usually is).
31
+ const tailLines = max >= 8 ? 3 : 2;
32
+ const headLines = Math.max(1, max - tailLines - 1);
33
+ const lines = text.split("\n");
34
+ if (color === "red" || lines.length <= max) {
35
+ return _jsx(WrappedLines, { text: text, width: width, keyPrefix: keyPrefix, color: color });
36
+ }
37
+ const head = lines.slice(0, headLines).join("\n");
38
+ const tail = lines.slice(lines.length - tailLines).join("\n");
39
+ const hidden = lines.length - headLines - tailLines;
40
+ return (_jsxs(_Fragment, { children: [_jsx(WrappedLines, { text: head, width: width, keyPrefix: `${keyPrefix}-h`, color: color }), _jsx(Text, { dimColor: true, children: `… ${hidden} line${hidden === 1 ? "" : "s"} hidden …` }), _jsx(WrappedLines, { text: tail, width: width, keyPrefix: `${keyPrefix}-t`, color: color })] }));
41
+ }
42
+ //# sourceMappingURL=truncated-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncated-output.js","sourceRoot":"","sources":["../../src/ui/truncated-output.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACzD,IAAI,EAAE,CAAC;IACP,YAAY,EAAE,CAAC;IACf,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,UAAU,EAAE,EAAE;CACd,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,KAAK,EACL,QAAQ,GAOR;IACA,MAAM,GAAG,GACR,QAAQ,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,SAAS;QACrD,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAC9B,CAAC,CAAC,6BAA6B,CAAC;IAClC,gEAAgE;IAChE,4DAA4D;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC5C,OAAO,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAI,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACpD,OAAO,CACN,8BACC,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,IAAI,EAAE,KAAK,EAAE,KAAK,GAAI,EACrF,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,MAAM,QAAQ,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,GAAQ,EAC7E,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,IAAI,EAAE,KAAK,EAAE,KAAK,GAAI,IACnF,CACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * Coalesce high-frequency streaming events (per-token assistant updates
4
+ * and per-chunk tool stdout) to one React commit per frame instead of
5
+ * per event. Pi-agent-core emits one message_update per token, and a
6
+ * fast model + long tool output can fire 100+ Hz — each dispatch runs
7
+ * the full reducer + React tree diff + Yoga layout for everything on
8
+ * screen. Throttling here is the single biggest cause of perceived
9
+ * scroll/render jankiness; everything else (Static for finalized
10
+ * messages, memoized children) is icing.
11
+ *
12
+ * Keyed coalescing: message_update has one slot, tool_execution_update
13
+ * has one slot per tool id. Latest event wins. Non-coalesceable events
14
+ * (message_start/end, tool_execution_start/end, turn_*, agent_*) flush
15
+ * any pending updates first so ordering stays correct.
16
+ */
17
+ export function useCoalescedAgentEvents(bundle, dispatch) {
18
+ const pendingRef = useRef(new Map());
19
+ const flushTimerRef = useRef(null);
20
+ useEffect(() => {
21
+ const STREAM_FRAME_MS = 16; // ~60fps cap
22
+ const flush = () => {
23
+ flushTimerRef.current = null;
24
+ if (pendingRef.current.size === 0)
25
+ return;
26
+ const events = [...pendingRef.current.values()];
27
+ pendingRef.current.clear();
28
+ for (const event of events) {
29
+ dispatch({ type: "agent-event", event });
30
+ }
31
+ };
32
+ const scheduleFlush = () => {
33
+ if (flushTimerRef.current != null)
34
+ return;
35
+ flushTimerRef.current = setTimeout(flush, STREAM_FRAME_MS);
36
+ };
37
+ const unsubscribe = bundle.subscribe((event) => {
38
+ if (event.type === "message_update") {
39
+ pendingRef.current.set("msg", event);
40
+ scheduleFlush();
41
+ return;
42
+ }
43
+ if (event.type === "tool_execution_update") {
44
+ pendingRef.current.set(`tool:${event.toolCallId}`, event);
45
+ scheduleFlush();
46
+ return;
47
+ }
48
+ // Any other event flushes the queue before dispatching so the
49
+ // reducer sees pending streaming updates before the terminal
50
+ // event (message_end, tool_execution_end, etc.).
51
+ if (pendingRef.current.size > 0) {
52
+ if (flushTimerRef.current != null) {
53
+ clearTimeout(flushTimerRef.current);
54
+ flushTimerRef.current = null;
55
+ }
56
+ flush();
57
+ }
58
+ dispatch({ type: "agent-event", event });
59
+ });
60
+ return () => {
61
+ unsubscribe();
62
+ if (flushTimerRef.current != null) {
63
+ clearTimeout(flushTimerRef.current);
64
+ flushTimerRef.current = null;
65
+ }
66
+ pendingRef.current.clear();
67
+ };
68
+ }, [bundle, dispatch]);
69
+ }
70
+ //# sourceMappingURL=use-coalesced-agent-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-coalesced-agent-events.js","sourceRoot":"","sources":["../../src/ui/use-coalesced-agent-events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAK1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAmB,EAAE,QAAkB;IAC9E,MAAM,UAAU,GAAG,MAAM,CAA0B,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IAE1D,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC,aAAa;QAEzC,MAAM,KAAK,GAAG,GAAG,EAAE;YAClB,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;YAC7B,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO;YAC1C,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAChD,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC5B,QAAQ,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,CAAC;QACF,CAAC,CAAC;QAEF,MAAM,aAAa,GAAG,GAAG,EAAE;YAC1B,IAAI,aAAa,CAAC,OAAO,IAAI,IAAI;gBAAE,OAAO;YAC1C,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5D,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACrC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACrC,aAAa,EAAE,CAAC;gBAChB,OAAO;YACR,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;gBAC5C,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC1D,aAAa,EAAE,CAAC;gBAChB,OAAO;YACR,CAAC;YACD,8DAA8D;YAC9D,6DAA6D;YAC7D,iDAAiD;YACjD,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBACjC,IAAI,aAAa,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;oBACnC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;oBACpC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;gBAC9B,CAAC;gBACD,KAAK,EAAE,CAAC;YACT,CAAC;YACD,QAAQ,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACX,WAAW,EAAE,CAAC;YACd,IAAI,aAAa,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBACnC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gBACpC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,CAAC;YACD,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { generateSuggestion } from "../agent/prompt-suggestion.js";
3
+ /**
4
+ * Inline prompt-suggestion ghost text. Schedules a single forecast
5
+ * call when the agent goes idle; cancels the prior call on every new
6
+ * state change so we never race two suggestions or show a stale one
7
+ * after the user starts a new turn. 500ms debounce lets idle settle
8
+ * (e.g. agent finishes, a quick status emit follows, we don't want to
9
+ * fire twice). Disabled via env so users on metered BYOK providers
10
+ * can opt out.
11
+ */
12
+ export function usePromptSuggestion(bundle, status, messageCount) {
13
+ const [suggestion, setSuggestion] = useState(null);
14
+ const abortRef = useRef(null);
15
+ useEffect(() => {
16
+ // Always clear any active suggestion on state change — it was
17
+ // computed for the previous turn and the user has moved on.
18
+ setSuggestion(null);
19
+ abortRef.current?.abort();
20
+ abortRef.current = null;
21
+ if (process.env.CODEBASE_NO_SUGGESTIONS === "1")
22
+ return;
23
+ if (status !== "idle")
24
+ return;
25
+ if (messageCount < 2)
26
+ return;
27
+ const ac = new AbortController();
28
+ abortRef.current = ac;
29
+ const timer = setTimeout(async () => {
30
+ if (ac.signal.aborted)
31
+ return;
32
+ try {
33
+ const text = await generateSuggestion(bundle, { signal: ac.signal });
34
+ if (ac.signal.aborted)
35
+ return;
36
+ if (text)
37
+ setSuggestion(text);
38
+ }
39
+ catch {
40
+ // Suggestion failures are silent — they're a nicety, not load-bearing.
41
+ }
42
+ }, 500);
43
+ return () => {
44
+ clearTimeout(timer);
45
+ ac.abort();
46
+ if (abortRef.current === ac)
47
+ abortRef.current = null;
48
+ };
49
+ }, [bundle, status, messageCount]);
50
+ return { suggestion, dismiss: () => setSuggestion(null) };
51
+ }
52
+ //# sourceMappingURL=use-prompt-suggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-prompt-suggestion.js","sourceRoot":"","sources":["../../src/ui/use-prompt-suggestion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAClC,MAAmB,EACnB,MAAc,EACd,YAAoB;IAEpB,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACd,8DAA8D;QAC9D,4DAA4D;QAC5D,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QAExB,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG;YAAE,OAAO;QACxD,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO;QAC9B,IAAI,YAAY,GAAG,CAAC;YAAE,OAAO;QAE7B,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACnC,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO;YAC9B,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrE,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO;gBAC9B,IAAI,IAAI;oBAAE,aAAa,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACR,uEAAuE;YACxE,CAAC;QACF,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,OAAO,GAAG,EAAE;YACX,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,QAAQ,CAAC,OAAO,KAAK,EAAE;gBAAE,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QACtD,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAEnC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { wrapText } from "./wrap.js";
4
+ /**
5
+ * Render text as N <Text> elements, one per pre-wrapped line. Stacks
6
+ * vertically inside the parent column-flex Box. Pre-wrap means the
7
+ * wraps happen at word boundaries, so when the user select-and-copies
8
+ * they get clean line endings — no mid-word breaks at column edges.
9
+ */
10
+ export function WrappedLines({ text, width, keyPrefix, color, dimColor, italic }) {
11
+ const lines = wrapText(text, width);
12
+ return (_jsx(_Fragment, { children: lines.map((line, i) => (
13
+ // Wrapped lines have no per-line state — <Text> is pure-presentational —
14
+ // so reusing instances on re-wrap is harmless; index-as-key is fine here.
15
+ // biome-ignore lint/suspicious/noArrayIndexKey: stateless leaf, reuse is safe
16
+ _jsx(Text, { color: color, dimColor: dimColor, italic: italic, children: line.length === 0 ? " " : line }, `${keyPrefix}:${i}`))) }));
17
+ }
18
+ //# sourceMappingURL=wrapped-lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapped-lines.js","sourceRoot":"","sources":["../../src/ui/wrapped-lines.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAWrC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAqB;IAClG,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,OAAO,CACN,4BACE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QACvB,yEAAyE;QACzE,0EAA0E;QAC1E,8EAA8E;QAC9E,KAAC,IAAI,IAA2B,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAC9E,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IADrB,GAAG,SAAS,IAAI,CAAC,EAAE,CAEvB,CACP,CAAC,GACA,CACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebase-cli",
3
- "version": "2.0.0-pre.4",
3
+ "version": "2.0.0-pre.41",
4
4
  "description": "Codebase CLI — a TypeScript coding agent on the pi-mono runtime. OAuth-aware, any LLM provider, single install.",
5
5
  "keywords": [
6
6
  "ai",
@@ -54,15 +54,20 @@
54
54
  "check": "npm run typecheck && npm run lint && npm test",
55
55
  "bench": "node bench/run.mjs",
56
56
  "bench:report": "node bench/aggregate.mjs",
57
+ "bench:micro": "vitest bench --run",
57
58
  "prepublishOnly": "npm run clean && npm run check && npm run build",
58
59
  "prepack": "npm run build"
59
60
  },
60
61
  "dependencies": {
61
62
  "@earendil-works/pi-agent-core": "0.74.0",
62
63
  "@earendil-works/pi-ai": "0.74.0",
64
+ "@types/diff": "^7.0.2",
65
+ "@types/proper-lockfile": "^4.1.4",
66
+ "diff": "^9.0.0",
63
67
  "glob": "^13.0.1",
64
68
  "ignore": "^7.0.0",
65
69
  "ink": "^5.2.1",
70
+ "proper-lockfile": "^4.1.2",
66
71
  "react": "^18.3.1",
67
72
  "typebox": "^1.1.24"
68
73
  },