clearotron 0.3.2-beta.1 → 0.3.2-beta.3
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 +29 -0
- package/INSTALL.md +2 -0
- package/README.md +15 -10
- package/bin/onboard.mjs +4 -4
- package/build-info.json +2 -2
- package/docs/CLIENT-MCP.md +54 -54
- package/docs/DELIVERY.md +16 -15
- package/docs/E2E.md +8 -8
- package/docs/GLOSSARY.md +2 -2
- package/docs/INTAKE.md +11 -11
- package/docs/ONBOARDING.md +17 -16
- package/docs/PORTAL.md +18 -16
- package/docs/README.md +10 -10
- package/docs/SECURITY.md +20 -20
- package/docs/architecture/01-product-overview.md +17 -16
- package/docs/architecture/02-architecture.md +6 -6
- package/docs/architecture/03-run-lifecycle.md +7 -7
- package/docs/architecture/04-configuration-reference.md +15 -13
- package/docs/architecture/05-config-governance.md +39 -30
- package/docs/architecture/05-customer-profiles.md +35 -35
- package/docs/architecture/06-operations-runbook.md +20 -20
- package/docs/architecture/07-quality-and-audit.md +17 -17
- package/docs/architecture/08-development-guide.md +3 -3
- package/docs/architecture/09-security-and-data.md +27 -27
- package/docs/architecture/README.md +1 -1
- package/docs/branding.md +8 -3
- package/docs/configuration.md +18 -18
- package/docs/writing-standard.md +3 -3
- package/driver/CHANGELOG.md +33 -0
- package/driver/driver.config.mjs +19 -3
- package/driver/package.json +1 -1
- package/driver/portal-service.mjs +34 -4
- package/driver/suite-census.json +118 -46
- package/mcp-server/CHANGELOG.md +8 -0
- package/mcp-server/package.json +1 -1
- package/mcp-server/packs/client/CONNECT.md +6 -6
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-BsbasHjM.js → index-Bki5jT_N.js} +3376 -2971
- package/portal-ui/dist/assets/{index-DNQpLYZF.css → index-De2RFLbT.css} +972 -205
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/signa/src/core.js +29 -1
- package/scripts/ask-ai-render-check.mjs +287 -105
- package/scripts/release-note-required.mjs +16 -2
- package/scripts/release-pre-gate.mjs +111 -0
- package/scripts/settings-render-check.mjs +575 -0
- package/shared/brand.mjs +29 -0
- package/shared/connect-clients.mjs +99 -47
- package/shared/names-in-force.mjs +1 -0
- package/shared/stdio-connect.mjs +16 -2
- package/shared/writing-standard-classes.mjs +34 -3
|
@@ -0,0 +1,111 @@
|
|
|
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
|
+
// release-pre-gate.mjs — let a stable cut reach the version script when every note has already been
|
|
5
|
+
// consumed by a pre-release.
|
|
6
|
+
//
|
|
7
|
+
// THE PROBLEM THIS EXISTS FOR, MEASURED. `changesets/action` decides whether to run `version-script` by
|
|
8
|
+
// counting the release notes it can see, and it does that ONCE, at the top of the run, before it touches
|
|
9
|
+
// the working tree. Its reader is `readChangesetState`:
|
|
10
|
+
//
|
|
11
|
+
// let preState = await readPreState(cwd);
|
|
12
|
+
// let changesets = await readChangesets(cwd);
|
|
13
|
+
// if (preState !== undefined && preState.mode === "pre") {
|
|
14
|
+
// return { preState, changesets: changesets.filter((c) => !c.id.startsWith("pre/")) };
|
|
15
|
+
// }
|
|
16
|
+
// return { preState: undefined, changesets };
|
|
17
|
+
//
|
|
18
|
+
// `readChangesets` DOES enumerate `.changeset/pre/`, giving each note an id beginning `pre/`. The filter
|
|
19
|
+
// that hides them applies only while the tree says `mode: "pre"`.
|
|
20
|
+
//
|
|
21
|
+
// A pre-release consumes a note by MOVING it into `.changeset/pre/`, where it waits so the eventual
|
|
22
|
+
// stable can list every change since the last stable. So the ordinary state after cutting a beta is: no
|
|
23
|
+
// notes at the top level, every note under `pre/`, and the flag still saying `pre`. In that state the
|
|
24
|
+
// action counts zero, skips the version script, emits no pull request number, and the stable cut refuses
|
|
25
|
+
// with "Nothing to cut" — a refusal about the wrong thing, because the tree holds a whole release.
|
|
26
|
+
//
|
|
27
|
+
// WHAT THIS DOES, AND WHY IT IS NOT A TRICK. It writes the channel the dispatch asked for into the file
|
|
28
|
+
// the action reads, before the action reads it. A stable cut IS a tree leaving pre-release mode, and the
|
|
29
|
+
// notes under `pre/` ARE the notes that stable will carry; saying so is a true statement about this cut,
|
|
30
|
+
// not a device to get past a check. `release-version.mjs` already states the same principle for the
|
|
31
|
+
// other reader: "the mode a cut needs is a fact about the channel asked for, not about what the last cut
|
|
32
|
+
// happened to do." There are two readers of that fact and they are reached separately.
|
|
33
|
+
//
|
|
34
|
+
// THE WRITE IS DISCARDED, ON PURPOSE, AND THAT IS THE POINT. The action's own first act inside
|
|
35
|
+
// `runVersion` is `git checkout changeset-release/main` followed by `git reset --hard <the run's
|
|
36
|
+
// commit>`, which puts `pre.json` back to `pre`. The version script then runs in that rebuilt tree, finds
|
|
37
|
+
// the tree still in pre mode, and performs the real transition itself with `changeset pre exit` — which
|
|
38
|
+
// is where the transition has to happen, and the reason it was moved there. So this changes what the
|
|
39
|
+
// action COUNTS and nothing about what the cut DOES. Nothing here versions anything, and a tree this
|
|
40
|
+
// touched still produces the same version it would have produced had the gate never been in the way.
|
|
41
|
+
//
|
|
42
|
+
// WHAT IT REFUSES TO DO. It is silent on a beta, on a tree that is not in pre mode, on a tree whose notes
|
|
43
|
+
// are at the top level where the action can already see them, and on a tree with no notes anywhere. That
|
|
44
|
+
// last one matters most: a cut with genuinely nothing to cut must still refuse, and it still does,
|
|
45
|
+
// because this writes nothing when `.changeset/pre/` is empty.
|
|
46
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync } from "node:fs";
|
|
47
|
+
import { join, dirname } from "node:path";
|
|
48
|
+
import { fileURLToPath } from "node:url";
|
|
49
|
+
import { isEntrypoint } from "../shared/is-entrypoint.mjs";
|
|
50
|
+
|
|
51
|
+
const ROOT = join(dirname(dirname(fileURLToPath(import.meta.url))));
|
|
52
|
+
|
|
53
|
+
/** A note is a `.md` file that is not the directory's own README. */
|
|
54
|
+
export function countNotes(dir) {
|
|
55
|
+
if (!existsSync(dir)) return 0;
|
|
56
|
+
return readdirSync(dir).filter((f) => f.endsWith(".md") && f.toLowerCase() !== "readme.md").length;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* PURE. Whether this cut has to restate its channel for the action's counter, and nothing else.
|
|
61
|
+
*
|
|
62
|
+
* `null` means leave the tree alone, and every `null` here is a case the action already reads correctly
|
|
63
|
+
* — including the two that must keep refusing. Only the one state the action cannot see returns a write.
|
|
64
|
+
*
|
|
65
|
+
* Kept separate from the file it writes so the decision can be driven against every member of the class
|
|
66
|
+
* rather than only against the tree that happens to be checked out.
|
|
67
|
+
*/
|
|
68
|
+
export function preGateDecision({ cut, mode, topLevelNotes, preNotes }) {
|
|
69
|
+
// A beta never restates anything. A beta with no pending notes MUST still refuse, and that refusal is
|
|
70
|
+
// this function returning null.
|
|
71
|
+
if (cut !== "stable") return null;
|
|
72
|
+
// Not in pre mode: the action's filter is not engaged, so whatever is there is already counted.
|
|
73
|
+
if (mode !== "pre") return null;
|
|
74
|
+
// The action can see these. Touching the flag here would change the pull request's title for a cut
|
|
75
|
+
// that never needed help.
|
|
76
|
+
if (topLevelNotes > 0) return null;
|
|
77
|
+
// Nothing anywhere. "Nothing to cut" is then the truth, and the refusal downstream is correct.
|
|
78
|
+
if (preNotes === 0) return null;
|
|
79
|
+
return { mode: "exit" };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function main(root = ROOT, argv = process.argv.slice(2)) {
|
|
83
|
+
const cut = (argv.find((a) => a.startsWith("--cut=")) ?? "").slice("--cut=".length);
|
|
84
|
+
// `--root` exists so this can be driven against a built tree rather than only against the checkout it
|
|
85
|
+
// happens to live in. The workflow never passes it: there the script sits in the repository being cut,
|
|
86
|
+
// which is what ROOT already means.
|
|
87
|
+
const rootFlag = argv.find((a) => a.startsWith("--root="));
|
|
88
|
+
if (rootFlag) root = rootFlag.slice("--root=".length);
|
|
89
|
+
const preJson = join(root, ".changeset", "pre.json");
|
|
90
|
+
const flag = existsSync(preJson) ? JSON.parse(readFileSync(preJson, "utf8")) : null;
|
|
91
|
+
const mode = flag?.mode ?? "none";
|
|
92
|
+
const topLevelNotes = countNotes(join(root, ".changeset"));
|
|
93
|
+
const preNotes = countNotes(join(root, ".changeset", "pre"));
|
|
94
|
+
|
|
95
|
+
const decision = preGateDecision({ cut, mode, topLevelNotes, preNotes });
|
|
96
|
+
const state = `cut=${cut || "none"}, mode=${mode}, ${topLevelNotes} note(s) pending, ${preNotes} already consumed by the pre-release`;
|
|
97
|
+
if (!decision) {
|
|
98
|
+
// SAYS SO EITHER WAY. A step that is silent when it does nothing cannot be told from a step that did
|
|
99
|
+
// not run, and this one is skipped far more often than it acts.
|
|
100
|
+
console.log(`release-pre-gate: ${state} — leaving the flag alone.`);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
writeFileSync(preJson, `${JSON.stringify({ ...flag, ...decision }, null, 2)}\n`);
|
|
104
|
+
console.log(`release-pre-gate: ${state} — the notes this stable carries are all under .changeset/pre/,`
|
|
105
|
+
+ " where the action does not count them while the flag says pre. Writing mode=exit so it counts them."
|
|
106
|
+
+ " The version script performs the real transition after the action rebuilds the tree; this write is"
|
|
107
|
+
+ " discarded by that rebuild and changes no version.");
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (isEntrypoint(import.meta.url)) process.exit(main());
|