@cueloop/client 0.1.0-alpha.64 → 0.1.0-alpha.66

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 (109) hide show
  1. package/package.json +5 -5
  2. package/src/App.autoclose.test.tsx +2 -2
  3. package/src/App.diff.test.tsx +8 -73
  4. package/src/App.export.test.tsx +2 -2
  5. package/src/App.plan-review.test.tsx +60 -412
  6. package/src/App.prototype.test.tsx +1 -8
  7. package/src/App.readonly.test.tsx +85 -62
  8. package/src/App.rendering.test.tsx +5 -6
  9. package/src/App.submit-confirm.test.tsx +32 -70
  10. package/src/App.test.tsx +136 -66
  11. package/src/App.toast.test.tsx +17 -8
  12. package/src/App.tsx +243 -284
  13. package/src/App.walk.test.tsx +1 -1
  14. package/src/app-screens.tsx +67 -52
  15. package/src/app-view-model.ts +6 -100
  16. package/src/components/AnnotationCard.stories.tsx +1 -1
  17. package/src/components/AnnotationCard.tsx +2 -2
  18. package/src/components/AppShell.stories.tsx +84 -0
  19. package/src/components/AppShell.tsx +127 -0
  20. package/src/components/Breadcrumb.stories.tsx +1 -1
  21. package/src/components/ChangesColumn.stories.tsx +39 -0
  22. package/src/components/ChangesColumn.tsx +147 -0
  23. package/src/components/CodeBlock.stories.tsx +1 -1
  24. package/src/components/CompletionOverlay.stories.tsx +1 -1
  25. package/src/components/ConfirmCard.stories.tsx +1 -1
  26. package/src/components/ConfirmCard.tsx +3 -4
  27. package/src/components/ConfirmDialog.stories.tsx +1 -1
  28. package/src/components/DiffSheet.stories.tsx +1 -1
  29. package/src/components/InboxList.stories.tsx +23 -8
  30. package/src/components/InboxList.tsx +45 -19
  31. package/src/components/KeybindsDialog.stories.tsx +1 -1
  32. package/src/components/KeybindsDialog.tsx +61 -17
  33. package/src/components/MarkerPopover.stories.tsx +1 -1
  34. package/src/components/MenuBar.stories.tsx +3 -12
  35. package/src/components/MenuBar.tsx +25 -56
  36. package/src/components/PromptDialog.stories.tsx +1 -1
  37. package/src/components/PrototypeSheet.stories.tsx +1 -1
  38. package/src/components/ReviewPanel.stories.tsx +15 -1
  39. package/src/components/ReviewRail.stories.tsx +15 -1
  40. package/src/components/ReviewRail.tsx +13 -6
  41. package/src/components/SettingsDialog.stories.tsx +7 -1
  42. package/src/components/SettingsDialog.tsx +112 -66
  43. package/src/components/SettingsRows.stories.tsx +1 -1
  44. package/src/components/ShellHeader.stories.tsx +50 -0
  45. package/src/components/ShellHeader.tsx +137 -0
  46. package/src/components/ThreadFooter.stories.tsx +30 -0
  47. package/src/components/ThreadFooter.tsx +49 -0
  48. package/src/components/ThreadView.selection.test.tsx +812 -0
  49. package/src/components/ThreadView.slash.test.tsx +113 -0
  50. package/src/components/ThreadView.stories.tsx +26 -0
  51. package/src/components/ThreadView.tsx +1708 -0
  52. package/src/components/ThreadsSidebar.stories.tsx +36 -0
  53. package/src/components/ThreadsSidebar.tsx +57 -0
  54. package/src/components/Toast.stories.tsx +1 -1
  55. package/src/components/TreePane.stories.tsx +106 -0
  56. package/src/components/TreePane.tsx +156 -0
  57. package/src/components/WalkWizard.stories.tsx +1 -1
  58. package/src/components/__snapshots__/stories.test.tsx.snap +463 -305
  59. package/src/components/agent-launcher.stories.tsx +1 -1
  60. package/src/components/file-tree.test.ts +45 -0
  61. package/src/components/file-tree.ts +57 -0
  62. package/src/components/pages/Workspace.stories.tsx +181 -0
  63. package/src/components/primitives/Button.stories.tsx +1 -1
  64. package/src/components/primitives/Card.stories.tsx +1 -1
  65. package/src/components/primitives/Dialog.stories.tsx +1 -1
  66. package/src/components/primitives/IconButton.stories.tsx +36 -0
  67. package/src/components/primitives/IconButton.tsx +43 -0
  68. package/src/components/primitives/StatusBar.stories.tsx +1 -1
  69. package/src/components/primitives/Tabs.stories.tsx +1 -1
  70. package/src/components/primitives/Toolbar.stories.tsx +1 -1
  71. package/src/components/primitives/Tree.stories.tsx +124 -0
  72. package/src/components/primitives/Tree.tsx +87 -0
  73. package/src/components/primitives/icons.ts +38 -0
  74. package/src/components/primitives/tree-model.test.ts +99 -0
  75. package/src/components/primitives/tree-model.ts +137 -0
  76. package/src/components/quick-actions-editor.stories.tsx +1 -1
  77. package/src/components/session-tree.test.ts +114 -0
  78. package/src/components/session-tree.ts +94 -0
  79. package/src/components/stories-app.tsx +142 -82
  80. package/src/components/story-tree.test.ts +100 -0
  81. package/src/components/story.ts +55 -0
  82. package/src/components/theme-context.stories.tsx +1 -1
  83. package/src/diff-hunk-curate.ts +4 -104
  84. package/src/index.ts +1 -0
  85. package/src/intent-dispatch.test.ts +136 -3
  86. package/src/intent-dispatch.ts +92 -24
  87. package/src/key-bindings.test.ts +1 -1
  88. package/src/keymap.test.ts +4 -4
  89. package/src/keymap.ts +14 -7
  90. package/src/session-controller.curate.test.ts +89 -2
  91. package/src/session-controller.share.test.ts +195 -55
  92. package/src/session-controller.tree.test.ts +228 -0
  93. package/src/session-controller.ts +331 -72
  94. package/src/share.ts +114 -16
  95. package/src/test-support.test.ts +193 -1
  96. package/src/test-support.ts +64 -0
  97. package/src/theme.ts +4 -4
  98. package/src/thread-chords.test.ts +154 -0
  99. package/src/thread-chords.ts +144 -0
  100. package/src/thread-selection.test.ts +210 -0
  101. package/src/thread-selection.ts +243 -0
  102. package/src/tree-view.test.ts +128 -0
  103. package/src/tree-view.ts +148 -0
  104. package/src/use-settings-dialog.tsx +9 -0
  105. package/src/view-plan.ts +29 -12
  106. package/src/App.review-panel.test.tsx +0 -143
  107. package/src/components/PlanSheet.stories.tsx +0 -113
  108. package/src/components/PlanSheet.tsx +0 -419
  109. package/src/components/plan-sheet-run-style.ts +0 -88
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cueloop/client",
3
- "version": "0.1.0-alpha.64",
3
+ "version": "0.1.0-alpha.66",
4
4
  "description": "The cueloop review UI: projection renderer, keyboard grammar, review rail",
5
5
  "homepage": "https://github.com/mmurakaru/cueloop#readme",
6
6
  "bugs": {
@@ -26,10 +26,10 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@cueloop/daemon": "0.1.0-alpha.64",
30
- "@cueloop/extension-api": "0.1.0-alpha.64",
31
- "@cueloop/integration-obsidian": "0.1.0-alpha.64",
32
- "@cueloop/schema": "0.1.0-alpha.64",
29
+ "@cueloop/daemon": "0.1.0-alpha.66",
30
+ "@cueloop/extension-api": "0.1.0-alpha.66",
31
+ "@cueloop/integration-obsidian": "0.1.0-alpha.66",
32
+ "@cueloop/schema": "0.1.0-alpha.66",
33
33
  "@opentui/core": "^0.5.8",
34
34
  "@opentui/keymap": "0.5.8",
35
35
  "@opentui/react": "^0.5.8",
@@ -10,7 +10,7 @@ import { ManualClock } from "@opentui/core/testing";
10
10
  import { DaemonServer } from "@cueloop/daemon";
11
11
  import type { ReviewSession } from "@cueloop/schema";
12
12
  import { App } from "./App";
13
- import { isolateUserConfig, press, settle, waitForText } from "./test-support";
13
+ import { isolateUserConfig, press, settle, waitForText, pressKey } from "./test-support";
14
14
 
15
15
  const PLAN = "# Plan\n\nShip the thing.\n";
16
16
 
@@ -56,7 +56,7 @@ async function renderApp(onExit?: (code: number) => void) {
56
56
  type Setup = Awaited<ReturnType<typeof renderApp>>;
57
57
 
58
58
  async function submitApprove(setup: Setup): Promise<void> {
59
- await press(setup, "enter"); // open submit (approve default: no pending items)
59
+ await pressKey(setup, "RETURN", { meta: true }); // open submit (approve default: no pending items)
60
60
  await press(setup, "enter"); // confirm
61
61
  await waitForText(setup, "review approved");
62
62
  }
@@ -152,50 +152,9 @@ describe("diff review", () => {
152
152
  expect(stored.workingCopy).toBe("");
153
153
  });
154
154
 
155
- test("a rejected change lists in the rail and undo (u) restores it", async () => {
156
- // Arrange - a diff session that carries full file contents
157
- const withFiles = server.core.sessionCreate({
158
- workspace: { repoRoot: "/repo", branch: "main" },
159
- artifact: {
160
- type: "diff",
161
- content: PATCH,
162
- meta: { title: "working tree" },
163
- files: [
164
- {
165
- path: "src/store.ts",
166
- oldContents: "export class Store {\n private items = [];\n}\n",
167
- newContents: "export class Store {\n private items = new Map();\n}\n",
168
- status: "modified",
169
- },
170
- ],
171
- },
172
- });
173
- const setup = await testRender(<App home={home} sessionId={withFiles.id} />, {
174
- width: 120,
175
- height: 30,
176
- });
177
-
178
- await waitForText(setup, "cueloop");
179
-
180
- // Act - reject the change under the added line
181
- // rows: file(0), hunk(1), ctx(2), del(3), add(4)
182
- for (let i = 0; i < 4; i++) await press(setup, "j");
183
- await press(setup, "x");
184
-
185
- // Assert - the rail shows a removal card titled REJECT · me for the change
186
- await waitForText(setup, "REJECT · me");
187
- expect(server.core.sessionGet(withFiles.id).workingCopy).toBe("");
188
-
189
- // Act - undo restores it (no selection, so the last item)
190
- await press(setup, "u");
191
-
192
- // Assert - the change returns to the curated diff (working copy cleared)
193
- await waitForText(setup, "removal restored");
194
- expect(server.core.sessionGet(withFiles.id).workingCopy).toBeUndefined();
195
- });
196
-
197
- test("a selected removal card shows an undo button that restores it on click", async () => {
198
- // Arrange - a diff session that carries full file contents
155
+ test("a diff opens with the Changes column listing every changed file", async () => {
156
+ // Arrange - two changed files; config.ts is not in the patch text, so it can
157
+ // only appear here by way of the Changes column reading artifact.files
199
158
  const withFiles = server.core.sessionCreate({
200
159
  workspace: { repoRoot: "/repo", branch: "main" },
201
160
  artifact: {
@@ -203,12 +162,8 @@ describe("diff review", () => {
203
162
  content: PATCH,
204
163
  meta: { title: "working tree" },
205
164
  files: [
206
- {
207
- path: "src/store.ts",
208
- oldContents: "export class Store {\n private items = [];\n}\n",
209
- newContents: "export class Store {\n private items = new Map();\n}\n",
210
- status: "modified",
211
- },
165
+ { path: "src/store.ts", oldContents: "a", newContents: "b", status: "modified" },
166
+ { path: "src/config.ts", oldContents: "", newContents: "c", status: "added" },
212
167
  ],
213
168
  },
214
169
  });
@@ -219,28 +174,8 @@ describe("diff review", () => {
219
174
 
220
175
  await waitForText(setup, "cueloop");
221
176
 
222
- // Act - reject the change; the removal card lands unselected (no undo button)
223
- for (let i = 0; i < 4; i++) await press(setup, "j");
224
- await press(setup, "x");
225
- await waitForText(setup, "REJECT · me");
226
- expect(setup.captureCharFrame()).not.toContain("undo");
227
-
228
- // Act - click the card to select it; the undo button appears
229
- const clickText = async (needle: string): Promise<void> => {
230
- const lines = setup.captureCharFrame().split("\n");
231
- const row = lines.findIndex((line) => line.includes(needle));
232
-
233
- await setup.mockMouse.click(lines[row]!.indexOf(needle) + 1, row);
234
- };
235
-
236
- await clickText("REJECT · me");
237
- await waitForText(setup, "undo");
238
-
239
- // Act - click the undo button
240
- await clickText("undo");
241
-
242
- // Assert - the change returns to the curated diff (working copy cleared)
243
- await waitForText(setup, "removal restored");
244
- expect(server.core.sessionGet(withFiles.id).workingCopy).toBeUndefined();
177
+ // Assert - the context default opens the column for a diff, so both files show
178
+ await waitForText(setup, "config.ts");
179
+ expect(setup.captureCharFrame()).toContain("store.ts");
245
180
  });
246
181
  });
@@ -17,7 +17,7 @@ import { testRender } from "@opentui/react/test-utils";
17
17
  import { DaemonServer } from "@cueloop/daemon";
18
18
  import type { ReviewSession } from "@cueloop/schema";
19
19
  import { App } from "./App";
20
- import { isolateUserConfig, press, waitForState, waitForText } from "./test-support";
20
+ import { isolateUserConfig, press, waitForState, waitForText, pressKey } from "./test-support";
21
21
 
22
22
  const PLAN = `# Migration Plan
23
23
 
@@ -69,7 +69,7 @@ describe("obsidian export on resolve", () => {
69
69
  await waitForText(setup, "cueloop");
70
70
 
71
71
  // Act
72
- await press(setup, "enter"); // open the submit overlay, keep the default verdict (approve)
72
+ await pressKey(setup, "RETURN", { meta: true }); // open the submit overlay, keep the default verdict (approve)
73
73
 
74
74
  // Assert
75
75
  await waitForText(setup, "[Approve]");