Commit Graph

620 Commits

Author SHA1 Message Date
Claude (adr007-display) 09fa78e7cd test(command,wasm): column width, row-header width and column group labels follow displays (improvise-cq1q.12)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-08 22:38:16 -07:00
Claude (adr007-display) 7a7ff81731 docs(context): core.md section 21 and test evidence for displays beside keys, second slice (improvise-cq1q.12)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-08 21:58:46 -07:00
Claude (adr007-display) 7a4dc07642 feat(tui,wasm,io): the grid, page bar, item rows and CSV export draw displays (improvise-cq1q.12)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-08 21:46:12 -07:00
Claude (adr007-display) 386b693bf5 wip(protocol,command): AxisFrame, PageAxis, CategoryRow and ViewSummary carry displays (improvise-cq1q.12)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-08 21:44:11 -07:00
Ed Langley d571abbd8a Merge pull request #322 from fiddlerwoaroof/feat/8jk6.3-date-hierarchy
feat(import): a date column imports as one hierarchical category (improvise-8jk6.3)
2026-10-02 22:32:35 -07:00
Claude (cmdlang) 8fa504fbdc Merge gh/main into fix/31oe-cmdlang; renumber cli.md §13/§14 to §14/§15
#321 added its own cli.md section 13, so this PR's sections become 14 (pipe
quoting, surplus arguments) and 15 (names the document lacks), with every
citation renumbered. The stale descriptions of the deleted unknown_* helpers in
cli.md, command.md and the test evidence now describe RequireKnown, and section
15 says a refused name stops the rest of a `:` line but not a headless one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 22:00:38 -07:00
Claude (8jk63-fix) 581934886d Merge remote-tracking branch 'gh/main' into feat/8jk6.3-date-hierarchy
# Conflicts:
#	context/test-evidence/formula-and-io.md
#	crates/improvise-io/src/import/wizard.rs
#	src/main.rs
2026-10-02 22:00:32 -07:00
Ed Langley 8da5a3101b Merge pull request #333 from fiddlerwoaroof/fix/felo13-layout-quadratic
perf(layout): O(1) axis index, layout and widths cached across keypresses (improvise-felo.13)
2026-10-02 21:55:37 -07:00
Claude (cmdlang) c99353777b fix(command): refuse a malformed coordinate on : and let a later segment see an earlier one (improvise-31oe.3)
PR #316 review blockers. A cursor fallback (clear-cell, yank, paste,
drill-into-cell) now answers only for coordinates that were omitted, so
`:clear-cell Type/Clothing Month/Feb junk` is refused instead of clearing the
cursor's cell. The unknown-name checks move from `execute` to a RequireKnown
effect run at apply time, so `:create-view Second . switch-view Second` is
accepted as `improvise cmd` accepts it. Also pins that a quoted `.` is an
argument.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 21:33:16 -07:00
Claude (imp321) 8f93d4e14a Merge commit '8220a065819652bb224d0b25f5724d6e3a5fbbe8' into fix/headless-import-refusals 2026-10-02 20:30:44 -07:00
Claude (cmdlang) 2e90872a40 Merge commit '8220a065819652bb224d0b25f5724d6e3a5fbbe8' into fix/31oe-cmdlang 2026-10-02 20:30:30 -07:00
Claude (cmdlang) ca61bda130 fix(command): refuse a coordinate argument that is not Category/Item instead of dropping it (improvise-31oe.3)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 20:30:29 -07:00
Edward Langley 0f116ff582 Merge commit '8220a065819652bb224d0b25f5724d6e3a5fbbe8' into feat/8jk6.3-date-hierarchy 2026-10-02 20:30:05 -07:00
Claude (felo13) 49ea84ca5f fix(docs): register the layout evidence pages; test the two gaps the review found (improvise-felo.13)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 19:18:47 -07:00
Claude (felo13) 14cef311dd docs(evidence): layout cost evidence and measurements; fmt the merged bench (improvise-felo.13)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 19:01:46 -07:00
Claude (felo13) 3b168a2ec8 perf(grid): keep the whole-grid summary per layout and read a window over it; exact-key probe in DataStore (improvise-felo.13)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 18:54:47 -07:00
Claude (felo13) b42aae2e08 perf(app): rebuild the layout and remeasure widths only when their inputs moved (improvise-felo.13)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 18:47:30 -07:00
Claude (felo13) 311ae96218 test(layout): a lookup and a cursor key do work independent of grid size (improvise-felo.13)
Two of the three fail on purpose: cell_key is linear in the row index and a
cursor key rebuilds the layout. The third guards the invalidation the fix adds.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-10-02 18:44:06 -07:00
Cursor Agent c355e5e844 fix(improvise-2mqz): keep download sessions in lockstep
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
2026-09-27 17:49:15 +00:00
Cursor Agent e2d5d95980 Merge remote-tracking branch 'origin/main' into cursor/improvise-2mqz-download-frames
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
2026-09-27 17:18:31 +00:00
Cursor Agent b872923331 fix(improvise-2mqz): export the requesting session view
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
2026-09-27 16:51:50 +00:00
Cursor Agent e0f04ee334 feat(improvise-2mqz): add wire forms for SaveAs and ExportCsv downloads
This commit implements the download flow for SaveAs and ExportCsv per the
USER RULING on improvise-2mqz. The correct shape is:
- A request frame asks the host for BYTES
- ServerFrame returns the bytes (or Rejected)
- Browser triggers downloads via Blob + <a download>

Key changes:

Protocol layer (improvise-protocol):
- Add Request::DownloadDocument and Request::DownloadCsv variants
- Add ClientFrame::DownloadDocument and ClientFrame::DownloadCsv
- Add ServerFrame::DocumentBytes and ServerFrame::CsvBytes
- Add KeyOutcome::LocalThenRequest variant for operations that need
  both local fold (mode change, buffer clear) AND a server request
- Update stranding() to unstrand SavePrompt and ExportPrompt modes
- Update keymap to use rebind() instead of commit() for commit-save
  and commit-export (because LocalThenRequest can't be in a Sequence)

Host layer (improvise-command):
- Handle new ClientFrames in host.rs returning bytes or Rejected
- Add Rejection::ExportFailed variant for CSV export failures
- Update CommitSave and CommitExport to clear their buffers
- Make render_csv() public in improvise-io for host use

WASM client layer (improvise-wasm-client):
- Add PendingDownload type with filename, bytes, and kind
- Store pending downloads for JavaScript retrieval via take_pending_download()

Browser layer (web/app.js):
- Add triggerDownload() function using Blob + <a download>
- Poll for pending downloads after frame handling

This unstrands SavePrompt and ExportPrompt which were previously refused
by stranding() due to missing wire forms.

Refs: improvise-2mqz

Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
2026-09-25 19:15:40 +00:00
Claude (agent-adr007) 3116d524fb feat(core,protocol): a display beside the key, painted by the three panels (improvise-cq1q.3)
- `Category`, `Item` and `View` each gain a private `display` that starts equal
  to the key and changes only through `set_display` / `set_item_display`.
- `CategoryRow`, `TileEntry` and `ViewSummary` carry `display` beside their key
  field. The key stays what commands are composed from.
- The category-panel headers, the tile bar and the view list paint the display
  in the TUI and the browser. The active-view marker still compares keys.
- No production code sets a display yet, so behaviour is unchanged.
- This is the first slice of ADR 007 step 2. The grid, page bar, records labels,
  item rows and CSV export are improvise-cq1q.12; messages and the view title
  are improvise-cq1q.13.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-25 12:12:59 -07:00
Claude (agent-hier) 6b910889c0 Merge commit '44718e8a' into feat/8jk6.3-date-hierarchy
# Conflicts:
#	crates/improvise-io/src/import/wizard.rs
#	tests/headless_cli.rs
2026-09-24 22:47:28 -07:00
Claude (agent-hier) 44718e8ab3 Merge commit 'c91cc055c8ad81afd8f055b71c74af6819020637' into feat/felo6-group-parents
# Conflicts:
#	context/test-evidence/formula-and-io.md
2026-09-24 22:42:49 -07:00
Claude (agent-cmdlang) 2c6b751edd Merge commit 'c91cc055c8ad81afd8f055b71c74af6819020637' into fix/31oe-cmdlang
# Conflicts:
#	context/code/cli.md
#	context/test-evidence/cli.md
2026-09-24 22:33:04 -07:00
Claude (agent-hier) 195f3b44b8 feat(import): a date column imports as one hierarchical category, the flat split a choice (improvise-8jk6.3)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 22:15:14 -07:00
Claude (agent-headless-import) 8bd4b1a77b fix(import): headless import refuses instead of silently succeeding (improvise-8jk6.4, improvise-8jk6.5, improvise-8jk6.6)
- 8jk6.4: the CSV parser yields source text (CsvRecords), and only the
  role reads it as a number. A forced category keeps 00565796 and
  220944e2 verbatim; measures and analysis read the text through
  csv_parser::number_in. CsvRecords reaches a pipeline only through
  ImportPipeline::from_csv, so handing CSV text to the JSON constructor
  no longer compiles.
- 8jk6.5: an import formula that does not parse is refused by name with
  its parse error: the build refuses (headless exits non-zero and writes
  nothing), and the wizard keeps it out of the list with the text still
  in the buffer.
- 8jk6.6: an import that kept no record refuses and says why, from the
  build and from the wizard's review step. A partial skip stays a
  warning with a count and exit 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 21:54:39 -07:00
Claude (agent-cmdlang) c40b6d3215 fix(command): refuse set-axis, set-page and siblings naming what the document lacks (improvise-31oe.2)
set-axis reads its axis at parse time, so an unknown keyword is an argument
error. set-axis, set-page, hide-item, show-item, toggle-group and switch-view
refuse an unknown category, item, group or view by name instead of doing
nothing, so a headless run exits non-zero.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 21:47:37 -07:00
Claude (agent-hier) e497aef110 feat: nested group runs reach the wire, and views persist expanded(N) and collapsed folds (improvise-felo.6)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 21:43:55 -07:00
Claude (agent-cmdlang) 197ce61d65 fix(command): read |pipe quoting| and refuse surplus arguments (improvise-31oe.3)
The command-line lexer reads |…| as one argument through the shared
unescape_pipe_body, anywhere in a word, so a coordinate can quote each half.
Double quotes stay verbatim. Every registration now declares MaxArgs, and the
registry refuses arguments beyond it, naming them, on both arms.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 21:43:18 -07:00
Claude (agent-lpzu) bb505f8faf feat(import): give each merged file a view filtered to it (improvise-lpzu)
A CSV merge now records each file's columns, and the build adds one view
per file: File on Filter at that file's item, its own categories seated
as a fresh import seats them, the rest on None, and other files'
measures hidden. The merged Default view stays the initial view. The
headless and wizard paths both carry the sources.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 20:48:16 -07:00
Edward Langley bd957fd619 Merge commit '4f38a35e945f54e1a0bbde3155ba518d4f298b71' into feat/felo1-max-categories-24 2026-09-24 19:22:37 -07:00
Edward Langley 7d1f90dbf9 feat(core): raise MAX_CATEGORIES from 12 to 24, with one home (improvise-felo.1)
The wizard's private copy of the limit is gone; it reads the model's
now-public constant. Tests that fill to the cap derive it. Why 12 was
chosen and what 24 costs: context/code/core.md section 9.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 19:19:39 -07:00
Edward Langley 92233cff14 Merge remote-tracking branch 'gh/main' into feat/cgqt-import-collision-step
# Conflicts:
#	context/test-evidence/tui.md
2026-09-24 18:43:40 -07:00
Edward Langley 1a2952058d Import asks what to do with records that share every coordinate (improvise-cgqt)
When source records collide on every coordinate, the import wizard now asks:
sum them, keep them separate with a generated occurrence category, or go
back. Collisions are found before the build by the same placement pass the
build uses, and are carried to the TUI as structured data (WizardCache) and
listed in full, scrollable. At the 12-category cap, "keep separate" is shown
disabled with its reason and remedy.

Every wizard warning and message now wraps to the panel instead of being
truncated, and long lists scroll.

Headless paths no longer sum silently: `import --no-wizard` takes
`--on-duplicate refuse|sum|separate` (default refuse), and `:import-json`
refuses and points at `:import`.

Reasoning: context/code/formula-and-io.md, "Colliding records are a
question, not a default"; context/code/tui.md; context/code/cli.md §11.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 18:43:19 -07:00
Edward Langley 241cc5f384 fix(tui): the grid and the tile bar scroll by the width they are drawn in (improvise-gtn7.1)
Grid: App::cmd_context counted visible_cols from term_width while
draw_content gave the grid term_width minus the 32-column side panel, so
with any panel open the cursor was scrolled past the last drawn column.
viewport::grid_width, reached through App::grid_width, is now the one
answer: draw_content splits on it and the keypress path counts on it.

Tile bar: the scroll measured from the end of the prefix while the draw
began one column later, two once scrolled (the left arrow), so the
selected tile could be dropped. tiles_left(start) is now where both the
scroll (first_tile) and the draw begin.

The grid defect dates from b5418f2e; it became the launch state when
50e4a372 opened the category panel by default, which is why it read as
a regression. Mixed-width columns still lose the cursor with no panel
open: improvise-gtn7.2. Reasoning: context/code/tui.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 18:32:47 -07:00
Edward Langley ffc7d0aecc Merge gh/main 08ad7b81 into fix/wpxr-empty-record-view
Every write the merged PRs added now names a view, chosen deliberately:

- The keyboard commit names OpenedCell::view, captured when the editor
  opened, as EditTarget does for the mouse (context/code/clients.md).
- RenameRecordCoordinate names no view. Its record must hold cells, so it
  resolves in the store alone: NamedRecord::Stored, as does the rename
  destination records_at_stake adds. named_records replaces cells_named as
  the exhaustive list records_named is read off.
- #252/#265's non_item_refusal moves into Grids::unwritable. The strict view
  lookup (a missing view is RecordGone) and the Grids memo are kept.
- Test fixtures name a view their document has: Default for host() and
  host_on_a_fold(), the records view for the rename pair, and the viewing
  client's own view in browser_round_trip.

Evidence files: both sides kept, every heading of both parents verified
present. Test names: the merge holds every test of both parents.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 12:53:03 -07:00
Edward Langley a7ec482552 Merge #251 (3f5f90a5, improvise-20ek/milr rename races) into the editor integration branch
Resolutions:
- client.rs imports: EditorSession (main) and ModelCommand (#251).
- client.rs refused(): #251 keeps the popped frame to learn which record it
  renamed; main (#279/3kfc) calls settle_sent() after the pop. Both kept, in
  the order pop, settle_sent, replay, then #251's Opened::Retry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 12:14:44 -07:00
Edward Langley 5e8e838f23 Merge #221 (c7b5b825, improvise-fdk1 coordinate rename) into the editor integration branch
Resolutions:
- CellId: #221 gives Coordinate fields { record, category }; main (#292)
  adds NonItem { category, item }. Every exhaustive match now names both
  (render.rs, core.rs x2, project.rs, resolve.rs x3, wasm-client lib.rs and
  render.rs); project.rs's basis arm keeps #221's Coordinate-carries-a-record.
- resolve.rs edit_or_drill: #221 drops the "renaming a coordinate" decline
  (Coordinate opens an editor); main's NonItem decline arm is kept.
  coordinate_at_cursor's None arm gains NonItem. reopened_at keeps #295's
  declined_at shape; declined_at's editable arm names Coordinate { .. }.
- client.rs: kept main's status_seen/status_owner and #221's opened +
  OpenedCoordinate; every settle site calls both settle_opened and
  settle_status. Main's new rebase() also gets settle_opened, since it
  rebuilds the view exactly as apply() does.
- view/mod.rs: re-export both GridEval (main) and record_row (#221).
- context/code/command.md and context/test-evidence/clients.md: both sides
  appended independent sections; kept both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
2026-09-24 12:13:42 -07:00
Edward Langley 46896a7512 Merge PR #250 (3e417729) into the 2026-09-24 integration wave
Conflicts with #294 in render.rs and project.rs resolved as tested:
#250's side of every hunk (levelled GroupEnd { level }, groups()/group_of,
axis_frame's carried headers, the try_from level check), then #294's shape
(Item { tuple, .. }, FrameEntry::item(..), the DataItem { tuple, collapsed }
arm, and GroupEnd { .. } in folds). Evidence EOF appends keep both sides.
2026-09-24 02:49:32 -07:00
Edward Langley 586264d9c5 Merge PR #267 (eded3179) into the 2026-09-24 integration wave 2026-09-24 02:48:15 -07:00
Edward Langley 78e9d930b9 Merge PR #261 (b32a7690) into the 2026-09-24 integration wave
# Conflicts:
#	context/test-evidence/command.md
2026-09-24 02:48:15 -07:00
Edward Langley 903d824e38 Merge PR #254 (3c513540) into the 2026-09-24 integration wave
# Conflicts:
#	context/test-evidence/command.md
#	context/test-evidence/core.md
#	crates/improvise-command/src/ui/app.rs
2026-09-24 02:48:03 -07:00
Edward Langley 783f92cdce Merge PR #266 (d0e36142) into the 2026-09-24 integration wave
# Conflicts:
#	crates/improvise-wasm-client/tests/lockstep.rs
2026-09-24 02:47:20 -07:00
Edward Langley 52946bd3e3 Merge PR #246 (37dbf02e) into the 2026-09-24 integration wave
# Conflicts:
#	context/test-evidence/clients.md
#	context/test-evidence/command.md
2026-09-24 02:46:58 -07:00
Edward Langley 88598c6f7e Merge PR #292 (3f98a17c) into the 2026-09-24 integration wave
# Conflicts:
#	context/test-evidence/command.md
#	crates/improvise-command/src/ui/app.rs
#	tests/shipped_documents_load.rs
2026-09-24 02:46:37 -07:00
Edward Langley 1efb774f9f Merge PR #294 (088d469f) into the 2026-09-24 integration wave
# Conflicts:
#	crates/improvise-wasm-client/tests/lockstep.rs
2026-09-24 02:45:54 -07:00
Edward Langley 90ea09360f Merge PR #222 (32b64f18) into the 2026-09-24 integration wave 2026-09-24 02:44:48 -07:00
Edward Langley 789b505547 Merge PR #238 (a6b5acc2) into the 2026-09-24 integration wave 2026-09-24 02:44:40 -07:00