@orkestrel/scaffold 0.0.80 → 0.0.82
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 +167 -13
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +5 -3
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +2 -2
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +41 -38
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +5 -5
- package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/styles.md +9 -9
- package/dist/host/claude/agents/orkestrel.md +52 -52
- package/dist/host/claude/rules/application.md +20 -6
- package/dist/host/claude/rules/architecture.md +2 -2
- package/dist/host/claude/rules/browser.md +9 -0
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/styles.md +35 -12
- package/dist/host/claude/rules/tests.md +15 -10
- package/dist/host/claude/rules/workspace.md +128 -98
- package/dist/host/claude/skills/orkestrel-journey/SKILL.md +1 -1
- package/dist/host/configs/helpers.ts +157 -9
- package/dist/host/configs/policy.ts +64 -61
- package/dist/host/dotfiles/oxlintrc.json +132 -16
- package/dist/host/dotfiles/prettierignore +1 -1
- package/dist/host/guides/README.md +9 -5
- package/dist/host/guides/scaffold.md +475 -115
- package/dist/host/manifest.json +27 -27
- package/dist/host/tests/config.test.ts +996 -39
- package/dist/host/tests/policy.test.ts +11 -0
- package/dist/host/tests/setupPolicy.ts +396 -22
- package/dist/src/core/index.cjs +1263 -161
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +297 -35
- package/dist/src/core/index.d.ts +297 -35
- package/dist/src/core/index.js +1243 -162
- package/dist/src/core/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -20,6 +20,7 @@ export interface PolicyExpression extends PolicyNode {
|
|
|
20
20
|
readonly callee?: PolicyExpression
|
|
21
21
|
readonly argument?: PolicyExpression | null
|
|
22
22
|
readonly arguments?: readonly PolicyExpression[]
|
|
23
|
+
readonly elements?: ReadonlyArray<PolicyExpression | null>
|
|
23
24
|
readonly body?: PolicyExpression | readonly PolicyExpression[]
|
|
24
25
|
readonly quasis?: readonly PolicyExpression[]
|
|
25
26
|
readonly expressions?: readonly PolicyExpression[]
|
|
@@ -514,39 +515,65 @@ export function isPolicyDeclaredFunction(node: PolicyExpression): boolean {
|
|
|
514
515
|
return node.type === 'FunctionDeclaration' || node.type === 'TSDeclareFunction'
|
|
515
516
|
}
|
|
516
517
|
|
|
517
|
-
/**
|
|
518
|
-
export function isPolicyAnonymous(node: PolicyExpression): boolean {
|
|
519
|
-
return node.type === 'ArrowFunctionExpression' || node.id === null
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/** Returns the outermost parenthesized expression holding a policy function. */
|
|
518
|
+
/** Returns a policy function's position through parentheses, object values, and array elements. */
|
|
523
519
|
export function functionToPolicyPosition(node: PolicyExpression): PolicyExpression {
|
|
524
520
|
let position = node
|
|
525
|
-
while (position.parent
|
|
526
|
-
|
|
521
|
+
while (position.parent !== undefined && position.parent !== null) {
|
|
522
|
+
const parent = position.parent
|
|
523
|
+
if (parent.type === 'ParenthesizedExpression') {
|
|
524
|
+
position = parent
|
|
525
|
+
continue
|
|
526
|
+
}
|
|
527
|
+
if (
|
|
528
|
+
parent.type === 'Property' &&
|
|
529
|
+
parent.kind === 'init' &&
|
|
530
|
+
parent.method === false &&
|
|
531
|
+
parent.computed !== true &&
|
|
532
|
+
parent.value === position &&
|
|
533
|
+
parent.parent?.type === 'ObjectExpression'
|
|
534
|
+
) {
|
|
535
|
+
position = parent.parent
|
|
536
|
+
continue
|
|
537
|
+
}
|
|
538
|
+
if (parent.type === 'ArrayExpression' && parent.elements?.includes(position) === true) {
|
|
539
|
+
position = parent
|
|
540
|
+
continue
|
|
541
|
+
}
|
|
542
|
+
break
|
|
527
543
|
}
|
|
528
544
|
return position
|
|
529
545
|
}
|
|
530
546
|
|
|
531
|
-
/** Reports whether a
|
|
547
|
+
/** Reports whether a literal position is admitted as an argument, return, or arrow body. */
|
|
548
|
+
export function isPolicyPosition(position: PolicyExpression): boolean {
|
|
549
|
+
const parent = position.parent
|
|
550
|
+
return (
|
|
551
|
+
((parent?.type === 'CallExpression' || parent?.type === 'NewExpression') &&
|
|
552
|
+
parent.arguments?.includes(position) === true) ||
|
|
553
|
+
(parent?.type === 'ReturnStatement' && parent.argument === position) ||
|
|
554
|
+
(parent?.type === 'ArrowFunctionExpression' && parent.body === position)
|
|
555
|
+
)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/** Reports whether a function expression is passed as an argument through its literal position. */
|
|
532
559
|
export function isPolicyCallback(node: PolicyExpression): boolean {
|
|
533
|
-
if (
|
|
560
|
+
if (node.type !== 'ArrowFunctionExpression' && node.type !== 'FunctionExpression') return false
|
|
534
561
|
const position = functionToPolicyPosition(node)
|
|
535
562
|
const parent = position.parent
|
|
536
563
|
return (
|
|
537
564
|
(parent?.type === 'CallExpression' || parent?.type === 'NewExpression') &&
|
|
538
|
-
|
|
565
|
+
isPolicyPosition(position)
|
|
539
566
|
)
|
|
540
567
|
}
|
|
541
568
|
|
|
542
|
-
/** Reports whether a
|
|
569
|
+
/** Reports whether a function expression is returned as a result through its literal position. */
|
|
543
570
|
export function isPolicyResult(node: PolicyExpression): boolean {
|
|
544
|
-
if (
|
|
571
|
+
if (node.type !== 'ArrowFunctionExpression' && node.type !== 'FunctionExpression') return false
|
|
545
572
|
const position = functionToPolicyPosition(node)
|
|
546
573
|
const parent = position.parent
|
|
547
574
|
return (
|
|
548
|
-
(parent?.type === 'ReturnStatement'
|
|
549
|
-
(
|
|
575
|
+
(parent?.type === 'ReturnStatement' || parent?.type === 'ArrowFunctionExpression') &&
|
|
576
|
+
isPolicyPosition(position)
|
|
550
577
|
)
|
|
551
578
|
}
|
|
552
579
|
|
|
@@ -581,42 +608,6 @@ export function hasPolicyFunctionAncestor(node: PolicyExpression): boolean {
|
|
|
581
608
|
return method
|
|
582
609
|
}
|
|
583
610
|
|
|
584
|
-
/** Reports whether an arrow is the policy plugin's sanctioned visitor-table delegation. */
|
|
585
|
-
export function isPolicyVisitor(node: PolicyExpression): boolean {
|
|
586
|
-
const body = expressionToPolicyBody(node)
|
|
587
|
-
if (
|
|
588
|
-
node.type !== 'ArrowFunctionExpression' ||
|
|
589
|
-
node.expression !== true ||
|
|
590
|
-
body?.type !== 'CallExpression' ||
|
|
591
|
-
body.callee?.type !== 'Identifier' ||
|
|
592
|
-
typeof body.callee.name !== 'string' ||
|
|
593
|
-
!body.callee.name.startsWith('report')
|
|
594
|
-
) {
|
|
595
|
-
return false
|
|
596
|
-
}
|
|
597
|
-
const property = node.parent
|
|
598
|
-
const object = property?.parent
|
|
599
|
-
const returned = object?.parent
|
|
600
|
-
const block = returned?.parent
|
|
601
|
-
const create = block?.parent
|
|
602
|
-
const definition = create?.parent
|
|
603
|
-
return (
|
|
604
|
-
property?.type === 'Property' &&
|
|
605
|
-
property.method === false &&
|
|
606
|
-
property.value === node &&
|
|
607
|
-
object?.type === 'ObjectExpression' &&
|
|
608
|
-
returned?.type === 'ReturnStatement' &&
|
|
609
|
-
returned.argument === object &&
|
|
610
|
-
block?.type === 'BlockStatement' &&
|
|
611
|
-
create?.type === 'FunctionExpression' &&
|
|
612
|
-
definition?.type === 'Property' &&
|
|
613
|
-
definition.method === true &&
|
|
614
|
-
definition.value === create &&
|
|
615
|
-
definition.key?.type === 'Identifier' &&
|
|
616
|
-
definition.key.name === 'create'
|
|
617
|
-
)
|
|
618
|
-
}
|
|
619
|
-
|
|
620
611
|
/**
|
|
621
612
|
* Returns the module-scope statement that owns a policy function, or `undefined` when none does.
|
|
622
613
|
*
|
|
@@ -849,15 +840,17 @@ export function reportComments(context: PolicyContext): void {
|
|
|
849
840
|
|
|
850
841
|
/** Reports function syntax nested inside another function body. */
|
|
851
842
|
export function reportNested(context: PolicyContext, node: PolicyExpression): void {
|
|
852
|
-
if (
|
|
853
|
-
!hasPolicyFunctionAncestor(node) ||
|
|
854
|
-
isPolicyMethod(node) ||
|
|
855
|
-
isPolicyCallback(node) ||
|
|
856
|
-
isPolicyResult(node) ||
|
|
857
|
-
isPolicyVisitor(node)
|
|
858
|
-
) {
|
|
843
|
+
if (!hasPolicyFunctionAncestor(node) || isPolicyCallback(node) || isPolicyResult(node)) {
|
|
859
844
|
return
|
|
860
845
|
}
|
|
846
|
+
if (isPolicyMethod(node)) {
|
|
847
|
+
if (node.parent?.type === 'MethodDefinition') return
|
|
848
|
+
const object = node.parent?.parent
|
|
849
|
+
if (object?.type === 'ObjectExpression') {
|
|
850
|
+
const position = functionToPolicyPosition(object)
|
|
851
|
+
if (isPolicyPosition(position)) return
|
|
852
|
+
}
|
|
853
|
+
}
|
|
861
854
|
context.report({ node, messageId: 'nested' })
|
|
862
855
|
}
|
|
863
856
|
|
|
@@ -969,7 +962,16 @@ export function reportFunction(context: PolicyContext, node: PolicyExpression):
|
|
|
969
962
|
return
|
|
970
963
|
}
|
|
971
964
|
if (region.type !== 'VariableDeclaration') return
|
|
972
|
-
|
|
965
|
+
let position = node
|
|
966
|
+
while (position.parent?.type === 'ParenthesizedExpression') position = position.parent
|
|
967
|
+
// Module placement admits direct callbacks; a literal member still belongs in a function file.
|
|
968
|
+
if (
|
|
969
|
+
(node.type === 'ArrowFunctionExpression' || node.id === null) &&
|
|
970
|
+
functionToPolicyPosition(node) === position &&
|
|
971
|
+
(isPolicyCallback(node) || isPolicyResult(node))
|
|
972
|
+
) {
|
|
973
|
+
return
|
|
974
|
+
}
|
|
973
975
|
context.report({ node, messageId: 'function' })
|
|
974
976
|
}
|
|
975
977
|
|
|
@@ -1059,11 +1061,12 @@ export const NESTED_RULE: PolicyRuleInterface = {
|
|
|
1059
1061
|
meta: {
|
|
1060
1062
|
type: 'problem',
|
|
1061
1063
|
docs: {
|
|
1062
|
-
description:
|
|
1064
|
+
description:
|
|
1065
|
+
'Disallow nested functions except callbacks passed as arguments or returned as results, directly or as members of object or array literals in those positions.',
|
|
1063
1066
|
},
|
|
1064
1067
|
messages: {
|
|
1065
1068
|
nested:
|
|
1066
|
-
'Extract the function to module scope or make instance-bound work a method; only
|
|
1069
|
+
'Extract the function to module scope or make instance-bound work a method; only a callback passed as an argument or returned as the result, directly or as a member of an object or array literal in that position, may stay in a function body.',
|
|
1067
1070
|
},
|
|
1068
1071
|
},
|
|
1069
1072
|
create(context) {
|
|
@@ -132,16 +132,20 @@
|
|
|
132
132
|
"error",
|
|
133
133
|
{
|
|
134
134
|
"patterns": [
|
|
135
|
+
{
|
|
136
|
+
"regex": "^(?:@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
137
|
+
"message": "src/core must not depend on Vue extension modules"
|
|
138
|
+
},
|
|
135
139
|
{
|
|
136
140
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
137
141
|
"message": "imports must not use machine-specific absolute paths"
|
|
138
142
|
},
|
|
139
143
|
{
|
|
140
|
-
"regex": "^(
|
|
144
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
141
145
|
"message": "imports must not use non-Node URL schemes"
|
|
142
146
|
},
|
|
143
147
|
{
|
|
144
|
-
"regex": "(?:^|/)(
|
|
148
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
145
149
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
146
150
|
},
|
|
147
151
|
{
|
|
@@ -180,16 +184,20 @@
|
|
|
180
184
|
"error",
|
|
181
185
|
{
|
|
182
186
|
"patterns": [
|
|
187
|
+
{
|
|
188
|
+
"regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
189
|
+
"message": "src/browser must not depend on Vue extension modules"
|
|
190
|
+
},
|
|
183
191
|
{
|
|
184
192
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
185
193
|
"message": "imports must not use machine-specific absolute paths"
|
|
186
194
|
},
|
|
187
195
|
{
|
|
188
|
-
"regex": "^(
|
|
196
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
189
197
|
"message": "imports must not use non-Node URL schemes"
|
|
190
198
|
},
|
|
191
199
|
{
|
|
192
|
-
"regex": "(?:^|/)(
|
|
200
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
193
201
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
194
202
|
},
|
|
195
203
|
{
|
|
@@ -217,6 +225,54 @@
|
|
|
217
225
|
]
|
|
218
226
|
}
|
|
219
227
|
},
|
|
228
|
+
{
|
|
229
|
+
"files": ["src/vue/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
|
|
230
|
+
"rules": {
|
|
231
|
+
"no-restricted-imports": [
|
|
232
|
+
"error",
|
|
233
|
+
{
|
|
234
|
+
"patterns": [
|
|
235
|
+
{
|
|
236
|
+
"regex": "^(?:@src/(?:|[^/?#cbv][^/?#]*|c|c[^/?#o][^/?#]*|co|co[^/?#r][^/?#]*|cor|cor[^/?#e][^/?#]*|core[^/?#][^/?#]*|b|b[^/?#r][^/?#]*|br|br[^/?#o][^/?#]*|bro|bro[^/?#w][^/?#]*|brow|brow[^/?#s][^/?#]*|brows|brows[^/?#e][^/?#]*|browse|browse[^/?#r][^/?#]*|browser[^/?#][^/?#]*|v|v[^/?#u][^/?#]*|vu|vu[^/?#e][^/?#]*|vue[^/?#][^/?#]*)(?:[/?#]|$)|(?:\\.\\./)+(?:src/)?(?:[^/.scbv][^/.]*|s|s[^/.r][^/.]*|sr|sr[^/.c][^/.]*|src[^/.][^/.]*|c|c[^/.o][^/.]*|co|co[^/.r][^/.]*|cor|cor[^/.e][^/.]*|core[^/.][^/.]*|b|b[^/.r][^/.]*|br|br[^/.o][^/.]*|bro|bro[^/.w][^/.]*|brow|brow[^/.s][^/.]*|brows|brows[^/.e][^/.]*|browse|browse[^/.r][^/.]*|browser[^/.][^/.]*|v|v[^/.u][^/.]*|vu|vu[^/.e][^/.]*|vue[^/.][^/.]*)(?:/|$))",
|
|
237
|
+
"message": "Vue faces must not depend on sibling sheet faces"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
241
|
+
"message": "imports must not use machine-specific absolute paths"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
245
|
+
"message": "imports must not use non-Node URL schemes"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
249
|
+
"message": "internal import paths must not contain noncanonical dot segments"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"regex": "^(?:(?:\\./)+\\.\\.(?:/|$)|(?:\\.\\./)+(?:\\./)+)|//",
|
|
253
|
+
"message": "relative import paths must not contain normalized traversal segments"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"regex": "\\\\",
|
|
257
|
+
"message": "import paths must use portable forward slashes"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"regex": "^typescript(?:[/?#]|$)",
|
|
261
|
+
"message": "the in-process compiler API is not a surface the fleet uses"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"regex": "^(?:@app(?:[/?#]|$)|(?:\\.\\./)+app(?:[/?#]|$))",
|
|
265
|
+
"message": "src environments must not depend on private app modules"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"regex": "^(?:node:|(?:_(?:http_(?:agent|client|common|incoming|outgoing|server)|stream_(?:duplex|passthrough|readable|transform|wrap|writable)|tls_(?:common|wrap))|assert(?:/strict)?|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|diagnostics_channel|dns(?:/promises)?|domain|events|fs(?:/promises)?|http|http2|https|inspector(?:/promises)?|module|net|os|path(?:/(?:posix|win32))?|perf_hooks|process|punycode|querystring|readline(?:/promises)?|repl|sqlite|stream(?:/(?:consumers|promises|web))?|string_decoder|sys|timers(?:/promises)?|tls|trace_events|tty|url|util(?:/types)?|v8|vm|wasi|worker_threads|zlib)(?:[/?#]|$)|@src/server(?:[/?#]|$)|@orkestrel/[^/]+/server(?:[/?#]|$)|(?:\\.\\./)+(?:server|src/server|app/server)(?:[/?#]|$))",
|
|
269
|
+
"message": "src/vue must not depend on Node or server-only modules"
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
},
|
|
220
276
|
{
|
|
221
277
|
"files": ["src/server/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
|
|
222
278
|
"rules": {
|
|
@@ -224,16 +280,20 @@
|
|
|
224
280
|
"error",
|
|
225
281
|
{
|
|
226
282
|
"patterns": [
|
|
283
|
+
{
|
|
284
|
+
"regex": "^(?:@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
285
|
+
"message": "src/server must not depend on Vue extension modules"
|
|
286
|
+
},
|
|
227
287
|
{
|
|
228
288
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
229
289
|
"message": "imports must not use machine-specific absolute paths"
|
|
230
290
|
},
|
|
231
291
|
{
|
|
232
|
-
"regex": "^(
|
|
292
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
233
293
|
"message": "imports must not use non-Node URL schemes"
|
|
234
294
|
},
|
|
235
295
|
{
|
|
236
|
-
"regex": "(?:^|/)(
|
|
296
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
237
297
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
238
298
|
},
|
|
239
299
|
{
|
|
@@ -272,16 +332,20 @@
|
|
|
272
332
|
"error",
|
|
273
333
|
{
|
|
274
334
|
"patterns": [
|
|
335
|
+
{
|
|
336
|
+
"regex": "^(?:@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
337
|
+
"message": "app/core must not depend on Vue extension modules"
|
|
338
|
+
},
|
|
275
339
|
{
|
|
276
340
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
277
341
|
"message": "imports must not use machine-specific absolute paths"
|
|
278
342
|
},
|
|
279
343
|
{
|
|
280
|
-
"regex": "^(
|
|
344
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
281
345
|
"message": "imports must not use non-Node URL schemes"
|
|
282
346
|
},
|
|
283
347
|
{
|
|
284
|
-
"regex": "(?:^|/)(
|
|
348
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
285
349
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
286
350
|
},
|
|
287
351
|
{
|
|
@@ -316,16 +380,20 @@
|
|
|
316
380
|
"error",
|
|
317
381
|
{
|
|
318
382
|
"patterns": [
|
|
383
|
+
{
|
|
384
|
+
"regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
385
|
+
"message": "app/browser must not depend on Vue extension modules"
|
|
386
|
+
},
|
|
319
387
|
{
|
|
320
388
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
321
389
|
"message": "imports must not use machine-specific absolute paths"
|
|
322
390
|
},
|
|
323
391
|
{
|
|
324
|
-
"regex": "^(
|
|
392
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
325
393
|
"message": "imports must not use non-Node URL schemes"
|
|
326
394
|
},
|
|
327
395
|
{
|
|
328
|
-
"regex": "(?:^|/)(
|
|
396
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
329
397
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
330
398
|
},
|
|
331
399
|
{
|
|
@@ -349,6 +417,50 @@
|
|
|
349
417
|
]
|
|
350
418
|
}
|
|
351
419
|
},
|
|
420
|
+
{
|
|
421
|
+
"files": ["app/vue/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
|
|
422
|
+
"rules": {
|
|
423
|
+
"no-restricted-imports": [
|
|
424
|
+
"error",
|
|
425
|
+
{
|
|
426
|
+
"patterns": [
|
|
427
|
+
{
|
|
428
|
+
"regex": "^(?:@(?:src|app)/(?:|[^/?#cbv][^/?#]*|c|c[^/?#o][^/?#]*|co|co[^/?#r][^/?#]*|cor|cor[^/?#e][^/?#]*|core[^/?#][^/?#]*|b|b[^/?#r][^/?#]*|br|br[^/?#o][^/?#]*|bro|bro[^/?#w][^/?#]*|brow|brow[^/?#s][^/?#]*|brows|brows[^/?#e][^/?#]*|browse|browse[^/?#r][^/?#]*|browser[^/?#][^/?#]*|v|v[^/?#u][^/?#]*|vu|vu[^/?#e][^/?#]*|vue[^/?#][^/?#]*)(?:[/?#]|$)|(?:\\.\\./)+(?:src/|app/)?(?:[^/.sacbv][^/.]*|s|s[^/.r][^/.]*|sr|sr[^/.c][^/.]*|src[^/.][^/.]*|a|a[^/.p][^/.]*|ap|ap[^/.p][^/.]*|app[^/.][^/.]*|c|c[^/.o][^/.]*|co|co[^/.r][^/.]*|cor|cor[^/.e][^/.]*|core[^/.][^/.]*|b|b[^/.r][^/.]*|br|br[^/.o][^/.]*|bro|bro[^/.w][^/.]*|brow|brow[^/.s][^/.]*|brows|brows[^/.e][^/.]*|browse|browse[^/.r][^/.]*|browser[^/.][^/.]*|v|v[^/.u][^/.]*|vu|vu[^/.e][^/.]*|vue[^/.][^/.]*)(?:/|$))",
|
|
429
|
+
"message": "Vue faces must not depend on sibling sheet faces"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
433
|
+
"message": "imports must not use machine-specific absolute paths"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
437
|
+
"message": "imports must not use non-Node URL schemes"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
441
|
+
"message": "internal import paths must not contain noncanonical dot segments"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"regex": "^(?:(?:\\./)+\\.\\.(?:/|$)|(?:\\.\\./)+(?:\\./)+)|//",
|
|
445
|
+
"message": "relative import paths must not contain normalized traversal segments"
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"regex": "\\\\",
|
|
449
|
+
"message": "import paths must use portable forward slashes"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"regex": "^typescript(?:[/?#]|$)",
|
|
453
|
+
"message": "the in-process compiler API is not a surface the fleet uses"
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
"regex": "^(?:node:|(?:_(?:http_(?:agent|client|common|incoming|outgoing|server)|stream_(?:duplex|passthrough|readable|transform|wrap|writable)|tls_(?:common|wrap))|assert(?:/strict)?|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|diagnostics_channel|dns(?:/promises)?|domain|events|fs(?:/promises)?|http|http2|https|inspector(?:/promises)?|module|net|os|path(?:/(?:posix|win32))?|perf_hooks|process|punycode|querystring|readline(?:/promises)?|repl|sqlite|stream(?:/(?:consumers|promises|web))?|string_decoder|sys|timers(?:/promises)?|tls|trace_events|tty|url|util(?:/types)?|v8|vm|wasi|worker_threads|zlib)(?:[/?#]|$)|@app/server(?:[/?#]|$)|@src/server(?:[/?#]|$)|@orkestrel/[^/]+/server(?:[/?#]|$)|(?:\\.\\./)+(?:server|src/server|app/server)(?:[/?#]|$))",
|
|
457
|
+
"message": "app/vue must not depend on Node or server-only modules"
|
|
458
|
+
}
|
|
459
|
+
]
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
}
|
|
463
|
+
},
|
|
352
464
|
{
|
|
353
465
|
"files": ["app/server/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
|
|
354
466
|
"rules": {
|
|
@@ -356,16 +468,20 @@
|
|
|
356
468
|
"error",
|
|
357
469
|
{
|
|
358
470
|
"patterns": [
|
|
471
|
+
{
|
|
472
|
+
"regex": "^(?:@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
|
|
473
|
+
"message": "app/server must not depend on Vue extension modules"
|
|
474
|
+
},
|
|
359
475
|
{
|
|
360
476
|
"regex": "^(?:/|[A-Za-z]:[\\\\/])",
|
|
361
477
|
"message": "imports must not use machine-specific absolute paths"
|
|
362
478
|
},
|
|
363
479
|
{
|
|
364
|
-
"regex": "^(
|
|
480
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
365
481
|
"message": "imports must not use non-Node URL schemes"
|
|
366
482
|
},
|
|
367
483
|
{
|
|
368
|
-
"regex": "(?:^|/)(
|
|
484
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
369
485
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
370
486
|
},
|
|
371
487
|
{
|
|
@@ -405,11 +521,11 @@
|
|
|
405
521
|
"message": "imports must not use machine-specific absolute paths"
|
|
406
522
|
},
|
|
407
523
|
{
|
|
408
|
-
"regex": "^(
|
|
524
|
+
"regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
|
|
409
525
|
"message": "imports must not use non-Node URL schemes"
|
|
410
526
|
},
|
|
411
527
|
{
|
|
412
|
-
"regex": "(?:^|/)(
|
|
528
|
+
"regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
|
|
413
529
|
"message": "internal import paths must not contain noncanonical dot segments"
|
|
414
530
|
},
|
|
415
531
|
{
|
|
@@ -433,7 +549,7 @@
|
|
|
433
549
|
"message": "src/bin must not depend on private app modules"
|
|
434
550
|
},
|
|
435
551
|
{
|
|
436
|
-
"regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@src/browser(?:[/?#]|$)|@orkestrel/[^/]+/browser(?:[/?#]|$)|(?:\\.\\./)+(?:browser|src/browser|app/browser)(?:[/?#]|$))",
|
|
552
|
+
"regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@src/(?:browser|vue)(?:[/?#]|$)|@orkestrel/[^/]+/(?:browser|vue)(?:[/?#]|$)|(?:\\.\\./)+(?:browser|vue|src/(?:browser|vue)|app/browser)(?:[/?#]|$))",
|
|
437
553
|
"message": "src/bin must not depend on browser-only modules"
|
|
438
554
|
}
|
|
439
555
|
]
|
|
@@ -446,7 +562,7 @@
|
|
|
446
562
|
"tests/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}",
|
|
447
563
|
"configs/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}",
|
|
448
564
|
"scripts/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}",
|
|
449
|
-
"
|
|
565
|
+
"./*.{cjs,cts,js,mjs,mts,ts}"
|
|
450
566
|
],
|
|
451
567
|
"rules": {
|
|
452
568
|
"no-restricted-imports": [
|
|
@@ -16,15 +16,19 @@ guide mirrors, and the `WriteTransaction` those writes stage through. The `scaff
|
|
|
16
16
|
([`src/bin`](../src/bin)) publishes no barrel, so it is documented in prose and sits outside the
|
|
17
17
|
surface bijection.
|
|
18
18
|
|
|
19
|
-
The [Blueprint reference](scaffold.md#blueprint) describes the journey axis and its adopter-edited
|
|
20
|
-
`configs/app/vite.journey.config.ts` wrapper, the `SetupRuntime` list, and the `setup:browser`
|
|
21
|
-
project. The generated workspace runs journey variants and browser setup proofs through its
|
|
22
|
-
`test` chain.
|
|
23
|
-
|
|
24
19
|
That bijection is the row's contract, and [`tests/guides.test.ts`](../tests/guides.test.ts)
|
|
25
20
|
enforces it: every symbol the guide documents exists in the core barrel or the server barrel, and
|
|
26
21
|
every symbol either barrel exports is documented.
|
|
27
22
|
|
|
23
|
+
The [Blueprint reference](scaffold.md#blueprint) describes the structural facts, the
|
|
24
|
+
`SetupRuntime` list, and the `setup:browser` project. The
|
|
25
|
+
[surfaces and extensions reference](scaffold.md#surfaces-and-extensions) describes the browser
|
|
26
|
+
surface with its journey and showcase modes, the styles surface with its themes target, the `vue`
|
|
27
|
+
faces and named-sheet extensions, the creation options, their refusals, and the advisories on a
|
|
28
|
+
declared selection, the marker each fact is read from, the ownership of every path a sheet face
|
|
29
|
+
emits, the page stamp, the external resolution of each published face, the vendored proofs, the
|
|
30
|
+
root setup mirror, and the migration guard. Both sections belong to the `scaffold.md` row.
|
|
31
|
+
|
|
28
32
|
## By directory
|
|
29
33
|
|
|
30
34
|
| Directory | Guide |
|