@akanjs/cli 3.0.0-alpha.54 → 3.0.0-alpha.56
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 +1 -1
- package/{cloud.command-v5g0c7nm.js → cloud.command-f0rhw014.js} +2 -2
- package/guidelines/agentRule/agentRule.instruction.md +39 -2
- package/guidelines/conventions/conventions.instruction.md +11 -0
- package/{index-rrcdemys.js → index-0g9ajdz8.js} +1 -1
- package/{index-d3vvvzsd.js → index-8md8zszv.js} +3 -0
- package/index.js +3 -3
- package/{localRegistry.command-5hp7am6e.js → localRegistry.command-bms0qn6t.js} +1 -1
- package/package.json +2 -2
- package/{workspace.command-s2g36sgr.js → workspace.command-ma3g994j.js} +2 -2
package/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
42faa72ba08c227bbdd76ee0e90f8c9bc8f48fb88ce39741551775de99367977
|
|
@@ -27,6 +27,14 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
27
27
|
cannot spend the LLM key.
|
|
28
28
|
`persist` keeps the transcript across reloads (sessionStorage; `{ storage: "local" }` to outlive the tab),
|
|
29
29
|
default off, and `shortcut={false}` gives the browser back the Cmd/Ctrl+L the launcher otherwise captures.
|
|
30
|
+
**`persist` also takes a `SessionHistory` of the app's own** — `{ load, save, clear }` — which is how a
|
|
31
|
+
transcript lives on a server instead of in web storage. All three may answer asynchronously; a `load` still in
|
|
32
|
+
flight when the user sends the first message is **dropped, not merged**, because the conversation on screen is
|
|
33
|
+
the one they are having — which makes **sending on mount a race the restore loses**, so an opening prompt waits
|
|
34
|
+
for `session.isRestoring` to clear or goes into `defaultDraft` and lets the user send it. Saves are chained rather than fired per change, so a slow store cannot land an older
|
|
35
|
+
transcript last. **Every session option on the chat — `runner`, `instructions`, `maxTurns`, `compact`,
|
|
36
|
+
`builtins`, `persist`, `onCompact` — is ignored when an enclosing `Agent.Zone` or `AgentProvider` already holds
|
|
37
|
+
a session**: the chat binds to that one, and the options belong to whoever built it.
|
|
30
38
|
**A session the chat made ends when the chat unmounts** — nothing renders its approvals once it is gone, so a
|
|
31
39
|
turn left running would drive a screen the user has navigated away from; a session handed down by an
|
|
32
40
|
`AgentProvider` or an `Agent.Zone` belongs to whoever provided it.
|
|
@@ -34,7 +42,10 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
34
42
|
`open` / `onOpenChange` drive it from the app's own control (`launcher={false}` then draws no launcher of its
|
|
35
43
|
own), `launcherClassName` / `panelClassName` reach one surface each where `className` reaches both, `intro`
|
|
36
44
|
replaces the empty-state line — where starter questions go — and `header` adds controls beside the built-in
|
|
37
|
-
clear and close.
|
|
45
|
+
clear and close. `chrome={false}` drops the header bar whole, for an `inline` chat inside a panel the app
|
|
46
|
+
already titles, and `defaultDraft` opens the composer with text in it without sending it. A panel driven by a
|
|
47
|
+
controlled `open` with **no** `onOpenChange` draws no close button at all rather than an inert one. Then the
|
|
48
|
+
slots: `AgentLauncher`, `AgentBubble`, `AgentComposer`, `AgentApproval`,
|
|
38
49
|
`AgentQuestion`, `AgentMenu`, `AgentMarkdown` and `AgentCode` each replace one part in `_overrides.tsx`, and
|
|
39
50
|
`akanjs/ui` exports every default beside them (`DefaultBubble`, `DefaultComposer`, …) so a skin composes the
|
|
40
51
|
one it is replacing. `AgentCode` is where a highlighter binds — the fence's language reaches it — and a
|
|
@@ -112,6 +123,31 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
112
123
|
`data-agent-zone` container; guides follow the layout cascade (ancestors and own, never a sibling's). Zone
|
|
113
124
|
membership is positional — there is no per-declaration zone key, so a lib component joins whatever zone the app
|
|
114
125
|
mounts it in.
|
|
126
|
+
- **Everything a zone publishes is named `<id>.<name>`,** and that name is what instructions must use. A bare
|
|
127
|
+
`createVideoProject` inside a zone naming its tool `videoProjectDraft.createVideoProject` is a tool that does
|
|
128
|
+
not exist: the model calls it, the surface answers `Unknown tool`, and a turn is gone. Build the name from the
|
|
129
|
+
id (``const zoneTool = (name) => `${ZONE}.${name}` ``) rather than writing it in two places, and read
|
|
130
|
+
`Agent.Context`'s **Assemble** to see the published list — the names exist in neither file's source. The dot is
|
|
131
|
+
the surface's own join and never reaches a provider: `AgentService` renames it to `__` on the wire, because
|
|
132
|
+
every OpenAI-compatible and Anthropic function schema allows `[A-Za-z0-9_-]` only, up to 64 characters.
|
|
133
|
+
- **`builtins` decides which of the runtime's own tools a session gets** — all of them by default, `false` none,
|
|
134
|
+
an array exactly the ones it names, on `Agent.Zone` and `Agent.Chat` alike. A zone whose conversation must stay
|
|
135
|
+
on one screen takes `navigate` and `goBack` off it: `<Agent.Zone id="wizard" builtins={["readScreen",
|
|
136
|
+
"readState"]}>`. The tools are **withheld, not discouraged** — a withheld name answers the same "unknown tool"
|
|
137
|
+
a name that was never registered gets, so no prompt can talk the model past it, and the narrowing is the
|
|
138
|
+
session's alone: the surface is shared, and the neighbouring zone still navigates. Shadowing a built-in by
|
|
139
|
+
declaring a hook tool of the same name works at the root and **not inside a zone**, where the hook entry is
|
|
140
|
+
registered under its scope-prefixed name and never collides — `builtins` is the zone's answer. A tool the screen
|
|
141
|
+
declares under a built-in name is the screen's, not the runtime's, so `builtins={false}` leaves it standing.
|
|
142
|
+
- **A zone can be handed a session instead of building one**: `<Agent.Zone session={mine} onSession={…}>`. The app
|
|
143
|
+
then owns it, so unmounting the zone leaves it running — the opposite of a session the zone made, which it
|
|
144
|
+
aborts. `onSession` fires either way, for a page that wants to send into the conversation from outside it.
|
|
145
|
+
- **`akanjs/ui` exports what a custom transport or transcript needs**, so no app reaches into the package's
|
|
146
|
+
internals: `httpRunner` (the wire the default runner speaks — point it at an endpoint of the app's own and
|
|
147
|
+
streaming is kept), `fetchRunner` (the default, to wrap), `AgentSession`, `AgentProvider`, and the
|
|
148
|
+
`AgentRunner` / `RunnerRequest` / `RunnerEvent` / `ChatMessage` / `SessionHistory` / `PublishedTool` /
|
|
149
|
+
`ContextBlock` types. `onCompact(replaced, summary)` reports a compaction's cut, for a host that keeps a
|
|
150
|
+
server-side summary and has to move its own watermark to the same place.
|
|
115
151
|
- **Route guidance is `<Agent.Guide instructions="..." />`** rendered from a `_layout.tsx` or a page — the render
|
|
116
152
|
tree is the cascade: nested Guides concatenate outer-to-inner and navigating away withdraws them. It is a
|
|
117
153
|
component, not a pageConfig field. Module `*.abstract.md` files are developer docs and are never served to the
|
|
@@ -386,7 +422,8 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
|
|
|
386
422
|
## Built-In Tools
|
|
387
423
|
- The framework publishes five built-ins on every store surface: `navigate` (internal paths only, the same
|
|
388
424
|
router `Link` rides), `goBack` (this session's history — global, because history is not a control a page owns and
|
|
389
|
-
a page that draws no back link is not one you may not leave
|
|
425
|
+
a page that draws no back link is not one you may not leave — a screen that must not be left withholds them
|
|
426
|
+
with `builtins`, not with prose), `readScreen` (the rendered DOM as compact text —
|
|
390
427
|
headings, links, control values, and `(disabled)` on a control or button that has it; the chat's own UI is
|
|
391
428
|
skipped via `data-agent-ui`, and a password value is never read), `readState(key)` (one masked store key), and
|
|
392
429
|
`highlight(target)`. Declaring a hook tool under one of those names shadows the built-in, so reuse them only to
|
|
@@ -96,6 +96,17 @@ back.
|
|
|
96
96
|
the resolved data as a prop. A component is a PascalCase binding whose own initializer is `async`, so an async
|
|
97
97
|
handler declared inside a synchronous component, an inline `onClick={async () => …}`, and
|
|
98
98
|
`lazy(async () => import(…))` are all untouched.
|
|
99
|
+
- **Never call `fetch.init*` from a client file** (`no-init-fetch-in-client.grit`). `fetch.init<Model><Suffix>` and
|
|
100
|
+
`fetch.get<Model>Init<Suffix>` compose the slice's list and insight queries into the hydration snapshot that
|
|
101
|
+
`Load.Units` / `Load.View` seed the store from. From a route it resolves before the first byte; after hydration it
|
|
102
|
+
is two extra round-trips for a shell the browser already painted, landing in a value nothing reads. Load it in the
|
|
103
|
+
page and pass the result down as an `init` prop — or hand the unawaited promise across — and reload from the client
|
|
104
|
+
through the generated `st.do.init<Model><Suffix>()`. The gate is the file: the real `"use client"` directive (the
|
|
105
|
+
same text as a string literal or inside sample code is not one) plus `*.store.ts`, which is client-only by role and
|
|
106
|
+
carries no directive. The name is matched by shape, since a lint rule cannot know which slices exist: the
|
|
107
|
+
generated one always carries two capital-led segments (`init` + `Capitalize<refName>` + `Capitalize<suffix>`), so
|
|
108
|
+
a hand-written `initPayment` is out and `initializeSomething` was never in. `view` / `edit` hydrate alike but are
|
|
109
|
+
left unmatched — `edit<X>` is a plausible custom endpoint name.
|
|
99
110
|
- `noArrayIndexKey` and `useExhaustiveDependencies` are **off** on purpose: `key={idx}` for embedded scalars and
|
|
100
111
|
short dependency arrays are intentional, not oversights.
|
|
101
112
|
- **A grit plugin diagnostic is suppressed as `lint/plugin`, not `plugin`** — `// biome-ignore lint/plugin: <reason>`
|
|
@@ -283,6 +283,9 @@ ${chalk.green("\u27A4")} Authentication Required`));
|
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
+
Logger.info("Logging in to npm...");
|
|
287
|
+
await workspace.spawn("npm", ["login"], { stdio: "inherit" });
|
|
288
|
+
Logger.info("Logged in to npm");
|
|
286
289
|
for (const library of akanPkgs) {
|
|
287
290
|
Logger.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
|
|
288
291
|
await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
|
package/index.js
CHANGED
|
@@ -19,16 +19,16 @@ import path from "path";
|
|
|
19
19
|
|
|
20
20
|
// pkgs/@akanjs/cli/commandModules.ts
|
|
21
21
|
var commandModules = {
|
|
22
|
-
workspace: async () => (await import("./workspace.command-
|
|
22
|
+
workspace: async () => (await import("./workspace.command-ma3g994j.js")).WorkspaceCommand,
|
|
23
23
|
agent: async () => (await import("./agent.command-tsx1nsdj.js")).AgentCommand,
|
|
24
24
|
application: async () => (await import("./application.command-n8ex8g9h.js")).ApplicationCommand,
|
|
25
25
|
library: async () => (await import("./library.command-p3jgf5h2.js")).LibraryCommand,
|
|
26
|
-
localRegistry: async () => (await import("./localRegistry.command-
|
|
26
|
+
localRegistry: async () => (await import("./localRegistry.command-bms0qn6t.js")).LocalRegistryCommand,
|
|
27
27
|
package: async () => (await import("./package.command-fbpa6r4w.js")).PackageCommand,
|
|
28
28
|
module: async () => (await import("./module.command-hb3xm07r.js")).ModuleCommand,
|
|
29
29
|
page: async () => (await import("./page.command-92vrmw96.js")).PageCommand,
|
|
30
30
|
context: async () => (await import("./context.command-s7a41qjs.js")).ContextCommand,
|
|
31
|
-
cloud: async () => (await import("./cloud.command-
|
|
31
|
+
cloud: async () => (await import("./cloud.command-f0rhw014.js")).CloudCommand,
|
|
32
32
|
guideline: async () => (await import("./guideline.command-qrw84ttb.js")).GuidelineCommand,
|
|
33
33
|
scalar: async () => (await import("./scalar.command-zcsjgvax.js")).ScalarCommand,
|
|
34
34
|
primitive: async () => (await import("./primitive.command-k6b9jfxr.js")).PrimitiveCommand,
|
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.56",
|
|
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.56",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"dayjs": "^1.11.20",
|
|
@@ -11,11 +11,11 @@ import"./index-ss469dec.js";
|
|
|
11
11
|
import"./index-kkya2ped.js";
|
|
12
12
|
import {
|
|
13
13
|
CloudScript
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-0g9ajdz8.js";
|
|
15
15
|
import {
|
|
16
16
|
getLatestPackageVersion,
|
|
17
17
|
getNpmRegistryUrl
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-8md8zszv.js";
|
|
19
19
|
import {
|
|
20
20
|
PackageScript
|
|
21
21
|
} from "./index-x1dbhd80.js";
|