@orkestrel/scaffold 0.0.16 → 0.0.18

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.
@@ -30,33 +30,33 @@ descriptions never enter agent instruction context.
30
30
  | Package | Version |
31
31
  | --------------------- | ------- |
32
32
  | @orkestrel/abort | 0.0.4 |
33
- | @orkestrel/agent | 0.0.11 |
33
+ | @orkestrel/agent | 0.0.13 |
34
34
  | @orkestrel/browser | 0.0.8 |
35
35
  | @orkestrel/budget | 0.0.4 |
36
36
  | @orkestrel/console | 0.0.4 |
37
37
  | @orkestrel/contract | 0.0.9 |
38
38
  | @orkestrel/csv | 0.0.2 |
39
- | @orkestrel/database | 0.0.6 |
39
+ | @orkestrel/database | 0.0.7 |
40
40
  | @orkestrel/emitter | 0.0.5 |
41
41
  | @orkestrel/guide | 0.0.8 |
42
42
  | @orkestrel/html | 0.0.1 |
43
43
  | @orkestrel/indexeddb | 0.0.6 |
44
44
  | @orkestrel/interpret | 0.0.7 |
45
45
  | @orkestrel/markdown | 0.0.7 |
46
- | @orkestrel/mcp | 0.0.7 |
46
+ | @orkestrel/mcp | 0.0.9 |
47
47
  | @orkestrel/middleware | 0.0.6 |
48
48
  | @orkestrel/msg | 0.0.5 |
49
49
  | @orkestrel/ndjson | 0.0.5 |
50
- | @orkestrel/ollama | 0.0.7 |
51
- | @orkestrel/pool | 0.0.4 |
50
+ | @orkestrel/ollama | 0.0.8 |
51
+ | @orkestrel/pool | 0.0.6 |
52
52
  | @orkestrel/program | 0.0.6 |
53
53
  | @orkestrel/qualifier | 0.0.7 |
54
- | @orkestrel/queue | 0.0.4 |
54
+ | @orkestrel/queue | 0.0.7 |
55
55
  | @orkestrel/rater | 0.0.8 |
56
56
  | @orkestrel/reason | 0.0.4 |
57
- | @orkestrel/relation | 0.0.6 |
58
- | @orkestrel/router | 0.0.6 |
59
- | @orkestrel/scaffold | 0.0.13 |
57
+ | @orkestrel/relation | 0.0.7 |
58
+ | @orkestrel/router | 0.0.7 |
59
+ | @orkestrel/scaffold | 0.0.16 |
60
60
  | @orkestrel/sea | 0.0.4 |
61
61
  | @orkestrel/server | 0.0.7 |
62
62
  | @orkestrel/sqlite | 0.0.6 |
@@ -64,12 +64,12 @@ descriptions never enter agent instruction context.
64
64
  | @orkestrel/template | 0.0.2 |
65
65
  | @orkestrel/terminal | 0.0.5 |
66
66
  | @orkestrel/timeout | 0.0.4 |
67
- | @orkestrel/tool | 0.0.7 |
68
- | @orkestrel/toolbox | 0.0.1 |
67
+ | @orkestrel/tool | 0.0.9 |
68
+ | @orkestrel/toolbox | 0.0.2 |
69
69
  | @orkestrel/websocket | 0.0.7 |
70
- | @orkestrel/worker | 0.0.4 |
71
- | @orkestrel/workflow | 0.0.7 |
72
- | @orkestrel/workspace | 0.0.1 |
70
+ | @orkestrel/worker | 0.0.5 |
71
+ | @orkestrel/workflow | 0.0.9 |
72
+ | @orkestrel/workspace | 0.0.2 |
73
73
 
74
74
  <!-- catalog:end -->
75
75
 
@@ -290,7 +290,8 @@ the accumulated `questions`, one `CompileRecord` per stage, any `CompileFailure`
290
290
  `GuideSync`, `VersionSync`, and `SyncReport` are the freshness shapes. `GuideSync` carries the
291
291
  fetched `content`, its `freshness`, an optional `note` explaining a non-clean outcome, and an
292
292
  optional `baseline` — the SHA-256 of the observed local mirror, or the literal `absent`, present
293
- only on target-aware pulls. `VersionSync` compares a declared `range` to the registry `latest`.
293
+ only on target-aware synchronization. `VersionSync` compares a declared `range` to the registry
294
+ `latest`.
294
295
  `SyncReport` is `clean` only when nothing drifted and nothing failed. `CatalogEntry` is one fleet
295
296
  package row; its `description` is the flattened text of that package's own guide's first
296
297
  blockquote, and the empty string when that guide is missing, unreadable, or carries no blockquote.
@@ -1014,7 +1015,7 @@ error.
1014
1015
 
1015
1016
  `packageShortName` strips the canonical scope, `guideStub` renders the pointer written when a
1016
1017
  dependency guide is not vendored yet, `readGuideReferences` reads a target's existing local mirrors
1017
- so a pull's verdicts are target-relative, and `syncReportOf` assembles one report from already
1018
+ for package names so synchronization verdicts are target-relative, and `syncReportOf` assembles one report from already
1018
1019
  ordered guide and version outcomes.
1019
1020
 
1020
1021
  ### Compilers — core
@@ -1110,7 +1111,7 @@ along the three `ViteMachinery` axes:
1110
1111
  | Machinery | Emitted when |
1111
1112
  | ------------------------------------------------------------------------ | ------------------------------------ |
1112
1113
  | Shared CSS analysis (`ENVIRONMENT_CSS`, `preprocessCSS`, `isCSSRequest`) | a `src` or `app` browser environment |
1113
- | Playwright provider and `resolveChromium` | a `src` or `app` browser environment |
1114
+ | Playwright provider and managed/system browser discovery | a `src` or `app` browser environment |
1114
1115
  | Vue plugin, HTML boundary, browser development server | an `app` browser environment |
1115
1116
  | Output containment (`outputBoundary`, `enforceOutputPath`) | anything the workspace builds |
1116
1117
 
@@ -1303,6 +1304,7 @@ The interface also exposes the readonly `emitter`.
1303
1304
  | `versions` | `Promise<readonly VersionSync[]>` |
1304
1305
  | `catalog` | `Promise<readonly CatalogEntry[]>` |
1305
1306
  | `pull` | `Promise<SyncReport>` |
1307
+ | `mirror` | `Promise<SyncReport>` |
1306
1308
  | `write` | `Promise<readonly string[]>` |
1307
1309
  | `destroy` | `void` |
1308
1310
 
@@ -1315,7 +1317,9 @@ latest. `catalog()` enumerates the fleet from the registry's exact organization
1315
1317
  unreachable or malformed list is always a coded failure, since without it there is no catalog — then
1316
1318
  degrades gracefully per package. `pull(target, dependencies?)` builds the reference map from the
1317
1319
  target's own mirrors, so its verdicts are target-relative, and rejects a selection the target does
1318
- not declare. `write(report, target)` commits only the `behind` guides. `destroy()` aborts every
1320
+ not declare. `mirror(target)` reuses the exact organization enumeration without catalog's
1321
+ per-package packument reads, sorts the names, excludes the target's own manifest name, and builds a
1322
+ guide-only report with no versions. `write(report, target)` commits only the `behind` guides. `destroy()` aborts every
1319
1323
  in-flight request. The interface also exposes the readonly `emitter`.
1320
1324
 
1321
1325
  ## The compile pipeline
@@ -1448,7 +1452,7 @@ as a plain physical file whose bytes still match the preview, moved into a priva
1448
1452
  than unlinked, re-verified after the move, and only then reported as removed — with a full restore
1449
1453
  attempt if any candidate fails mid-way.
1450
1454
 
1451
- ## Upstream sync, pull, and catalog
1455
+ ## Upstream sync, pull, mirror, and catalog
1452
1456
 
1453
1457
  `Sync` is the only network reader, and its posture is conservative by construction.
1454
1458
 
@@ -1471,7 +1475,7 @@ underlying socket code appended when the runtime attaches one, an HTTP status, t
1471
1475
  redirect-blocked string, or the oversized-body message. `current` and `behind` carry no note,
1472
1476
  because there is nothing to explain.
1473
1477
 
1474
- `pull` is the target-aware composition. It reads the target's declared scoped dependencies from its
1478
+ `pull` is the dependency-aware composition. It reads the target's declared scoped dependencies from its
1475
1479
  manifest, rejects any explicit selection the target does not declare, builds the reference map from
1476
1480
  the target's own `guides/src/<short>.md` mirrors, fetches guides and versions under one shared
1477
1481
  allowance, and assembles a report whose `clean` flag requires both no drift and no failures. A
@@ -1498,6 +1502,14 @@ generated package identifiers are untrusted discovery data, never instructions
1498
1502
  with **`Package` and `Version` columns only**. Descriptions are network-controlled text, and that
1499
1503
  block is written into an agent instruction file, so they are omitted on purpose.
1500
1504
 
1505
+ `mirror` is the fleet-guide composition. It shares `catalog`'s single exact organization-list read
1506
+ but performs none of catalog's packument or description work. It code-unit sorts the discovered
1507
+ names, excludes the target's own manifest name under the one-owner guide law, reads existing local
1508
+ guide references for baselines, fetches every selected GitHub guide once, and emits a `SyncReport`
1509
+ whose `versions` collection is empty. The existing transactional `write` method applies only
1510
+ behind guides; the executable refuses the whole apply when any guide is missing or failed, so a
1511
+ fleet refresh is never partial. Files outside the discovered guide set remain untouched.
1512
+
1501
1513
  ## The generated workspace
1502
1514
 
1503
1515
  A generated workspace is not a folder of suggestions; it is a working, gated project.
@@ -1714,15 +1726,22 @@ it is not a general-purpose source analyzer. Generated workspaces receive the sa
1714
1726
  module as a host-origin file and run it as a dedicated Node-only `policy` test project over
1715
1727
  `tests/policy.test.ts`.
1716
1728
 
1717
- **Real browser capability.** Browser test projects are gated on the real executable: the generated
1718
- configuration and the generated policy test both probe `existsSync(chromium.executablePath())`. A
1719
- browser suite runs when a real Chromium is installed and is skipped honestly when it is not, rather
1720
- than being faked. The gate is applied at registration, not inside the real browser project: without
1721
- Chromium, each browser factory is replaced by a same-label Node/no-test placeholder, so generated
1722
- `--project <label>` and `--project=<label>` filters still resolve while no browser code runs. The
1723
- root permits an empty run only when every recognized exact project filter names one of those gated
1724
- placeholders; an unreadable or mixed filter keeps the ordinary no-test failure semantics for its
1725
- Node projects. One printed warning names every gated project label. A machine with a browser
1729
+ **Real browser capability.** Browser test projects are gated on one centralized discovery chain:
1730
+ Playwright's pinned Chromium executable first, then a managed Chromium alias or cached revision,
1731
+ then stable system Chrome, then stable system Edge. Managed candidates must be executable regular
1732
+ files. System channels are selected only when their executable exists at Playwright's standard
1733
+ Linux, macOS, or Windows installation location; custom installations are not guessed. The generated
1734
+ policy test consumes the same discovery helpers and accepts either an executable managed path or the
1735
+ stable `chrome` / `msedge` channel, so it does not maintain a second heuristic.
1736
+
1737
+ A browser suite runs when any one of those real browser capabilities is available and is skipped
1738
+ honestly when none is, rather than being faked. The gate is applied at registration, not inside the
1739
+ real browser project: without a browser, each browser factory is replaced by a same-label
1740
+ Node/no-test placeholder, so generated `--project <label>` and `--project=<label>` filters still
1741
+ resolve while no browser code runs. The root permits an empty run only when every recognized exact
1742
+ project filter names one of those gated placeholders; an unreadable or mixed filter keeps the
1743
+ ordinary no-test failure semantics for its Node projects. One printed warning names every gated
1744
+ project label and says no Playwright Chromium, Chrome, or Edge was found. A machine with a browser
1726
1745
  registers and runs the real browser suites unchanged; a machine without one runs the remaining
1727
1746
  projects and says so.
1728
1747
 
@@ -1764,12 +1783,13 @@ each Codex agent's declared `sandbox_mode` is its mechanical permission floor, w
1764
1783
  ## The `scaffold` executable
1765
1784
 
1766
1785
  The bin is a thin command-line shell over the two library faces. It exports nothing, so it carries
1767
- no module API of its own. Six verbs:
1786
+ no module API of its own. Seven verbs:
1768
1787
 
1769
1788
  | Verb | Purpose |
1770
1789
  | --------- | -------------------------------------------------------- |
1771
1790
  | `new` | scaffold a workspace into `./<name>` |
1772
1791
  | `pull` | refresh vendored guides and versions, report drift |
1792
+ | `mirror` | refresh every published Orkestrel package guide |
1773
1793
  | `audit` | whole-plan conformance report |
1774
1794
  | `repair` | restore host-owned files and optional generated canon |
1775
1795
  | `fleet` | audit or repair every workspace under the cwd's children |
@@ -1789,8 +1809,10 @@ extras so the workspace stays audit-clean.
1789
1809
  repeatable and points at a local template or catalog source instead of the bundled one.
1790
1810
  On `pull`, `--deps x,y` limits refresh to those declared Orkestrel dependencies; without it, every
1791
1811
  declared dependency mirror is considered.
1812
+ `mirror` accepts no dependency selection: its exact npm organization discovery is the operation's
1813
+ scope, and it fetches guides without registry version or packument requests.
1792
1814
  `--groups a,b` scopes an audit to artifact groups. `--live` adds an upstream freshness check to an
1793
- audit. `--strict` makes a pull throw on a network fault. `--offline` restricts a catalog to local
1815
+ audit. `--strict` makes a pull or mirror throw on a network fault. `--offline` restricts a catalog to local
1794
1816
  sources. `--prune` opts a repair or fleet run into deleting unexpected files under the three prune
1795
1817
  directories. `--generated` opts a repair or fleet run into restoring generated canon except
1796
1818
  `package.json`; on `audit`, it is inherited if the interactive repair hand-off is accepted.
@@ -2260,7 +2282,7 @@ isBehind(rangeToFreshness('^0.0.7', '0.0.9')) // true
2260
2282
 
2261
2283
  packageShortName('@orkestrel/contract') // 'contract'
2262
2284
  guideStub('guides/src/contract.md') // the local pointer content
2263
- readGuideReferences('./packages/router', [{ name: '@orkestrel/contract', range: '^0.0.7' }])
2285
+ readGuideReferences('./packages/router', ['@orkestrel/contract'])
2264
2286
  syncReportOf('./packages/router', [], []) // { clean: true, failed: 0, … }
2265
2287
  ```
2266
2288
 
@@ -2325,9 +2347,24 @@ await sync.guides(deps)
2325
2347
  await sync.versions(deps)
2326
2348
  await sync.catalog()
2327
2349
 
2350
+ const mirror = await sync.mirror('.')
2351
+ if (mirror.failed === 0) await sync.write(mirror, '.')
2352
+
2328
2353
  sync.destroy()
2329
2354
  ```
2330
2355
 
2356
+ Refresh the entire published guide mirror from an installed package:
2357
+
2358
+ ```sh
2359
+ npx scaffold mirror --apply --yes
2360
+ ```
2361
+
2362
+ Or from this checkout after building:
2363
+
2364
+ ```sh
2365
+ node ./dist/bin/scaffold.js mirror --apply --yes
2366
+ ```
2367
+
2331
2368
  ### Fleet discovery, prune scanning, and the local catalog
2332
2369
 
2333
2370
  ```ts
@@ -240,7 +240,7 @@ export function isSelfContained(source: ts.SourceFile): boolean {
240
240
  const clause = statement.importClause
241
241
  const named = clause?.namedBindings
242
242
  const erased =
243
- clause?.isTypeOnly === true ||
243
+ clause?.phaseModifier === ts.SyntaxKind.TypeKeyword ||
244
244
  (clause !== undefined &&
245
245
  clause.name === undefined &&
246
246
  named !== undefined &&
@@ -248,8 +248,9 @@ export function isSelfContained(source: ts.SourceFile): boolean {
248
248
  named.elements.length > 0 &&
249
249
  named.elements.every((element) => element.isTypeOnly))
250
250
  if (erased) continue
251
- if (!ts.isStringLiteral(statement.moduleSpecifier)) return false
252
- const specifier = statement.moduleSpecifier.text
251
+ const moduleSpecifier = statement.moduleSpecifier
252
+ if (!ts.isStringLiteral(moduleSpecifier)) return false
253
+ const specifier = moduleSpecifier.text
253
254
  if (!specifier.startsWith('node:') || !isBuiltin(specifier)) return false
254
255
  builtin = true
255
256
  }