@orkestrel/scaffold 0.0.102 → 0.0.104
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/agents/skills/orkestrel-dispatch/scripts/helpers.js +84 -1
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +21 -6
- package/dist/agents/skills/orkestrel-harden/scripts/titles.js +338 -0
- package/dist/agents/skills/orkestrel-publish/scripts/swap.js +3 -39
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +433 -47
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +2 -1
- package/dist/bin/main.js +16 -9
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/orchestration.md +3 -3
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +2 -2
- package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +1 -1
- package/dist/host/agents/skills/orkestrel-build/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +3 -3
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +10 -10
- package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +1 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +100 -1
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +27 -6
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +4 -4
- package/dist/host/agents/skills/orkestrel-falsify/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +8 -7
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +6 -6
- package/dist/host/agents/skills/orkestrel-harden/SKILL.md +6 -1
- package/dist/host/agents/skills/orkestrel-harden/references/bindings.md +1700 -0
- package/dist/host/agents/skills/orkestrel-harden/references/contract.md +2 -2
- package/dist/host/agents/skills/orkestrel-harden/references/equivalence.md +48 -0
- package/dist/host/agents/skills/orkestrel-harden/references/hardening.md +4 -2
- package/dist/host/agents/skills/orkestrel-harden/scripts/titles.ts +425 -0
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +9 -8
- package/dist/host/agents/skills/orkestrel-polish/SKILL.md +3 -3
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +1 -0
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +56 -13
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +6 -6
- package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +5 -49
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +646 -49
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +2 -1
- package/dist/host/agents/transports/codex.md +1 -1
- package/dist/host/claude/agents/orkestrel.md +54 -53
- package/dist/host/claude/agents/reviewer.md +4 -4
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/patterns.md +1 -1
- package/dist/host/claude/rules/quality.md +2 -2
- package/dist/host/claude/rules/styles.md +1 -1
- package/dist/host/claude/rules/tests.md +34 -8
- package/dist/host/claude/rules/typescript.md +29 -0
- package/dist/host/claude/rules/workspace.md +35 -28
- package/dist/host/claude/rules/writing.md +34 -26
- package/dist/host/claude/settings.json +2 -0
- package/dist/host/claude/skills/orkestrel-debrief/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-falsify/SKILL.md +1 -1
- package/dist/host/codex/agents/analyst.toml +3 -3
- package/dist/host/codex/agents/reviewer.toml +4 -4
- package/dist/host/configs/helpers.ts +4 -16
- package/dist/host/configs/policy.ts +13 -2
- package/dist/host/dotfiles/editorconfig +0 -1
- package/dist/host/dotfiles/gitattributes +0 -1
- package/dist/host/dotfiles/gitignore +0 -1
- package/dist/host/dotfiles/oxlintrc.json +25 -11
- package/dist/host/guides/agent.md +1638 -598
- package/dist/host/guides/budget.md +89 -29
- package/dist/host/guides/form.md +477 -91
- package/dist/host/guides/mcp.md +14 -2
- package/dist/host/guides/ollama.md +97 -73
- package/dist/host/guides/probe.md +1 -1
- package/dist/host/guides/scaffold.md +158 -101
- package/dist/host/guides/study.md +2635 -0
- package/dist/host/guides/table.md +225 -15
- package/dist/host/guides/terminal.md +22 -20
- package/dist/host/guides/test.md +689 -255
- package/dist/host/manifest.json +88 -64
- package/dist/host/tests/config.test.ts +189 -146
- package/dist/host/tests/policy.test.ts +39 -1
- package/dist/host/tests/setupPolicy.ts +104 -57
- package/dist/src/core/index.cjs +1387 -611
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +35 -20
- package/dist/src/core/index.d.ts +35 -20
- package/dist/src/core/index.js +1385 -612
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +12 -12
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +12 -12
- package/dist/src/server/index.d.ts +12 -12
- package/dist/src/server/index.js +12 -12
- package/dist/src/server/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -70,7 +70,7 @@ import configuration, { resolveWorkspacePath } from '../vite.config.js'
|
|
|
70
70
|
import * as rootConfiguration from '../vite.config.js'
|
|
71
71
|
import tsconfig from '../tsconfig.json' with { type: 'json' }
|
|
72
72
|
import {
|
|
73
|
-
|
|
73
|
+
COMPUTED_IMPORT_PATHS,
|
|
74
74
|
collectSheets,
|
|
75
75
|
collectStudies,
|
|
76
76
|
collectFrameworks,
|
|
@@ -323,16 +323,27 @@ describe('selected faces', () => {
|
|
|
323
323
|
}
|
|
324
324
|
const script =
|
|
325
325
|
'vite build --config configs/src/vite.styles.config.ts && vite build --config configs/src/vite.themes.config.ts'
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
inspectSheetConfiguration(
|
|
335
|
-
|
|
326
|
+
const scratch = createPolicyScratch({ prefix: 'config-sheet-setup-' })
|
|
327
|
+
const withoutStyles = {
|
|
328
|
+
test: { ...project.test, setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'] },
|
|
329
|
+
}
|
|
330
|
+
try {
|
|
331
|
+
expect(inspectSheetConfiguration(withoutStyles, script, scratch.path)).toEqual([])
|
|
332
|
+
scratch.write('tests/setupStyles.ts', 'export {}\n')
|
|
333
|
+
expect(inspectSheetConfiguration(project, script, scratch.path)).toEqual([])
|
|
334
|
+
expect(inspectSheetConfiguration(withoutStyles, script, scratch.path)).toContain(
|
|
335
|
+
'./tests/setupStyles.ts',
|
|
336
|
+
)
|
|
337
|
+
expect(
|
|
338
|
+
inspectSheetConfiguration(
|
|
339
|
+
project,
|
|
340
|
+
script.split(' && ').reverse().join(' && '),
|
|
341
|
+
scratch.path,
|
|
342
|
+
),
|
|
343
|
+
).toContain('themes order')
|
|
344
|
+
} finally {
|
|
345
|
+
scratch.destroy()
|
|
346
|
+
}
|
|
336
347
|
})
|
|
337
348
|
|
|
338
349
|
it('resolves showcase and journey modes for every occupied application', async () => {
|
|
@@ -707,19 +718,24 @@ describe('root configuration', () => {
|
|
|
707
718
|
)
|
|
708
719
|
.filter(([, path]) => existsSync(resolve(POLICY_ROOT, path)))
|
|
709
720
|
.map(([label, , include, setup]): [string, PolicyProject] => [label, { include, setup }]),
|
|
710
|
-
...['policy', 'config', 'guides', 'conformance', 'distribution', 'integration']
|
|
711
|
-
.filter((label) =>
|
|
721
|
+
...['policy', 'config', 'guides', 'conformance', 'tree', 'distribution', 'integration']
|
|
722
|
+
.filter((label) => readdirSync(resolve(POLICY_ROOT, 'tests')).includes(`${label}.test.ts`))
|
|
712
723
|
.map((label): [string, PolicyProject] => [
|
|
713
724
|
label,
|
|
714
725
|
{
|
|
715
726
|
include: `tests/${label}.test.ts`,
|
|
716
727
|
setup: [
|
|
717
728
|
'./tests/setup.ts',
|
|
718
|
-
...(label === 'conformance' ? ['./tests/setupServer.ts'] : []),
|
|
729
|
+
...(label === 'conformance' || label === 'tree' ? ['./tests/setupServer.ts'] : []),
|
|
719
730
|
...(label === 'integration' &&
|
|
720
731
|
(collectSheets(POLICY_ROOT).length > 0 ||
|
|
721
732
|
existsSync(resolve(POLICY_ROOT, 'src/styles/themes/index.scss')))
|
|
722
|
-
? [
|
|
733
|
+
? [
|
|
734
|
+
'./tests/setupBrowser.ts',
|
|
735
|
+
...(existsSync(resolve(POLICY_ROOT, 'tests/setupStyles.ts'))
|
|
736
|
+
? ['./tests/setupStyles.ts']
|
|
737
|
+
: []),
|
|
738
|
+
]
|
|
723
739
|
: []),
|
|
724
740
|
],
|
|
725
741
|
},
|
|
@@ -910,8 +926,8 @@ describe('root configuration', () => {
|
|
|
910
926
|
// before its result is read. Extra factories are ignored without validating their result shape.
|
|
911
927
|
expect(extraLoads).toStrictEqual([])
|
|
912
928
|
for (const [label, project] of expected) expect(configured.get(label)).toStrictEqual(project)
|
|
913
|
-
for (const label of ['setup', 'setup:browser']) {
|
|
914
|
-
const name = label === 'setup' ? '
|
|
929
|
+
for (const label of ['setup', 'setup:browser', 'tree']) {
|
|
930
|
+
const name = label === 'setup:browser' ? 'setupBrowser' : label
|
|
915
931
|
expect(projects.some((entry) => typeof entry === 'function' && entry.name === name)).toBe(
|
|
916
932
|
expected.has(label),
|
|
917
933
|
)
|
|
@@ -1281,6 +1297,7 @@ describe('root configuration', () => {
|
|
|
1281
1297
|
const distribution = Object.getOwnPropertyDescriptor(scripts, 'test:distribution')?.value
|
|
1282
1298
|
const integration = Object.getOwnPropertyDescriptor(scripts, 'test:integration')?.value
|
|
1283
1299
|
const conformance = Object.getOwnPropertyDescriptor(scripts, 'test:conformance')?.value
|
|
1300
|
+
const tree = Object.getOwnPropertyDescriptor(scripts, 'test:tree')?.value
|
|
1284
1301
|
const service = Object.getOwnPropertyDescriptor(scripts, 'test:service')?.value
|
|
1285
1302
|
const studies = Object.getOwnPropertyDescriptor(scripts, 'test:studies')?.value
|
|
1286
1303
|
const publish = Object.getOwnPropertyDescriptor(scripts, 'prepublishOnly')?.value
|
|
@@ -1307,6 +1324,7 @@ describe('root configuration', () => {
|
|
|
1307
1324
|
expect(registered.has('config')).toBe(true)
|
|
1308
1325
|
expect(registered.has('control')).toBe(false)
|
|
1309
1326
|
const hasConformance = registered.has('conformance')
|
|
1327
|
+
const hasTree = registered.has('tree')
|
|
1310
1328
|
const hasDistribution = registered.has('distribution')
|
|
1311
1329
|
const hasService = registered.has('service')
|
|
1312
1330
|
const hasStudies = registered.has('studies')
|
|
@@ -1349,6 +1367,13 @@ describe('root configuration', () => {
|
|
|
1349
1367
|
expect(typeof test === 'string' && test.includes('npm run test:conformance')).toBe(
|
|
1350
1368
|
hasConformance,
|
|
1351
1369
|
)
|
|
1370
|
+
expect(tree).toBe(
|
|
1371
|
+
hasTree
|
|
1372
|
+
? 'vitest run --config vite.config.ts --no-cache --reporter=dot --project tree'
|
|
1373
|
+
: undefined,
|
|
1374
|
+
)
|
|
1375
|
+
expect(typeof test === 'string' && test.includes('npm run test:tree')).toBe(hasTree)
|
|
1376
|
+
expect(typeof publish === 'string' && publish.includes('npm run test:tree')).toBe(false)
|
|
1352
1377
|
expect(service).toBe(
|
|
1353
1378
|
hasService
|
|
1354
1379
|
? 'vitest run --config vite.config.ts --no-cache --reporter=dot --project service'
|
|
@@ -2821,8 +2846,25 @@ createSomething({
|
|
|
2821
2846
|
expect(DATA_SOURCE_FILES).not.toContain('plugins.ts')
|
|
2822
2847
|
})
|
|
2823
2848
|
|
|
2824
|
-
it('
|
|
2825
|
-
const
|
|
2849
|
+
it('pins the global dynamic-require setting to esmodule false with no override touching it', () => {
|
|
2850
|
+
const configured = readConfigRecord(
|
|
2851
|
+
JSON.parse(readFileSync(resolve(POLICY_ROOT, '.oxlintrc.json'), 'utf8')),
|
|
2852
|
+
)
|
|
2853
|
+
expect(readConfigRecord(configured.rules)['import/no-dynamic-require']).toEqual([
|
|
2854
|
+
'error',
|
|
2855
|
+
{ esmodule: false },
|
|
2856
|
+
])
|
|
2857
|
+
if (!Array.isArray(configured.overrides)) throw new Error('Missing lint overrides')
|
|
2858
|
+
const touching = configured.overrides
|
|
2859
|
+
.map(readConfigRecord)
|
|
2860
|
+
.filter(
|
|
2861
|
+
(override) => readConfigRecord(override.rules)['import/no-dynamic-require'] !== undefined,
|
|
2862
|
+
)
|
|
2863
|
+
expect(touching).toEqual([])
|
|
2864
|
+
})
|
|
2865
|
+
|
|
2866
|
+
it('permits a computed import() and refuses a computed require at every module path', () => {
|
|
2867
|
+
const fixture = createPolicyScratch({ prefix: 'computed-imports-' })
|
|
2826
2868
|
try {
|
|
2827
2869
|
fixture.write(
|
|
2828
2870
|
'configs/policy.ts',
|
|
@@ -2831,64 +2873,50 @@ createSomething({
|
|
|
2831
2873
|
const configured = readConfigRecord(
|
|
2832
2874
|
JSON.parse(readFileSync(resolve(POLICY_ROOT, '.oxlintrc.json'), 'utf8')),
|
|
2833
2875
|
)
|
|
2876
|
+
const required = COMPUTED_IMPORT_PATHS.map((path) => path.replace(/\.(\w+)$/u, '.require.$1'))
|
|
2877
|
+
for (const path of COMPUTED_IMPORT_PATHS) {
|
|
2878
|
+
fixture.write(path, 'const selected = process.argv[2]\nvoid import(selected)\ndebugger\n')
|
|
2879
|
+
}
|
|
2880
|
+
for (const path of required) {
|
|
2881
|
+
fixture.write(path, 'const selected = process.argv[2]\nvoid require(selected)\ndebugger\n')
|
|
2882
|
+
}
|
|
2883
|
+
const paths = [...COMPUTED_IMPORT_PATHS, ...required]
|
|
2834
2884
|
// Include campaign fixtures even when the workspace's default lint walk ignores them.
|
|
2835
2885
|
fixture.write('.oxlintrc.json', JSON.stringify({ ...configured, ignorePatterns: [] }))
|
|
2836
|
-
const
|
|
2837
|
-
|
|
2838
|
-
const required = admitted ? path.replace(/\.(\w+)$/u, '.require.$1') : undefined
|
|
2839
|
-
if (required !== undefined) {
|
|
2840
|
-
fixture.write(
|
|
2841
|
-
required,
|
|
2842
|
-
'const selected = process.argv[2]\nvoid require(selected)\ndebugger\n',
|
|
2843
|
-
)
|
|
2844
|
-
}
|
|
2845
|
-
return { path, required }
|
|
2846
|
-
})
|
|
2847
|
-
const paths = written.map(({ path }) => path)
|
|
2848
|
-
const requires = written.flatMap(({ required }) => (required === undefined ? [] : [required]))
|
|
2849
|
-
const codes = readImportDiagnostics(fixture.path, [...paths, ...requires])
|
|
2850
|
-
for (const [path, admitted] of ARTIFACT_IMPORT_CASES) {
|
|
2886
|
+
const codes = readImportDiagnostics(fixture.path, paths)
|
|
2887
|
+
for (const path of COMPUTED_IMPORT_PATHS) {
|
|
2851
2888
|
expect({ path, refused: codes.has('import(no-dynamic-require) ' + path) }).toEqual({
|
|
2852
2889
|
path,
|
|
2853
|
-
refused:
|
|
2890
|
+
refused: false,
|
|
2854
2891
|
})
|
|
2855
|
-
expect(codes.has('eslint(no-debugger) ' + path)).toBe(true)
|
|
2856
2892
|
}
|
|
2857
|
-
for (const path of
|
|
2858
|
-
expect(codes.has('import(no-dynamic-require) ' + path)).
|
|
2859
|
-
|
|
2893
|
+
for (const path of required) {
|
|
2894
|
+
expect({ path, refused: codes.has('import(no-dynamic-require) ' + path) }).toEqual({
|
|
2895
|
+
path,
|
|
2896
|
+
refused: true,
|
|
2897
|
+
})
|
|
2860
2898
|
}
|
|
2899
|
+
// The sentinel proves each fixture was linted, so an unlinted path cannot read as permitted.
|
|
2900
|
+
for (const path of paths) expect(codes.has('eslint(no-debugger) ' + path)).toBe(true)
|
|
2861
2901
|
|
|
2862
|
-
|
|
2863
|
-
'error',
|
|
2864
|
-
{ esmodule: true },
|
|
2865
|
-
])
|
|
2866
|
-
if (!Array.isArray(configured.overrides)) throw new Error('Missing lint overrides')
|
|
2867
|
-
const overrides = configured.overrides.map(readConfigRecord)
|
|
2868
|
-
const artifact = overrides.filter(
|
|
2869
|
-
(override) => readConfigRecord(override.rules)['import/no-dynamic-require'] !== undefined,
|
|
2870
|
-
)
|
|
2871
|
-
expect(artifact).toEqual([
|
|
2872
|
-
{
|
|
2873
|
-
files: [
|
|
2874
|
-
'src/server/artifacts/**/*.{js,mjs,ts,mts}',
|
|
2875
|
-
'tools/artifacts/**/*.{js,mjs,ts,mts}',
|
|
2876
|
-
'.orkestrel/*/instruments/**/tools/artifacts/**/*.{js,mjs,ts,mts}',
|
|
2877
|
-
],
|
|
2878
|
-
rules: { 'import/no-dynamic-require': ['error', { esmodule: false }] },
|
|
2879
|
-
},
|
|
2880
|
-
])
|
|
2902
|
+
// The control restores the ESM setting and must refuse the same computed imports.
|
|
2881
2903
|
fixture.write(
|
|
2882
2904
|
'.oxlintrc.json',
|
|
2883
2905
|
JSON.stringify({
|
|
2884
2906
|
...configured,
|
|
2885
2907
|
ignorePatterns: [],
|
|
2886
|
-
|
|
2908
|
+
rules: {
|
|
2909
|
+
...readConfigRecord(configured.rules),
|
|
2910
|
+
'import/no-dynamic-require': ['error', { esmodule: true }],
|
|
2911
|
+
},
|
|
2887
2912
|
}),
|
|
2888
2913
|
)
|
|
2889
|
-
const
|
|
2890
|
-
for (const path of
|
|
2891
|
-
expect(
|
|
2914
|
+
const strict = readImportDiagnostics(fixture.path, paths)
|
|
2915
|
+
for (const path of paths) {
|
|
2916
|
+
expect({ path, refused: strict.has('import(no-dynamic-require) ' + path) }).toEqual({
|
|
2917
|
+
path,
|
|
2918
|
+
refused: true,
|
|
2919
|
+
})
|
|
2892
2920
|
}
|
|
2893
2921
|
} finally {
|
|
2894
2922
|
fixture.destroy()
|
|
@@ -2913,72 +2941,89 @@ createSomething({
|
|
|
2913
2941
|
const pattern = readConfigRecord(patternValue)
|
|
2914
2942
|
const message = pattern.message
|
|
2915
2943
|
if (typeof message !== 'string') throw new Error('Missing pattern message')
|
|
2916
|
-
const
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
['data:text/plain,x', true],
|
|
2920
|
-
['node:fs', false],
|
|
2921
|
-
['n:entry', true],
|
|
2922
|
-
['no:entry', true],
|
|
2923
|
-
['nod:entry', true],
|
|
2924
|
-
['nodea:entry', true],
|
|
2925
|
-
['1bad:entry', false],
|
|
2926
|
-
['./data:entry', false],
|
|
2927
|
-
]
|
|
2928
|
-
: message.includes('noncanonical dot')
|
|
2944
|
+
const alias = /@src\/(core|browser|server) alias/u.exec(message)?.[1]
|
|
2945
|
+
const listed: ReadonlyArray<readonly [string, boolean]> =
|
|
2946
|
+
alias !== undefined
|
|
2929
2947
|
? [
|
|
2930
|
-
[
|
|
2931
|
-
[
|
|
2932
|
-
[
|
|
2933
|
-
[
|
|
2934
|
-
[
|
|
2935
|
-
[
|
|
2936
|
-
[
|
|
2948
|
+
[`../${alias}/index.js`, true],
|
|
2949
|
+
[`../../${alias}/types.js`, true],
|
|
2950
|
+
[`../../src/${alias}/index.js`, true],
|
|
2951
|
+
[`../${alias}`, true],
|
|
2952
|
+
[`../${alias}/`, true],
|
|
2953
|
+
[`../${alias}?raw`, true],
|
|
2954
|
+
[`../${alias}#fragment`, true],
|
|
2955
|
+
[`@src/${alias}`, false],
|
|
2956
|
+
[`./${alias}/index.js`, false],
|
|
2957
|
+
[`../${alias}x/index.js`, false],
|
|
2958
|
+
[`../${alias}.ext/index.js`, false],
|
|
2937
2959
|
]
|
|
2938
|
-
: message.includes('
|
|
2960
|
+
: message.includes('URL schemes')
|
|
2939
2961
|
? [
|
|
2940
|
-
['
|
|
2941
|
-
['
|
|
2942
|
-
['
|
|
2943
|
-
['
|
|
2944
|
-
['
|
|
2945
|
-
['
|
|
2946
|
-
['
|
|
2947
|
-
['
|
|
2948
|
-
['
|
|
2949
|
-
['../src/print/index.js', true],
|
|
2950
|
-
['../browser?x', true],
|
|
2951
|
-
['../print.ext/index.js', false],
|
|
2952
|
-
...(Array.isArray(block.files) &&
|
|
2953
|
-
block.files.some(
|
|
2954
|
-
(file: unknown) => typeof file === 'string' && file.startsWith('app/vue/'),
|
|
2955
|
-
)
|
|
2956
|
-
? [['@app/print', true] as const]
|
|
2957
|
-
: []),
|
|
2958
|
-
]
|
|
2959
|
-
: [
|
|
2960
|
-
[
|
|
2961
|
-
message.includes('absolute paths')
|
|
2962
|
-
? '/machine/module.js'
|
|
2963
|
-
: message.includes('normalized traversal')
|
|
2964
|
-
? './../core/index.js'
|
|
2965
|
-
: message.includes('forward slashes')
|
|
2966
|
-
? '..\\core\\index.js'
|
|
2967
|
-
: message.includes('compiler API')
|
|
2968
|
-
? 'typescript'
|
|
2969
|
-
: message.includes('private app')
|
|
2970
|
-
? '@app/core'
|
|
2971
|
-
: message.includes('stylesheets')
|
|
2972
|
-
? './index.css'
|
|
2973
|
-
: message.includes('host-independent') ||
|
|
2974
|
-
message.includes('Node or server')
|
|
2975
|
-
? 'node:fs'
|
|
2976
|
-
: message.includes('Vue extension')
|
|
2977
|
-
? '@src/vue'
|
|
2978
|
-
: '@src/browser',
|
|
2979
|
-
true,
|
|
2980
|
-
],
|
|
2962
|
+
['https://host/x', true],
|
|
2963
|
+
['data:text/plain,x', true],
|
|
2964
|
+
['node:fs', false],
|
|
2965
|
+
['n:entry', true],
|
|
2966
|
+
['no:entry', true],
|
|
2967
|
+
['nod:entry', true],
|
|
2968
|
+
['nodea:entry', true],
|
|
2969
|
+
['1bad:entry', false],
|
|
2970
|
+
['./data:entry', false],
|
|
2981
2971
|
]
|
|
2972
|
+
: message.includes('noncanonical dot')
|
|
2973
|
+
? [
|
|
2974
|
+
['../core/../server/index.js', true],
|
|
2975
|
+
['../core/./index.js', true],
|
|
2976
|
+
['../core/index.js', false],
|
|
2977
|
+
['./index.js', false],
|
|
2978
|
+
['../../core/index.js', false],
|
|
2979
|
+
['.../../index.js', true],
|
|
2980
|
+
['.name/../index.js', true],
|
|
2981
|
+
]
|
|
2982
|
+
: message.includes('sibling sheet')
|
|
2983
|
+
? [
|
|
2984
|
+
['@src/print', true],
|
|
2985
|
+
['../print/index.js', true],
|
|
2986
|
+
['@src/core', false],
|
|
2987
|
+
['@src/browser', false],
|
|
2988
|
+
['@src/vue', false],
|
|
2989
|
+
['@app/core', false],
|
|
2990
|
+
['@app/browser', false],
|
|
2991
|
+
['@src/corex', true],
|
|
2992
|
+
['@src/', true],
|
|
2993
|
+
['../src/print/index.js', true],
|
|
2994
|
+
['../browser?x', true],
|
|
2995
|
+
['../print.ext/index.js', false],
|
|
2996
|
+
...(Array.isArray(block.files) &&
|
|
2997
|
+
block.files.some(
|
|
2998
|
+
(file: unknown) =>
|
|
2999
|
+
typeof file === 'string' && file.startsWith('app/vue/'),
|
|
3000
|
+
)
|
|
3001
|
+
? [['@app/print', true] as const]
|
|
3002
|
+
: []),
|
|
3003
|
+
]
|
|
3004
|
+
: [
|
|
3005
|
+
[
|
|
3006
|
+
message.includes('absolute paths')
|
|
3007
|
+
? '/machine/module.js'
|
|
3008
|
+
: message.includes('normalized traversal')
|
|
3009
|
+
? './../core/index.js'
|
|
3010
|
+
: message.includes('forward slashes')
|
|
3011
|
+
? '..\\core\\index.js'
|
|
3012
|
+
: message.includes('compiler API')
|
|
3013
|
+
? 'typescript'
|
|
3014
|
+
: message.includes('private app')
|
|
3015
|
+
? '@app/core'
|
|
3016
|
+
: message.includes('stylesheets')
|
|
3017
|
+
? './index.css'
|
|
3018
|
+
: message.includes('host-independent') ||
|
|
3019
|
+
message.includes('Node or server')
|
|
3020
|
+
? 'node:fs'
|
|
3021
|
+
: message.includes('Vue extension')
|
|
3022
|
+
? '@src/vue'
|
|
3023
|
+
: '@src/browser',
|
|
3024
|
+
true,
|
|
3025
|
+
],
|
|
3026
|
+
]
|
|
2982
3027
|
const face =
|
|
2983
3028
|
message.includes('another styles face') && typeof pattern.regex === 'string'
|
|
2984
3029
|
? /@src\/(bootstrap|tailwindcss|styles)\(/u.exec(pattern.regex)?.[1]
|
|
@@ -3132,21 +3177,34 @@ createSomething({
|
|
|
3132
3177
|
]),
|
|
3133
3178
|
]
|
|
3134
3179
|
: []),
|
|
3180
|
+
...(['src/browser', 'src/server', 'src/vue', 'src/bin'].includes(owner)
|
|
3181
|
+
? ['../core/index.js', '../../src/core/index.js']
|
|
3182
|
+
: []),
|
|
3183
|
+
...(owner === 'src/vue' ? ['../browser/index.js', '../../src/browser/index.js'] : []),
|
|
3184
|
+
...(owner === 'src/bin' ? ['../server/index.js', '../../src/server/index.js'] : []),
|
|
3135
3185
|
]
|
|
3136
3186
|
const admitted = [
|
|
3137
3187
|
...(owner.endsWith('/vue')
|
|
3138
3188
|
? [
|
|
3139
3189
|
'@src/core',
|
|
3140
3190
|
'@src/browser',
|
|
3141
|
-
'../core/index.js',
|
|
3142
|
-
'../browser/index.js',
|
|
3143
3191
|
'vue',
|
|
3144
3192
|
'@vue/runtime-core',
|
|
3145
3193
|
...(owner.startsWith('app/')
|
|
3146
|
-
? [
|
|
3194
|
+
? [
|
|
3195
|
+
'@app/core',
|
|
3196
|
+
'@app/browser',
|
|
3197
|
+
'@src/vue',
|
|
3198
|
+
'../../src/vue/index.js',
|
|
3199
|
+
'../browser/index.js',
|
|
3200
|
+
]
|
|
3147
3201
|
: []),
|
|
3148
3202
|
]
|
|
3149
3203
|
: ['@src/core']),
|
|
3204
|
+
...(['src/browser', 'src/server', 'src/vue', 'src/bin'].includes(owner)
|
|
3205
|
+
? []
|
|
3206
|
+
: ['../core/index.js']),
|
|
3207
|
+
...(owner === 'src/bin' ? ['@src/server'] : []),
|
|
3150
3208
|
...(sheet
|
|
3151
3209
|
? [
|
|
3152
3210
|
...faces
|
|
@@ -3174,7 +3232,6 @@ createSomething({
|
|
|
3174
3232
|
[
|
|
3175
3233
|
...admitted,
|
|
3176
3234
|
'./index.js',
|
|
3177
|
-
'../core/index.js',
|
|
3178
3235
|
...(owner.endsWith('/server') || owner === 'src/bin' ? ['node:fs'] : []),
|
|
3179
3236
|
],
|
|
3180
3237
|
false,
|
|
@@ -3930,36 +3987,22 @@ describe('configuration helpers', () => {
|
|
|
3930
3987
|
)
|
|
3931
3988
|
})
|
|
3932
3989
|
|
|
3933
|
-
it('admits computed
|
|
3934
|
-
for (const
|
|
3990
|
+
it('admits a computed import() through Vite at every module path while collecting literal specifiers', async () => {
|
|
3991
|
+
for (const path of [...COMPUTED_IMPORT_PATHS, '../outside/src/server/load.ts']) {
|
|
3935
3992
|
await expect(
|
|
3936
3993
|
configHelpers.environmentAssetSources(
|
|
3937
3994
|
'void import(process.argv[2])',
|
|
3938
3995
|
resolve(POLICY_ROOT, path),
|
|
3939
3996
|
),
|
|
3940
3997
|
).resolves.toEqual([])
|
|
3941
|
-
}
|
|
3942
|
-
for (const [path] of ARTIFACT_IMPORT_CASES.filter(([, admitted]) => !admitted)) {
|
|
3943
3998
|
await expect(
|
|
3944
3999
|
configHelpers.environmentAssetSources(
|
|
3945
|
-
|
|
4000
|
+
"void import('@src/browser')",
|
|
3946
4001
|
resolve(POLICY_ROOT, path),
|
|
3947
4002
|
),
|
|
3948
|
-
).
|
|
4003
|
+
).resolves.toEqual(['@src/browser'])
|
|
3949
4004
|
}
|
|
3950
|
-
await expect(
|
|
3951
|
-
configHelpers.environmentAssetSources(
|
|
3952
|
-
"void import('@src/browser')",
|
|
3953
|
-
resolve(POLICY_ROOT, 'src/server/artifacts/Artifacts.ts'),
|
|
3954
|
-
),
|
|
3955
|
-
).resolves.toEqual(['@src/browser'])
|
|
3956
4005
|
expect(configHelpers.environmentSourceError('src/server', '@src/browser')).toBeDefined()
|
|
3957
|
-
await expect(
|
|
3958
|
-
configHelpers.environmentAssetSources(
|
|
3959
|
-
'void import(process.argv[2])',
|
|
3960
|
-
resolve(POLICY_ROOT, '../outside/src/server/artifacts/Artifacts.ts'),
|
|
3961
|
-
),
|
|
3962
|
-
).rejects.toThrow('Dynamic imports must use static string values')
|
|
3963
4006
|
})
|
|
3964
4007
|
|
|
3965
4008
|
it('drives each plugin through its real Vite hooks', async () => {
|
|
@@ -88,10 +88,23 @@ describe('surface policy controls', () => {
|
|
|
88
88
|
}
|
|
89
89
|
})
|
|
90
90
|
|
|
91
|
-
it('
|
|
91
|
+
it('ignores a target catalog row the installed scaffold does not stage', () => {
|
|
92
92
|
const scratch = createPolicySurfaceFixture()
|
|
93
93
|
try {
|
|
94
94
|
scratch.write(POLICY_CATALOG_FILE, createPolicyCatalog(['other', 'sample', 'uncovered']))
|
|
95
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([])
|
|
96
|
+
} finally {
|
|
97
|
+
scratch.destroy()
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('refuses a staged catalog row absent from the installed guides', () => {
|
|
102
|
+
const scratch = createPolicySurfaceFixture()
|
|
103
|
+
try {
|
|
104
|
+
scratch.write(
|
|
105
|
+
`${POLICY_SURFACE_HOST}/${POLICY_SURFACE_CATALOG}`,
|
|
106
|
+
createPolicyCatalog(['other', 'sample', 'uncovered']),
|
|
107
|
+
)
|
|
95
108
|
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
96
109
|
{
|
|
97
110
|
rule: 'surface',
|
|
@@ -212,6 +225,31 @@ describe('surface policy controls', () => {
|
|
|
212
225
|
}
|
|
213
226
|
})
|
|
214
227
|
|
|
228
|
+
it('excludes the distribution harness in an adopter while reporting target-owned collisions', () => {
|
|
229
|
+
const scratch = createPolicySurfaceFixture()
|
|
230
|
+
try {
|
|
231
|
+
scratch.write('tests/setupDistribution.ts', 'export function readShared() {}\n')
|
|
232
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([])
|
|
233
|
+
scratch.write('tests/setupExtra.ts', 'export function readShared() {}\n')
|
|
234
|
+
expect(inspectPolicyWorkspace(scratch.path)).toEqual([
|
|
235
|
+
{
|
|
236
|
+
rule: 'mirror',
|
|
237
|
+
path: 'tests/setupExtra.ts',
|
|
238
|
+
message:
|
|
239
|
+
'exporting setup module requires its sibling proof or an import from tests/setup.test.ts',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
rule: 'surface',
|
|
243
|
+
path: 'tests/setupExtra.ts',
|
|
244
|
+
line: 1,
|
|
245
|
+
message: 'surface name belongs to one package: readShared (other)',
|
|
246
|
+
},
|
|
247
|
+
])
|
|
248
|
+
} finally {
|
|
249
|
+
scratch.destroy()
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
|
|
215
253
|
it('refuses a barrel statement outside the relative star-export population', () => {
|
|
216
254
|
const scratch = createPolicySurfaceFixture()
|
|
217
255
|
try {
|