ADR-013 Phase 4: relocate 4 self-contained plugin frontends

Relocate applications, geenforce, knowledgebase, and machines - each owns only
its own views dir, so a clean move to plugins/<name>/frontend/ (views/ +
routes.js, core imports rewritten to @/). geenforce's entryForm.js helper + its
vitest spec move with it (ManifestEditor imports it as a sibling).

Machinery fixes this batch surfaced:
- routes.gen.js codegen uses namespace imports (import * as p_x). A route file
  without a `toplevel` export is undefined on the namespace instead of a strict-
  ESM missing-binding build error.
- vitest gains a `pretest` stage so plugin-frontend specs (now under
  plugins/<name>/frontend/) run from their staged copy in src/.plugins-staged/.

Verified live: GE-Enforce (the most complex, uses the entryForm sibling helper)
renders fully from its staged frontend. Build + 58 vitest + naming green.
This commit is contained in:
cproudlock
2026-07-18 23:51:23 -04:00
parent af9a3b190b
commit 23dc9fa379
21 changed files with 52 additions and 49 deletions

View File

@@ -45,11 +45,11 @@ const childParts = []
const topParts = []
for (const name of chosen) {
const id = 'p_' + name.replace(/[^a-zA-Z0-9]/g, '_')
lines.push(
`import ${id}Default, { toplevel as ${id}Top } from `
+ `'../.plugins-staged/${name}/routes.js'`)
childParts.push(`...(${id}Default || [])`)
topParts.push(`...(${id}Top || [])`)
// Namespace import so a route file without a `toplevel` export is not a
// (strict ESM) build error - the binding is just undefined on the namespace.
lines.push(`import * as ${id} from '../.plugins-staged/${name}/routes.js'`)
childParts.push(`...(${id}.default || [])`)
topParts.push(`...(${id}.toplevel || [])`)
}
lines.push('')
lines.push(`export const stagedChildren = [${childParts.join(', ')}]`)