@akanjs/cli 3.0.0-alpha.33 → 3.0.0-alpha.35

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.
package/.build-stamp CHANGED
@@ -1 +1 @@
1
- 92c020a25f9a2117ffc1aac1e1581b005e93ce7da63656e22aa9756cad18ea57
1
+ 19d013737b1748d534b589ea7399041a437db6f36d396f7ce0e2617c8883bf31
@@ -59,10 +59,13 @@ that looks wrong; do not "fix" it back.
59
59
  - **Never redeclare a generated CRUD endpoint name** in `*.signal.ts` (`no-redeclare-predefined-endpoint.grit`).
60
60
  - **Never type a `*.Util.tsx` / `*.Zone.tsx` prop as a `cnst` model** (`no-model-type-in-util-zone.grit`). Those two
61
61
  roles are always client components, so a `cnst.Banner` / `cnst.LightBanner` prop is a class instance the server has
62
- to hand across the boundary; take `bannerId: string` and read the model from the store instead. Two shapes are
63
- exempt because neither is an instance: `cnst.<Enum>["value"]`, whose indexed access resolves to a string union, and
64
- a `ClientInit` / `ClientView` / `ClientEdit` type argument, which the framework maps to `GetStateObject<…>` plain
65
- data. Any *other* indexed access is still flagged `cnst.Banner["image"]` is a `File`.
62
+ to hand across the boundary; take `bannerId: string` and read the model from the store instead. Three shapes are
63
+ exempt because none of them is an instance: `cnst.<Enum>["value"]`, whose indexed access resolves to a string
64
+ union; a `ClientInit` / `ClientView` / `ClientEdit` type argument, which the framework maps to `GetStateObject<…>`
65
+ plain data; and a `ModelsProps<cnst.Setting>` type argument, whose only use of the model is the `onClickItem`
66
+ callback, so nothing model-shaped ever lands on a prop. `ModelProps<"setting", cnst.LightSetting>` is *not* exempt
67
+ — that one spreads the model onto the props themselves, and `Unit` / `View`, which take it, are server components
68
+ this rule does not cover. Any *other* indexed access is still flagged — `cnst.Banner["image"]` is a `File`.
66
69
  **Only prop positions are read** — a `*Props` interface or type alias, and the inline object type on the
67
70
  component's own parameter. A `cnst` type that never leaves the file is not a boundary crossing and stays legal: a
68
71
  local annotation, a callback parameter the framework itself types with the model
@@ -678,6 +681,10 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
678
681
  providers the way middleware is applied: `option.applyAdaptor(LlmAdaptorRole, ClaudeLlm)`, where the
679
682
  implementation is an `adapt()` class in a `srvkit/` implementing `LlmAdaptor.chat(request, onDelta?)` — ignore
680
683
  `onDelta` and the chat still answers whole.
684
+ - **A dialog's close is the dialog's own dismissal, not a state flip.** `closeDialogIn<Ns>` (and `Dialog.Close`)
685
+ run through whatever `Dialog.Modal` registered, so the agent takes the exact path the X button takes —
686
+ `confirmClose` still prompts and `onCancel` still fires. A close that only set `open` to false would skip both,
687
+ which is a different action wearing the same name.
681
688
  - **`<Agent.Zone id="comments">` runs a second agent over one section, in parallel with the root.** Everything
682
689
  mounted inside — `st.use` subscriptions, hook tools, Guides — belongs to that zone's own conversation *and*
683
690
  stays visible to the root agent: **zones are views, never walls**, so wrapping a section costs the root nothing.
@@ -715,17 +722,36 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
715
722
  callable still drives the click a person makes. It does not throw: a tool schema is built during render, and an
716
723
  agent-tooling mistake that aborted the render would cost the route its server rendering. `st.useState`'s `set`
717
724
  degrades the same way, to read-only.
718
- - **A component that renders once per row publishes nothing.** A tool registered under one name by fifty rows is
719
- forty-nine collisions and one survivor. The container publishes one tool taking the id instead
720
- `removeTask(taskId)`, never fifty `removeTask` and the agent reads the ids from the `<slice>.items` resource
721
- `Load.Units` and `Data.ListContainer` already expose.
725
+ - **A component that renders once per row never closes over its row's id it takes the id as an argument.** A
726
+ tool that captured its own row would be fifty registrations of one name, forty-nine of them shadowed, and the
727
+ survivor would remove whichever row happened to mount last. Take the id instead `removeTask(taskId)`, never
728
+ fifty `removeTask` and every row's registration is then interchangeable, so a row component may publish after
729
+ all: say so with `shared: true` and the repeats are one declaration rather than a warned-about clash. The ids
730
+ come from the `<slice>.items` resource `Load.Units` and `Data.ListContainer` already expose. `shared` is a claim
731
+ about the *tool*, not a way to quiet a console: two rows whose tools would do different things (a different
732
+ `modal`, a different redirect) are not interchangeable, and that one wants a `namespace` or nothing at all.
722
733
  - **`akanjs/ui` publishes its own controls, so an app writes nothing for them.** `Data.ListContainer` (and every
723
- `Model.AdminPanel`) publishes its toolbar and its row and modal verbs; `Load.Units`, `Load.Pagination` and
724
- `Data.Pagination` publish `setPageOf<Model>`; `Layout.Sider`, `System.SelectLanguage`, `Link.Back` and
725
- `System.ThemeToggle` publish the shell. **A component that can render twice on one screen takes a
726
- `namespace` prop and publishes nothing without it** — `Tab`, `Dialog`, `ScreenNavigator`. Pass one
727
- (`<Tab namespace="detail">`) and the tool becomes `switchTabInDetail`; leave it off and that tab is invisible to
728
- the agent, because two tabs answering to `switchTab` would mean the first to mount loses.
734
+ `Model.AdminPanel`) publishes its toolbar and its row verbs; `Model.NewWrapper` (so `Model.New` too) publishes
735
+ `new<Model>`; `Load.Units`, `Load.Pagination` and `Data.Pagination` publish `setPageOf<Model>`; `Layout.Sider`,
736
+ `System.SelectLanguage`, `Link.Back` and `System.ThemeToggle` publish the shell. **A component that can render
737
+ twice on one screen takes a `namespace` prop and publishes nothing without it** — `Tab`, `Dialog`,
738
+ `ScreenNavigator`. Pass one (`<Tab namespace="detail">`) and the tool becomes `switchTabInDetail`; leave it off
739
+ and that tab is invisible to the agent, because two tabs answering to `switchTab` would mean the first to mount
740
+ loses. `Model.NewWrapper` takes the same prop but publishes without one, because its slice already names it —
741
+ a second create trigger for the same slice, opening a form seeded differently, is what needs the suffix.
742
+ - **The `Model.*` row wrappers publish their verb, taking the id.** `Model.EditWrapper`, `Model.ViewWrapper`,
743
+ `Model.RemoveWrapper` and `Model.Remove` publish `edit<Model>` / `view<Model>` / `remove<Model>` with a
744
+ `modelId` argument, so a list built from `Load.Units` and an app's own `Unit` reaches the same verbs an
745
+ `AdminPanel` does. `Model.SureToRemove` publishes the same — except under `typeNameToRemove`, where it
746
+ publishes nothing: that gate makes a person retype the model's name, an approval card is one click, and
747
+ offering the lever at a friction the screen does not have is not the same control.
748
+ - **A modal publishes its verbs while it is open, and only then.** `Model.EditModal` publishes `submit<Model>`
749
+ and `cancelEditOf<Model>`, `Model.ViewModal` publishes `closeViewOf<Model>`, and `Model.ViewEditModal`
750
+ publishes `edit<Model>` / `submit<Model>` / `closeViewOf<Model>` — each from a subtree that mounts with the
751
+ open modal, never from the component that merely holds it. That is what makes a list legal: `Data.CardList`
752
+ renders one editor per row, and at most one of them is ever open, so one name is registered rather than fifty.
753
+ It also means the verb is absent from the catalogue while nothing is open, which is honest — and costs the
754
+ agent nothing, because the catalogue is re-read on the turn that follows the tool call that opened the form.
729
755
  - **A form control publishes its own setter, and reading a form publishes one tool that fills several at once.**
730
756
  Both are free: an app writes no `st.tool` for a form. A `Field.*` / `Input.*` / `Select` / `Switch` handed
731
757
  `onChange={st.do.setTitleOnTask}` **by reference** publishes `setTitleOnTask` while it is on screen — the same
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/cli",
3
- "version": "3.0.0-alpha.33",
3
+ "version": "3.0.0-alpha.35",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -34,7 +34,7 @@
34
34
  "@langchain/openai": "^1.4.6",
35
35
  "@tailwindcss/node": "^4.3.0",
36
36
  "@trapezedev/project": "^7.1.4",
37
- "akanjs": "3.0.0-alpha.33",
37
+ "akanjs": "3.0.0-alpha.35",
38
38
  "chalk": "^5.6.2",
39
39
  "commander": "^14.0.3",
40
40
  "dayjs": "^1.11.20",