@orkestrel/scaffold 0.0.39 → 0.0.41
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/dist/bin/main.js +8 -1
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +2 -2
- package/dist/host/agents/orchestration.md +33 -2
- package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +16 -16
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +3 -3
- package/dist/host/agents/skills/orkestrel-align-packages/references/integration.md +1 -1
- package/dist/host/agents/skills/orkestrel-build-application/SKILL.md +7 -2
- package/dist/host/claude/agents/builder.md +2 -2
- package/dist/host/claude/agents/orkestrel.md +48 -48
- package/dist/host/claude/rules/application.md +6 -4
- package/dist/host/claude/rules/architecture.md +2 -0
- package/dist/host/claude/rules/documentation.md +6 -0
- package/dist/host/claude/rules/tests.md +11 -1
- package/dist/host/claude/rules/typescript.md +15 -1
- package/dist/host/claude/rules/workspace.md +43 -13
- package/dist/host/claude/rules/writing.md +125 -0
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +10 -1
- package/dist/host/claude/skills/orkestrel-align-packages/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-build-application/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-harden-package/SKILL.md +1 -1
- package/dist/host/configs/policy.ts +185 -0
- package/dist/host/dotfiles/oxlintrc.json +13 -1
- package/dist/host/dotfiles/prettierignore +3 -0
- package/dist/host/guides/scaffold.md +13 -7
- package/dist/host/manifest.json +11 -7
- package/dist/host/tests/config.test.ts +195 -4
- package/dist/host/tests/policy.test.ts +82 -0
- package/dist/host/tests/setupPolicy.ts +863 -21
- package/dist/src/core/index.cjs +68 -6
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +11 -9
- package/dist/src/core/index.d.ts +11 -9
- package/dist/src/core/index.js +68 -6
- package/dist/src/core/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/host/agents/skills/orkestrel-build-application/references/application.md +0 -129
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Developer-facing writing rules
|
|
2
|
+
|
|
3
|
+
These rules govern prose a developer reads, including chat replies, reports, guides, README files,
|
|
4
|
+
and commit messages.
|
|
5
|
+
`AGENTS.md` § Writing governs prose everywhere, and this file does not restate it; this file adds
|
|
6
|
+
only what a developer audience decides. An instruction file follows `AGENTS.md` § Instruction files
|
|
7
|
+
first, and these rules wherever a rule here names no different form for it.
|
|
8
|
+
|
|
9
|
+
## Voice and actor
|
|
10
|
+
|
|
11
|
+
- Write `must` for a requirement, `can` for an option or an ability, and `might` for a possibility.
|
|
12
|
+
A recommendation takes the imperative, the same form `AGENTS.md` § Writing fixes for instructions.
|
|
13
|
+
Never write `should`, and never soften a recommendation into `We recommend`.
|
|
14
|
+
- Address the developer as `you`. Name the software component that acts, and make it the subject of
|
|
15
|
+
the sentence. Reserve `user` for someone using software the developer builds. Never write `we`,
|
|
16
|
+
`our`, or `let's` about agent work.
|
|
17
|
+
- Give software no human faculties. A component reports, returns, detects, or refuses; it never
|
|
18
|
+
knows, thinks, wants, or sees.
|
|
19
|
+
- Use the passive voice only where naming the actor adds blame and nothing else, such as a defect
|
|
20
|
+
count. Name the actor wherever the reader needs it.
|
|
21
|
+
- Use negative contractions (`don't`, `isn't`, `can't`) in a reply or a guide. Do not use them in an
|
|
22
|
+
instruction file.
|
|
23
|
+
|
|
24
|
+
## Sentence and paragraph order
|
|
25
|
+
|
|
26
|
+
- Put the condition, the goal, or the location before the instruction, so a reader the instruction
|
|
27
|
+
does not apply to stops at the first clause. Put the result or the reason after it. This governs a
|
|
28
|
+
sentence, not a document: a report still opens with its finding.
|
|
29
|
+
- Put the key point in the first sentence of every paragraph and every list item, not only in the
|
|
30
|
+
opening of the reply or the section.
|
|
31
|
+
- Keep the helper words `that`, `then`, `of`, `a`, and `the`. Do not drop one for brevity.
|
|
32
|
+
- Name the noun after `this`, `these`, or `it` wherever the reader could attach the pronoun to
|
|
33
|
+
another referent.
|
|
34
|
+
- State what the reader can do. Do not write a double negative.
|
|
35
|
+
|
|
36
|
+
## Claims and time
|
|
37
|
+
|
|
38
|
+
- Claim only what the reader can check. Never write `ensure`, `guarantee`, a superlative, or an
|
|
39
|
+
effort adjective as a claim about behavior, and cite the run behind every number. `ensure`
|
|
40
|
+
addressed to an executor as a directive is outside this ban.
|
|
41
|
+
- Write the present tense for what exists. Do not write `currently`, `now`, `new`, `latest`, or
|
|
42
|
+
`soon`; where time matters, give the version or the date.
|
|
43
|
+
- Recommend one path, the shortest one you proved. Rule on every option you list, and drop an option
|
|
44
|
+
equivalent to the one you recommend.
|
|
45
|
+
|
|
46
|
+
## Code tokens, references, and links
|
|
47
|
+
|
|
48
|
+
- Put a code token in backticks and follow it with a noun: the `parse` method, the `vite.config.ts`
|
|
49
|
+
file, the `--check` flag. Never inflect, pluralize, or possessivize a code token, and never use one
|
|
50
|
+
as an English verb.
|
|
51
|
+
- Point to other material with `preceding`, `following`, `earlier`, or `later`, never with `above` or
|
|
52
|
+
`below`. Use `earlier` and `later` for a version range too.
|
|
53
|
+
- Write link text as the destination's title or a descriptive phrase, introduced by `see`. Never
|
|
54
|
+
write `here`, `this document`, or a bare URL in prose.
|
|
55
|
+
- Paraphrase third-party content and link its source; never paste it into prose you author. A
|
|
56
|
+
vendored mirror is fetched bytes rather than authored prose, and `.claude/rules/documentation.md`
|
|
57
|
+
governs it.
|
|
58
|
+
|
|
59
|
+
## Structure
|
|
60
|
+
|
|
61
|
+
- Keep a required fact in the main flow. A note or a notice carries only what the reader can skip,
|
|
62
|
+
never a prerequisite, a step, or a warning the task depends on.
|
|
63
|
+
- In a reply or a guide, introduce every list, table, and code fence with a complete sentence naming
|
|
64
|
+
what follows; a rule file's list sits bare under its heading. Number a list only where order or
|
|
65
|
+
rank matters. Use a table only for rows with comparable fields.
|
|
66
|
+
- Write a heading in sentence case, verb first for a task and a noun phrase for a concept. Identity
|
|
67
|
+
numbering — a claim, an audit verdict, a plan unit — is data rather than a heading style, and
|
|
68
|
+
stays.
|
|
69
|
+
|
|
70
|
+
## Examples, numbers, and abbreviations
|
|
71
|
+
|
|
72
|
+
- Build an example from fictional data with descriptive names and no personally identifiable
|
|
73
|
+
information. Write a placeholder in `UPPER_SNAKE_CASE` and explain it on first use. Never write
|
|
74
|
+
`foo`, `bar`, or `baz`.
|
|
75
|
+
- Expand an abbreviation the reader may not know on first use, with the short form in parentheses.
|
|
76
|
+
Skip the expansion for one this audience reads daily, such as `API`, `CLI`, `JSON`, `URL`, or a
|
|
77
|
+
file format.
|
|
78
|
+
- Write a numeral for a technical quantity, a version, or a count. Write a date as `YYYY-MM-DD` in
|
|
79
|
+
evidence, commit messages, and reports.
|
|
80
|
+
- Use the serial comma. Mark omitted code with a comment in the sample's language, never with `...`.
|
|
81
|
+
|
|
82
|
+
## Substitutions
|
|
83
|
+
|
|
84
|
+
Replace each term in this table with its replacement. Quote a literal code identifier as itself; it
|
|
85
|
+
is exempt from every row.
|
|
86
|
+
|
|
87
|
+
| Term | Replacement |
|
|
88
|
+
| ------------------------ | ----------------------------------------- |
|
|
89
|
+
| `should` | `must`, `can`, `might`, or the imperative |
|
|
90
|
+
| `simply`, `easy`, `just` | Delete |
|
|
91
|
+
| `currently`, `now` | Delete, or give the date |
|
|
92
|
+
| `new`, `latest` | Delete, or give the version |
|
|
93
|
+
| `utilize`, `leverage` | `use` |
|
|
94
|
+
| `via` | `through`, `by using` |
|
|
95
|
+
| `in order to` | `to` |
|
|
96
|
+
| `e.g.`, `i.e.` | `for example`, `that is` |
|
|
97
|
+
| `etc.` | Bound the list, or recast the sentence |
|
|
98
|
+
| `performant`, `robust` | The measured property |
|
|
99
|
+
| `allows you to` | `lets you` |
|
|
100
|
+
| `and/or` | `and`, `or`, or `both` |
|
|
101
|
+
| `since` (causal) | `because` |
|
|
102
|
+
| `once` (temporal) | `after` |
|
|
103
|
+
| `please` | Delete |
|
|
104
|
+
| `sanity check` | `quick check` |
|
|
105
|
+
| `dummy` | `placeholder` |
|
|
106
|
+
| `blacklist`, `whitelist` | `denylist`, `allowlist` |
|
|
107
|
+
| `master`, `slave` | `primary`, `replica` |
|
|
108
|
+
|
|
109
|
+
- Write singular `they` for a person of unstated gender.
|
|
110
|
+
- This table carries no row for `execute`, `abort`, `kill`, `terminate`, or `run`:
|
|
111
|
+
`.claude/rules/names.md` § Fixed lifecycle vocabulary owns those words, and no row here overrides
|
|
112
|
+
it.
|
|
113
|
+
|
|
114
|
+
## Not adopted
|
|
115
|
+
|
|
116
|
+
- Do not add conversational personality, warmth, or memorability to a reply; the prose stays plain.
|
|
117
|
+
- Do not import a license to break these rules where a departure reads better; an exception exists
|
|
118
|
+
only where a rule states it.
|
|
119
|
+
- `We recommend` as a recommendation form — refused in § Voice and actor.
|
|
120
|
+
- Do not apply a source guide's sample indentation or line-length chrome; the repository formatter
|
|
121
|
+
and `.claude/rules/typescript.md` decide code presentation.
|
|
122
|
+
- Do not write an unspaced em dash; this project spaces it.
|
|
123
|
+
- Do not cap a sentence at a word count; `AGENTS.md` § Writing owns sentence length.
|
|
124
|
+
- Do not treat an external word list as vocabulary law; the preceding substitution table is the
|
|
125
|
+
adopted set.
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: enterprise-bootstrap
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Design and build distinctive, production-grade user interfaces with Bootstrap
|
|
5
|
+
5.3 and intentional frontend craft. Use for ANY UI work — creating, restyling,
|
|
6
|
+
reviewing, or extending pages, screens, components, layouts, app shells,
|
|
7
|
+
dashboards, admin panels, SaaS tools, data tables, filter bars, forms,
|
|
8
|
+
wizards, navigation, modals, empty/loading/error states, dark mode, marketing
|
|
9
|
+
surfaces — whenever the task touches HTML/CSS/visual design, mentions
|
|
10
|
+
Bootstrap or its components, or must look professional and avoid templated
|
|
11
|
+
defaults. Covers aesthetics, typography, color modes, design tokens,
|
|
12
|
+
accessibility (WCAG 2.2 AA), responsive layout, and enterprise app patterns.
|
|
4
13
|
---
|
|
5
14
|
|
|
6
15
|
# Load the canonical workflow
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: orkestrel-align-packages
|
|
3
|
-
description: Audit and improve how
|
|
3
|
+
description: Audit and improve how two or more Orkestrel packages, or their core, server, browser, and app environments, fit together. Use for coordinated package-stack refactors, cross-package extraction, developer-ergonomics reviews, end-to-end or live integration testing, dependency and guide alignment, and fleet/package-manager campaigns. Preserve host-independent core boundaries, update dependents topologically, and use the package-hardening workflow for each implementation unit.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Load the canonical workflow
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: orkestrel-build-application
|
|
3
|
-
description: Design, scaffold, extend, or harden Orkestrel app
|
|
3
|
+
description: Design, scaffold, extend, or harden Orkestrel `app/core`, `app/browser`, and `app/server` environments. Use for app-only or mixed src/app workspaces, app environment isolation, Vue browser entries, Node server entries, app aliases/configs/scripts/tests, cross-environment contracts, and application guide parity.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Load the canonical workflow
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: orkestrel-harden-package
|
|
3
|
-
description: Research, audit, refactor, implement, centralize, test, document, and locally verify an individual Orkestrel TypeScript package to enterprise-grade production readiness. Use
|
|
3
|
+
description: Research, audit, refactor, implement, centralize, test, document, and locally verify an individual Orkestrel TypeScript package to enterprise-grade production readiness under the repository's current AGENTS.md. Use when asked to fill missing or deferred capabilities, compare upstream or legacy implementations, salvage prior art, centralize source or test declarations, eliminate nested functions or superfluous wrappers, maximize declared @orkestrel dependencies—especially @orkestrel/contract—or add rigorous real-implementation and live-service tests. Select only the phases required by a narrow request; run the full workflow for production readiness or comprehensive hardening.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Load the canonical workflow
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** The expression fields inspected by the policy rules. */
|
|
2
|
+
export interface PolicyExpression {
|
|
3
|
+
readonly type: string
|
|
4
|
+
readonly range: [number, number]
|
|
5
|
+
readonly name?: unknown
|
|
6
|
+
readonly value?: unknown
|
|
7
|
+
readonly object?: PolicyExpression
|
|
8
|
+
readonly property?: PolicyExpression
|
|
9
|
+
readonly computed?: boolean
|
|
10
|
+
readonly callee?: PolicyExpression
|
|
11
|
+
readonly quasis?: readonly PolicyExpression[]
|
|
12
|
+
readonly expressions?: readonly PolicyExpression[]
|
|
13
|
+
readonly accessibility?: 'private' | 'protected' | 'public' | null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** One diagnostic emitted by a policy rule. */
|
|
17
|
+
export interface PolicyDiagnostic {
|
|
18
|
+
readonly node: PolicyExpression
|
|
19
|
+
readonly messageId: string
|
|
20
|
+
readonly data?: Readonly<Record<string, string>>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The Oxlint context operations used by the policy rules. */
|
|
24
|
+
export interface PolicyContext {
|
|
25
|
+
report(diagnostic: PolicyDiagnostic): void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The rule documentation fields supplied to Oxlint. */
|
|
29
|
+
export interface PolicyDocs {
|
|
30
|
+
readonly [key: string]: unknown
|
|
31
|
+
readonly description: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The rule metadata fields supplied to Oxlint. */
|
|
35
|
+
export interface PolicyMeta {
|
|
36
|
+
readonly type: 'problem'
|
|
37
|
+
readonly docs: PolicyDocs
|
|
38
|
+
readonly messages: Readonly<Record<string, string>>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The Oxlint visitor entries used by the policy rules. */
|
|
42
|
+
export interface PolicyVisitor {
|
|
43
|
+
readonly [key: string]: ((node: PolicyExpression) => void) | undefined
|
|
44
|
+
readonly CallExpression?: (node: PolicyExpression) => void
|
|
45
|
+
readonly MethodDefinition?: (node: PolicyExpression) => void
|
|
46
|
+
readonly PropertyDefinition?: (node: PolicyExpression) => void
|
|
47
|
+
readonly AccessorProperty?: (node: PolicyExpression) => void
|
|
48
|
+
readonly TSAbstractMethodDefinition?: (node: PolicyExpression) => void
|
|
49
|
+
readonly TSAbstractPropertyDefinition?: (node: PolicyExpression) => void
|
|
50
|
+
readonly TSAbstractAccessorProperty?: (node: PolicyExpression) => void
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The complete behavior exposed by one policy rule. */
|
|
54
|
+
export interface PolicyRuleInterface {
|
|
55
|
+
readonly meta: PolicyMeta
|
|
56
|
+
create(context: PolicyContext): PolicyVisitor
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Report banned calls on the named Vitest and Jest framework objects. */
|
|
60
|
+
export function reportMocking(context: PolicyContext, node: PolicyExpression): void {
|
|
61
|
+
const callee = node.callee
|
|
62
|
+
if (
|
|
63
|
+
callee === undefined ||
|
|
64
|
+
callee.type !== 'MemberExpression' ||
|
|
65
|
+
callee.object === undefined ||
|
|
66
|
+
callee.property === undefined ||
|
|
67
|
+
callee.computed === undefined
|
|
68
|
+
) {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const object = callee.object
|
|
73
|
+
if (object.type !== 'Identifier' || (object.name !== 'vi' && object.name !== 'jest')) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const property = callee.property
|
|
78
|
+
let member: string | undefined
|
|
79
|
+
if (callee.computed) {
|
|
80
|
+
if (property.type === 'Literal' && typeof property.value === 'string') {
|
|
81
|
+
member = property.value
|
|
82
|
+
} else if (
|
|
83
|
+
property.type === 'TemplateLiteral' &&
|
|
84
|
+
property.quasis?.length === 1 &&
|
|
85
|
+
property.expressions?.length === 0
|
|
86
|
+
) {
|
|
87
|
+
const quasi = property.quasis[0]
|
|
88
|
+
const value = quasi?.value
|
|
89
|
+
if (typeof value === 'object' && value !== null) {
|
|
90
|
+
const cooked: unknown = Object.getOwnPropertyDescriptor(value, 'cooked')?.value
|
|
91
|
+
const raw: unknown = Object.getOwnPropertyDescriptor(value, 'raw')?.value
|
|
92
|
+
member = typeof cooked === 'string' ? cooked : typeof raw === 'string' ? raw : undefined
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} else if (property.type === 'Identifier' && typeof property.name === 'string') {
|
|
96
|
+
member = property.name
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
switch (member) {
|
|
100
|
+
case 'mock':
|
|
101
|
+
case 'doMock':
|
|
102
|
+
case 'unstable_mockModule':
|
|
103
|
+
context.report({ node, messageId: 'mock' })
|
|
104
|
+
break
|
|
105
|
+
case 'fn':
|
|
106
|
+
case 'spyOn':
|
|
107
|
+
context.report({ node, messageId: 'spy' })
|
|
108
|
+
break
|
|
109
|
+
case 'useFakeTimers':
|
|
110
|
+
case 'setSystemTime':
|
|
111
|
+
context.report({ node, messageId: 'clock' })
|
|
112
|
+
break
|
|
113
|
+
case 'stubGlobal':
|
|
114
|
+
case 'stubEnv':
|
|
115
|
+
context.report({ node, messageId: 'stub' })
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Report TypeScript privacy keywords on class members. */
|
|
121
|
+
export function reportPrivacy(context: PolicyContext, node: PolicyExpression): void {
|
|
122
|
+
if (node.accessibility === 'private' || node.accessibility === 'protected') {
|
|
123
|
+
context.report({
|
|
124
|
+
node,
|
|
125
|
+
messageId: 'keyword',
|
|
126
|
+
data: { keyword: node.accessibility },
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Ban framework mocking, spying, fake clocks, and global or environment stubs. */
|
|
132
|
+
export const MOCKING_RULE: PolicyRuleInterface = {
|
|
133
|
+
meta: {
|
|
134
|
+
type: 'problem',
|
|
135
|
+
docs: {
|
|
136
|
+
description:
|
|
137
|
+
'Disallow named vi and jest mocking APIs; a renamed import alias escapes this name-based rule.',
|
|
138
|
+
},
|
|
139
|
+
messages: {
|
|
140
|
+
mock: 'Replace module mocking with a real injected collaborator; a missing seam is a missing injection point, not an untestable truth.',
|
|
141
|
+
spy: 'Use createRecorder from @orkestrel/test; framework spies and mock functions are banned.',
|
|
142
|
+
clock:
|
|
143
|
+
'Use real short timers and waitForDelay from @orkestrel/test; never replace the host clock.',
|
|
144
|
+
stub: 'Drive the real implementation or a protocol-faithful fixture; never stub globals or environment.',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
create(context) {
|
|
148
|
+
return {
|
|
149
|
+
CallExpression: (node) => reportMocking(context, node),
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Ban compile-time-only TypeScript privacy keywords on class members. */
|
|
155
|
+
export const PRIVACY_RULE: PolicyRuleInterface = {
|
|
156
|
+
meta: {
|
|
157
|
+
type: 'problem',
|
|
158
|
+
docs: {
|
|
159
|
+
description:
|
|
160
|
+
'Disallow private and protected class members in favor of runtime-enforced # privacy.',
|
|
161
|
+
},
|
|
162
|
+
messages: {
|
|
163
|
+
keyword: 'Use runtime-enforced # privacy; TypeScript {{keyword}} is compile-time-only.',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
create(context) {
|
|
167
|
+
return {
|
|
168
|
+
MethodDefinition: (node) => reportPrivacy(context, node),
|
|
169
|
+
PropertyDefinition: (node) => reportPrivacy(context, node),
|
|
170
|
+
AccessorProperty: (node) => reportPrivacy(context, node),
|
|
171
|
+
TSAbstractMethodDefinition: (node) => reportPrivacy(context, node),
|
|
172
|
+
TSAbstractPropertyDefinition: (node) => reportPrivacy(context, node),
|
|
173
|
+
TSAbstractAccessorProperty: (node) => reportPrivacy(context, node),
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** The workspace Oxlint plugin. */
|
|
179
|
+
export default {
|
|
180
|
+
meta: { name: 'policy' },
|
|
181
|
+
rules: {
|
|
182
|
+
'no-mocking': MOCKING_RULE,
|
|
183
|
+
'no-keyword-privacy': PRIVACY_RULE,
|
|
184
|
+
},
|
|
185
|
+
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
|
|
3
3
|
"plugins": ["import", "typescript", "vitest"],
|
|
4
|
+
"jsPlugins": [{ "name": "policy", "specifier": "./configs/policy.ts" }],
|
|
4
5
|
"rules": {
|
|
5
6
|
"@typescript-eslint/no-explicit-any": "error",
|
|
6
7
|
"@typescript-eslint/no-non-null-assertion": "error",
|
|
7
8
|
"typescript/consistent-type-assertions": ["error", { "assertionStyle": "never" }],
|
|
8
9
|
"typescript/no-require-imports": "error",
|
|
9
10
|
"typescript/array-type": ["error", { "default": "array-simple" }],
|
|
11
|
+
"typescript/parameter-properties": "error",
|
|
12
|
+
"typescript/explicit-member-accessibility": ["error", { "accessibility": "no-public" }],
|
|
10
13
|
"typescript/ban-ts-comment": [
|
|
11
14
|
"error",
|
|
12
15
|
{
|
|
@@ -50,7 +53,10 @@
|
|
|
50
53
|
"no-underscore-dangle": "warn",
|
|
51
54
|
|
|
52
55
|
"vitest/no-alias-methods": "error",
|
|
53
|
-
"vitest/warn-todo": "off"
|
|
56
|
+
"vitest/warn-todo": "off",
|
|
57
|
+
|
|
58
|
+
"policy/no-mocking": "error",
|
|
59
|
+
"policy/no-keyword-privacy": "error"
|
|
54
60
|
},
|
|
55
61
|
"categories": {
|
|
56
62
|
"correctness": "error",
|
|
@@ -67,6 +73,12 @@
|
|
|
67
73
|
"import/no-default-export": "off"
|
|
68
74
|
}
|
|
69
75
|
},
|
|
76
|
+
{
|
|
77
|
+
"files": ["configs/policy.ts"],
|
|
78
|
+
"rules": {
|
|
79
|
+
"import/no-default-export": "off"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
70
82
|
{
|
|
71
83
|
"files": ["*.vue"],
|
|
72
84
|
"rules": {
|
|
@@ -465,7 +465,8 @@ the registry, so `new` fails when the registry names no release for a package it
|
|
|
465
465
|
workspace would otherwise declare a dependency that does not resolve.
|
|
466
466
|
|
|
467
467
|
`new --bin` creates the executable entry, its test, and its scoped Vite and TypeScript wrappers. The
|
|
468
|
-
other structural facts do not need creation flags. Add `tests/
|
|
468
|
+
other structural facts do not need creation flags. Add a root `tests/setup*.test.ts` proof for
|
|
469
|
+
`setup`, `tests/guides.test.ts` for `guides`,
|
|
469
470
|
`tests/distribution.test.ts` for `distribution`, `tests/integration.test.ts` for `integration`,
|
|
470
471
|
`tests/conformance.test.ts` for `conformance`, `tests/setupService.ts` for `service`,
|
|
471
472
|
`tests/setupGlobal.ts` for `global`, and `configs/app/vite.showcase.config.ts` for `showcase`;
|
|
@@ -478,8 +479,9 @@ vendor list from edited text.
|
|
|
478
479
|
`audit`, `repair`, `catalog`, and `overwrite` derive the blueprint from the target itself. The name
|
|
479
480
|
and the declared `@orkestrel/*` packages come from `package.json`. The two environment axes come
|
|
480
481
|
from the directories the target actually ships, because a directory is the fact and a declaration
|
|
481
|
-
beside it could disagree.
|
|
482
|
-
`bin`, `tests/
|
|
482
|
+
beside it could disagree. Nine more facts come from exact-case files: `src/bin/main.ts` selects
|
|
483
|
+
`bin`, each root `tests/setup*.test.ts` match selects `setup`, `tests/guides.test.ts` selects
|
|
484
|
+
`guides`, `tests/distribution.test.ts` selects `distribution`,
|
|
483
485
|
`tests/integration.test.ts` selects `integration`, `tests/conformance.test.ts` selects
|
|
484
486
|
`conformance`, `tests/setupService.ts` selects `service`, `tests/setupGlobal.ts` selects `global`,
|
|
485
487
|
and `configs/app/vite.showcase.config.ts` selects `showcase`. A containing directory does not select
|
|
@@ -596,10 +598,14 @@ because the shape is chosen once and read afterwards: `new` refuses the advisory
|
|
|
596
598
|
`repair` need the plan to describe and restore a target that already has that shape. A library
|
|
597
599
|
caller creating a workspace holds the same refusal, and the Compile section below states it.
|
|
598
600
|
|
|
599
|
-
`bin`, `guides`, `distribution`, `integration`, `conformance`, `service`, `vendors`,
|
|
600
|
-
`showcase` are structural facts. Each is set only when the workspace physically ships
|
|
601
|
-
or exact-case file that defines it, never because of the workspace's name and never
|
|
602
|
-
sibling fact is set.
|
|
601
|
+
`bin`, `setup`, `guides`, `distribution`, `integration`, `conformance`, `service`, `vendors`,
|
|
602
|
+
`global`, and `showcase` are structural facts. Each is set only when the workspace physically ships
|
|
603
|
+
the directory or exact-case file that defines it, never because of the workspace's name and never
|
|
604
|
+
because a sibling fact is set.
|
|
605
|
+
|
|
606
|
+
`setup` registers every root `tests/setup*.test.ts` proof in one Node project that loads
|
|
607
|
+
`tests/setup.ts`. A nested or wrong-case match does not set the fact. The generated manifest emits
|
|
608
|
+
`test:setup` and invokes it from `test` only while the fact is set.
|
|
603
609
|
|
|
604
610
|
A structural fact is read when a verb runs, not when the file appears. Writing
|
|
605
611
|
`tests/integration.test.ts` into a workspace sets the fact, but the root configuration on disk was
|
package/dist/host/manifest.json
CHANGED
|
@@ -80,11 +80,6 @@
|
|
|
80
80
|
"destination": ".agents/skills/orkestrel-build-application/agents/openai.yaml",
|
|
81
81
|
"executable": false
|
|
82
82
|
},
|
|
83
|
-
{
|
|
84
|
-
"storage": "agents/skills/orkestrel-build-application/references/application.md",
|
|
85
|
-
"destination": ".agents/skills/orkestrel-build-application/references/application.md",
|
|
86
|
-
"executable": false
|
|
87
|
-
},
|
|
88
83
|
{
|
|
89
84
|
"storage": "agents/skills/orkestrel-debrief/SKILL.md",
|
|
90
85
|
"destination": ".agents/skills/orkestrel-debrief/SKILL.md",
|
|
@@ -315,6 +310,11 @@
|
|
|
315
310
|
"destination": ".claude/rules/workspace.md",
|
|
316
311
|
"executable": false
|
|
317
312
|
},
|
|
313
|
+
{
|
|
314
|
+
"storage": "claude/rules/writing.md",
|
|
315
|
+
"destination": ".claude/rules/writing.md",
|
|
316
|
+
"executable": false
|
|
317
|
+
},
|
|
318
318
|
{
|
|
319
319
|
"storage": "claude/settings.json",
|
|
320
320
|
"destination": ".claude/settings.json",
|
|
@@ -440,6 +440,11 @@
|
|
|
440
440
|
"destination": "configs/helpers.ts",
|
|
441
441
|
"executable": false
|
|
442
442
|
},
|
|
443
|
+
{
|
|
444
|
+
"storage": "configs/policy.ts",
|
|
445
|
+
"destination": "configs/policy.ts",
|
|
446
|
+
"executable": false
|
|
447
|
+
},
|
|
443
448
|
{
|
|
444
449
|
"storage": "cursor/mcp.json",
|
|
445
450
|
"destination": ".cursor/mcp.json",
|
|
@@ -546,7 +551,6 @@
|
|
|
546
551
|
".agents/skills/orkestrel-align-packages/references",
|
|
547
552
|
".agents/skills/orkestrel-build-application",
|
|
548
553
|
".agents/skills/orkestrel-build-application/agents",
|
|
549
|
-
".agents/skills/orkestrel-build-application/references",
|
|
550
554
|
".agents/skills/orkestrel-debrief",
|
|
551
555
|
".agents/skills/orkestrel-debrief/agents",
|
|
552
556
|
".agents/skills/orkestrel-debrief/references",
|
|
@@ -576,5 +580,5 @@
|
|
|
576
580
|
".codex/agents",
|
|
577
581
|
".cursor/rules"
|
|
578
582
|
],
|
|
579
|
-
"digest": "
|
|
583
|
+
"digest": "cdc9d27a693c15833702e2afe0a7ef1da3f4cdec10dccfb3d5f4a6920d57acd8"
|
|
580
584
|
}
|