@patze/code-cli 0.31.0 → 0.42.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 (171) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/VERSION +1 -1
  3. package/dist/cli/commands/agent.d.ts.map +1 -1
  4. package/dist/cli/commands/agent.js +11 -11
  5. package/dist/cli/commands/agent.js.map +1 -1
  6. package/dist/cli/commands/diff-format.js +4 -4
  7. package/dist/cli/commands/diff-format.js.map +1 -1
  8. package/dist/cli/commands/doctor.js +2 -2
  9. package/dist/cli/commands/doctor.js.map +1 -1
  10. package/dist/cli/commands/exec.d.ts.map +1 -1
  11. package/dist/cli/commands/exec.js +8 -5
  12. package/dist/cli/commands/exec.js.map +1 -1
  13. package/dist/cli/commands/inspect-format.js +1 -1
  14. package/dist/cli/commands/inspect-format.js.map +1 -1
  15. package/dist/cli/commands/plan-format.js +1 -1
  16. package/dist/cli/commands/plan-format.js.map +1 -1
  17. package/dist/cli/commands/status-format.d.ts.map +1 -1
  18. package/dist/cli/commands/status-format.js +3 -3
  19. package/dist/cli/commands/status-format.js.map +1 -1
  20. package/dist/cli/commands/trust-loop-snapshot.d.ts.map +1 -1
  21. package/dist/cli/commands/trust-loop-snapshot.js +19 -0
  22. package/dist/cli/commands/trust-loop-snapshot.js.map +1 -1
  23. package/dist/cli/help.d.ts.map +1 -1
  24. package/dist/cli/help.js +12 -11
  25. package/dist/cli/help.js.map +1 -1
  26. package/dist/cli/interactive/agent-event-feed.d.ts +6 -3
  27. package/dist/cli/interactive/agent-event-feed.d.ts.map +1 -1
  28. package/dist/cli/interactive/agent-event-feed.js +110 -63
  29. package/dist/cli/interactive/agent-event-feed.js.map +1 -1
  30. package/dist/cli/interactive/agent-execute-turn.d.ts +3 -0
  31. package/dist/cli/interactive/agent-execute-turn.d.ts.map +1 -1
  32. package/dist/cli/interactive/agent-execute-turn.js +8 -0
  33. package/dist/cli/interactive/agent-execute-turn.js.map +1 -1
  34. package/dist/cli/interactive/agent-stream-format.js +4 -4
  35. package/dist/cli/interactive/agent-stream-format.js.map +1 -1
  36. package/dist/cli/interactive/agent-turn-classify.d.ts.map +1 -1
  37. package/dist/cli/interactive/agent-turn-classify.js +1 -3
  38. package/dist/cli/interactive/agent-turn-classify.js.map +1 -1
  39. package/dist/cli/interactive/agent-turn-context.d.ts.map +1 -1
  40. package/dist/cli/interactive/agent-turn-context.js +9 -3
  41. package/dist/cli/interactive/agent-turn-context.js.map +1 -1
  42. package/dist/cli/interactive/agent-turn-format.d.ts.map +1 -1
  43. package/dist/cli/interactive/agent-turn-format.js +2 -5
  44. package/dist/cli/interactive/agent-turn-format.js.map +1 -1
  45. package/dist/cli/interactive/agent-turn.d.ts +1 -0
  46. package/dist/cli/interactive/agent-turn.d.ts.map +1 -1
  47. package/dist/cli/interactive/agent-turn.js +40 -28
  48. package/dist/cli/interactive/agent-turn.js.map +1 -1
  49. package/dist/cli/interactive/auth-gate.d.ts +6 -0
  50. package/dist/cli/interactive/auth-gate.d.ts.map +1 -0
  51. package/dist/cli/interactive/auth-gate.js +29 -0
  52. package/dist/cli/interactive/auth-gate.js.map +1 -0
  53. package/dist/cli/interactive/codex-diff-feed.d.ts +14 -0
  54. package/dist/cli/interactive/codex-diff-feed.d.ts.map +1 -0
  55. package/dist/cli/interactive/codex-diff-feed.js +76 -0
  56. package/dist/cli/interactive/codex-diff-feed.js.map +1 -0
  57. package/dist/cli/interactive/codex-feed-demo.d.ts +9 -0
  58. package/dist/cli/interactive/codex-feed-demo.d.ts.map +1 -0
  59. package/dist/cli/interactive/codex-feed-demo.js +72 -0
  60. package/dist/cli/interactive/codex-feed-demo.js.map +1 -0
  61. package/dist/cli/interactive/codex-feed-format.d.ts +35 -0
  62. package/dist/cli/interactive/codex-feed-format.d.ts.map +1 -0
  63. package/dist/cli/interactive/codex-feed-format.js +142 -0
  64. package/dist/cli/interactive/codex-feed-format.js.map +1 -0
  65. package/dist/cli/interactive/codex-feed-writer.d.ts +18 -0
  66. package/dist/cli/interactive/codex-feed-writer.d.ts.map +1 -0
  67. package/dist/cli/interactive/codex-feed-writer.js +144 -0
  68. package/dist/cli/interactive/codex-feed-writer.js.map +1 -0
  69. package/dist/cli/interactive/codex-preview-feed.d.ts +13 -0
  70. package/dist/cli/interactive/codex-preview-feed.d.ts.map +1 -0
  71. package/dist/cli/interactive/codex-preview-feed.js +127 -0
  72. package/dist/cli/interactive/codex-preview-feed.js.map +1 -0
  73. package/dist/cli/interactive/cookbook-feed-writer.d.ts +2 -12
  74. package/dist/cli/interactive/cookbook-feed-writer.d.ts.map +1 -1
  75. package/dist/cli/interactive/cookbook-feed-writer.js +2 -86
  76. package/dist/cli/interactive/cookbook-feed-writer.js.map +1 -1
  77. package/dist/cli/interactive/header.d.ts.map +1 -1
  78. package/dist/cli/interactive/header.js +4 -12
  79. package/dist/cli/interactive/header.js.map +1 -1
  80. package/dist/cli/interactive/line-editor.d.ts +2 -0
  81. package/dist/cli/interactive/line-editor.d.ts.map +1 -1
  82. package/dist/cli/interactive/line-editor.js +7 -5
  83. package/dist/cli/interactive/line-editor.js.map +1 -1
  84. package/dist/cli/interactive/model-command.d.ts.map +1 -1
  85. package/dist/cli/interactive/model-command.js +2 -2
  86. package/dist/cli/interactive/model-command.js.map +1 -1
  87. package/dist/cli/interactive/permissions-command.d.ts.map +1 -1
  88. package/dist/cli/interactive/permissions-command.js +7 -8
  89. package/dist/cli/interactive/permissions-command.js.map +1 -1
  90. package/dist/cli/interactive/permissions-format.d.ts.map +1 -1
  91. package/dist/cli/interactive/permissions-format.js +5 -6
  92. package/dist/cli/interactive/permissions-format.js.map +1 -1
  93. package/dist/cli/interactive/plain-agent-render.d.ts +5 -4
  94. package/dist/cli/interactive/plain-agent-render.d.ts.map +1 -1
  95. package/dist/cli/interactive/plain-agent-render.js +12 -44
  96. package/dist/cli/interactive/plain-agent-render.js.map +1 -1
  97. package/dist/cli/interactive/plain-codex-feed.d.ts +11 -0
  98. package/dist/cli/interactive/plain-codex-feed.d.ts.map +1 -0
  99. package/dist/cli/interactive/plain-codex-feed.js +37 -0
  100. package/dist/cli/interactive/plain-codex-feed.js.map +1 -0
  101. package/dist/cli/interactive/reset-agent.d.ts +8 -0
  102. package/dist/cli/interactive/reset-agent.d.ts.map +1 -0
  103. package/dist/cli/interactive/reset-agent.js +23 -0
  104. package/dist/cli/interactive/reset-agent.js.map +1 -0
  105. package/dist/cli/interactive/session-controller.d.ts +1 -0
  106. package/dist/cli/interactive/session-controller.d.ts.map +1 -1
  107. package/dist/cli/interactive/session-controller.js +21 -10
  108. package/dist/cli/interactive/session-controller.js.map +1 -1
  109. package/dist/cli/interactive/session-hints.d.ts +4 -0
  110. package/dist/cli/interactive/session-hints.d.ts.map +1 -0
  111. package/dist/cli/interactive/session-hints.js +28 -0
  112. package/dist/cli/interactive/session-hints.js.map +1 -0
  113. package/dist/cli/interactive/session-store.d.ts +1 -1
  114. package/dist/cli/interactive/session-store.d.ts.map +1 -1
  115. package/dist/cli/interactive/session-store.js +2 -5
  116. package/dist/cli/interactive/session-store.js.map +1 -1
  117. package/dist/cli/interactive/session.d.ts +3 -1
  118. package/dist/cli/interactive/session.d.ts.map +1 -1
  119. package/dist/cli/interactive/session.js +8 -2
  120. package/dist/cli/interactive/session.js.map +1 -1
  121. package/dist/cli/interactive/shell.d.ts.map +1 -1
  122. package/dist/cli/interactive/shell.js +59 -20
  123. package/dist/cli/interactive/shell.js.map +1 -1
  124. package/dist/cli/interactive/slash-dispatch.d.ts +6 -0
  125. package/dist/cli/interactive/slash-dispatch.d.ts.map +1 -1
  126. package/dist/cli/interactive/slash-dispatch.js +29 -5
  127. package/dist/cli/interactive/slash-dispatch.js.map +1 -1
  128. package/dist/cli/interactive/slash-menu-core.d.ts +10 -0
  129. package/dist/cli/interactive/slash-menu-core.d.ts.map +1 -0
  130. package/dist/cli/interactive/slash-menu-core.js +34 -0
  131. package/dist/cli/interactive/slash-menu-core.js.map +1 -0
  132. package/dist/cli/interactive/slash-menu.d.ts +3 -0
  133. package/dist/cli/interactive/slash-menu.d.ts.map +1 -1
  134. package/dist/cli/interactive/slash-menu.js +16 -4
  135. package/dist/cli/interactive/slash-menu.js.map +1 -1
  136. package/dist/cli/interactive/slash-registry.d.ts.map +1 -1
  137. package/dist/cli/interactive/slash-registry.js +8 -5
  138. package/dist/cli/interactive/slash-registry.js.map +1 -1
  139. package/dist/cli/interactive/tools-catalog.js +2 -2
  140. package/dist/cli/interactive/tools-catalog.js.map +1 -1
  141. package/dist/cli/interactive/trace-glyphs.d.ts.map +1 -1
  142. package/dist/cli/interactive/trace-glyphs.js +2 -11
  143. package/dist/cli/interactive/trace-glyphs.js.map +1 -1
  144. package/dist/cli/interactive/transcript-upsert.d.ts.map +1 -1
  145. package/dist/cli/interactive/transcript-upsert.js +6 -6
  146. package/dist/cli/interactive/transcript-upsert.js.map +1 -1
  147. package/dist/cli/one-shot-args.d.ts +1 -0
  148. package/dist/cli/one-shot-args.d.ts.map +1 -1
  149. package/dist/cli/one-shot-args.js +3 -2
  150. package/dist/cli/one-shot-args.js.map +1 -1
  151. package/dist/config/model-preferences.d.ts +1 -0
  152. package/dist/config/model-preferences.d.ts.map +1 -1
  153. package/dist/config/model-preferences.js +11 -2
  154. package/dist/config/model-preferences.js.map +1 -1
  155. package/dist/config/models.d.ts +9 -0
  156. package/dist/config/models.d.ts.map +1 -1
  157. package/dist/config/models.js +64 -12
  158. package/dist/config/models.js.map +1 -1
  159. package/dist/runtime/apply-verify.js +3 -3
  160. package/dist/runtime/apply-verify.js.map +1 -1
  161. package/dist/runtime/permissions.d.ts +2 -1
  162. package/dist/runtime/permissions.d.ts.map +1 -1
  163. package/dist/runtime/permissions.js +25 -11
  164. package/dist/runtime/permissions.js.map +1 -1
  165. package/dist/runtime/sandbox.d.ts +1 -0
  166. package/dist/runtime/sandbox.d.ts.map +1 -1
  167. package/dist/runtime/sandbox.js +4 -1
  168. package/dist/runtime/sandbox.js.map +1 -1
  169. package/opentui/src/App.tsx +102 -17
  170. package/opentui/src/transcript-render.ts +144 -2
  171. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- export type PermissionMode = "read-only" | "suggest" | "edit-with-approval" | "full-auto";
1
+ export type PermissionMode = "standard" | "suggest" | "edit-with-approval" | "full-auto";
2
2
  export type PermissionModeDef = {
3
3
  mode: PermissionMode;
4
4
  label: string;
@@ -7,6 +7,7 @@ export type PermissionModeDef = {
7
7
  };
8
8
  export declare const PERMISSION_MODES: PermissionModeDef[];
9
9
  export declare const DEFAULT_PERMISSION_MODE: PermissionMode;
10
+ export declare function normalizePermissionMode(value: string | null | undefined): PermissionMode | null;
10
11
  export declare function isPermissionMode(value: string): value is PermissionMode;
11
12
  export declare function getPermissionModeDef(mode: PermissionMode): PermissionModeDef;
12
13
  export declare function resolvePermissionModeArg(raw: string): PermissionMode | null;
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,oBAAoB,GAAG,WAAW,CAAA;AAEzF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;CAC1C,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,EAyB/C,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,cAA4B,CAAA;AAElE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEvE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,CAE5E;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAM3E;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAGvE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEnE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAElE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,cAAc,EAAE,CAgBjF"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,oBAAoB,GAAG,WAAW,CAAA;AAExF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;CAC1C,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,EAyB/C,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,cAA2B,CAAA;AAMjE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAU/F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEvE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,CAE5E;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAE3E;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAGvE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEnE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAElE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,cAAc,EAAE,CAqBjF"}
@@ -1,14 +1,14 @@
1
1
  export const PERMISSION_MODES = [
2
2
  {
3
- mode: "read-only",
4
- label: "Read-only",
5
- description: "Inspect, plan, and diff only. No writes, shell, or apply.",
3
+ mode: "standard",
4
+ label: "Standard",
5
+ description: "Default agent mode live coding agent with server-side tools.",
6
6
  phase: "active",
7
7
  },
8
8
  {
9
9
  mode: "suggest",
10
10
  label: "Suggest",
11
- description: "Patch proposals, diff, and approval gate. No writes, shell, or apply yet.",
11
+ description: "Patch proposals, diff, and approval gate before local apply.",
12
12
  phase: "active",
13
13
  },
14
14
  {
@@ -24,7 +24,21 @@ export const PERMISSION_MODES = [
24
24
  phase: "forbidden",
25
25
  },
26
26
  ];
27
- export const DEFAULT_PERMISSION_MODE = "read-only";
27
+ export const DEFAULT_PERMISSION_MODE = "standard";
28
+ const LEGACY_PERMISSION_ALIASES = {
29
+ "read-only": "standard",
30
+ };
31
+ export function normalizePermissionMode(value) {
32
+ const normalized = value?.trim().toLowerCase();
33
+ if (!normalized) {
34
+ return null;
35
+ }
36
+ const alias = LEGACY_PERMISSION_ALIASES[normalized];
37
+ if (alias) {
38
+ return alias;
39
+ }
40
+ return isPermissionMode(normalized) ? normalized : null;
41
+ }
28
42
  export function isPermissionMode(value) {
29
43
  return PERMISSION_MODES.some((entry) => entry.mode === value);
30
44
  }
@@ -32,11 +46,7 @@ export function getPermissionModeDef(mode) {
32
46
  return PERMISSION_MODES.find((entry) => entry.mode === mode) ?? PERMISSION_MODES[0];
33
47
  }
34
48
  export function resolvePermissionModeArg(raw) {
35
- const normalized = raw.trim().toLowerCase();
36
- if (!normalized) {
37
- return null;
38
- }
39
- return isPermissionMode(normalized) ? normalized : null;
49
+ return normalizePermissionMode(raw);
40
50
  }
41
51
  export function canActivatePermissionMode(mode) {
42
52
  const def = getPermissionModeDef(mode);
@@ -49,7 +59,7 @@ export function permissionAllowsApply(mode) {
49
59
  return mode === "edit-with-approval";
50
60
  }
51
61
  export function permissionAllowsDiff(mode) {
52
- return mode === "read-only" || mode === "suggest" || mode === "edit-with-approval";
62
+ return mode === "standard" || mode === "suggest" || mode === "edit-with-approval";
53
63
  }
54
64
  export function suggestPermissionModes(input, limit = 3) {
55
65
  const needle = input.trim().toLowerCase();
@@ -64,6 +74,10 @@ export function suggestPermissionModes(input, limit = 3) {
64
74
  }))
65
75
  .filter((entry) => entry.score > 0)
66
76
  .sort((left, right) => right.score - left.score);
77
+ const legacy = LEGACY_PERMISSION_ALIASES[needle];
78
+ if (legacy && !scored.some((entry) => entry.mode === legacy)) {
79
+ scored.unshift({ mode: legacy, score: 100 });
80
+ }
67
81
  return scored.slice(0, limit).map((entry) => entry.mode);
68
82
  }
69
83
  function scorePermissionMatch(needle, candidate) {
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/runtime/permissions.ts"],"names":[],"mappings":"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"}
@@ -5,5 +5,6 @@ export type SandboxPosture = {
5
5
  writeAllowed: boolean;
6
6
  description: string;
7
7
  };
8
+ export declare function formatSandboxModeLabel(mode: SandboxMode): string;
8
9
  export declare function resolveSandbox(mode: SandboxMode): SandboxPosture;
9
10
  //# sourceMappingURL=sandbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/runtime/sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,WAAW,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAgBhE"}
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/runtime/sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,WAAW,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAEhE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAgBhE"}
@@ -1,3 +1,6 @@
1
+ export function formatSandboxModeLabel(mode) {
2
+ return mode === "workspace-write" ? "workspace" : "local";
3
+ }
1
4
  export function resolveSandbox(mode) {
2
5
  if (mode === "workspace-write") {
3
6
  return {
@@ -11,7 +14,7 @@ export function resolveSandbox(mode) {
11
14
  mode: "read-only",
12
15
  networkAllowed: false,
13
16
  writeAllowed: false,
14
- description: "Read-only local inspection; mutations require apply + server approval.",
17
+ description: "Local inspection only; agent runs on the server when auth is ready.",
15
18
  };
16
19
  }
17
20
  //# sourceMappingURL=sandbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/runtime/sandbox.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,cAAc,CAAC,IAAiB;IAC9C,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI;YACJ,cAAc,EAAE,KAAK;YACrB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,8EAA8E;SAC5F,CAAA;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,KAAK;QACrB,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,wEAAwE;KACtF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/runtime/sandbox.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,sBAAsB,CAAC,IAAiB;IACtD,OAAO,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAiB;IAC9C,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI;YACJ,cAAc,EAAE,KAAK;YACrB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,8EAA8E;SAC5F,CAAA;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,cAAc,EAAE,KAAK;QACrB,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,qEAAqE;KACnF,CAAA;AACH,CAAC"}
@@ -24,6 +24,11 @@ import { classifyPlainOutput, createTranscriptSink, inferErrorKind } from "./tui
24
24
  import { upsertTranscriptEntry } from "../../dist/cli/interactive/transcript-upsert.js"
25
25
  import { applyOpenTuiAgentEvent } from "../../dist/cli/interactive/opentui-agent-event.js"
26
26
  import type { AgentEvent } from "../../dist/cli/interactive/agent-events.js"
27
+ import {
28
+ formatModelDisplayName,
29
+ getModelCatalogEntry,
30
+ PATZE_MODEL_CATALOG,
31
+ } from "../../dist/config/models.js"
27
32
 
28
33
  extend({ "tui-input": InputRenderable })
29
34
 
@@ -76,7 +81,7 @@ type InteractiveController = {
76
81
  useActivitySpinner?: boolean
77
82
  onAgentEvent?: (event: AgentEvent) => void
78
83
  }
79
- ) => Promise<{ exitShell: boolean; exitCode: number; streamed?: boolean }>
84
+ ) => Promise<{ exitShell: boolean; exitCode: number; streamed?: boolean; clearVisibleTranscript?: boolean }>
80
85
  }
81
86
 
82
87
  function parseCwdArg(): string {
@@ -117,6 +122,8 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
117
122
  const [supportedModels, setSupportedModels] = useState<string[]>([])
118
123
  const [slashMenuReady, setSlashMenuReady] = useState(false)
119
124
  const [startupHeader, setStartupHeader] = useState<string[]>([])
125
+ const [composerPlaceholder, setComposerPlaceholder] = useState("Describe a task… · / for commands")
126
+ const [emptySessionHints, setEmptySessionHints] = useState<string[]>([])
120
127
 
121
128
  const followTranscript = useCallback(() => {
122
129
  if (scrollPinnedRef.current) {
@@ -259,6 +266,16 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
259
266
  } else {
260
267
  setExecutionTarget(null)
261
268
  }
269
+
270
+ const authGate = await importPatzeDist<
271
+ typeof import("../../dist/cli/interactive/auth-gate.js")
272
+ >("cli/interactive/auth-gate.js")
273
+ setComposerPlaceholder(authGate.resolveComposerPlaceholder(controller.cwd))
274
+
275
+ const sessionHints = await importPatzeDist<
276
+ typeof import("../../dist/cli/interactive/session-hints.js")
277
+ >("cli/interactive/session-hints.js")
278
+ setEmptySessionHints(sessionHints.buildEmptySessionHints(controller.cwd))
262
279
  }, [])
263
280
 
264
281
  useEffect(() => {
@@ -367,7 +384,7 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
367
384
  const result = await controller.processLine(value, sink, {
368
385
  signal: abort.signal,
369
386
  onActivity: setActivityLabel,
370
- useActivitySpinner: false,
387
+ useActivitySpinner: true,
371
388
  onAgentEvent: (event) => {
372
389
  setActivityLabel(null)
373
390
  setTranscript((items) =>
@@ -379,6 +396,10 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
379
396
  if (result.streamed) {
380
397
  clearStreaming()
381
398
  }
399
+ if (result.clearVisibleTranscript) {
400
+ setTranscript([])
401
+ markScrollPinned()
402
+ }
382
403
  await refreshStatusMeta()
383
404
  if (result.exitShell) {
384
405
  exitApp()
@@ -443,8 +464,7 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
443
464
 
444
465
  switch (name?.toLowerCase()) {
445
466
  case "help":
446
- setInput("/")
447
- setMode("command")
467
+ await submitToController("/help")
448
468
  return
449
469
  case "model":
450
470
  if (!args.trim()) {
@@ -525,7 +545,7 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
525
545
  : composerChromeRows)
526
546
  )
527
547
 
528
- const composerModelLabel = `${currentModel}${modelThinking ? " · thinking" : ""}${modelFast ? " · fast" : ""}`
548
+ const composerModelLabel = `${formatModelDisplayName(currentModel)}${modelThinking ? " · thinking" : ""}${modelFast ? " · fast" : ""}`
529
549
  const composerPathLabel = shortenComposerPath(cwd)
530
550
 
531
551
  const scrollableEntries = useMemo(() => transcript, [transcript])
@@ -556,19 +576,58 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
556
576
  }, [input, slashMenuReady])
557
577
 
558
578
  const modelItems = useMemo(() => {
559
- const models = supportedModels.length
560
- ? supportedModels
561
- : ["composer-2.5-fast", "composer-2.5", "composer-2", "gpt-5.4-mini", "gpt-5.4"]
579
+ const catalogIds = PATZE_MODEL_CATALOG.map((entry) => entry.id)
580
+ const merged = [...new Set([...catalogIds, ...supportedModels])]
562
581
  const normalized = modelSearch.trim().toLowerCase()
563
- return models
564
- .filter((model) => !normalized || model.toLowerCase().includes(normalized))
565
- .map((model) => ({
566
- name: model,
567
- description: model === currentModel ? "current" : "",
568
- value: model,
569
- }))
582
+ return merged
583
+ .filter((model) => {
584
+ if (!normalized) {
585
+ return true
586
+ }
587
+ const display = formatModelDisplayName(model).toLowerCase()
588
+ if (model.toLowerCase().includes(normalized) || display.includes(normalized)) {
589
+ return true
590
+ }
591
+ if (normalized === "patze" && model === "composer-2.5-fast") {
592
+ return true
593
+ }
594
+ return false
595
+ })
596
+ .map((model) => {
597
+ const entry = getModelCatalogEntry(model)
598
+ const isCurrent = model.toLowerCase() === currentModel.toLowerCase()
599
+ return {
600
+ name: formatModelDisplayName(model),
601
+ description: isCurrent
602
+ ? entry?.description
603
+ ? `${entry.description} · current`
604
+ : "current"
605
+ : entry?.description ?? model,
606
+ value: model,
607
+ }
608
+ })
570
609
  }, [currentModel, modelSearch, supportedModels])
571
610
 
611
+ const toggleFeedExpand = useCallback((target: "think" | "diff") => {
612
+ setTranscript((items) => {
613
+ for (let index = items.length - 1; index >= 0; index -= 1) {
614
+ const entry = items[index]
615
+ const matchesThink = target === "think" && entry.label === "think" && entry.detailText
616
+ const matchesDiff =
617
+ target === "diff" && entry.kind === "meta" && entry.label === "diff" && entry.detailText
618
+ if (matchesThink || matchesDiff) {
619
+ return items.map((candidate, candidateIndex) =>
620
+ candidateIndex === index
621
+ ? { ...candidate, expanded: !candidate.expanded }
622
+ : candidate
623
+ )
624
+ }
625
+ }
626
+ return items
627
+ })
628
+ followTranscript()
629
+ }, [followTranscript])
630
+
572
631
  useKeyboard((key: KeyEvent) => {
573
632
  const character = getInputCharacter(key)
574
633
 
@@ -611,6 +670,16 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
611
670
  if (mode === "input") {
612
671
  const pageSize = Math.max(1, transcriptViewportRows - 1)
613
672
 
673
+ if (key.ctrl && key.name === "t") {
674
+ toggleFeedExpand("think")
675
+ return
676
+ }
677
+
678
+ if (key.ctrl && key.name === "d") {
679
+ toggleFeedExpand("diff")
680
+ return
681
+ }
682
+
614
683
  if (key.shift && (key.name === "return" || key.name === "enter")) {
615
684
  setInput((value) => `${value}\n`)
616
685
  return
@@ -688,6 +757,15 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
688
757
  createElement(
689
758
  "box",
690
759
  { flexDirection: "column", height: transcriptViewportRows },
760
+ transcript.length === 0 && emptySessionHints.length
761
+ ? emptySessionHints.map((hint, index) =>
762
+ createElement("text", {
763
+ key: `hint-${index}`,
764
+ content: hint,
765
+ attributes: TextAttributes.DIM,
766
+ })
767
+ )
768
+ : null,
691
769
  visibleTranscriptLines.map((line) =>
692
770
  createElement(TranscriptLine, { key: line.id, line })
693
771
  )
@@ -701,6 +779,13 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
701
779
  }`
702
780
  )
703
781
  : null,
782
+ busy && activityLabel
783
+ ? createElement("text", {
784
+ content: `${["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"][activityFrame % 10]} ${activityLabel}…`,
785
+ fg: "yellow",
786
+ attributes: TextAttributes.DIM,
787
+ })
788
+ : null,
704
789
  mode === "command"
705
790
  ? createElement(
706
791
  "box",
@@ -785,7 +870,7 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
785
870
  ? `${["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"][activityFrame % 10]} ${activityLabel}… · Ctrl+C cancel`
786
871
  : "Ctrl+C cancel · waiting for agent…"
787
872
  : ready
788
- ? "Ask anything…"
873
+ ? composerPlaceholder
789
874
  : "Loading Patze Code…",
790
875
  value: input,
791
876
  onInput: (value: string) => {
@@ -810,7 +895,7 @@ export function App({ cwd: cwdArg }: { cwd?: string }) {
810
895
  createElement("text", {
811
896
  content: busy
812
897
  ? "Esc exit · Ctrl+C cancel run · agent executing"
813
- : "Esc exit · Ctrl+C quit · /diff · /approve · /apply when patch ready",
898
+ : "Esc exit · Ctrl+C quit · / commands · ctrl+t thought · ctrl+d diff · /status",
814
899
  attributes: TextAttributes.DIM,
815
900
  })
816
901
  )
@@ -12,6 +12,9 @@ export type TranscriptEntry = {
12
12
  label: string
13
13
  text: string
14
14
  upsertKey?: string
15
+ /** Full thinking body when collapsed summary is truncated. */
16
+ detailText?: string
17
+ expanded?: boolean
15
18
  }
16
19
 
17
20
  export type TranscriptPart = {
@@ -37,17 +40,65 @@ export function buildTranscriptLines(entries: TranscriptEntry[], columns: number
37
40
  entry.kind === "assistant"
38
41
  ? renderMarkdownLines(entry.text || "...", textWidth)
39
42
  : wrapText(entry.text || "...", textWidth).map((text) => ({
40
- parts: [{ text }],
43
+ parts: parseCodexFeedParts(entry.kind, entry.label, text),
41
44
  }))
42
45
  )
43
46
 
44
- return renderedLines.map((line, index) => ({
47
+ const lines = renderedLines.map((line, index) => ({
45
48
  id: `${entry.id}-${index}`,
46
49
  kind: entry.kind,
47
50
  label: index === 0 ? entry.label : "",
48
51
  parts: line.parts,
49
52
  }))
53
+
54
+ if (entry.label === "think" && entry.detailText) {
55
+ return appendExpandableDetailLines(lines, entry, textWidth, {
56
+ hint: ` (+${entry.detailText.length} chars · ctrl+t expand)`,
57
+ renderDetailLine: (text) => [{ text: ` ${text}`, color: "gray" as const, dimColor: true }],
58
+ })
59
+ }
60
+
61
+ if (entry.kind === "meta" && entry.label === "diff" && entry.detailText) {
62
+ return appendExpandableDetailLines(lines, entry, textWidth, {
63
+ hint: ` (+${entry.detailText.split("\n").length} lines · ctrl+d expand)`,
64
+ renderDetailLine: (text) => parseCodexDiffParts(text.startsWith(" ") ? text : ` ${text}`),
65
+ })
66
+ }
67
+
68
+ return lines
69
+ })
70
+ }
71
+
72
+ function appendExpandableDetailLines(
73
+ lines: TranscriptLine[],
74
+ entry: TranscriptEntry,
75
+ textWidth: number,
76
+ options: {
77
+ hint: string
78
+ renderDetailLine: (text: string) => TranscriptPart[]
79
+ }
80
+ ): TranscriptLine[] {
81
+ if (entry.expanded) {
82
+ const detailLines = entry.detailText!
83
+ .split("\n")
84
+ .flatMap((rawLine, index) =>
85
+ wrapText(rawLine, textWidth - 2).map((text, wrapIndex) => ({
86
+ id: `${entry.id}-detail-${index}-${wrapIndex}`,
87
+ kind: entry.kind,
88
+ label: "",
89
+ parts: options.renderDetailLine(text),
90
+ }))
91
+ )
92
+ return [...lines, ...detailLines]
93
+ }
94
+
95
+ lines.push({
96
+ id: `${entry.id}-expand-hint`,
97
+ kind: entry.kind,
98
+ label: "",
99
+ parts: [{ text: options.hint, color: "gray", dimColor: true }],
50
100
  })
101
+ return lines
51
102
  }
52
103
 
53
104
  function trimTrailingBlankLines(lines: Array<{ parts: TranscriptPart[] }>) {
@@ -156,6 +207,97 @@ function renderMarkdownLines(value: string, width: number) {
156
207
  return lines
157
208
  }
158
209
 
210
+ function parseCodexFeedParts(kind: TranscriptEntryKind, label: string, text: string): TranscriptPart[] {
211
+ if (kind === "meta" && label === "diff") {
212
+ return parseCodexDiffParts(text)
213
+ }
214
+
215
+ if (kind === "tool") {
216
+ const match = text.match(/^([…✓✗])\s+(.*)$/)
217
+ if (match) {
218
+ const glyph = match[1]
219
+ const body = match[2] ?? ""
220
+ const glyphColor =
221
+ glyph === "✓" ? "green" : glyph === "✗" ? "red" : ("yellow" as const)
222
+ const bodyParts = parseCodexToolBodyParts(body)
223
+ return [{ text: `${glyph} `, color: glyphColor, bold: true }, ...bodyParts]
224
+ }
225
+ return parseCodexToolBodyParts(text)
226
+ }
227
+
228
+ if (kind === "status" || (kind === "meta" && label === "done")) {
229
+ if (text.startsWith("→ ")) {
230
+ return [{ text, color: "cyan" }]
231
+ }
232
+ if (text.startsWith("…")) {
233
+ return [{ text, color: "gray", dimColor: true }]
234
+ }
235
+ if (text.startsWith("✓")) {
236
+ return [{ text, color: "green" }]
237
+ }
238
+ if (text.startsWith("✗")) {
239
+ return [{ text, color: "red" }]
240
+ }
241
+ if (text.startsWith("○")) {
242
+ return [{ text, color: "yellow" }]
243
+ }
244
+ if (text.startsWith("●")) {
245
+ return [{ text, color: "cyan", bold: true }]
246
+ }
247
+ }
248
+
249
+ if (kind === "status" && label === "think") {
250
+ if (text.startsWith("…")) {
251
+ return [{ text, color: "gray", dimColor: true }]
252
+ }
253
+ if (text.startsWith("✓")) {
254
+ return [{ text, color: "green" }]
255
+ }
256
+ }
257
+
258
+ if (kind === "meta") {
259
+ if (text.startsWith("✓ completed")) {
260
+ return [{ text, color: "green", bold: true }]
261
+ }
262
+ if (text.startsWith("deliverables")) {
263
+ return [{ text, color: "cyan" }]
264
+ }
265
+ }
266
+
267
+ return [{ text }]
268
+ }
269
+
270
+ function parseCodexToolBodyParts(body: string): TranscriptPart[] {
271
+ if (body.startsWith("+ create")) {
272
+ return [{ text: body, color: "green" }]
273
+ }
274
+ if (body.startsWith("~ modify")) {
275
+ return [{ text: body, color: "yellow" }]
276
+ }
277
+ if (body.startsWith("- delete")) {
278
+ return [{ text: body, color: "red" }]
279
+ }
280
+ if (body.startsWith("▸")) {
281
+ return [{ text: body, color: "magenta" }]
282
+ }
283
+ return [{ text: body }]
284
+ }
285
+
286
+ function parseCodexDiffParts(text: string): TranscriptPart[] {
287
+ const trimmed = text.trim()
288
+ if (trimmed === "…") {
289
+ return [{ text: " …", color: "gray", dimColor: true }]
290
+ }
291
+ const line = text.startsWith(" ") ? text : ` ${text}`
292
+ if (line.startsWith(" - ")) {
293
+ return [{ text: line, color: "red" }]
294
+ }
295
+ if (line.startsWith(" + ")) {
296
+ return [{ text: line, color: "green" }]
297
+ }
298
+ return [{ text: line, color: "gray", dimColor: true }]
299
+ }
300
+
159
301
  function wrapText(value: string, width: number) {
160
302
  const lines: string[] = []
161
303
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patze/code-cli",
3
- "version": "0.31.0",
3
+ "version": "0.42.0",
4
4
  "description": "Patze Code — local terminal coding agent client for PatzeAgents",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",