clearotron 0.3.2-beta.8 → 0.3.2-beta.9
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/.env.example +34 -3
- package/CONTRIBUTING.md +8 -8
- package/INSTALL.md +6 -6
- package/SECURITY.md +3 -3
- package/bin/brandowner.mjs +3 -3
- package/bin/framework-preflight.mjs +1 -1
- package/bin/start.mjs +18 -4
- package/build-info.json +2 -2
- package/docs/DELIVERY.md +2 -1
- package/docs/INTAKE.md +1 -1
- package/docs/ONBOARDING.md +1 -1
- package/docs/architecture/03-run-lifecycle.md +6 -6
- package/docs/architecture/04-configuration-reference.md +6 -3
- package/docs/architecture/05-config-governance.md +6 -1
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/architecture/06-operations-runbook.md +3 -3
- package/docs/architecture/08-development-guide.md +6 -6
- package/docs/configuration.md +5 -5
- package/docs/decisions/0003-credential-model.md +1 -1
- package/docs/writing-standard.md +4 -0
- package/driver/CHANGELOG.md +48 -0
- package/driver/README.md +3 -3
- package/driver/binding-layers.mjs +1 -1
- package/driver/citation-census.json +3 -3
- package/driver/{prelim-variants-record.mjs → clearance-variants-record.mjs} +24 -24
- package/driver/common-law-receipts.mjs +2 -2
- package/driver/company-bundle.mjs +3 -3
- package/driver/compose-read.mjs +8 -14
- package/driver/consumption-ledger.mjs +2 -2
- package/driver/contract-arm2-baseline.json +2 -3
- package/driver/contract-dictation-registry.mjs +19 -19
- package/driver/contract-e3-backlog.mjs +19 -19
- package/driver/contract-e3-baseline.json +14 -14
- package/driver/contract-vocabulary.mjs +24 -17
- package/driver/deliver-trigger.sh +16 -16
- package/driver/demo-container.mjs +3 -3
- package/driver/dev-portal.mjs +3 -3
- package/driver/disposition-call.mjs +1 -1
- package/driver/doubt-ledger.mjs +2 -2
- package/driver/drainer-identity.mjs +34 -8
- package/driver/driver.config.mjs +95 -45
- package/driver/engine/mcp/README.md +1 -1
- package/driver/engine/mcp/dispositions-server.mjs +3 -3
- package/driver/engine/mcp/gather-config.mjs +9 -9
- package/driver/engine/mcp/perplexity-server.mjs +2 -2
- package/driver/engine/mcp/recording-server.mjs +5 -5
- package/driver/enqueue-schema.mjs +6 -2
- package/driver/findings-model.mjs +5 -2
- package/driver/flag-snapshot.mjs +6 -3
- package/driver/form-neighbourhood.mjs +54 -7
- package/driver/framework.mjs +4 -4
- package/driver/gateway.mjs +12 -6
- package/driver/jx-lanes.mjs +2 -2
- package/driver/jx-units.mjs +1 -1
- package/driver/jx.mjs +30 -2
- package/driver/knockout-review-record.mjs +56 -4
- package/driver/known-conflicts.mjs +1 -1
- package/driver/named-band.mjs +1 -33
- package/driver/ordinary-words.mjs +51 -0
- package/driver/outbox-backoff.mjs +31 -16
- package/driver/package.json +1 -1
- package/driver/partial-payload-baseline.json +2 -2
- package/driver/phase0.mjs +3 -3
- package/driver/pipeline-knockout.mjs +5 -5
- package/driver/pipeline.mjs +206 -68
- package/driver/placement-form.mjs +77 -1
- package/driver/placement-model.mjs +1 -1
- package/driver/portal-report.mjs +92 -5
- package/driver/portal-service.mjs +34 -8
- package/driver/portal-upstream.mjs +1 -1
- package/driver/preserve-merge.mjs +3 -3
- package/driver/product-rows.mjs +2 -2
- package/driver/products.mjs +1 -1
- package/driver/profiles/README.md +3 -3
- package/driver/profiles/demo-brand-owner.json +2 -2
- package/driver/profiles.mjs +55 -17
- package/driver/progress.mjs +18 -8
- package/driver/provider-usage.mjs +8 -8
- package/driver/publish/index.mjs +110 -5
- package/driver/publish/knockout.mjs +29 -4
- package/driver/publish/pool-admin.mjs +1 -1
- package/driver/publish/publish-inputs.mjs +18 -2
- package/driver/publish/render-knockout.mjs +115 -24
- package/driver/publish/render.mjs +153 -34
- package/driver/publish/search-depth.mjs +133 -4
- package/driver/publish/templates/report.css +60 -3
- package/driver/publish/xlsx.mjs +8 -1
- package/driver/queue-order.mjs +2 -2
- package/driver/recording-agreement.mjs +1 -1
- package/driver/reference-score.mjs +1 -1
- package/driver/register-count.mjs +50 -5
- package/driver/register-coverage.mjs +67 -0
- package/driver/register-grant-vocabulary.mjs +1 -1
- package/driver/register-plan.mjs +19 -2
- package/driver/registry-fidelity.mjs +3 -3
- package/driver/repair-composers.mjs +1 -1
- package/driver/repair-contract.mjs +1 -1
- package/driver/replay-archive.mjs +6 -6
- package/driver/report-overview-record.mjs +2 -2
- package/driver/run-requirements.mjs +3 -3
- package/driver/runner.mjs +2 -2
- package/driver/scope-facts.mjs +20 -5
- package/driver/scope-ledger.mjs +5 -5
- package/driver/search-policy.mjs +22 -12
- package/driver/skills/README.md +15 -15
- package/driver/skills/blind-frame/SKILL.md +2 -2
- package/driver/skills/case-law-citation/SKILL.md +4 -4
- package/driver/skills/case-law-citation/sources/eurlex.md +1 -1
- package/driver/skills/{prelim-common-law → clearance-common-law}/SKILL.md +22 -22
- package/driver/skills/{prelim-common-law → clearance-common-law}/perplexity-prompts.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/SKILL.md +10 -10
- package/driver/skills/{prelim-register → clearance-register}/digest.md +2 -2
- package/driver/skills/{prelim-register → clearance-register}/providers/README.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/providers/clarivate.md +37 -35
- package/driver/skills/{prelim-register → clearance-register}/providers/corsearch.md +20 -11
- package/driver/skills/{prelim-register → clearance-register}/providers/signa.md +5 -5
- package/driver/skills/{prelim-register → clearance-register}/register-recipes.md +3 -3
- package/driver/skills/{prelim-register → clearance-register}/status-rules.md +2 -2
- package/driver/skills/{prelim-register → clearance-register}/stealth-filer-indicators.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/unit.md +2 -2
- package/driver/skills/{prelim-search → clearance-search}/SKILL.md +31 -31
- package/driver/skills/{prelim-search → clearance-search}/delivery-contract.md +1 -1
- package/driver/skills/{prelim-search → clearance-search}/phase2-execution.md +18 -18
- package/driver/skills/{prelim-search → clearance-search}/synthesis-rules.md +7 -7
- package/driver/skills/{prelim-variants → clearance-variants}/SKILL.md +18 -18
- package/driver/skills/{prelim-variants → clearance-variants}/transliteration-scripts.md +5 -5
- package/driver/skills/frame-diff/SKILL.md +1 -1
- package/driver/skills/knockout-assess/SKILL.md +10 -7
- package/driver/skills/matter-frame/SKILL.md +3 -3
- package/driver/skills/narrative-refutation/SKILL.md +9 -9
- package/driver/skills/placement-inquiry/SKILL.md +5 -5
- package/driver/stage-context.mjs +1 -1
- package/driver/stages-knockout.mjs +4 -4
- package/driver/stages.mjs +53 -53
- package/driver/status-snapshot.mjs +2 -2
- package/driver/suite-census.json +218 -92
- package/driver/surface-exit-verdict.mjs +58 -0
- package/driver/systemd/README.md +2 -2
- package/driver/systemd/clearotron-worker.service +1 -1
- package/driver/terminal-clamp.mjs +2 -0
- package/driver/usage-ledger.mjs +1 -1
- package/driver/variant-manifest-model.mjs +4 -4
- package/driver/verify-knockout.mjs +27 -0
- package/driver/verify.mjs +67 -6
- package/driver/whatif-queue.mjs +1 -1
- package/driver/wordlists/en.txt +63906 -0
- package/mcp-server/CHANGELOG.md +4 -0
- package/mcp-server/README.md +1 -1
- package/mcp-server/lib/README.md +1 -1
- package/mcp-server/lib/options.mjs +8 -7
- package/mcp-server/lib/plan.mjs +18 -2
- package/mcp-server/lib/runs.mjs +1 -1
- package/mcp-server/lib/usage.mjs +3 -3
- package/mcp-server/lib/whatif.mjs +1 -1
- package/mcp-server/package.json +1 -1
- package/mcp-server/server.mjs +3 -0
- package/package.json +12 -11
- package/portal-ui/dist/assets/{index-CVOIvdhc.css → index-CtvwLCti.css} +207 -3
- package/portal-ui/dist/assets/{index-6jzO9HiX.js → index-EVaSo5-g.js} +1459 -482
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/README.md +1 -1
- package/providers/_shared/enumerate.mjs +6 -6
- package/providers/_shared/execute-plan.mjs +3 -3
- package/providers/_shared/ledger.mjs +119 -5
- package/providers/_shared/provider-text.mjs +2 -2
- package/providers/_shared/screen.mjs +2 -2
- package/providers/_shared/script-form.mjs +3 -3
- package/providers/_shared/territory-codes.mjs +23 -3
- package/providers/clarivate/README.md +1 -1
- package/providers/clarivate/src/capabilities.js +12 -12
- package/providers/clarivate/src/core.js +37 -43
- package/providers/corsearch/README.md +1 -1
- package/providers/corsearch/src/capabilities.js +5 -5
- package/providers/corsearch/src/core.js +3 -3
- package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/perplexity/src/core.js +1 -1
- package/providers/signa/README.md +1 -1
- package/providers/signa/src/capabilities.js +42 -49
- package/providers/signa/src/core.js +106 -29
- package/providers/uspto-local/src/sync.js +1 -1
- package/scripts/README.md +1 -0
- package/scripts/ask-ai-render-check.mjs +127 -1
- package/scripts/authority-boundary-probe.mjs +4 -4
- package/scripts/backfill-started-at.mjs +2 -2
- package/scripts/census-merge-driver.mjs +33 -2
- package/scripts/citation-anchor-report.mjs +181 -0
- package/scripts/dead-names.mjs +1 -1
- package/scripts/deprecate-below.mjs +66 -8
- package/scripts/drain-preflight.mjs +1 -1
- package/scripts/e2e.mjs +174 -0
- package/scripts/env-audit.mjs +27 -0
- package/scripts/env-classify.mjs +20 -2
- package/scripts/freeze-example-run.mjs +20 -10
- package/scripts/live-surface-check.mjs +124 -41
- package/scripts/markdown-link-check.mjs +1 -1
- package/scripts/merge-shape-check.mjs +242 -0
- package/scripts/mint-names-in-force.mjs +5 -5
- package/scripts/mint-offered-territories.mjs +72 -0
- package/scripts/mint-public-residue.mjs +2 -2
- package/scripts/mint-reference-strip-backlog.mjs +2 -2
- package/scripts/mint-suite-census.mjs +75 -2
- package/scripts/mint-writing-standard-backlog.mjs +2 -2
- package/scripts/purge-runs.mjs +7 -7
- package/scripts/reconcile-runs.mjs +2 -2
- package/scripts/release-approve-parked.mjs +20 -2
- package/scripts/release-await-cut.mjs +120 -1
- package/scripts/release-note-required.mjs +76 -8
- package/scripts/report-header-render-check.mjs +164 -0
- package/shared/brand.mjs +27 -0
- package/shared/connect-clients.mjs +39 -11
- package/shared/env-aliases.mjs +1 -1
- package/shared/identifier-scan.mjs +65 -9
- package/shared/identifier-sentinels.mjs +22 -0
- package/shared/names-in-force.mjs +3 -1
- package/shared/offered-territories.json +738 -0
- package/shared/pre-rename-spellings.mjs +53 -0
- package/shared/reference-guard-classes.mjs +40 -2
- package/shared/stdio-connect.mjs +39 -4
- package/shared/tree-commit.mjs +48 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/euipo.md +0 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/free-tier.md +0 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/uspto-local.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/field-doctrine-pharma.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/firm-wide-reasoning.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/report-prose.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/template-formatting.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/templates/email/generic.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/templates/search-request-form.html +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/worked-examples-demo.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/worked-examples.md +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
|
|
3
|
+
// pre-rename-spellings.mjs — names the identifier rename moved that an install still carries on disk.
|
|
4
|
+
//
|
|
5
|
+
// The internal identifier `prelim` became `clearance`. Where that identifier is only a name in the code, the
|
|
6
|
+
// rename is complete. Where it names something an install has already WRITTEN — a directory its runs live
|
|
7
|
+
// under, the session-key prefix its fetched records are filed by — the new name finds nothing, and nothing
|
|
8
|
+
// says so. Each such name is read in both spellings here, the old one as the new.
|
|
9
|
+
//
|
|
10
|
+
// ── The studio segment ──
|
|
11
|
+
//
|
|
12
|
+
// THE SEGMENT IS A PLACE ON DISK, NOT A NAME. Every run an install has made — its slug directories, its
|
|
13
|
+
// `archive/`, its queue, its matter ledger — sits under `<workspace>/studio/<segment>/`. The identifier
|
|
14
|
+
// rename changed the segment the code computes from `prelim-search` to `clearance-search`, which moves
|
|
15
|
+
// nothing on disk: it points every reader at an empty directory, and an empty directory reads as "no runs"
|
|
16
|
+
// and "no queued jobs", never as an error. So an install keeps the segment it has: the old spelling
|
|
17
|
+
// wherever that directory exists, and the new one only for an install that has no other.
|
|
18
|
+
//
|
|
19
|
+
// One definition, imported by every site that builds or recognises the path, including the scripts and
|
|
20
|
+
// servers that deliberately do not load the driver's configuration module.
|
|
21
|
+
|
|
22
|
+
import { existsSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
/** The two spellings, the one every pre-rename install wrote under first: it wins wherever it exists. */
|
|
26
|
+
export const STUDIO_SEGMENTS = Object.freeze(["prelim-search", "clearance-search"]);
|
|
27
|
+
|
|
28
|
+
/** A regex source matching either spelling, for code that recognises a studio path rather than builds one. */
|
|
29
|
+
export const STUDIO_SEGMENT_RE = "(?:prelim|clearance)-search";
|
|
30
|
+
|
|
31
|
+
/** The segment the install under `workspaceDir` uses. */
|
|
32
|
+
export function studioSegmentFor(workspaceDir) {
|
|
33
|
+
try { if (existsSync(join(String(workspaceDir ?? ""), "studio", STUDIO_SEGMENTS[0]))) return STUDIO_SEGMENTS[0]; }
|
|
34
|
+
catch { /* unreadable ⇒ the new spelling, whose read then fails loudly where it happens */ }
|
|
35
|
+
return STUDIO_SEGMENTS[1];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** `<workspaceDir>/studio/<segment>`. */
|
|
39
|
+
export const studioDirFor = (workspaceDir) => join(String(workspaceDir ?? ""), "studio", studioSegmentFor(workspaceDir));
|
|
40
|
+
|
|
41
|
+
// ── The run's session-key prefix ──
|
|
42
|
+
//
|
|
43
|
+
// A run's register calls and fetched record bodies are filed under `<prefix><slug>-<codename>-…`, and the
|
|
44
|
+
// run's own readers filter by that prefix. A run started before the rename and resumed after it has rows
|
|
45
|
+
// under `prelim-` and is now asked about `clearance-`: its records would read as never fetched, and the
|
|
46
|
+
// delivery check fails the run on records it holds.
|
|
47
|
+
/** Every spelling of one run prefix: `[prefix, the same run under the other identifier]`. PURE. */
|
|
48
|
+
export function runPrefixSpellings(runPrefix) {
|
|
49
|
+
const p = String(runPrefix ?? "");
|
|
50
|
+
if (p.startsWith("clearance-")) return [p, `prelim-${p.slice("clearance-".length)}`];
|
|
51
|
+
if (p.startsWith("prelim-")) return [p, `clearance-${p.slice("prelim-".length)}`];
|
|
52
|
+
return [p];
|
|
53
|
+
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
//
|
|
33
33
|
// ── WHAT IS DELIBERATELY NOT HERE ────────────────────────────────────────────────────────────────
|
|
34
34
|
//
|
|
35
|
-
// PRODUCT VOCABULARY. `lane`, `round`, `box`, `ruling`, `
|
|
35
|
+
// PRODUCT VOCABULARY. `lane`, `round`, `box`, `ruling`, `clearance`, `knockout`, `seat` and `jx` are this
|
|
36
36
|
// product's own nouns. A guard refusing them fires thousands of times, and a guard that fires on
|
|
37
37
|
// correct prose is one whose next reader deletes from the workflow.
|
|
38
38
|
//
|
|
@@ -378,6 +378,40 @@ export function censusOf(files, read) {
|
|
|
378
378
|
* @param {string} root
|
|
379
379
|
* @returns {{files: string[], laid: number} | {error: string}}
|
|
380
380
|
*/
|
|
381
|
+
/**
|
|
382
|
+
* A reader that answers with what HEAD PUBLISHES at a path, not with whatever is sitting there.
|
|
383
|
+
*
|
|
384
|
+
* `publishedOf` asks whether a PATH is in HEAD and never whose bytes are at it. A laid file at a NEW path
|
|
385
|
+
* is correctly excluded; a laid file that SHADOWS a published path passes that filter, and the census then
|
|
386
|
+
* measures the private file as though the public tree carried it. Measured on the beta-8 overlay:
|
|
387
|
+
* `corpus/scripts/report-print-check.mjs` lays over `scripts/report-print-check.mjs`, the private copy
|
|
388
|
+
* carries two bare references in its comments and the published file carries none, and the residue census
|
|
389
|
+
* reported `0 → 2` against the public tree. Three of that run's nine reds were this one cause.
|
|
390
|
+
*
|
|
391
|
+
* The same hole swallows an ordinary uncommitted edit: mint a backlog with unsaved work in the tree and it
|
|
392
|
+
* records what you have not published yet. The path filter cannot see either, because both are a question
|
|
393
|
+
* about bytes.
|
|
394
|
+
*
|
|
395
|
+
* ONLY THE FILES THAT DIFFER ARE FETCHED FROM HEAD. Asking git for every file's blob would spawn a process
|
|
396
|
+
* per file over the whole corpus; asking which paths differ costs one call, and for the rest the bytes on
|
|
397
|
+
* disk ARE the published bytes. So the common case stays a plain read and correctness does not depend on
|
|
398
|
+
* how fast it is.
|
|
399
|
+
*
|
|
400
|
+
* A file that differs and cannot be read out of HEAD is not silently read from disk: that is the permissive
|
|
401
|
+
* answer and the one that reinstates the defect. It throws, and `censusOf` skips a file it cannot read —
|
|
402
|
+
* which undercounts rather than miscounts, and undercounting a floor is the safe direction.
|
|
403
|
+
*/
|
|
404
|
+
export function publishedReader(root, read) {
|
|
405
|
+
let differs = new Set();
|
|
406
|
+
try {
|
|
407
|
+
differs = new Set(execFileSync("git", ["-C", root, "diff", "--name-only", "HEAD"],
|
|
408
|
+
{ encoding: "utf8", maxBuffer: 1 << 28 }).split("\n").map((s) => s.trim()).filter(Boolean));
|
|
409
|
+
} catch { differs = new Set(); }
|
|
410
|
+
return (f) => (differs.has(f)
|
|
411
|
+
? execFileSync("git", ["-C", root, "show", `HEAD:${f}`], { encoding: "utf8", maxBuffer: 1 << 28 })
|
|
412
|
+
: read(f));
|
|
413
|
+
}
|
|
414
|
+
|
|
381
415
|
export function publishedOf(trackedList, root) {
|
|
382
416
|
let head;
|
|
383
417
|
try {
|
|
@@ -389,5 +423,9 @@ export function publishedOf(trackedList, root) {
|
|
|
389
423
|
return { error: `could not read HEAD in ${root}: ${String(e.message).split("\n")[0]}` };
|
|
390
424
|
}
|
|
391
425
|
const files = trackedList.filter((f) => head.has(f));
|
|
392
|
-
|
|
426
|
+
// THE PATHS, not only how many. A count tells a reader that something was not counted and leaves them
|
|
427
|
+
// to find out what; every caller that acts on `laid` needs to name them, and deriving the list again at
|
|
428
|
+
// each call site is three chances to derive it differently.
|
|
429
|
+
const laidPaths = trackedList.filter((f) => !head.has(f));
|
|
430
|
+
return { files, laid: laidPaths.length, laidPaths };
|
|
393
431
|
}
|
package/shared/stdio-connect.mjs
CHANGED
|
@@ -61,8 +61,15 @@ export function stdioConnectCommand({ installRoot = stableInstallRoot({ installR
|
|
|
61
61
|
* descriptions of one thing drift into three different promises about what it does.
|
|
62
62
|
*/
|
|
63
63
|
export function stdioConnectOffer(opts = {}) {
|
|
64
|
+
// ASKED OF THE SAME COMPOSER THE PAGE ASKS, so a terminal under WSL offers the two sides the page
|
|
65
|
+
// offers and neither surface has to know how a launcher is built. `command` is what it has always
|
|
66
|
+
// been — off WSL the one line, and under WSL the Windows-side one, which is the row that leads there
|
|
67
|
+
// too — and `variants` is null unless the caller named a WSL target, so no surface grows a second
|
|
68
|
+
// line because this file changed.
|
|
69
|
+
const both = stdioConnectFor("claude-cli", opts);
|
|
64
70
|
return {
|
|
65
|
-
command:
|
|
71
|
+
command: both.text,
|
|
72
|
+
variants: both.variants,
|
|
66
73
|
name: STDIO_SERVER_NAME,
|
|
67
74
|
// Deliberately states the two facts a reader needs to judge it: no network, and it only works from a
|
|
68
75
|
// machine with this install on its disk. Both are why it is offered to staff and not to a client.
|
|
@@ -315,13 +322,41 @@ export function remoteConnectFor(shape, { address = null } = {}) {
|
|
|
315
322
|
* absence is a finding: a row naming a shape nobody implemented should surface as missing, and the
|
|
316
323
|
* table's own arm refuses such a row outright.
|
|
317
324
|
*/
|
|
325
|
+
/**
|
|
326
|
+
* THE TWO SIDES OF A WSL INSTALL, in the product's own words and in ONE place.
|
|
327
|
+
*
|
|
328
|
+
* An install inside WSL can be reached by an assistant on the Windows side — Claude Desktop, Claude Code
|
|
329
|
+
* in PowerShell — through the `wsl.exe` wrapper, and by an assistant running inside the distribution
|
|
330
|
+
* with the plain `node` line. They are different commands and the reader has to be told which is which;
|
|
331
|
+
* the owner pasted the Windows one into Claude Code inside WSL and got a closed connection.
|
|
332
|
+
*
|
|
333
|
+
* Ruled 2026-09-17: these words exactly, and no other new sentence. They are exported rather than spelled
|
|
334
|
+
* at each surface so the page and the terminal cannot drift apart — one author, as everything else here.
|
|
335
|
+
*/
|
|
336
|
+
export const WSL_ROW_HEADINGS = Object.freeze({ fromWindows: "From Windows", insideWsl: "Inside WSL" });
|
|
337
|
+
|
|
318
338
|
export function stdioConnectFor(shape, { installRoot = stableInstallRoot({ installRoot: INSTALL_ROOT }), workDir = null, reportsDir = null, platform = process.platform, wsl = null } = {}) {
|
|
319
339
|
const spec = Object.hasOwn(STDIO_SHAPES, String(shape ?? "")) ? STDIO_SHAPES[shape] : null;
|
|
320
340
|
if (!spec) return null;
|
|
321
341
|
const server = join(installRoot, "mcp-server", "server.mjs");
|
|
342
|
+
const render = (target) => spec.render({ server, workDir, reportsDir, platform, wsl: target });
|
|
343
|
+
const base = { shape, kind: spec.kind, where: spec.where, after: spec.after, name: STDIO_SERVER_NAME };
|
|
344
|
+
// OFF WSL NOTHING CHANGES: one launcher, no variants, and `variants: null` rather than an empty array
|
|
345
|
+
// so a consumer cannot read "this install has no sides" as "this install has two sides, both missing".
|
|
346
|
+
if (!wsl) return { ...base, text: render(null), variants: null };
|
|
347
|
+
// ON WSL, TWO, AND THE SECOND IS NOT WRITTEN TWICE. The inside-WSL launcher is exactly what this shape
|
|
348
|
+
// renders for an install that is not under WSL at all — the same author, asked with the target taken
|
|
349
|
+
// away — so it is the line every off-WSL install already offers and every arm already covers, rather
|
|
350
|
+
// than a second composition that can drift from it.
|
|
351
|
+
//
|
|
352
|
+
// `text` stays the Windows-side one. Every consumer that reads a single `text` today keeps the answer
|
|
353
|
+
// it has always had, and only the surfaces that ask for `variants` draw the pair.
|
|
322
354
|
return {
|
|
323
|
-
|
|
324
|
-
text:
|
|
325
|
-
|
|
355
|
+
...base,
|
|
356
|
+
text: render(wsl),
|
|
357
|
+
variants: [
|
|
358
|
+
{ heading: WSL_ROW_HEADINGS.fromWindows, text: render(wsl) },
|
|
359
|
+
{ heading: WSL_ROW_HEADINGS.insideWsl, text: render(null) },
|
|
360
|
+
],
|
|
326
361
|
};
|
|
327
362
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
|
|
3
|
+
//
|
|
4
|
+
// tree-commit.mjs — the tree a path belongs to, and the commit that tree carries.
|
|
5
|
+
//
|
|
6
|
+
// A CHECKOUT ANSWERS THROUGH GIT; A PACKAGED INSTALL ANSWERS THROUGH ITS build-info.json. An install
|
|
7
|
+
// from the registry is a copy of the package, not a clone: there is no git there and there never will
|
|
8
|
+
// be, so asking git about it fails every time, and a deploy check that treats that failure as a fault
|
|
9
|
+
// reports every packaged box as broken. What a packaged install does carry is `build-info.json`, written
|
|
10
|
+
// by `prepack`, naming the commit it was packed from — read here through the one reader of that file.
|
|
11
|
+
//
|
|
12
|
+
// Git is asked first, and only its failure sends the question to the stamp: a checkout's HEAD is the
|
|
13
|
+
// truth about a checkout, and a stale stamp left in one must not outvote it.
|
|
14
|
+
import { dirname } from "node:path";
|
|
15
|
+
import { execFileSync } from "node:child_process";
|
|
16
|
+
import { packagedBuild } from "./packaged-build.mjs";
|
|
17
|
+
|
|
18
|
+
/** `git -C <repo> <args>`, keeping git's own sentence when it fails. */
|
|
19
|
+
export function gitTry(repo, ...args) {
|
|
20
|
+
try {
|
|
21
|
+
return { ok: true, out: execFileSync("git", ["-C", repo, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim(), err: null };
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return { ok: false, out: null, err: String(e?.stderr || e?.message || e).replace(/\s+/g, " ").trim().slice(0, 120) };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* `{ root, head, source, why }` for the tree holding `path`. `source` is "git" or "build-info"; `root`
|
|
29
|
+
* null means neither could say, and `why` names both failures. Readers are injected so an arm can drive
|
|
30
|
+
* a packaged install without building one.
|
|
31
|
+
*/
|
|
32
|
+
export function treeOf(path, { git = gitTry, build = packagedBuild } = {}) {
|
|
33
|
+
const top = git(path, "rev-parse", "--show-toplevel");
|
|
34
|
+
if (top.ok) {
|
|
35
|
+
const head = git(top.out, "rev-parse", "HEAD");
|
|
36
|
+
return { root: top.out, head: head.ok ? head.out : null, source: "git",
|
|
37
|
+
why: head.ok ? null : `git could not read HEAD in ${top.out}: ${head.err}` };
|
|
38
|
+
}
|
|
39
|
+
// WALK UP to the package root: a unit's WorkingDirectory or a running module sits somewhere inside
|
|
40
|
+
// the installed package, and the stamp is at its top.
|
|
41
|
+
for (let d = path; ; d = dirname(d)) {
|
|
42
|
+
const b = build(d);
|
|
43
|
+
if (b) return { root: d, head: b.commit, source: "build-info", why: null };
|
|
44
|
+
if (dirname(d) === d) break;
|
|
45
|
+
}
|
|
46
|
+
return { root: null, head: null, source: null,
|
|
47
|
+
why: `git could not read ${path} (${top.err}), and no build-info.json above it names a commit` };
|
|
48
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.manifest.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/driver/skills/{prelim-search → clearance-search}/templates/search-request-form.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|