@orkestrel/scaffold 0.0.1 → 0.0.3
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/README.md +34 -17
- package/dist/bin/scaffold.js +1162 -1200
- package/dist/bin/scaffold.js.map +1 -1
- package/dist/host/AGENTS.md +124 -925
- package/dist/host/CLAUDE.md +260 -495
- package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +53 -0
- package/dist/host/agents/skills/orkestrel-align-packages/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-align-packages/references/fleet.md +50 -0
- package/dist/host/agents/skills/orkestrel-align-packages/references/integration.md +56 -0
- package/dist/host/agents/skills/orkestrel-build-application/SKILL.md +64 -0
- package/dist/host/agents/skills/orkestrel-build-application/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-build-application/references/application.md +129 -0
- package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +64 -0
- package/dist/host/agents/skills/orkestrel-harden-package/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-harden-package/references/centralization.md +85 -0
- package/dist/host/agents/skills/orkestrel-harden-package/references/contract.md +57 -0
- package/dist/host/agents/skills/orkestrel-harden-package/references/hardening.md +93 -0
- package/dist/host/agents/skills/orkestrel-harden-package/references/research.md +61 -0
- package/dist/host/claude/agents/application.md +32 -0
- package/dist/host/claude/agents/builder.md +12 -7
- package/dist/host/claude/agents/checker.md +15 -8
- package/dist/host/claude/agents/codex.md +40 -0
- package/dist/host/claude/agents/grok.md +20 -37
- package/dist/host/claude/agents/orkestrel.md +89 -222
- package/dist/host/claude/agents/planner.md +14 -34
- package/dist/host/claude/agents/reviewer.md +39 -24
- package/dist/host/claude/agents/verifier.md +15 -10
- package/dist/host/claude/rules/application.md +57 -0
- package/dist/host/claude/rules/architecture.md +179 -0
- package/dist/host/claude/rules/browser.md +28 -0
- package/dist/host/claude/rules/documentation.md +64 -0
- package/dist/host/claude/rules/names.md +209 -0
- package/dist/host/claude/rules/patterns.md +130 -0
- package/dist/host/claude/rules/quality.md +45 -0
- package/dist/host/claude/rules/styles.md +64 -0
- package/dist/host/claude/rules/tests.md +123 -0
- package/dist/host/claude/rules/typescript.md +78 -0
- package/dist/host/claude/rules/workspace.md +180 -0
- package/dist/host/claude/settings.json +116 -0
- package/dist/host/claude/skills/orkestrel-align-packages/SKILL.md +10 -0
- package/dist/host/claude/skills/orkestrel-build-application/SKILL.md +12 -0
- package/dist/host/claude/skills/orkestrel-harden-package/SKILL.md +10 -0
- package/dist/host/codex/agents/analyst.toml +15 -0
- package/dist/host/codex/agents/application.toml +25 -0
- package/dist/host/codex/agents/builder.toml +24 -0
- package/dist/host/codex/agents/checker.toml +15 -0
- package/dist/host/codex/agents/grok.toml +17 -0
- package/dist/host/codex/agents/implementer.toml +17 -0
- package/dist/host/codex/agents/orkestrel.toml +16 -0
- package/dist/host/codex/agents/planner.toml +20 -0
- package/dist/host/codex/agents/reviewer.toml +18 -0
- package/dist/host/codex/agents/verifier.toml +14 -0
- package/dist/host/codex/config.toml +64 -0
- package/dist/host/dotfiles/oxlintrc.json +307 -1
- package/dist/host/guides/src/scaffold.md +2060 -1970
- package/dist/host/manifest.json +355 -137
- package/dist/host/scripts/codex.sh +49 -0
- package/dist/host/scripts/cursor.sh +33 -47
- package/dist/host/scripts/deps.sh +34 -16
- package/dist/host/scripts/ollama.sh +6 -149
- package/dist/host/tests/setupPolicy.ts +354 -0
- package/dist/src/core/index.cjs +6745 -1191
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +923 -273
- package/dist/src/core/index.d.ts +923 -273
- package/dist/src/core/index.js +6657 -1184
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +3132 -593
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +643 -95
- package/dist/src/server/index.d.ts +643 -95
- package/dist/src/server/index.js +3054 -594
- package/dist/src/server/index.js.map +1 -1
- package/package.json +15 -12
- package/dist/host/claude/agents/composer.md +0 -64
- package/dist/host/claude/agents/researcher.md +0 -38
- package/dist/host/claude/agents/scout.md +0 -35
- package/dist/host/github/workflows/ci.yml +0 -64
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verifier
|
|
3
|
-
description: 'Runs the authoritative quality gates
|
|
3
|
+
description: 'Runs the exact authoritative quality gates or evidence commands named by the dispatch and reports exit-code truth with exact failure excerpts. Defaults to source-nonmutating check variants before build/test. Independent of every executor; never fixes.'
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
effort: low
|
|
7
|
+
permissionMode: default
|
|
8
|
+
maxTurns: 14
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
You are the **Verifier** — the gate
|
|
10
|
-
(see CLAUDE.md).
|
|
11
|
-
|
|
11
|
+
You are the **Verifier** — the independent gate runner in this project's role set
|
|
12
|
+
(see CLAUDE.md). No builder's self-report counts as gate evidence. You are an
|
|
13
|
+
Executor: run the gates yourself, spawn nothing.
|
|
12
14
|
|
|
13
15
|
## Job
|
|
14
16
|
|
|
15
|
-
1.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
1. Read `AGENTS.md`, applicable rules, the dispatch-named skill and required
|
|
18
|
+
references, and the governing guide/spec.
|
|
19
|
+
2. Run exactly the commands the dispatch names, in order. When asked for the default
|
|
20
|
+
independent sweep, use `npm run format:check` → `npm run lint:check` →
|
|
21
|
+
`npm run check` → `npm run build` → `npm test`. These do not rewrite source;
|
|
22
|
+
build artifacts are allowed. Never invent a different gate set.
|
|
23
|
+
3. Evidence runs count as gates: when dispatched to reproduce a failure, run the
|
|
19
24
|
named command and capture its exact output — reproduce, capture, bisect
|
|
20
25
|
mechanically if told to; nothing more.
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
4. Record each gate's TRUE outcome by exit code. A gate that "mostly passes" FAILED.
|
|
27
|
+
5. On failure, capture the exact failing excerpt — trimmed to the failure, not the
|
|
23
28
|
noise — and the file:line it points to.
|
|
24
29
|
|
|
25
30
|
## Output contract — the Gate Report
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- 'app/**/*'
|
|
4
|
+
- 'tests/app/**/*'
|
|
5
|
+
- 'configs/app/**/*'
|
|
6
|
+
- 'package.json'
|
|
7
|
+
- 'tsconfig.json'
|
|
8
|
+
- 'vite.config.ts'
|
|
9
|
+
- '.oxlintrc.json'
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Application composition
|
|
13
|
+
|
|
14
|
+
- Select only needed app environments; app-only, src-only, and mixed workspaces
|
|
15
|
+
are first-class.
|
|
16
|
+
- The CLI names the independent selections `--src` and `--app`.
|
|
17
|
+
`--surfaces` is not an alias and must fail as an unknown option.
|
|
18
|
+
- Core-only, browser-only, and server-only applications are valid. A combined
|
|
19
|
+
browser+server application includes app/core for shared contracts.
|
|
20
|
+
- Every selected environment has an `index.ts` barrel. `main.ts` is an executable
|
|
21
|
+
entry and never owns reusable declarations.
|
|
22
|
+
- app/core is host-independent and check/test-only.
|
|
23
|
+
- app/browser uses app/core contracts, Vue 3 when selected, an `index.html`
|
|
24
|
+
entry, `vue-tsc`, and real Chromium tests.
|
|
25
|
+
- app/server uses app/core contracts, parses environment values before binding,
|
|
26
|
+
defaults to loopback, emits `dist/app/server/main.cjs`, and keeps only
|
|
27
|
+
`node:*` external.
|
|
28
|
+
- Browser/server integration crosses a contract/transport boundary. Neither
|
|
29
|
+
environment imports the other's implementation. `.oxlintrc.json`
|
|
30
|
+
`no-restricted-imports` enforces declared package, alias, and conventional
|
|
31
|
+
relative import direction. Scoped TypeScript configurations remove Node/DOM
|
|
32
|
+
globals from the wrong environment. Vite's actual browser and server builds
|
|
33
|
+
resolve Vue, assets, CSS, workers, and runtime module graphs. Generated
|
|
34
|
+
consumers must pass lint, scoped typechecking, production builds, and real
|
|
35
|
+
integration tests. Do not introduce a custom parser or source-language
|
|
36
|
+
analyzer to duplicate the project toolchain.
|
|
37
|
+
- Scoped checks include `.ts`, `.tsx`, `.mts`, and `.cts`. Vue SFCs and CSS
|
|
38
|
+
belong to browser environments; SCSS requires an authorized compiler dependency.
|
|
39
|
+
- Published `src` environments never import private `app` modules. Src core is
|
|
40
|
+
host-independent; src browser/server may import src core but never one
|
|
41
|
+
another's implementation. Apply the same environment law to
|
|
42
|
+
`@orkestrel/<package>/browser` and `/server` exports.
|
|
43
|
+
- App-only manifests are unscoped and `private: true`, with no package export
|
|
44
|
+
map or publish configuration. Mixed manifests publish only `dist/src`, and
|
|
45
|
+
Vue remains development-only because app output is never published.
|
|
46
|
+
- app/server process signals belong to a tested, explicitly stoppable,
|
|
47
|
+
generation-safe runner whose stale failures cannot release a newer run;
|
|
48
|
+
convenience startup returns the runner so normal cleanup cannot be hidden.
|
|
49
|
+
`ApplicationServerRunner` lives alone in `ApplicationServerRunner.ts`, and the
|
|
50
|
+
`startApplicationServer` convenience factory belongs in `factories.ts`.
|
|
51
|
+
`main.ts` invokes it and owns no reusable declarations or duplicated signal
|
|
52
|
+
handling.
|
|
53
|
+
- Do not add showcase, auth, storage, proxy, CSS framework, or other product
|
|
54
|
+
policy unless the request requires it.
|
|
55
|
+
- Test repeated lifecycle, concurrent calls, malformed environment input,
|
|
56
|
+
protocol rejection, abort/cleanup where applicable, and cross-environment
|
|
57
|
+
contract parity using real hosts.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- 'src/**/*.ts'
|
|
4
|
+
- 'app/**/*.{ts,vue}'
|
|
5
|
+
- 'tests/**/*.ts'
|
|
6
|
+
- 'configs/**/*.ts'
|
|
7
|
+
- 'vite.config.ts'
|
|
8
|
+
- 'tsconfig.json'
|
|
9
|
+
- 'package.json'
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Architecture and placement rules
|
|
13
|
+
|
|
14
|
+
## Centralized-file pattern
|
|
15
|
+
|
|
16
|
+
| Content | Sole location |
|
|
17
|
+
| ------------------------- | -------------------------------------------- |
|
|
18
|
+
| Interfaces/types | `*/types.ts` |
|
|
19
|
+
| Constants/data | `*/constants.ts` |
|
|
20
|
+
| Pure helpers | `*/helpers.ts` |
|
|
21
|
+
| Guards | `*/validators.ts` |
|
|
22
|
+
| Guard combinators | `*/combinators.ts` |
|
|
23
|
+
| Owned snapshots | `*/cloners.ts` |
|
|
24
|
+
| Coercers | `*/parsers.ts` |
|
|
25
|
+
| Shape values | `*/shapers.ts` |
|
|
26
|
+
| Shape/algorithm compilers | `*/compilers.ts` |
|
|
27
|
+
| Entity/value factories | `*/factories.ts` |
|
|
28
|
+
| Middleware factories | `*/middlewares.ts` |
|
|
29
|
+
| Seeders | `*/seeders.ts` |
|
|
30
|
+
| Schemas | `*/schemas.ts` |
|
|
31
|
+
| Relations | `*/relations.ts` |
|
|
32
|
+
| Error classes/guards | `*/errors.ts` |
|
|
33
|
+
| Public exports | `*/index.ts` |
|
|
34
|
+
| Implementations | `*/[domain]/[Entity].ts`, one class per file |
|
|
35
|
+
|
|
36
|
+
Use only the centralized files an environment needs.
|
|
37
|
+
|
|
38
|
+
## Declaration placement
|
|
39
|
+
|
|
40
|
+
- An implementation file contains imports and exactly one class implementation with `#` fields.
|
|
41
|
+
- It contains no module-scope interface, type, constant, or free function—even when private to that file.
|
|
42
|
+
- Extract local declarations by kind. “Only used here” and “not exported” are not exemptions.
|
|
43
|
+
- Every declaration in a centralized file is exported. Fold away a trivial single-use declaration or export/test it; never leave it hidden.
|
|
44
|
+
- The only permitted non-exported module-scope declarations are in a runtime entrypoint that must be self-contained and cannot import siblings, such as raw source loaded in a worker. Explain that necessity in a comment.
|
|
45
|
+
- Perform a cleanup sweep after implementation: no stray implementation-file declarations, non-exported/wrong-kind centralized declarations, prohibited nested declarations, duplicate implementations, compatibility aliases, superfluous wrappers, stale imports/barrel rows, or untested extracted functions.
|
|
46
|
+
|
|
47
|
+
## Kind purity
|
|
48
|
+
|
|
49
|
+
- Each centralized file contains only its named kind.
|
|
50
|
+
- Module-scope constants live only in `constants.ts`, use UPPER_SNAKE_CASE, and freeze object/array data with `Object.freeze`.
|
|
51
|
+
- A camelCase namespace containing functions is helper behavior, not constant data; place it in `helpers.ts`.
|
|
52
|
+
- `helpers.ts` is exported reusable infrastructure. A reusable regex, parser, header flattener, signer, or similar fragment has one implementation used by source, tests, and fixtures.
|
|
53
|
+
- A would-be helper has two outcomes:
|
|
54
|
+
- trivial and genuinely single-use → fold into its caller;
|
|
55
|
+
- non-trivial or reusable → extract, export, unit-test, and route every duplicate through it.
|
|
56
|
+
- `factories.ts`, `compilers.ts`, and `parsers.ts` are centralized files, not hiding places. Factory glue extracts to `helpers.ts`; pure compiler/parser recursion remains exported in its own kind file.
|
|
57
|
+
|
|
58
|
+
## Wrapper test
|
|
59
|
+
|
|
60
|
+
A wrapper survives only when it adds a real boundary, invariant, composition, translation, lifecycle, or materially narrower contract.
|
|
61
|
+
|
|
62
|
+
- Delete one-line delegates, pass-through factories, rename-only helpers/getters, compatibility aliases, and wrappers around semantically identical platform or declared-dependency primitives.
|
|
63
|
+
- Rename or import the real symbol and update every consumer atomically. Do not preserve a wrapper to avoid downstream edits.
|
|
64
|
+
- Do not re-export a dependency's symbol from this package.
|
|
65
|
+
- A public class method composes real entity behavior; it never exists only to forward 1:1 to a helper.
|
|
66
|
+
- Audit callers and callees after every extraction so the old path and duplicate implementation do not remain.
|
|
67
|
+
|
|
68
|
+
## Functions and orchestration
|
|
69
|
+
|
|
70
|
+
- Never declare or assign a function inside another function or method.
|
|
71
|
+
- This bans local `function`, `function*`, and `const fn = () => ...`, regardless of caller count.
|
|
72
|
+
- The only in-body function expression allowed is an anonymous callback passed directly as an argument.
|
|
73
|
+
- Instance-bound work that reaches state or sibling methods is a method, not a free function.
|
|
74
|
+
|
|
75
|
+
Separate three roles:
|
|
76
|
+
|
|
77
|
+
1. **Public method:** implements the interface and genuinely composes behavior; never forwards 1:1 to one helper.
|
|
78
|
+
2. **`#` private method:** stateful/instance-bound orchestration or the class's defining recursive/compositional algorithm.
|
|
79
|
+
3. **Centralized helper:** pure referentially transparent leaf, independently understandable/testable without class knowledge.
|
|
80
|
+
|
|
81
|
+
Apply the leaf test:
|
|
82
|
+
|
|
83
|
+
1. Reaches `#` state or a sibling method → private method.
|
|
84
|
+
2. Pure self-contained computation (key, format, compare, convert, lookup, projection, one unification) → exported helper.
|
|
85
|
+
3. Recursive spine or composition of leaves (`solve`, `isolate`, `prove`, chaining, relational join), even if pure → private method.
|
|
86
|
+
4. Defining engine internals remain methods when extraction would hollow the class into a thin delegate.
|
|
87
|
+
|
|
88
|
+
Extract pure leaves aggressively; keep the class's actual behavior.
|
|
89
|
+
|
|
90
|
+
## Class order
|
|
91
|
+
|
|
92
|
+
1. `#` private fields: context, options, state/result, child managers.
|
|
93
|
+
2. Constructor: initialize context/options and instantiate child managers.
|
|
94
|
+
3. Public interface: getters, then methods.
|
|
95
|
+
4. `#` private methods.
|
|
96
|
+
|
|
97
|
+
Store child managers in `#` fields and expose readonly getters typed as their interfaces.
|
|
98
|
+
|
|
99
|
+
## Middleware
|
|
100
|
+
|
|
101
|
+
- Middleware is behavior `(context, next) => ...`, never a class with one `handle` method.
|
|
102
|
+
- Place middleware factories in `middlewares.ts` as `createX(options): Middleware`; keep them distinct from entity/value factories.
|
|
103
|
+
- Keep middleware-local state closure-private.
|
|
104
|
+
- If consumers must address, share, inspect, or replace that state, extract the state to a pluggable class supplied as an option, with an in-memory default.
|
|
105
|
+
- Extract reusable cross-middleware machinery to helpers/classes.
|
|
106
|
+
- `MiddlewareManager` is the sole manager of the middleware composition chain; do not create one manager per middleware.
|
|
107
|
+
|
|
108
|
+
## Environment/module placement
|
|
109
|
+
|
|
110
|
+
- Shared cross-environment logic belongs in the central core/shared layer. Other environments import core; core imports neither browser nor server.
|
|
111
|
+
- An environment with multiple modules keeps cross-module types/helpers at the environment root and module-specific declarations inside the module.
|
|
112
|
+
- Promote a declaration to the environment root only when at least two modules use it.
|
|
113
|
+
- The environment barrel re-exports root files and module barrels.
|
|
114
|
+
- Cover cross-cutting environment-root helpers with behavioral tests; each module API receives its own guide parity.
|
|
115
|
+
|
|
116
|
+
### Entity subfolders
|
|
117
|
+
|
|
118
|
+
- When one entity grows a family (entity + manager or sibling implementations), nest only its class files in a lowercase plural folder.
|
|
119
|
+
- Keep its interfaces in module-root `types.ts`, factories in module-root `factories.ts`, and exports in the module barrel.
|
|
120
|
+
- Entity subfolders never grow their own centralized files.
|
|
121
|
+
|
|
122
|
+
### Extension categories
|
|
123
|
+
|
|
124
|
+
- A designed extension point—drivers, stores, transports—gets its category folder even with one concrete class.
|
|
125
|
+
- This applies both to consumer implementations of another domain's contract and default implementations beside the defining contract.
|
|
126
|
+
- The contract remains in module-root `types.ts`; only concrete classes nest.
|
|
127
|
+
- Nest because the category is a designed growth seam, not because a class name happens to end in `Store` or `Driver`.
|
|
128
|
+
- Co-equal native-object wrappers that are core primitives stay flat.
|
|
129
|
+
|
|
130
|
+
### Stores
|
|
131
|
+
|
|
132
|
+
Choose the access shape:
|
|
133
|
+
|
|
134
|
+
- **Point access:** `get`, `set`, `delete`.
|
|
135
|
+
- **Bulk restore:** `save`, `load`, `remove`, `clear`.
|
|
136
|
+
|
|
137
|
+
Both obey:
|
|
138
|
+
|
|
139
|
+
- The stored value carries its own id; do not pass a separate id to `set`/`save`.
|
|
140
|
+
- Every primitive is async and returns a `Promise`.
|
|
141
|
+
- Deleting/removing a missing key is a no-op.
|
|
142
|
+
- Concrete stores live in `stores/`; the interface stays in module-root `types.ts`; `create*Store` factories stay in `factories.ts`.
|
|
143
|
+
|
|
144
|
+
## Barrel exports
|
|
145
|
+
|
|
146
|
+
- `*/index.ts` is the sole public barrel.
|
|
147
|
+
- Only an `index.ts` may re-export.
|
|
148
|
+
- A barrel contains only `export * from './module.js'` declarations. Do not use
|
|
149
|
+
named, default, namespace, or type-only barrel exports.
|
|
150
|
+
- A star-export collision is a design failure: rename the conflicting concept
|
|
151
|
+
at its owner and update consumers. Never hide the collision with a selective
|
|
152
|
+
barrel row.
|
|
153
|
+
- Never re-export a symbol originating in another package; fix consumer imports to the originating package.
|
|
154
|
+
- Implementation files export their own classes directly.
|
|
155
|
+
- When a symbol moves, update every import; never leave a compatibility re-export.
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
export * from './types.js'
|
|
159
|
+
export * from './constants.js'
|
|
160
|
+
export * from './errors.js'
|
|
161
|
+
export * from './validators.js'
|
|
162
|
+
export * from './helpers.js'
|
|
163
|
+
export * from './factories.js'
|
|
164
|
+
export * from './greeters/Greeter.js'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## System constraints
|
|
168
|
+
|
|
169
|
+
- Build a capability with its first real consumer; do not speculate.
|
|
170
|
+
- Keep interfaces to the smallest primitives the capability requires.
|
|
171
|
+
- For multiple backends, implement shared querying/paging/aggregation in one engine over those primitives. A backend may override an operation only with a genuine native fast path and otherwise falls back to the engine.
|
|
172
|
+
- Centralize any pattern repeated twice.
|
|
173
|
+
- Keep everything generic/reusable and free of unrelated-project logic.
|
|
174
|
+
- Do not expand public API without concrete multi-site need.
|
|
175
|
+
- Do not remove structural files because they are currently empty.
|
|
176
|
+
- Prefer the smallest complete implementation that preserves architecture.
|
|
177
|
+
- No deprecation aliases, compatibility shims, or backward-compatibility branches; update all consumers atomically.
|
|
178
|
+
- No polling/busy loops or recursive microtasks as architecture. Park idle work on an event/abort wakeup and yield long work in cooperative quanta.
|
|
179
|
+
- Framework/server utilities provide mechanism—HMAC, CORS, parsing, sessions, cookies, CSRF, static serving—not product policy such as user models, login flow, or authorization.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- 'src/browser/**/*.ts'
|
|
4
|
+
- 'app/browser/**/*.{ts,vue}'
|
|
5
|
+
- 'tests/{src,app}/browser/**/*'
|
|
6
|
+
- 'tests/setupBrowser.ts'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Vue and browser rules
|
|
10
|
+
|
|
11
|
+
- Never use Vue `$emit`.
|
|
12
|
+
- Coordinate reactivity through props, controllers, stores, services, and composables.
|
|
13
|
+
- A composable exposes readonly refs plus methods; consumers never mutate returned refs directly:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
function useTheme(): {
|
|
17
|
+
readonly mode: Readonly<Ref<ThemeMode>>
|
|
18
|
+
toggle(): void
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Use utility classes for layout: flex, gap, spacing, sizing.
|
|
23
|
+
- Use the framework's token-backed semantic classes for color/chrome: `.surface`, `.button`, `.muted`, `.accent`.
|
|
24
|
+
- A `[data-theme]` change must retheme the whole interface through tokens.
|
|
25
|
+
- Add custom SCSS only when no utility provides the behavior.
|
|
26
|
+
- Integrate through the framework's Sass variables/functions instead of hand-rolled values.
|
|
27
|
+
- Never write literal colors.
|
|
28
|
+
- Prefer native platform APIs—Popover, `<dialog>`, `hashchange` routing, native events/storage/observers—over custom replacements or added dependencies.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- '*.md'
|
|
4
|
+
- 'guides/**/*.md'
|
|
5
|
+
- 'tests/guides/**/*.ts'
|
|
6
|
+
- 'src/**/types.ts'
|
|
7
|
+
- 'src/**/index.ts'
|
|
8
|
+
- 'app/**/types.ts'
|
|
9
|
+
- 'app/**/index.ts'
|
|
10
|
+
- 'src/styles/**/*'
|
|
11
|
+
- '.agents/skills/**/*.md'
|
|
12
|
+
- '.claude/skills/**/*.md'
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Documentation and parity rules
|
|
16
|
+
|
|
17
|
+
Documentation is an enforced contract, not explanatory decoration.
|
|
18
|
+
|
|
19
|
+
## Authority and workflow
|
|
20
|
+
|
|
21
|
+
- Read the matching spec/guide before code, form the intended design, then compare implementation. Existing code is a verification target, not ground truth.
|
|
22
|
+
- `AGENTS.md` and its linked rules are the sole convention source. Do not create competing instruction copies in guides.
|
|
23
|
+
- `guides/README.md` is the map: maintain both a concept index (`spec ↔ source ↔ tests ↔ showcase`) and directory index.
|
|
24
|
+
- `ROADMAP.md` is the sequenced plan of record. Each chunk reaches green before the next.
|
|
25
|
+
- A showcase is executable proof of public API. A missing demonstration is a missing feature, detectable by parity.
|
|
26
|
+
|
|
27
|
+
## Parity
|
|
28
|
+
|
|
29
|
+
- Every backticked API in a guide resolves to a real public export.
|
|
30
|
+
- Every public export is documented.
|
|
31
|
+
- TypeScript, SCSS, Markdown, tests, and showcase remain aligned.
|
|
32
|
+
- A parity failure identifies drift; never suppress or weaken the test.
|
|
33
|
+
|
|
34
|
+
For behavioral interfaces/classes:
|
|
35
|
+
|
|
36
|
+
- Document public methods under `## Methods`.
|
|
37
|
+
- Use one method table per interface, keyed by its backticked name.
|
|
38
|
+
- The table's methods exactly match the interface's call-signature members.
|
|
39
|
+
- Readonly data properties remain in the interface's `## Surface` row.
|
|
40
|
+
- Each implementing class exposes exactly its interface methods—no missing or extra public behavior.
|
|
41
|
+
|
|
42
|
+
Parity scope:
|
|
43
|
+
|
|
44
|
+
- Normally scope a guide to one module directory.
|
|
45
|
+
- A layer concept may include the core module and backend modules implementing it.
|
|
46
|
+
- Cross-cutting environment-root helpers are covered by behavioral tests rather than forced into one module guide.
|
|
47
|
+
|
|
48
|
+
## Guide examples
|
|
49
|
+
|
|
50
|
+
Code fences import through the package's published specifier:
|
|
51
|
+
|
|
52
|
+
- primary/core API: `@orkestrel/<name>`;
|
|
53
|
+
- secondary environment API: `@orkestrel/<name>/<environment>`.
|
|
54
|
+
|
|
55
|
+
Never use in-repository `@src/*` aliases in public guide examples; reserve them for source/tests.
|
|
56
|
+
|
|
57
|
+
## Workflow skills
|
|
58
|
+
|
|
59
|
+
- Skills prescribe reusable process; they do not copy naming, placement, syntax, lifecycle, or test laws from `AGENTS.md` and rules.
|
|
60
|
+
- Keep `SKILL.md` concise and route conditional detail to one-level `references/`.
|
|
61
|
+
- Frontmatter contains only `name` and a trigger-focused `description`.
|
|
62
|
+
- Do not put model routing or package version catalogs in a skill.
|
|
63
|
+
- Validate every referenced resource and `agents/openai.yaml`; do not leave template TODOs or auxiliary README/changelog files.
|
|
64
|
+
- Keep provider bridges minimal: they load one canonical workflow and add no competing instructions.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- '**/*.{ts,tsx,mts,cts,vue}'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Naming and API-shape rules
|
|
7
|
+
|
|
8
|
+
Names are public API. A consumer should be able to predict them without documentation.
|
|
9
|
+
|
|
10
|
+
## Entity-scoped names: one word
|
|
11
|
+
|
|
12
|
+
Properties/getters, methods, option keys, and event names belong to an entity whose type already supplies context. Use one descriptive word:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
interface AgentInterface {
|
|
16
|
+
readonly id: string
|
|
17
|
+
readonly context: AgentContextInterface
|
|
18
|
+
readonly status: AgentStatus
|
|
19
|
+
generate(): Promise<string>
|
|
20
|
+
stream(options?: AgentStreamOptions): AsyncGenerator<string, string>
|
|
21
|
+
abort(): void
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Hard targets:
|
|
26
|
+
|
|
27
|
+
- Public properties: one word.
|
|
28
|
+
- Public methods: one word; use two only when no single verb is accurate.
|
|
29
|
+
- Ungrouped option keys: one word.
|
|
30
|
+
- Grouped option key: the configured entity noun; every leaf remains one word.
|
|
31
|
+
- Events: one present-tense verb or noun.
|
|
32
|
+
- Private methods: two or three words are acceptable.
|
|
33
|
+
|
|
34
|
+
The rule does not apply to standalone helpers, type names with role suffixes, or qualified constants.
|
|
35
|
+
|
|
36
|
+
## Split instead of compounding
|
|
37
|
+
|
|
38
|
+
A compound entity member usually means the API contains multiple entities or behaviors. Do not create `addTool`, `removeDocument`, `databasePath`, or `serverTimeout`.
|
|
39
|
+
|
|
40
|
+
### Group options by entity
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
interface ServerOptions {
|
|
44
|
+
readonly server?: { readonly port?: number; readonly timeout?: number }
|
|
45
|
+
readonly database?: { readonly path?: string; readonly timeout?: number }
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Never flatten these into prefixed keys.
|
|
50
|
+
|
|
51
|
+
### Extract sub-entities
|
|
52
|
+
|
|
53
|
+
Move prefixed method families to a manager and expose it as a noun:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
interface AgentContextInterface {
|
|
57
|
+
readonly instructions: InstructionManagerInterface
|
|
58
|
+
readonly documents: DocumentManagerInterface
|
|
59
|
+
readonly tools: ToolManagerInterface
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Call `context.instructions.add(input)`, not `context.addInstruction(input)`.
|
|
64
|
+
|
|
65
|
+
### Split behavioral variants
|
|
66
|
+
|
|
67
|
+
Do not hide multiple algorithms behind a discriminator parameter:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
parseJSON(input)
|
|
71
|
+
parseYAML(input)
|
|
72
|
+
parseTOML(input)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Do not write `parse(input, format)`. A literal that selects a different action is a magic mode and requires separate functions/methods.
|
|
76
|
+
|
|
77
|
+
Distinguish behavior from data:
|
|
78
|
+
|
|
79
|
+
- Different value selects a different action/algorithm/shape of work → split.
|
|
80
|
+
- Different value selects a datum for the same operation → keep it as data.
|
|
81
|
+
- Discriminants, reasoning/error codes, uniformly applied value enums, and field/key selectors are data.
|
|
82
|
+
|
|
83
|
+
## Standalone helpers
|
|
84
|
+
|
|
85
|
+
Module helpers have no owning entity at the call site, so default to `{verb}{Noun}`:
|
|
86
|
+
|
|
87
|
+
`generateId`, `computeHash`, `extractColumns`, `derivePhaseStatus`, `inferLanguage`, `normalizePath`, `sanitizeFilename`, `matchesGlobPattern`, `belongsTo`, `hasMany`.
|
|
88
|
+
|
|
89
|
+
- A one-word helper is valid only when its meaning and arguments are unmistakable: `delay`, `clamp`, `tokenize`, `similarity`.
|
|
90
|
+
- Reject vague helpers such as `process` or `handle`.
|
|
91
|
+
- A helper prefix has one project-wide meaning: `extract*` extracts structure, `infer*` derives, `compute*` calculates deterministically, and `matches*` is a predicate.
|
|
92
|
+
- When a helper family grows around one shape, promote it to a class with entity-scoped one-word methods.
|
|
93
|
+
|
|
94
|
+
## General vocabulary
|
|
95
|
+
|
|
96
|
+
- Describe what a thing is, not its implementation.
|
|
97
|
+
- Prefer short common English; avoid jargon, abbreviations, and non-universal acronyms.
|
|
98
|
+
- One concept has one word project-wide. Do not alternate `count`/`length`/`size`/`total` or `abort`/`cancel`.
|
|
99
|
+
- Properties are nouns; methods are verbs.
|
|
100
|
+
- Booleans read as assertions: `aborted`, `exhausted`, `expired`.
|
|
101
|
+
- A binary behavior switch is a boolean, such as `bail`; never model it as `'continue' | 'halt'`.
|
|
102
|
+
- Genuine discriminants, multi-state lifecycles, conventional value pairs (`ascending`/`descending`, `and`/`or`), and external-spec literals remain unions.
|
|
103
|
+
- Absence is `undefined`, never `'none'`, `'unset'`, `'unknown'`, `''`, `-1`, or another sentinel. Use `null` only when an external protocol distinguishes it from omission.
|
|
104
|
+
- Derive facts from existing state through a getter or at the use site. Do not store a duplicate boolean/string label that can drift.
|
|
105
|
+
- Use a union only for irreducible modes, phases, discriminants, or external values.
|
|
106
|
+
- Accessors use bare nouns, never `get*`/`set*`.
|
|
107
|
+
- A discriminant names its axis (`relationship`, `command`, `category`, `operation`, `via`), never `kind` or `type`.
|
|
108
|
+
|
|
109
|
+
## Acronyms
|
|
110
|
+
|
|
111
|
+
Keep canonical case:
|
|
112
|
+
|
|
113
|
+
- Initialisms: `JSON`, `HTTP`, `NDJSON`, `SSE`, `URL`, `URI`, `SQL`, `API`, `DB`, `TTL`, `UUID`, `RFC`, `JWT`.
|
|
114
|
+
- Brands/proper names: `SQLite`, `IndexedDB`, `GitHub`, `OAuth`.
|
|
115
|
+
- PascalCase identifiers preserve the acronym: `JSONSchema`, `HTTPServer`, `NDJSONParser`, `SSEStream`, `URLPattern`, `SQLiteDriver`, `IndexedDBDriver`.
|
|
116
|
+
- camelCase lowers an acronym only when it leads: `jsonValue`, `urlPath`, `sqlText`; otherwise preserve it: `parseJSON`, `toJSON`, `fromNDJSON`, `signJWT`, `compileSQL`.
|
|
117
|
+
- Ecosystem-conventional `id` and leading `url`/`uri` remain lowercase.
|
|
118
|
+
- Domain folders remain lowercase: `http/`, `sqlite/`, `indexeddb/`, `websocket/`.
|
|
119
|
+
- Never title-fold canonical acronyms into `Json`, `Ndjson`, `Http`, `Sse`, or `Sqlite`.
|
|
120
|
+
|
|
121
|
+
## Type-level identifiers
|
|
122
|
+
|
|
123
|
+
| Kind | Required form |
|
|
124
|
+
| ------------------------- | --------------------------------------- |
|
|
125
|
+
| Behavioral interface | `{Entity}Interface` |
|
|
126
|
+
| Options/config | `{Entity}Options` |
|
|
127
|
+
| Creation input | `{Entity}Input` |
|
|
128
|
+
| Outcome/output | `{Entity}Result` |
|
|
129
|
+
| Execution context | `{Entity}Context` |
|
|
130
|
+
| Event map | `{Entity}EventMap` |
|
|
131
|
+
| Union/enum-like | `{Entity}{Noun}` |
|
|
132
|
+
| Plain non-behavioral data | `{Entity}` |
|
|
133
|
+
| Function type | `{Entity}Handler` or `{Entity}Function` |
|
|
134
|
+
| Manager interface | `{Entity}ManagerInterface` |
|
|
135
|
+
|
|
136
|
+
- Never prefix interfaces with `I`.
|
|
137
|
+
- Never pluralize type names.
|
|
138
|
+
- `Handler` is for function types, never classes.
|
|
139
|
+
|
|
140
|
+
## Value-level identifiers
|
|
141
|
+
|
|
142
|
+
| Kind | Required form |
|
|
143
|
+
| -------------- | ------------------------------------- |
|
|
144
|
+
| Class | PascalCase `{Entity}` |
|
|
145
|
+
| Manager class | PascalCase `{Entity}Manager` |
|
|
146
|
+
| Factory | camelCase `create{Entity}` |
|
|
147
|
+
| Guard | camelCase `is{Condition}` |
|
|
148
|
+
| Helper | camelCase `{verb}{Noun}` |
|
|
149
|
+
| Constant | UPPER_SNAKE_CASE `{QUALIFIER}_{NOUN}` |
|
|
150
|
+
| Property/field | camelCase bare noun |
|
|
151
|
+
| Method | camelCase bare verb |
|
|
152
|
+
| Boolean | camelCase adjective/past participle |
|
|
153
|
+
|
|
154
|
+
## Fixed derivation/construction forms
|
|
155
|
+
|
|
156
|
+
- `is*`: total `Guard<T>`; never throws; returns false off-shape.
|
|
157
|
+
- `parse*`: coercion producing `T | undefined`; cross-type conversion never belongs in a guard.
|
|
158
|
+
- `create*`: factory constructing an entity/value.
|
|
159
|
+
- `*Of`: builder combining constituent parts into a container/guard/value, such as `arrayOf(guard)` or `boundsOf(min, max)`.
|
|
160
|
+
- `{noun}To{Noun}`: projection from a whole to a derived view, such as `definitionToSnapshot`.
|
|
161
|
+
- `*Shape`: `ContractShape` value/JSON-Schema blueprint, not a function or type.
|
|
162
|
+
- Leading `_`: intentionally unused binding only; never privacy.
|
|
163
|
+
|
|
164
|
+
For `_` bindings:
|
|
165
|
+
|
|
166
|
+
- Use only for genuine callback/signature conformance, rest omission, swallowed catches, or intentionally unused loop variables.
|
|
167
|
+
- Verify each use is intentional; remove `_` and wire the value if it should be consumed.
|
|
168
|
+
- Remove the parameter when signature compatibility does not require it.
|
|
169
|
+
- Prefer a short justification for each rare `_` in `src/`.
|
|
170
|
+
|
|
171
|
+
## Tallies
|
|
172
|
+
|
|
173
|
+
- A lone unambiguous tally is `count`.
|
|
174
|
+
- When several distinct tallies coexist, name each fact: a pool may expose `size`, `idle`, and `active`; a queue may expose `count` and `active`.
|
|
175
|
+
- Do not expose several ambiguous `count` properties.
|
|
176
|
+
|
|
177
|
+
## Files and folders
|
|
178
|
+
|
|
179
|
+
| Kind | Pattern |
|
|
180
|
+
| -------------- | -------------------------------------------- |
|
|
181
|
+
| Domain folder | lowercase plural entity: `agents/`, `tools/` |
|
|
182
|
+
| Implementation | PascalCase entity: `Agent.ts` |
|
|
183
|
+
| Test | PascalCase entity + `.test`: `Agent.test.ts` |
|
|
184
|
+
| Guide | lowercase domain: `agents.md` |
|
|
185
|
+
|
|
186
|
+
## Fixed lifecycle vocabulary
|
|
187
|
+
|
|
188
|
+
| Verb | Exact meaning |
|
|
189
|
+
| --------- | ----------------------------------------- |
|
|
190
|
+
| `start` | Begin or restart |
|
|
191
|
+
| `stop` | End permanently |
|
|
192
|
+
| `pause` | Suspend resumably |
|
|
193
|
+
| `resume` | Continue after pause |
|
|
194
|
+
| `skip` | Mark intentionally unexecuted |
|
|
195
|
+
| `abort` | Cancel with signal propagation |
|
|
196
|
+
| `clear` | Reset state without destroying the entity |
|
|
197
|
+
| `destroy` | Tear down and release resources |
|
|
198
|
+
| `execute` | Run primary work to completion |
|
|
199
|
+
|
|
200
|
+
Never introduce synonyms such as `cancel`, `reset`, or `run` for these meanings.
|
|
201
|
+
|
|
202
|
+
## Rejected naming
|
|
203
|
+
|
|
204
|
+
- Generic words: `data`, `info`, `item`, `thing`, `obj`.
|
|
205
|
+
- Type-encoded names: `nameString`, `countNumber`.
|
|
206
|
+
- Abbreviations: `cfg`, `doc`, `msg`; write `config`, `document`, `message`.
|
|
207
|
+
- `@internal` methods; use `#` privacy.
|
|
208
|
+
- Compound entity members where grouping/extraction/splitting provides the context.
|
|
209
|
+
- Behavior-selecting magic strings.
|