@akira-tl/forgerelay 0.9.3 → 0.10.0
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/CHANGELOG.md +22 -0
- package/README.md +10 -4
- package/dist/cli/init.js +111 -24
- package/dist/cli/maintenance-prune.js +479 -0
- package/dist/cli/maintenance-retention.js +93 -0
- package/dist/cli/maintenance.js +598 -0
- package/dist/cli/setup-support.js +21 -0
- package/dist/cli/shell/setup.js +99 -0
- package/dist/cli.js +72 -16
- package/dist/mcp/hooks/hooks.js +6 -3
- package/dist/mcp/oauth/public-url.js +3 -0
- package/dist/mcp/oauth/router.js +14 -9
- package/dist/mcp/process/process-platform.js +24 -26
- package/dist/mcp/process/process-sessions.js +6 -3
- package/dist/mcp/server/transport/http-server.js +17 -9
- package/dist/mcp/server/workspace/runtime/workspace-open-presentation.js +6 -0
- package/dist/mcp/server/workspace/runtime/workspace-tools.js +1 -1
- package/dist/mcp/server-instructions.js +10 -1
- package/dist/runtime/config/config.js +60 -6
- package/dist/runtime/instructions/shell-instructions.js +100 -0
- package/dist/runtime/security/runtime-privilege.js +120 -0
- package/dist/runtime/shell/command-shell-runtime.js +235 -0
- package/dist/runtime/state/runtime-lease.js +109 -0
- package/dist/ui/.vite/manifest.json +276 -276
- package/dist/ui/activity-panel-app.html +2 -2
- package/dist/ui/assets/{activity-panel-app-Sl1Jro8v.js → activity-panel-app-BkODhDLg.js} +1 -1
- package/dist/ui/assets/{activity-panel-app-7Xe0alhm.css → activity-panel-app-DkfJzTZ3.css} +1 -1
- package/dist/ui/assets/{angular-html-B_yn91wW.js → angular-html-DjuELMdF.js} +1 -1
- package/dist/ui/assets/{angular-ts-DSgtloKz.js → angular-ts-2EXVZIIX.js} +1 -1
- package/dist/ui/assets/{apl-NatWtF8X.js → apl-Bb4IeT5V.js} +1 -1
- package/dist/ui/assets/{astro-BYFEVBuN.js → astro-Bjavu3nT.js} +1 -1
- package/dist/ui/assets/{blade-DoO7yvMR.js → blade-DKW2uHZo.js} +1 -1
- package/dist/ui/assets/{c-Rl2hMCcg.js → c-oLeHmzbj.js} +1 -1
- package/dist/ui/assets/{cobol-ByC5mWiB.js → cobol-CcqFMr5T.js} +1 -1
- package/dist/ui/assets/{coffee-Dez77Qov.js → coffee-BA20zqRF.js} +1 -1
- package/dist/ui/assets/{cpp-DtaAQT9h.js → cpp-D750WmDa.js} +1 -1
- package/dist/ui/assets/{crystal-Bgmbf8ec.js → crystal-Cv5I6OMI.js} +1 -1
- package/dist/ui/assets/{css-C1tjBtVN.js → css-CjPPWPeH.js} +1 -1
- package/dist/ui/assets/{edge-DeH6u8Wg.js → edge-aYRuudEZ.js} +1 -1
- package/dist/ui/assets/{elixir-_H3KnmWT.js → elixir-ChLitmz7.js} +1 -1
- package/dist/ui/assets/{elm-CsCe3U28.js → elm-Fs7L7u36.js} +1 -1
- package/dist/ui/assets/{erb-CbM-L2g8.js → erb-B-qXHxN1.js} +1 -1
- package/dist/ui/assets/{git-rebase-D0s5pDh9.js → git-rebase-DOVN5OEg.js} +1 -1
- package/dist/ui/assets/{glimmer-js-BfOToq_A.js → glimmer-js-BFt_vCTW.js} +1 -1
- package/dist/ui/assets/{glimmer-ts-CCUOkL2K.js → glimmer-ts-ufCHlR6C.js} +1 -1
- package/dist/ui/assets/{glsl-DH4ec9dE.js → glsl-Ex4JXGuC.js} +1 -1
- package/dist/ui/assets/{graphql-DilAMBoI.js → graphql-pQPXtBk5.js} +1 -1
- package/dist/ui/assets/{hack-BDkNDZlF.js → hack-B5hDguhd.js} +1 -1
- package/dist/ui/assets/{haml-D_QBp6K7.js → haml-BrNeI29U.js} +1 -1
- package/dist/ui/assets/{handlebars-DePUrTpC.js → handlebars-DCqTsL9-.js} +1 -1
- package/dist/ui/assets/{heavy-payload-DOwZpO6n.js → heavy-payload-DsmmHgvt.js} +3 -3
- package/dist/ui/assets/{html-By4dNnM4.js → html-D8k0CC9V.js} +1 -1
- package/dist/ui/assets/{html-derivative-DDw9Ef4Q.js → html-derivative-CC8flWmC.js} +1 -1
- package/dist/ui/assets/{http-B0QxWc9M.js → http-BYnWqNep.js} +1 -1
- package/dist/ui/assets/{hurl-vMQ4lda1.js → hurl-BND-z85s.js} +1 -1
- package/dist/ui/assets/{java-DYRe2lWG.js → java-Dug0oB9T.js} +1 -1
- package/dist/ui/assets/{javascript-CxyGqwcL.js → javascript-oDJ7WITC.js} +1 -1
- package/dist/ui/assets/{jinja-JUwV-fZt.js → jinja-Cv0t_F1U.js} +1 -1
- package/dist/ui/assets/{jison-7ZqCEvS8.js → jison-Car3MF55.js} +1 -1
- package/dist/ui/assets/{json-dbltgiiA.js → json-CEViCsf4.js} +1 -1
- package/dist/ui/assets/{jsx-oDopT7YQ.js → jsx-BfZ0zgSH.js} +1 -1
- package/dist/ui/assets/{julia-CkKiNSav.js → julia-CmX0b3Tn.js} +1 -1
- package/dist/ui/assets/{just-DuqCAKJ3.js → just-BuugLCVk.js} +1 -1
- package/dist/ui/assets/{latex-sudcRDSn.js → latex-FpTXqO03.js} +1 -1
- package/dist/ui/assets/{liquid-Di-08Js7.js → liquid-B37OzUFu.js} +1 -1
- package/dist/ui/assets/{lua-YlqdMoV0.js → lua-BHjcb8oq.js} +1 -1
- package/dist/ui/assets/{marko-CJRNyJDb.js → marko-CApj_fsH.js} +1 -1
- package/dist/ui/assets/{mdc-t12CzZHs.js → mdc-Ed5vQWq8.js} +1 -1
- package/dist/ui/assets/{nginx-57-b4XwT.js → nginx-u_rVEBox.js} +1 -1
- package/dist/ui/assets/{nim-BzrswYQa.js → nim-Ba9EdchT.js} +1 -1
- package/dist/ui/assets/{perl-D9JR_iIh.js → perl-BpU_6Wvz.js} +1 -1
- package/dist/ui/assets/{php-Py2gFHil.js → php-bKabofky.js} +1 -1
- package/dist/ui/assets/{pug-PzLLy0h1.js → pug-C_aLNkqe.js} +1 -1
- package/dist/ui/assets/{qml-By8fwgV4.js → qml-D9VisnRy.js} +1 -1
- package/dist/ui/assets/{r-CcezTbLq.js → r-CYqB1sLx.js} +1 -1
- package/dist/ui/assets/{razor-dG-vdhL_.js → razor-DNJKI8Rs.js} +1 -1
- package/dist/ui/assets/{regexp-BlsQ-N_8.js → regexp-DHrTHXkz.js} +1 -1
- package/dist/ui/assets/{rst-C2awDCat.js → rst-CbNdSFHv.js} +1 -1
- package/dist/ui/assets/{ruby-zA2W_49d.js → ruby-FyKG-pkF.js} +1 -1
- package/dist/ui/assets/{sas-D49bhyaN.js → sas-BbSPDl3X.js} +1 -1
- package/dist/ui/assets/{scss-BQb-cp01.js → scss-2nX9g6gD.js} +1 -1
- package/dist/ui/assets/{shellscript-Dga4H_Ni.js → shellscript-CmON6x2x.js} +1 -1
- package/dist/ui/assets/{shellsession-n3-5CqcF.js → shellsession-DtqIGlAX.js} +1 -1
- package/dist/ui/assets/{soy-XYBOf_BA.js → soy-BzUJMmJT.js} +1 -1
- package/dist/ui/assets/{sql-ET4u5Cpl.js → sql-CgVcFZmb.js} +1 -1
- package/dist/ui/assets/{stata-CLHcJHO_.js → stata-CNitlMot.js} +1 -1
- package/dist/ui/assets/{surrealql-BdjQ60T4.js → surrealql-BA8-xsRZ.js} +1 -1
- package/dist/ui/assets/{svelte-B2RPtKJe.js → svelte-El02yAxv.js} +1 -1
- package/dist/ui/assets/{templ-CrByPW_W.js → templ-DeUQ84aR.js} +1 -1
- package/dist/ui/assets/{tex-DZBkg363.js → tex-Cu-FqpPS.js} +1 -1
- package/dist/ui/assets/{ts-tags-DJR3Gphb.js → ts-tags-X42N6TGA.js} +1 -1
- package/dist/ui/assets/{tsx-CajzROyy.js → tsx-C1aPp9rY.js} +1 -1
- package/dist/ui/assets/{twig-BZjk5Zda.js → twig-Cj1Q4SQc.js} +1 -1
- package/dist/ui/assets/{typescript-B-EWToLj.js → typescript-Du9lVt1G.js} +1 -1
- package/dist/ui/assets/{vue-D_rHCCr8.js → vue-_uMGbFv8.js} +1 -1
- package/dist/ui/assets/{vue-html-CC4WlvVt.js → vue-html-D61naG-Q.js} +1 -1
- package/dist/ui/assets/{vue-vine-BgNMVgpk.js → vue-vine-CkFae4yV.js} +1 -1
- package/dist/ui/assets/{xml-BI86-WbH.js → xml-Cbwsc6ws.js} +1 -1
- package/dist/ui/assets/{xsl-DXeLZV4J.js → xsl-NyBx72XB.js} +1 -1
- package/dist/ui/assets/{yaml-60_PFlWa.js → yaml-Cgb6Uq9u.js} +1 -1
- package/dist/workspaces/context.js +32 -5
- package/dist/workspaces/presentation/workspace-presentation.js +1 -0
- package/dist/workspaces/sessions.js +2 -0
- package/dist/workspaces.js +2 -1
- package/docs/configuration.md +101 -14
- package/package.json +2 -2
- package/scripts/release/release-gate.test.mjs +1 -0
- package/scripts/release-proof.mjs +85 -9
- package/scripts/release-proof.test.mjs +79 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { createServer } from "node:http";
|
|
4
5
|
import { tmpdir } from "node:os";
|
|
5
6
|
import { join } from "node:path";
|
|
6
7
|
import test from "node:test";
|
|
@@ -21,10 +22,36 @@ async function runProof(cwd, action, env = {}) {
|
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
async function artifactApiEnv(t, { npmStatus = 404, githubStatus = 404 } = {}) {
|
|
26
|
+
const server = createServer((request, response) => {
|
|
27
|
+
if (request.url?.startsWith("/npm/")) response.statusCode = npmStatus;
|
|
28
|
+
else if (request.url?.startsWith("/github/")) response.statusCode = githubStatus;
|
|
29
|
+
else response.statusCode = 500;
|
|
30
|
+
response.end();
|
|
31
|
+
});
|
|
32
|
+
await new Promise((resolve, reject) => {
|
|
33
|
+
server.once("error", reject);
|
|
34
|
+
server.listen(0, "127.0.0.1", resolve);
|
|
35
|
+
});
|
|
36
|
+
t.after(() => new Promise((resolve) => server.close(resolve)));
|
|
37
|
+
const address = server.address();
|
|
38
|
+
assert.ok(address && typeof address === "object");
|
|
39
|
+
const base = `http://127.0.0.1:${address.port}`;
|
|
40
|
+
return {
|
|
41
|
+
NODE_ENV: "test",
|
|
42
|
+
FORGERELAY_TEST_NPM_REGISTRY_URL: `${base}/npm/`,
|
|
43
|
+
FORGERELAY_TEST_GITHUB_API_URL: `${base}/github/`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
24
47
|
test("release tag hook gate uses repository facts instead of requiring a local proof", async (t) => {
|
|
25
48
|
const root = await mkdtemp(join(tmpdir(), "forgerelay-release-proof-"));
|
|
26
49
|
t.after(() => rm(root, { recursive: true, force: true }));
|
|
27
|
-
await writeFile(join(root, "package.json"), JSON.stringify({
|
|
50
|
+
await writeFile(join(root, "package.json"), JSON.stringify({
|
|
51
|
+
name: "@akira-tl/forgerelay",
|
|
52
|
+
version: "1.2.3",
|
|
53
|
+
repository: { url: "git+https://github.com/Akira-TL/forgerelay.git" },
|
|
54
|
+
}) + "\n");
|
|
28
55
|
await mkdir(join(root, "docs", "releases"), { recursive: true });
|
|
29
56
|
await writeFile(join(root, "docs", "releases", "v1.2.3.md"), "# v1.2.3\n\nDedicated notes.\n");
|
|
30
57
|
await writeFile(join(root, "tracked.txt"), "verified\n");
|
|
@@ -93,6 +120,14 @@ test("release tag hook gate uses repository facts instead of requiring a local p
|
|
|
93
120
|
await rm(join(root, "untracked.txt"));
|
|
94
121
|
await git(root, ["add", "tracked.txt"]);
|
|
95
122
|
await git(root, ["commit", "--allow-empty", "-m", "new head"]);
|
|
123
|
+
await runProof(root, "write");
|
|
124
|
+
const mutableEnv = await artifactApiEnv(t);
|
|
125
|
+
const deletion = await runProof(root, "check-hook", {
|
|
126
|
+
...mutableEnv,
|
|
127
|
+
FORGERELAY_HOOK_PAYLOAD: JSON.stringify({ command: "git push --delete origin v1.2.3" }),
|
|
128
|
+
});
|
|
129
|
+
assert.match(deletion.stdout, /Release tag rebuild gate OK: v1\.2\.3/);
|
|
130
|
+
|
|
96
131
|
await assert.rejects(
|
|
97
132
|
() => runProof(root, "check-hook", {
|
|
98
133
|
FORGERELAY_HOOK_PAYLOAD: JSON.stringify({ command: "git push origin v1.2.3" }),
|
|
@@ -104,6 +139,49 @@ test("release tag hook gate uses repository facts instead of requiring a local p
|
|
|
104
139
|
);
|
|
105
140
|
});
|
|
106
141
|
|
|
142
|
+
test("release tag hook gate refuses deletion after an irreversible release artifact exists", async (t) => {
|
|
143
|
+
const root = await mkdtemp(join(tmpdir(), "forgerelay-release-proof-"));
|
|
144
|
+
t.after(() => rm(root, { recursive: true, force: true }));
|
|
145
|
+
await writeFile(join(root, "package.json"), JSON.stringify({
|
|
146
|
+
name: "@akira-tl/forgerelay",
|
|
147
|
+
version: "1.3.0",
|
|
148
|
+
repository: { url: "git+https://github.com/Akira-TL/forgerelay.git" },
|
|
149
|
+
}) + "\n");
|
|
150
|
+
await mkdir(join(root, "docs", "releases"), { recursive: true });
|
|
151
|
+
await writeFile(join(root, "docs", "releases", "v1.3.0.md"), "# v1.3.0\n\nDedicated notes.\n");
|
|
152
|
+
await git(root, ["init"]);
|
|
153
|
+
await git(root, ["config", "user.email", "proof@example.com"]);
|
|
154
|
+
await git(root, ["config", "user.name", "Release Proof Test"]);
|
|
155
|
+
await git(root, ["add", "."]);
|
|
156
|
+
await git(root, ["commit", "-m", "release 1.3.0"]);
|
|
157
|
+
await git(root, ["tag", "v1.3.0"]);
|
|
158
|
+
await runProof(root, "write");
|
|
159
|
+
|
|
160
|
+
const npmPublishedEnv = await artifactApiEnv(t, { npmStatus: 200, githubStatus: 404 });
|
|
161
|
+
await assert.rejects(
|
|
162
|
+
() => runProof(root, "check-hook", {
|
|
163
|
+
...npmPublishedEnv,
|
|
164
|
+
FORGERELAY_HOOK_PAYLOAD: JSON.stringify({ command: "git push --delete origin v1.3.0" }),
|
|
165
|
+
}),
|
|
166
|
+
(error) => {
|
|
167
|
+
assert.match(String(error.stderr ?? error), /npm package .* already exists/);
|
|
168
|
+
return true;
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const githubPublishedEnv = await artifactApiEnv(t, { npmStatus: 404, githubStatus: 200 });
|
|
173
|
+
await assert.rejects(
|
|
174
|
+
() => runProof(root, "check-hook", {
|
|
175
|
+
...githubPublishedEnv,
|
|
176
|
+
FORGERELAY_HOOK_PAYLOAD: JSON.stringify({ command: "git push --delete origin v1.3.0" }),
|
|
177
|
+
}),
|
|
178
|
+
(error) => {
|
|
179
|
+
assert.match(String(error.stderr ?? error), /GitHub Release .* already exists/);
|
|
180
|
+
return true;
|
|
181
|
+
},
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
107
185
|
test("release tag hook gate rejects a matching tag when dedicated notes are missing", async (t) => {
|
|
108
186
|
const root = await mkdtemp(join(tmpdir(), "forgerelay-release-proof-"));
|
|
109
187
|
t.after(() => rm(root, { recursive: true, force: true }));
|