@akanjs/cli 3.0.0-alpha.30 → 3.0.0-alpha.32
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
|
-
|
|
1
|
+
2099eccdeb7239ce6ccf7bf5c6a250594bfac9b4208510043dd0365fe7aa7e8f
|
|
@@ -63,6 +63,13 @@ that looks wrong; do not "fix" it back.
|
|
|
63
63
|
exempt because neither is an instance: `cnst.<Enum>["value"]`, whose indexed access resolves to a string union, and
|
|
64
64
|
a `ClientInit` / `ClientView` / `ClientEdit` type argument, which the framework maps to `GetStateObject<…>` plain
|
|
65
65
|
data. Any *other* indexed access is still flagged — `cnst.Banner["image"]` is a `File`.
|
|
66
|
+
**Only prop positions are read** — a `*Props` interface or type alias, and the inline object type on the
|
|
67
|
+
component's own parameter. A `cnst` type that never leaves the file is not a boundary crossing and stays legal: a
|
|
68
|
+
local annotation, a callback parameter the framework itself types with the model
|
|
69
|
+
(`renderItem={(ticket: cnst.LightTicket) => …}`), a module-scope helper, a non-`Props` local shape, and the props
|
|
70
|
+
of a component nested inside another one. A function-typed prop (`onPick?: (t: cnst.LightTicket) => void`) is
|
|
71
|
+
exempt for the same reason — a closure cannot cross the RSC boundary at all, so whoever passes it is a client
|
|
72
|
+
component already holding the value.
|
|
66
73
|
- **No deep imports past a barrel** (`no-deep-internal-import.grit`). Cross-module constant references such as
|
|
67
74
|
`../map/map.constant` are the sanctioned exception.
|
|
68
75
|
- **Never import across the client/server boundary.** Client files (`ui/`, `webkit/`, `page/`, `*.store.ts`, every
|
|
@@ -390,6 +397,15 @@ workflow changes.
|
|
|
390
397
|
- Numbers must use `Int` or `Float` — `Number` is rejected (`pkgs/akanjs/signal/endpointInfo.ts`).
|
|
391
398
|
- `Upload` is valid only inside a mutation flagged for file upload: `mutation([cnst.File], { fileUpload: true }).body("files", [Upload])` (see `libs/shared/lib/file/file.signal.ts`). It is not a model field type.
|
|
392
399
|
|
|
400
|
+
### Mutation HTTP Verb
|
|
401
|
+
|
|
402
|
+
- A `mutation` is `POST`. `{ method: "PATCH" | "PUT" | "DELETE" }` moves it, and one path may carry several verbs
|
|
403
|
+
— a `query` GET and a `mutation` POST on the same custom `path` are mounted side by side. Two endpoints claiming
|
|
404
|
+
the same path **and** verb fail the boot rather than silently shadowing one another.
|
|
405
|
+
- Reach for it only when a foreign wire protocol forces the verb (a client you cannot change that sends
|
|
406
|
+
`PATCH /rest/v1/<table>`). Akan's own `fetch.*` client, the OpenAPI document, and the API explorer all follow
|
|
407
|
+
whatever is declared, so nothing needs restating per caller.
|
|
408
|
+
|
|
393
409
|
### Reserved Endpoint Names
|
|
394
410
|
|
|
395
411
|
- Auto-generated CRUD endpoints (e.g. `create<Model>`, `update<Model>`, `remove<Model>`) already exist for every model. Do not declare an `Endpoint`/`Slice` with a name that collides with them.
|
|
@@ -648,9 +664,10 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
648
664
|
`AKAN_AGENT=false` takes it off — and negotiates streaming via `accept`, so assistant text arrives as it is
|
|
649
665
|
generated with zero app code. The endpoint is a stateless relay and **never executes tools**: every tool runs in
|
|
650
666
|
the caller's own browser session, gated by guards and the approval card. Its guard is `AgentRelayAccess`, which
|
|
651
|
-
**refuses every call until a
|
|
652
|
-
product with accounts
|
|
653
|
-
|
|
667
|
+
**refuses every call until the app names a guard of its own** — the same answer `None` gives, with no boot
|
|
668
|
+
warning. A product with accounts names it in its `option.ts`, `option.setAgentAccess(SignedIn)`, taking the same
|
|
669
|
+
guard classes every endpoint takes (an array is ANDed, `null` clears what a library set); without one the chat
|
|
670
|
+
cannot spend the LLM key.
|
|
654
671
|
`persist` keeps the transcript across reloads (sessionStorage; `{ storage: "local" }` to outlive the tab),
|
|
655
672
|
default off. Re-skin through the `AgentChat` slot in `_overrides.tsx`.
|
|
656
673
|
- **The LLM is configured in `option.ts`, never through the environment.** `option.setLlm({ apiKey, model, host })`
|
|
@@ -732,6 +749,27 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
732
749
|
- **`prompt()` endpoints double as the chat's slash commands.** There is no listing endpoint — the client reads
|
|
733
750
|
its own serialized signals — so a prompt's dictionary `.desc()` is what the menu shows, and its guards are
|
|
734
751
|
enforced by the prompt's own GET at call time.
|
|
752
|
+
- **The chat answers five slash commands of its own**, listed in the same `/` menu ahead of the prompts:
|
|
753
|
+
`/new` (`/clear`), `/retry`, `/copy`, `/help` and `/tools`. An app writes none of them and cannot add one — the
|
|
754
|
+
extension point for a product's own command is a `prompt()` endpoint, which is guarded and server-side.
|
|
755
|
+
**A built-in wins a name collision with a prompt of the same name**, the mirror image of the tool rule: a
|
|
756
|
+
component's `st.tool` shadows a built-in it means to replace, but no library's prompt may take `/new` away from
|
|
757
|
+
the user who typed it — so a shadowed prompt is dropped from the menu rather than listed twice. `/new` and
|
|
758
|
+
`/copy` are also dispatched *before* the is-a-turn-running check, because mid-turn is exactly when they are
|
|
759
|
+
reached for; `/new` therefore aborts the turn it is clearing and waits for it to wind down, since the loop
|
|
760
|
+
clears its own running flag a microtask later and a transcript emptied before that lands is one the dying turn
|
|
761
|
+
appends onto.
|
|
762
|
+
- **A command's output is a `local` message: rendered in the transcript, withheld from the wire.** The transcript
|
|
763
|
+
*is* the model's history, so `/help` text appended plainly would come back next turn as something the assistant
|
|
764
|
+
believes it said. `session.note(text)` is the only way to write one, `session.report(error)` stays what a
|
|
765
|
+
host-side *failure* lands in, and `local` messages are left out of a `/copy` export too — they are the chat
|
|
766
|
+
talking to itself. Their text is user-facing, so it goes through `l("base.*")` like every other chat string.
|
|
767
|
+
- **`/copy` exists because nothing else keeps the transcript.** The relay is stateless and the conversation lives
|
|
768
|
+
only in that browser, so an export is the one path a wrong answer has to whoever could fix it — which is why it
|
|
769
|
+
carries the route and the timestamp. `/retry` replays only the trailing user message, leaving anything before it
|
|
770
|
+
in place, so a prompt's own preamble is not sent twice.
|
|
771
|
+
- **↑ and ↓ in the composer walk what was sent.** A single-line input has nothing of its own on the vertical
|
|
772
|
+
arrows, and the half-written draft they were walked away from comes back at the bottom of the walk.
|
|
735
773
|
- The framework publishes five built-ins on every store surface: `navigate` (internal paths only, the same
|
|
736
774
|
router `Link` rides), `goBack` (this session's history — global, because history is not a control a page owns and
|
|
737
775
|
a page that draws no back link is not one you may not leave), `readScreen` (the rendered DOM as compact text —
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.32",
|
|
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.
|
|
37
|
+
"akanjs": "3.0.0-alpha.32",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"dayjs": "^1.11.20",
|