@akanjs/cli 3.0.0-alpha.14 → 3.0.0-alpha.16
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/{agent.command-zxaxy577.js → agent.command-h6tc0pzh.js} +5 -5
- package/{application.command-an05acvc.js → application.command-kphnfwyg.js} +4 -4
- package/buildBatch.proc.js +1 -1
- package/{capacitorApp-5q8ytkqw.js → capacitorApp-9ejk3k7q.js} +2 -2
- package/{cloud.command-yfd3pwr1.js → cloud.command-zn6mfscb.js} +7 -7
- package/{context.command-03b3jgab.js → context.command-pkbccyys.js} +12 -12
- package/{guideline.command-5qnjcgmk.js → guideline.command-0jj2k77g.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +39 -38
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +1 -3
- package/incrementalBuilder.proc.js +1 -1
- package/{index-3tqjdv03.js → index-1twehz1x.js} +23 -3
- package/{index-37mwgmp7.js → index-4agbdds8.js} +3 -3
- package/{index-jwvs48kc.js → index-4v0wvt37.js} +4 -4
- package/{index-xv5jv1fe.js → index-7ecpft60.js} +6 -3
- package/{index-6xh65612.js → index-8d9r0df5.js} +2 -2
- package/{index-hz5x5zdp.js → index-96vpa123.js} +3 -3
- package/{index-nz9ceqgp.js → index-9s991k9v.js} +1 -1
- package/{index-nmfen65g.js → index-aak9cctp.js} +4 -4
- package/{index-0hk3frny.js → index-b9m84bjp.js} +10 -10
- package/{index-9p2edf9w.js → index-bkwnr08k.js} +1 -1
- package/{index-znxjcx1p.js → index-djh5gpb7.js} +2 -2
- package/{index-pgs252a3.js → index-g3brq942.js} +5 -5
- package/{index-tk2e3m3y.js → index-gyvrhtpm.js} +1 -1
- package/{index-pdj7r8fa.js → index-gz91pc3p.js} +1 -1
- package/{index-nkzfkq0j.js → index-p42te6qb.js} +3 -3
- package/{index-v2r1wrzb.js → index-rv16ck4r.js} +4 -4
- package/{index-w7jphpt6.js → index-w7farjxd.js} +3 -3
- package/{index-9jwc3ew8.js → index-xwfkgss0.js} +2 -2
- package/index.js +18 -18
- package/{library.command-befyckb7.js → library.command-wbptp6q3.js} +3 -3
- package/{localRegistry.command-fkd3xw99.js → localRegistry.command-6ea3pgq0.js} +6 -6
- package/{module.command-xzjbbas7.js → module.command-ghkf919z.js} +5 -5
- package/{package.command-9xk8ye7a.js → package.command-ph2m34tv.js} +3 -3
- package/package.json +2 -2
- package/{page.command-4g2xszh7.js → page.command-atnzfn88.js} +3 -3
- package/{primitive.command-ffwn141j.js → primitive.command-7qbdhfc2.js} +6 -6
- package/{quality.command-8e6bhm55.js → quality.command-51q9kmhj.js} +90 -361
- package/{repair.command-w3tjhr9r.js → repair.command-weakn0yr.js} +5 -5
- package/{scalar.command-kj121mby.js → scalar.command-xdjhvsgb.js} +4 -4
- package/templates/appSample/srvkit/AuthGuard.ts +2 -2
- package/templates/workspaceRoot/CLAUDE.md.template +19 -0
- package/{workflow.command-mnkm1bwa.js → workflow.command-msm2tjee.js} +9 -9
- package/{workspace.command-waxe7ts7.js → workspace.command-gr8z82z9.js} +18 -18
package/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
de2c79f1b77d3ad7b42a84df41633392b3eba192d3d15335be7a976440157d1f
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AgentScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
4
|
+
} from "./index-7ecpft60.js";
|
|
5
|
+
import"./index-djh5gpb7.js";
|
|
6
|
+
import"./index-9s991k9v.js";
|
|
7
7
|
import"./index-j37qq1f2.js";
|
|
8
8
|
import {
|
|
9
9
|
Workspace,
|
|
10
10
|
command
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
11
|
+
} from "./index-bkwnr08k.js";
|
|
12
|
+
import"./index-1twehz1x.js";
|
|
13
13
|
import"./index-mxvakhsm.js";
|
|
14
14
|
import"./index-xys926f2.js";
|
|
15
15
|
import"./index-1577bej2.js";
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "./index-0wae5ebk.js";
|
|
5
5
|
import {
|
|
6
6
|
ApplicationScript
|
|
7
|
-
} from "./index-
|
|
8
|
-
import"./index-
|
|
7
|
+
} from "./index-rv16ck4r.js";
|
|
8
|
+
import"./index-p42te6qb.js";
|
|
9
9
|
import {
|
|
10
10
|
getMobileTargetChoices
|
|
11
11
|
} from "./index-76rn3g2c.js";
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
Sys,
|
|
16
16
|
Workspace,
|
|
17
17
|
command
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-bkwnr08k.js";
|
|
19
19
|
import"./index-fgc8r6dj.js";
|
|
20
20
|
import"./index-bjpxzr6s.js";
|
|
21
|
-
import"./index-
|
|
21
|
+
import"./index-1twehz1x.js";
|
|
22
22
|
import"./index-mxvakhsm.js";
|
|
23
23
|
import"./index-1577bej2.js";
|
|
24
24
|
import"./index-67546d0j.js";
|
package/buildBatch.proc.js
CHANGED
|
@@ -25,9 +25,9 @@ import {
|
|
|
25
25
|
selectLocalDevHost,
|
|
26
26
|
sortIosRunTargets,
|
|
27
27
|
writeRootCapacitorConfig
|
|
28
|
-
} from "./index-
|
|
28
|
+
} from "./index-gz91pc3p.js";
|
|
29
29
|
import"./index-76rn3g2c.js";
|
|
30
|
-
import"./index-
|
|
30
|
+
import"./index-1twehz1x.js";
|
|
31
31
|
import"./index-mxvakhsm.js";
|
|
32
32
|
import"./index-1577bej2.js";
|
|
33
33
|
import"./index-67546d0j.js";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
CloudScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
4
|
+
} from "./index-g3brq942.js";
|
|
5
|
+
import"./index-96vpa123.js";
|
|
6
|
+
import"./index-xwfkgss0.js";
|
|
7
7
|
import {
|
|
8
8
|
GlobalConfig
|
|
9
9
|
} from "./index-0cj2zxbm.js";
|
|
10
|
-
import"./index-
|
|
11
|
-
import"./index-
|
|
10
|
+
import"./index-rv16ck4r.js";
|
|
11
|
+
import"./index-p42te6qb.js";
|
|
12
12
|
import"./index-76rn3g2c.js";
|
|
13
13
|
import {
|
|
14
14
|
Workspace,
|
|
15
15
|
command
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-bkwnr08k.js";
|
|
17
17
|
import"./index-fgc8r6dj.js";
|
|
18
18
|
import"./index-bjpxzr6s.js";
|
|
19
|
-
import"./index-
|
|
19
|
+
import"./index-1twehz1x.js";
|
|
20
20
|
import"./index-mxvakhsm.js";
|
|
21
21
|
import"./index-1577bej2.js";
|
|
22
22
|
import"./index-46tjzh6s.js";
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
ContextScript
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
6
|
-
import"./index-
|
|
7
|
-
import"./index-
|
|
8
|
-
import"./index-
|
|
9
|
-
import"./index-
|
|
4
|
+
} from "./index-b9m84bjp.js";
|
|
5
|
+
import"./index-4agbdds8.js";
|
|
6
|
+
import"./index-w7farjxd.js";
|
|
7
|
+
import"./index-8d9r0df5.js";
|
|
8
|
+
import"./index-4v0wvt37.js";
|
|
9
|
+
import"./index-aak9cctp.js";
|
|
10
10
|
import"./index-ss469dec.js";
|
|
11
|
-
import"./index-
|
|
12
|
-
import"./index-
|
|
11
|
+
import"./index-gyvrhtpm.js";
|
|
12
|
+
import"./index-gz91pc3p.js";
|
|
13
13
|
import"./index-0cj2zxbm.js";
|
|
14
|
-
import"./index-
|
|
15
|
-
import"./index-
|
|
14
|
+
import"./index-djh5gpb7.js";
|
|
15
|
+
import"./index-9s991k9v.js";
|
|
16
16
|
import"./index-j37qq1f2.js";
|
|
17
17
|
import"./index-76rn3g2c.js";
|
|
18
18
|
import {
|
|
19
19
|
Workspace,
|
|
20
20
|
command
|
|
21
|
-
} from "./index-
|
|
22
|
-
import"./index-
|
|
21
|
+
} from "./index-bkwnr08k.js";
|
|
22
|
+
import"./index-1twehz1x.js";
|
|
23
23
|
import"./index-mxvakhsm.js";
|
|
24
24
|
import"./index-xys926f2.js";
|
|
25
25
|
import"./index-1577bej2.js";
|
|
@@ -344,10 +344,6 @@ than returning it (`no-return-in-store-action.grit`); a bare `return;` guard sta
|
|
|
344
344
|
`.of() → .model() → .insight() → .query() → .sort() → .enum() → .slice() → .endpoint() → .error() → .translate()`.
|
|
345
345
|
Name every argument in `.arg()`, including framework-supplied `skip` / `limit` / `sort`. Use `modelDictionary`,
|
|
346
346
|
`scalarDictionary`, or `serviceDictionary` to match the module kind.
|
|
347
|
-
**`.store()` sits between `.endpoint()` and `.error()` and is the one optional stage** — omit it entirely rather
|
|
348
|
-
than writing it empty. It names custom store actions (labels and `.desc()` only, no `.arg()`), and it is only
|
|
349
|
-
needed where inheriting would be wrong: an action named after the endpoint it calls already reads as that
|
|
350
|
-
endpoint's `.desc()`, which is most of them. `akan.agent.missing-store-description` names the rest.
|
|
351
347
|
|
|
352
348
|
**`<module>.abstract.md`** — a title line, one declarative sentence naming what the module owns, a `## Rules` list of
|
|
353
349
|
two to five invariants the code cannot show, and an optional workflow arrow chain
|
|
@@ -374,8 +370,10 @@ workflow changes.
|
|
|
374
370
|
|
|
375
371
|
- **Every `slice()` takes an explicit `{ guards: {…} }` second argument, and `root:` is always `Admin`.**
|
|
376
372
|
- **Every custom `mutation` / `query` / `message` names its own `guards: [...]` array.** Never rely on the slice default. `Public` belongs on a slice `get:`, never on a mutation.
|
|
373
|
+
- **The guards are also the MCP exposure decision** — see MCP Exposure. An endpoint that names none is not published to agents at all, and a mutation whose only guard is `Public` is refused, so a missing `guards` array now costs visibility as well as authorization.
|
|
377
374
|
- Resource guards are `Can<Verb><Model>` classes in `srvkit/guards.ts` that `implements Guard` with an `async canPass(context)`. They **fail closed**: no resource named ⇒ `false`; a load that throws ⇒ `logger.warn` then `false`. Admin bypass goes first.
|
|
378
375
|
- Keep `static name = "User";` on guard classes. `fetch` serializes guard names and the API explorer filters on them; it looks like dead code, and deleting it breaks the UI. Comment it so the next reader knows.
|
|
376
|
+
- **Every guard class also declares `static scope: GuardScope`, and it is required with no default.** `"account"` means the verdict reads the caller and nothing about the call, so it can be evaluated with no arguments — which is what lets an MCP listing hide what this caller certainly cannot use. `"resource"` means it needs the call's arguments (`context.getArg()`) and fails closed without them, so it is never evaluated for a listing: the entry stays visible and is stopped at call time. Getting it wrong is not a type error, so the marker is mandatory rather than defaulted — `SignedIn` / `Admin` / role checks are `"account"`, and every `Can<Verb><Model>` is `"resource"`.
|
|
379
377
|
- The acting user arrives via `.with(Self)` / `.with(CurrentUserId)` / `.with(Me)`. Never trust a client-supplied id.
|
|
380
378
|
- Guards ship with the library that owns the model and are imported by its own signals through the package path, so a mounting app inherits authorization and cannot forget it.
|
|
381
379
|
- Services re-check ownership even when a guard already gated the call — two independent gates.
|
|
@@ -477,8 +475,15 @@ Conventions that hold for both shapes:
|
|
|
477
475
|
|
|
478
476
|
### MCP Exposure
|
|
479
477
|
|
|
480
|
-
|
|
481
|
-
|
|
478
|
+
Every signal is served to AI agents as an MCP server on `POST /mcp`. **`/mcp` is mounted by default and exposure
|
|
479
|
+
follows an endpoint's guards — there is no per-endpoint opt-in, and nothing to write in a signal file.** An endpoint
|
|
480
|
+
that declares a real guard is published; one that declares none is refused, and so is a mutation whose only guard is
|
|
481
|
+
`Public`. `AKAN_MCP=false` takes the whole surface off. The reasoning is that the guards are already the
|
|
482
|
+
authorization decision and `filterForAccount` re-reads them per caller on every listing, so a second per-endpoint
|
|
483
|
+
switch says nothing the guards do not — while guaranteeing that every endpoint added later is invisible to agents
|
|
484
|
+
until somebody remembers it.
|
|
485
|
+
|
|
486
|
+
Settings live in the app's `main.ts` — `new AkanApp("./server", { mcp: { … } })` — which takes `enabled`, `readOnly`,
|
|
482
487
|
`path`, `version`, `instructions`, `allowedOrigins`, `pageSize`, `language`, and `auth`. That is the only
|
|
483
488
|
app-authored place for it: `server.ts` is generated and takes no options, and the gateway configures a child
|
|
484
489
|
through its environment — so each field also has an env spelling (`AKAN_MCP`, `AKAN_MCP_READONLY`,
|
|
@@ -490,26 +495,26 @@ has, and a value written in code wins over the env of the same name — an expli
|
|
|
490
495
|
concatenation.
|
|
491
496
|
|
|
492
497
|
```typescript
|
|
493
|
-
// <model>.signal.ts —
|
|
498
|
+
// <model>.signal.ts — every one of these is an MCP tool or prompt, with no `mcp:` option anywhere
|
|
494
499
|
export class TaskSlice extends slice(
|
|
495
500
|
srv.task,
|
|
496
|
-
|
|
497
|
-
{ guards: { root: Admin, get: SignedIn, cru: SignedIn }, mcp: { get: true, list: true } },
|
|
501
|
+
{ guards: { root: Admin, get: SignedIn, cru: SignedIn } },
|
|
498
502
|
(init) => ({
|
|
499
|
-
// its own guards: the map above reaches base CRUD and the root slice, never a named slice
|
|
500
|
-
|
|
503
|
+
// its own guards: the map above reaches base CRUD and the root slice, never a named slice — so a named slice
|
|
504
|
+
// that names none is refused rather than published, which is the one shape to watch for.
|
|
505
|
+
inTodo: init({ guards: [SignedIn] }).exec(function () {
|
|
501
506
|
return this.taskService.queryByStatuses(["todo"]);
|
|
502
507
|
}),
|
|
503
508
|
}),
|
|
504
509
|
) {}
|
|
505
510
|
|
|
506
511
|
export class TaskEndpoint extends endpoint(srv.task, ({ mutation, prompt }) => ({
|
|
507
|
-
startTask: mutation(cnst.Task, { guards: [SignedIn]
|
|
512
|
+
startTask: mutation(cnst.Task, { guards: [SignedIn] })
|
|
508
513
|
.param("taskId", ID)
|
|
509
514
|
.exec(async function (taskId) {
|
|
510
515
|
return await this.taskService.startTask(taskId);
|
|
511
516
|
}),
|
|
512
|
-
reviewTask: prompt({ guards: [SignedIn]
|
|
517
|
+
reviewTask: prompt({ guards: [SignedIn] })
|
|
513
518
|
.param("taskId", ID)
|
|
514
519
|
.exec(async function (taskId) {
|
|
515
520
|
const task = await this.taskService.getTask(taskId);
|
|
@@ -518,24 +523,21 @@ export class TaskEndpoint extends endpoint(srv.task, ({ mutation, prompt }) => (
|
|
|
518
523
|
})) {}
|
|
519
524
|
```
|
|
520
525
|
|
|
521
|
-
- **The refusals are fail-closed
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
must be filled**.
|
|
526
|
+
- **The refusals are fail-closed**: **an endpoint that declares no `guards` at all** (nobody decided who may reach
|
|
527
|
+
it), **a mutation with no real `guards`** (`[Public]` is having none, spelled out — it answers true
|
|
528
|
+
unconditionally), `pubsub` and `message` (their internal args read a socket an MCP request does not have), an
|
|
529
|
+
`Any` or `Upload` return, a file upload, and **an argument typed `Any` that must be filled**.
|
|
525
530
|
A `prompt` refuses two more, because its `arguments` is one string per name with no schema beside it: a **list
|
|
526
531
|
argument**, which could never carry a second value, and **any `Any` argument** — a tool leaves that out of its
|
|
527
|
-
schema, and a prompt has no schema to leave it out of.
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
fail-closed is right, and a silent fail-closed leaves you nothing to read. `akan quality scan` covers the two
|
|
533
|
-
shapes visible in source, `akan.mcp.missing-description` and `akan.mcp.unguarded-exposure`; the API explorer
|
|
534
|
-
badges the per-endpoint rules (`MCP` / `MCP refused`) from the same rule the catalogue runs.
|
|
532
|
+
schema, and a prompt has no schema to leave it out of.
|
|
533
|
+
- **Every refusal is named in the boot log**: one `warn` per endpoint plus a `MCP catalogue: tools=… prompts=…`
|
|
534
|
+
count. Read that line first when a tool you expected is missing — and it is the *only* place the answer exists,
|
|
535
|
+
because there is no absent opt-in to notice. The API explorer badges the same rule per endpoint (`MCP` /
|
|
536
|
+
`MCP refused`), from the same shared implementation the catalogue runs.
|
|
535
537
|
- **An `Any` argument is left out of the published schema** rather than described as `{}` — it tells a model
|
|
536
538
|
nothing — and a value sent for one is refused by name, so the endpoint reads it as omitted. That is what happens
|
|
537
539
|
to the root list's raw `query` descriptor: read as sent, it would be an arbitrary filter over every model you
|
|
538
|
-
|
|
540
|
+
publish. Declare a named filter slice when an agent should narrow a list.
|
|
539
541
|
- **A nullable model return publishes no `outputSchema`**, and its empty answer ships as the text `null` with no
|
|
540
542
|
`structuredContent`. That field is an object by definition, so `null` cannot ride in it any more than an array
|
|
541
543
|
can — a list is wrapped as `{ items: … }` for the same reason — and a declared schema obliges every result to
|
|
@@ -544,13 +546,13 @@ export class TaskEndpoint extends endpoint(srv.task, ({ mutation, prompt }) => (
|
|
|
544
546
|
- **An `outputSchema` names no `hidden` or `secret` field.** Every response has both stripped, so publishing them
|
|
545
547
|
promises a property no answer can carry — and on a model like `user` the names are the leak. Your *input* schema
|
|
546
548
|
keeps them: they are legal to send, and the same model describes a request body.
|
|
547
|
-
-
|
|
549
|
+
- A refused endpoint answers the *same* "unknown tool" as one that does not exist. Never make that
|
|
548
550
|
message more helpful — the difference is what enumerates your private surface. A guard's refusal is generalized
|
|
549
551
|
the same way: the caller reads `You are not permitted to perform this action.`, never `Access denied by guard:
|
|
550
552
|
Admin`, which names your authorization structure to the one caller barred from it. A domain `Err` resolves
|
|
551
553
|
through the dictionary first and keeps its own words.
|
|
552
|
-
- `
|
|
553
|
-
distrust hints; they are never a gate.
|
|
554
|
+
- The `readOnly` / `destructive` / `idempotent` hints a client renders are derived from the endpoint type and key
|
|
555
|
+
and are not configurable. Clients are told to distrust hints; they are never a gate.
|
|
554
556
|
- **`AKAN_MCP_READONLY=true` is the read-only-deployment valve, not the exposure switch.** It drops every mutation
|
|
555
557
|
whatever it declared, and reports each one in the boot log like any other refusal.
|
|
556
558
|
- OAuth resource metadata is published at `/.well-known/oauth-protected-resource` (and at that path plus the mount
|
|
@@ -558,12 +560,12 @@ export class TaskEndpoint extends endpoint(srv.task, ({ mutation, prompt }) => (
|
|
|
558
560
|
configure it; `insufficient_scope` is enforced only once `AKAN_MCP_SCOPES` is set. A token carrying no `aud` at
|
|
559
561
|
all is refused once `AKAN_MCP_AUTH_SERVERS` names an issuer — that issuer mints tokens for its other resources
|
|
560
562
|
too — and accepted while none is named, because a first-party Akan token is bound by app and environment.
|
|
561
|
-
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
563
|
+
- **The boot log names every published entry with no dictionary `.desc()`.** An agent picks a tool by its
|
|
564
|
+
description, so a missing one is a broken tool. What the framework generates has no text of its own and borrows
|
|
565
|
+
the model's: the generated list reads the `.of()` label, and the base CRUD tools append the model's `.desc()` to
|
|
566
|
+
their generated `Get X`. Write that model `.desc()` — it is the only text those entries can carry. There is no
|
|
567
|
+
`akan quality scan` rule for this any more: a source scanner found the exposure only as an `mcp:` literal, and
|
|
568
|
+
with exposure derived from the guards the resolved catalogue is the only place that can answer.
|
|
567
569
|
- A browser-hosted client needs `allowedOrigins` **and** the CORS answer the server sends back for those origins.
|
|
568
570
|
Every other MCP client sends no `Origin` at all, and the one that does is matched against the forwarded host so
|
|
569
571
|
a proxy does not turn each call into a 403 — which is only as trustworthy as an edge that *overwrites* that
|
|
@@ -588,9 +590,8 @@ export class TaskEndpoint extends endpoint(srv.task, ({ mutation, prompt }) => (
|
|
|
588
590
|
token signed wrong, like an opaque one, still degrades to an anonymous caller.
|
|
589
591
|
- **Resource URIs**: `akan://<model>/{id}`, `akan://<model>/light/{id}`, `akan://<model>/list` for the model's own
|
|
590
592
|
list, and `akan://<model>/list/<sliceKey>` for a slice's. The root list takes no third segment on purpose — any
|
|
591
|
-
token there is one a slice could also be named. **Those four are the whole set**, so
|
|
592
|
-
|
|
593
|
-
named in the boot log saying so.
|
|
593
|
+
token there is one a slice could also be named. **Those four are the whole set**, so only the generated reads are
|
|
594
|
+
addressable: a custom endpoint keeps its tool and gets no resource template.
|
|
594
595
|
- **The catalogue is one language**, `en` unless `language` says otherwise: it is built once at boot and cached by
|
|
595
596
|
clients, so there is no `Accept-Language` negotiation.
|
|
596
597
|
|
|
@@ -459,9 +459,7 @@ is convention that keeps hand-written code reading like generated code.
|
|
|
459
459
|
generated. Never `import type { RootStore } from "../st"` — it crashes `akan build` with a Bun SSR segfault.
|
|
460
460
|
- **`dictionary.ts`** — fixed chain with empty stages still written:
|
|
461
461
|
`.of() → .model() → .insight() → .query() → .sort() → .enum() → .slice() → .endpoint() → .error() → .translate()`.
|
|
462
|
-
Every label is `t(["English", "한국어"])`, and nearly every one also carries `.desc([en, ko])`.
|
|
463
|
-
`.store()`, sits between `.endpoint()` and `.error()` for custom store actions whose name differs from the
|
|
464
|
-
endpoint they call — omit it rather than writing it empty.
|
|
462
|
+
Every label is `t(["English", "한국어"])`, and nearly every one also carries `.desc([en, ko])`.
|
|
465
463
|
- **`srvkit/` adapters** — an injected singleton is an `adapt("name" as const, ({ use, env, plug, memory }) => ({…}))`
|
|
466
464
|
class, injected with `plug(TheClass)`. It self-registers, so do not add it to `lib/option.ts`. `this.logger` is
|
|
467
465
|
provided; lifecycle work goes in `override async onInit()`. A per-use value object stays a plain class you `new` at
|
|
@@ -155,9 +155,29 @@ ${AGENT_BLOCK_START}
|
|
|
155
155
|
${block}
|
|
156
156
|
${AGENT_BLOCK_END}
|
|
157
157
|
`;
|
|
158
|
+
var CLAUDE_COMMENT_RULE = `## Comments \u2014 Overrides Your Default
|
|
159
|
+
|
|
160
|
+
Write **no comments** unless the comment passes the test below. This is the rule agents break most often here, so it
|
|
161
|
+
is repeated outside the guide: a diff that adds a comment the test rejects is a diff to redo.
|
|
162
|
+
|
|
163
|
+
Before typing \`//\`, \`/*\`, or a doc block, ask \u2014 **does this sentence carry a fact that is nowhere in the code?**
|
|
164
|
+
|
|
165
|
+
- Restates the identifier, the signature, or the line under it \u2192 delete it.
|
|
166
|
+
- Labels a section (\`// helpers\`, \`// state\`) or narrates a step (\`// fetch the user\`, \`// then save\`) \u2192 delete it.
|
|
167
|
+
- JSDoc on an ordinary function, or a why/how preamble on ordinary logic \u2192 delete it.
|
|
168
|
+
- Explains the edit you just made, for whoever reads the diff \u2192 say it in your reply, not in the file.
|
|
169
|
+
- Names a vendor or protocol quirk, an infrastructure constraint, a library gotcha, security reasoning, a math
|
|
170
|
+
derivation, a domain field's business meaning, a state transition, or why an obvious alternative was rejected \u2192
|
|
171
|
+
keep it, one line.
|
|
172
|
+
|
|
173
|
+
That keep-list is exact \u2014 \`Comments\` in the guide is the full version. "It aids readability" and "this logic is
|
|
174
|
+
subtle" are not on it: rename or split the code instead. When you edit an existing file, match its density; if the
|
|
175
|
+
surrounding code carries none, your diff carries none.`;
|
|
158
176
|
var renderScopeClaudeMd = (scope) => `# ${scope.name} \u2014 Claude Code Guide
|
|
159
177
|
|
|
160
178
|
@AGENTS.md
|
|
179
|
+
|
|
180
|
+
${CLAUDE_COMMENT_RULE}
|
|
161
181
|
`;
|
|
162
182
|
|
|
163
183
|
// pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
|
|
@@ -1675,7 +1695,7 @@ class Executor {
|
|
|
1675
1695
|
}));
|
|
1676
1696
|
});
|
|
1677
1697
|
proc.on("exit", (code, signal) => {
|
|
1678
|
-
if (
|
|
1698
|
+
if (code || signal)
|
|
1679
1699
|
reject(new CommandExecutionError({
|
|
1680
1700
|
command,
|
|
1681
1701
|
cwd,
|
|
@@ -1773,7 +1793,7 @@ class Executor {
|
|
|
1773
1793
|
}));
|
|
1774
1794
|
});
|
|
1775
1795
|
proc.on("exit", (code, signal) => {
|
|
1776
|
-
if (
|
|
1796
|
+
if (code || signal)
|
|
1777
1797
|
reject(new CommandExecutionError({
|
|
1778
1798
|
command: modulePath,
|
|
1779
1799
|
args,
|
|
@@ -3052,4 +3072,4 @@ class ModuleExecutor extends Executor {
|
|
|
3052
3072
|
}
|
|
3053
3073
|
}
|
|
3054
3074
|
|
|
3055
|
-
export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, appRootAllowedFiles, appRootAllowedDirs, libFacetRootAllowedFiles, isScannedAppRootEntry, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
|
|
3075
|
+
export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, appRootAllowedFiles, appRootAllowedDirs, libFacetRootAllowedFiles, isScannedAppRootEntry, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AkanContextAnalyzer
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-djh5gpb7.js";
|
|
5
5
|
import {
|
|
6
6
|
createRepairReport,
|
|
7
7
|
generatedFilePathsForTarget,
|
|
8
8
|
renderRepairReport,
|
|
9
9
|
writeGeneratedSyncState,
|
|
10
10
|
writeWorkflowRunArtifact
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-9s991k9v.js";
|
|
12
12
|
import {
|
|
13
13
|
runner
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-bkwnr08k.js";
|
|
15
15
|
|
|
16
16
|
// pkgs/@akanjs/cli/repair/repair.runner.ts
|
|
17
17
|
var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
ModuleScript
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-aak9cctp.js";
|
|
5
5
|
import {
|
|
6
6
|
addFieldUiPolicyForType,
|
|
7
7
|
coerceFieldDefault,
|
|
@@ -34,15 +34,15 @@ import {
|
|
|
34
34
|
sourceFile,
|
|
35
35
|
validationCommandsForTarget,
|
|
36
36
|
viaBuilderParameterName
|
|
37
|
-
} from "./index-
|
|
37
|
+
} from "./index-9s991k9v.js";
|
|
38
38
|
import {
|
|
39
39
|
script
|
|
40
|
-
} from "./index-
|
|
40
|
+
} from "./index-bkwnr08k.js";
|
|
41
41
|
import {
|
|
42
42
|
AppExecutor,
|
|
43
43
|
LibExecutor,
|
|
44
44
|
ModuleExecutor
|
|
45
|
-
} from "./index-
|
|
45
|
+
} from "./index-1twehz1x.js";
|
|
46
46
|
|
|
47
47
|
// pkgs/@akanjs/cli/primitive/primitive.script.ts
|
|
48
48
|
import { capitalize } from "akanjs/common";
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AkanContextAnalyzer
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-djh5gpb7.js";
|
|
5
5
|
import {
|
|
6
6
|
Prompter
|
|
7
7
|
} from "./index-j37qq1f2.js";
|
|
8
8
|
import {
|
|
9
9
|
runner,
|
|
10
10
|
script
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-bkwnr08k.js";
|
|
12
12
|
import {
|
|
13
13
|
AGENT_BLOCK_END,
|
|
14
14
|
AGENT_BLOCK_START,
|
|
15
15
|
AppExecutor,
|
|
16
|
+
CLAUDE_COMMENT_RULE,
|
|
16
17
|
LibExecutor,
|
|
17
18
|
readDevkitVersion,
|
|
18
19
|
renderRecipeEntries,
|
|
19
20
|
stampBlockVersion,
|
|
20
21
|
upsertAgentBlock
|
|
21
|
-
} from "./index-
|
|
22
|
+
} from "./index-1twehz1x.js";
|
|
22
23
|
import {
|
|
23
24
|
collectRecipeSources,
|
|
24
25
|
scanRecipes
|
|
@@ -199,6 +200,8 @@ var renderClaudeMd = async (workspace) => {
|
|
|
199
200
|
return `# ${context.repoName} \u2014 Claude Code Guide
|
|
200
201
|
|
|
201
202
|
@AGENTS.md
|
|
203
|
+
|
|
204
|
+
${CLAUDE_COMMENT_RULE}
|
|
202
205
|
`;
|
|
203
206
|
};
|
|
204
207
|
var renderCursorRule = () => `---
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
createPassedPrimitiveReport,
|
|
10
10
|
generatedFilesForSync,
|
|
11
11
|
scalarChangedFiles
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-9s991k9v.js";
|
|
13
13
|
import {
|
|
14
14
|
Prompter
|
|
15
15
|
} from "./index-j37qq1f2.js";
|
|
16
16
|
import {
|
|
17
17
|
runner,
|
|
18
18
|
script
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-bkwnr08k.js";
|
|
20
20
|
|
|
21
21
|
// pkgs/@akanjs/cli/scalar/scalar.prompt.ts
|
|
22
22
|
import { input } from "@inquirer/prompts";
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
} from "./index-0cj2zxbm.js";
|
|
8
8
|
import {
|
|
9
9
|
openBrowser
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-rv16ck4r.js";
|
|
11
11
|
import {
|
|
12
12
|
runner
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-bkwnr08k.js";
|
|
14
14
|
import {
|
|
15
15
|
AppExecutor,
|
|
16
16
|
WorkspaceExecutor
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-1twehz1x.js";
|
|
18
18
|
|
|
19
19
|
// pkgs/@akanjs/cli/npmRegistry.ts
|
|
20
20
|
var defaultNpmRegistry = "https://registry.npmjs.org";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./index-ss469dec.js";
|
|
5
5
|
import {
|
|
6
6
|
PageScript
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-gyvrhtpm.js";
|
|
8
8
|
import {
|
|
9
9
|
AiSession
|
|
10
10
|
} from "./index-0cj2zxbm.js";
|
|
@@ -15,17 +15,17 @@ import {
|
|
|
15
15
|
generatedFilesForSync,
|
|
16
16
|
moduleSourcePaths,
|
|
17
17
|
sourceFile
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-9s991k9v.js";
|
|
19
19
|
import {
|
|
20
20
|
Prompter
|
|
21
21
|
} from "./index-j37qq1f2.js";
|
|
22
22
|
import {
|
|
23
23
|
runner,
|
|
24
24
|
script
|
|
25
|
-
} from "./index-
|
|
25
|
+
} from "./index-bkwnr08k.js";
|
|
26
26
|
import {
|
|
27
27
|
ModuleExecutor
|
|
28
|
-
} from "./index-
|
|
28
|
+
} from "./index-1twehz1x.js";
|
|
29
29
|
import {
|
|
30
30
|
FileSys
|
|
31
31
|
} from "./index-67546d0j.js";
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
RepairRunner
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-4agbdds8.js";
|
|
5
5
|
import {
|
|
6
6
|
WorkflowRunner
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-w7farjxd.js";
|
|
8
8
|
import {
|
|
9
9
|
ScalarScript
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-8d9r0df5.js";
|
|
11
11
|
import {
|
|
12
12
|
PrimitiveScript
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-4v0wvt37.js";
|
|
14
14
|
import {
|
|
15
15
|
ModuleScript
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-aak9cctp.js";
|
|
17
17
|
import {
|
|
18
18
|
isPlaceholderAppId
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-gz91pc3p.js";
|
|
20
20
|
import {
|
|
21
21
|
AkanContextAnalyzer,
|
|
22
22
|
akanMcpInstallConfigPaths,
|
|
@@ -27,14 +27,14 @@ import {
|
|
|
27
27
|
renderDoctorText,
|
|
28
28
|
resourceList,
|
|
29
29
|
upsertCodexMcpServerBlock
|
|
30
|
-
} from "./index-
|
|
30
|
+
} from "./index-djh5gpb7.js";
|
|
31
31
|
import {
|
|
32
32
|
buildAkanModuleContextIndex,
|
|
33
33
|
createWorkflowBaselineSummary,
|
|
34
34
|
createWorkflowStepRegistry,
|
|
35
35
|
jsonText,
|
|
36
36
|
toolingRolloutGate
|
|
37
|
-
} from "./index-
|
|
37
|
+
} from "./index-9s991k9v.js";
|
|
38
38
|
import {
|
|
39
39
|
Prompter
|
|
40
40
|
} from "./index-j37qq1f2.js";
|
|
@@ -45,10 +45,10 @@ import {
|
|
|
45
45
|
CommandContainer,
|
|
46
46
|
runner,
|
|
47
47
|
script
|
|
48
|
-
} from "./index-
|
|
48
|
+
} from "./index-bkwnr08k.js";
|
|
49
49
|
import {
|
|
50
50
|
AppExecutor
|
|
51
|
-
} from "./index-
|
|
51
|
+
} from "./index-1twehz1x.js";
|
|
52
52
|
|
|
53
53
|
// pkgs/@akanjs/cli/context/context.script.ts
|
|
54
54
|
import { Logger } from "akanjs/common";
|