@akira-tl/forgerelay 0.8.5 → 0.8.7

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +8 -10
  3. package/dist/activity/audit-store.js +44 -6
  4. package/dist/activity/mcp-query-tools.js +53 -36
  5. package/dist/activity/query-service.js +41 -11
  6. package/dist/cli.js +16 -17
  7. package/dist/composite-activity.js +124 -33
  8. package/dist/config.js +8 -13
  9. package/dist/db/migrations.js +9 -0
  10. package/dist/db/schema.js +1 -0
  11. package/dist/lsp/test-support/server-fixture.js +7 -7
  12. package/dist/mcp/server-instructions.js +2 -2
  13. package/dist/process-sessions.js +2 -2
  14. package/dist/remote-auth.js +11 -1
  15. package/dist/remote-mcp-connection-pool.js +90 -0
  16. package/dist/remote-transport.js +28 -14
  17. package/dist/remote-workspace-relay.js +53 -23
  18. package/dist/server.js +105 -70
  19. package/dist/skills.js +1 -1
  20. package/dist/subagents/profiles.js +1 -2
  21. package/dist/subagents/providers/adapters/pi.js +2 -2
  22. package/dist/subagents/providers/availability.js +2 -2
  23. package/dist/subagents/providers/path.js +4 -4
  24. package/dist/ui/.vite/manifest.json +32 -32
  25. package/dist/ui/activity-panel-app.html +3 -3
  26. package/dist/ui/assets/{activity-panel-app-E1ju2dqI.js → activity-panel-app-CUAN6zyW.js} +1 -1
  27. package/dist/ui/assets/{heavy-payload-CeW-n9w5.js → heavy-payload-CgzrutLm.js} +1 -1
  28. package/dist/ui/assets/{review-payload-B9CO298v.js → review-payload-BrLbezbq.js} +1 -1
  29. package/dist/ui/assets/{scrollbar-C2twAENW.js → scrollbar-CbhpdW05.js} +1 -1
  30. package/dist/ui/assets/workspace-app-Bhj96tsR.js +1 -0
  31. package/dist/ui/assets/{workspace-app-CwbJnb_w.js → workspace-app-CxwJuZyS.js} +1 -1
  32. package/dist/ui/assets/{workspace-app-BztEvZIC.js → workspace-app-D6UR0AFl.js} +3 -3
  33. package/dist/ui/assets/workspace-app-ldjBmCJR.css +1 -0
  34. package/dist/ui/assets/workspace-lifecycle-app-Cqfhx9pV.js +1 -0
  35. package/dist/ui/workspace-app.html +4 -4
  36. package/dist/ui/workspace-lifecycle-app.html +4 -4
  37. package/dist/user-config.js +3 -19
  38. package/dist/workspace-presentation.js +69 -0
  39. package/dist/workspace-store.js +29 -1
  40. package/dist/workspaces.js +59 -19
  41. package/docs/agent-profile-schema.md +4 -9
  42. package/docs/artifact-exchange.md +2 -1
  43. package/docs/chatgpt-coding-workflow.md +21 -19
  44. package/docs/configuration.md +34 -39
  45. package/docs/gotchas.md +10 -7
  46. package/docs/roadmap.md +11 -4
  47. package/docs/security.md +3 -2
  48. package/docs/setup.md +8 -5
  49. package/docs/versioning.md +1 -1
  50. package/package.json +3 -2
  51. package/scripts/debug/accept.mjs +7 -1
  52. package/scripts/debug/relay-accept.mjs +0 -1
  53. package/scripts/debug/runtime.mjs +0 -4
  54. package/scripts/debug/runtime.test.mjs +0 -2
  55. package/scripts/debug/traffic/run.sh +5 -0
  56. package/scripts/debug/traffic/traffic-audit.mjs +907 -0
  57. package/scripts/release/push-ready.mjs +124 -0
  58. package/scripts/release/push-ready.test.mjs +108 -0
  59. package/scripts/release/release-gate.test.mjs +1 -0
  60. package/scripts/release-proof.mjs +16 -1
  61. package/dist/ui/assets/workspace-app-YnUST8IP.css +0 -1
  62. package/dist/ui/assets/workspace-app-rKuhdae8.js +0 -1
  63. package/dist/ui/assets/workspace-lifecycle-app-CEfMdudP.js +0 -1
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync, spawnSync } from "node:child_process";
4
+ import { dirname, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const repoRoot = process.cwd();
8
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
9
+ const proofScript = resolve(scriptDir, "..", "release-proof.mjs");
10
+
11
+ try {
12
+ const branch = git(["symbolic-ref", "--quiet", "--short", "HEAD"]);
13
+ if (branch !== "main" && !branch.startsWith("release/")) {
14
+ throw new Error(`release-ready push must run from main or release/*, not ${branch}`);
15
+ }
16
+
17
+ verifyReleaseProof();
18
+ git(["fetch", "--quiet", "origin", "main"]);
19
+
20
+ const head = git(["rev-parse", "HEAD"]);
21
+ if (!gitSucceeds(["merge-base", "--is-ancestor", "origin/main", head])) {
22
+ throw new Error("release HEAD must fast-forward origin/main; reconcile remote main before publishing");
23
+ }
24
+
25
+ if (branch !== "main") {
26
+ assertLocalMainCanMove(head);
27
+ }
28
+
29
+ const refspecs = ["HEAD:refs/heads/main"];
30
+ if (branch !== "main") refspecs.push(`HEAD:refs/heads/${branch}`);
31
+ runGit(["push", "--atomic", "origin", ...refspecs]);
32
+
33
+ if (branch !== "main") {
34
+ runGit(["branch", "-f", "main", head]);
35
+ }
36
+
37
+ const remoteMain = git(["rev-parse", "origin/main"]);
38
+ const localMain = git(["rev-parse", "main"]);
39
+ if (remoteMain !== head || localMain !== head) {
40
+ throw new Error("release-ready push completed but local/remote main did not converge on release HEAD");
41
+ }
42
+
43
+ console.log(`Release-ready branches synchronized at ${head.slice(0, 12)} (${branch} -> origin/main).`);
44
+ } catch (error) {
45
+ console.error(`release-push-ready: ${error instanceof Error ? error.message : String(error)}`);
46
+ process.exitCode = 1;
47
+ }
48
+
49
+ function verifyReleaseProof() {
50
+ const result = spawnSync(process.execPath, [proofScript, "check"], {
51
+ cwd: repoRoot,
52
+ env: process.env,
53
+ encoding: "utf8",
54
+ stdio: ["ignore", "pipe", "pipe"],
55
+ windowsHide: true,
56
+ shell: false,
57
+ });
58
+ if (result.error) throw result.error;
59
+ if (result.status !== 0) {
60
+ const detail = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
61
+ throw new Error(detail || `release proof check failed with exit ${result.status ?? "unknown"}`);
62
+ }
63
+ }
64
+
65
+ function assertLocalMainCanMove(head) {
66
+ git(["rev-parse", "--verify", "refs/heads/main"]);
67
+ const uniquePatches = git(["cherry", head, "main"])
68
+ .split("\n")
69
+ .map((line) => line.trim())
70
+ .filter((line) => line.startsWith("+ "));
71
+ if (uniquePatches.length > 0) {
72
+ throw new Error(
73
+ `local main has commits with patches not present in release HEAD: ${uniquePatches.map((line) => line.slice(2, 14)).join(", ")}`,
74
+ );
75
+ }
76
+
77
+ const mainWorktree = checkedOutBranchWorktree("refs/heads/main");
78
+ if (mainWorktree) {
79
+ throw new Error(`local main is checked out in another worktree (${mainWorktree}); switch it away before release-ready push`);
80
+ }
81
+ }
82
+
83
+ function checkedOutBranchWorktree(branchRef) {
84
+ const records = git(["worktree", "list", "--porcelain"]).split(/\n\n+/);
85
+ for (const record of records) {
86
+ const lines = record.split("\n");
87
+ if (!lines.includes(`branch ${branchRef}`)) continue;
88
+ return lines.find((line) => line.startsWith("worktree "))?.slice("worktree ".length);
89
+ }
90
+ return undefined;
91
+ }
92
+
93
+ function git(args) {
94
+ return execFileSync("git", args, {
95
+ cwd: repoRoot,
96
+ encoding: "utf8",
97
+ stdio: ["ignore", "pipe", "pipe"],
98
+ }).trim();
99
+ }
100
+
101
+ function gitSucceeds(args) {
102
+ const result = spawnSync("git", args, {
103
+ cwd: repoRoot,
104
+ stdio: "ignore",
105
+ windowsHide: true,
106
+ shell: false,
107
+ });
108
+ if (result.error) throw result.error;
109
+ return result.status === 0;
110
+ }
111
+
112
+ function runGit(args) {
113
+ const result = spawnSync("git", args, {
114
+ cwd: repoRoot,
115
+ env: process.env,
116
+ stdio: "inherit",
117
+ windowsHide: true,
118
+ shell: false,
119
+ });
120
+ if (result.error) throw result.error;
121
+ if (result.status !== 0) {
122
+ throw new Error(`git ${args[0]} failed with exit ${result.status ?? "unknown"}`);
123
+ }
124
+ }
@@ -0,0 +1,108 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFileSync, spawnSync } from "node:child_process";
3
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import test from "node:test";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
10
+ const pushReadyScript = resolve(repoRoot, "scripts/release/push-ready.mjs");
11
+ const releaseProofScript = resolve(repoRoot, "scripts/release-proof.mjs");
12
+
13
+ function git(cwd, args) {
14
+ return execFileSync("git", args, {
15
+ cwd,
16
+ encoding: "utf8",
17
+ stdio: ["ignore", "pipe", "pipe"],
18
+ }).trim();
19
+ }
20
+
21
+ function writePackage(root, version = "1.2.3") {
22
+ writeFileSync(join(root, "package.json"), `${JSON.stringify({ version }, null, 2)}\n`);
23
+ }
24
+
25
+ function commitAll(root, message) {
26
+ git(root, ["add", "--all"]);
27
+ git(root, ["commit", "-m", message]);
28
+ }
29
+
30
+ function fixture() {
31
+ const root = mkdtempSync(join(tmpdir(), "forgerelay-release-push-ready-"));
32
+ const origin = join(root, "origin.git");
33
+ const checkout = join(root, "checkout");
34
+ mkdirSync(checkout, { recursive: true });
35
+ git(root, ["init", "--bare", origin]);
36
+ git(checkout, ["init", "-b", "main"]);
37
+ git(checkout, ["config", "user.email", "forgerelay@example.com"]);
38
+ git(checkout, ["config", "user.name", "ForgeRelay Test"]);
39
+ git(checkout, ["remote", "add", "origin", origin]);
40
+ writePackage(checkout);
41
+ writeFileSync(join(checkout, "README.md"), "base\n");
42
+ commitAll(checkout, "base");
43
+ git(checkout, ["push", "-u", "origin", "main"]);
44
+ return { root, origin, checkout };
45
+ }
46
+
47
+ function writeProof(checkout) {
48
+ execFileSync(process.execPath, [releaseProofScript, "write"], {
49
+ cwd: checkout,
50
+ stdio: "pipe",
51
+ });
52
+ }
53
+
54
+ test("release push-ready atomically advances remote main/release and synchronizes local main", () => {
55
+ const context = fixture();
56
+ try {
57
+ const { checkout, origin } = context;
58
+ git(checkout, ["switch", "-c", "release/1.2.3"]);
59
+ writeFileSync(join(checkout, "release.txt"), "release\n");
60
+ commitAll(checkout, "release");
61
+ const releaseHead = git(checkout, ["rev-parse", "HEAD"]);
62
+ writeProof(checkout);
63
+
64
+ execFileSync(process.execPath, [pushReadyScript], {
65
+ cwd: checkout,
66
+ stdio: "pipe",
67
+ });
68
+
69
+ assert.equal(git(checkout, ["rev-parse", "main"]), releaseHead);
70
+ assert.equal(git(checkout, ["rev-parse", "origin/main"]), releaseHead);
71
+ assert.equal(git(checkout, ["rev-parse", "origin/release/1.2.3"]), releaseHead);
72
+ assert.equal(git(origin, ["rev-parse", "refs/heads/main"]), releaseHead);
73
+ assert.equal(git(origin, ["rev-parse", "refs/heads/release/1.2.3"]), releaseHead);
74
+ } finally {
75
+ rmSync(context.root, { recursive: true, force: true });
76
+ }
77
+ });
78
+
79
+ test("release push-ready refuses to move main when local main has a real unique patch", () => {
80
+ const context = fixture();
81
+ try {
82
+ const { checkout, origin } = context;
83
+ const base = git(checkout, ["rev-parse", "HEAD"]);
84
+
85
+ writeFileSync(join(checkout, "main-only.txt"), "must preserve\n");
86
+ commitAll(checkout, "main only");
87
+ const localMain = git(checkout, ["rev-parse", "HEAD"]);
88
+
89
+ git(checkout, ["switch", "-c", "release/1.2.3", base]);
90
+ writeFileSync(join(checkout, "release.txt"), "release\n");
91
+ commitAll(checkout, "release");
92
+ writeProof(checkout);
93
+
94
+ const result = spawnSync(process.execPath, [pushReadyScript], {
95
+ cwd: checkout,
96
+ encoding: "utf8",
97
+ stdio: ["ignore", "pipe", "pipe"],
98
+ });
99
+
100
+ assert.notEqual(result.status, 0);
101
+ assert.match(`${result.stdout}\n${result.stderr}`, /local main has commits with patches not present in release HEAD/i);
102
+ assert.equal(git(checkout, ["rev-parse", "main"]), localMain);
103
+ assert.equal(git(origin, ["rev-parse", "refs/heads/main"]), base);
104
+ assert.throws(() => git(origin, ["rev-parse", "refs/heads/release/1.2.3"]));
105
+ } finally {
106
+ rmSync(context.root, { recursive: true, force: true });
107
+ }
108
+ });
@@ -34,6 +34,7 @@ test("optional release:verify records proof only after the cloud-equivalent pari
34
34
  pkg.scripts["release:verify"],
35
35
  "npm run release:parity && node scripts/release-proof.mjs write",
36
36
  );
37
+ assert.equal(pkg.scripts["release:push-ready"], "node scripts/release/push-ready.mjs");
37
38
  });
38
39
 
39
40
  test("cross-platform cloud CI delegates to one shell-free verification entrypoint", async () => {
@@ -83,6 +83,20 @@ function readProof() {
83
83
  return parsed;
84
84
  }
85
85
 
86
+ function checkProof() {
87
+ assertReleaseTreeClean("using the local release proof");
88
+ const proof = readProof();
89
+ const head = currentHead();
90
+ const version = packageVersion();
91
+ if (proof.head !== head) {
92
+ throw new Error(`release proof is for ${proof.head.slice(0, 12)}, but current HEAD is ${head.slice(0, 12)}. Run npm run release:verify again`);
93
+ }
94
+ if (proof.packageVersion !== version) {
95
+ throw new Error(`release proof is for package ${proof.packageVersion}, but package.json is ${version}. Run npm run release:verify again`);
96
+ }
97
+ console.log(`Release proof OK: ${head.slice(0, 12)} (${version}).`);
98
+ }
99
+
86
100
  function hookTag() {
87
101
  let payload;
88
102
  try {
@@ -141,8 +155,9 @@ function checkHookTag() {
141
155
  const action = process.argv[2];
142
156
  try {
143
157
  if (action === "write") writeProof();
158
+ else if (action === "check") checkProof();
144
159
  else if (action === "check-hook") checkHookTag();
145
- else throw new Error("usage: node scripts/release-proof.mjs <write|check-hook>");
160
+ else throw new Error("usage: node scripts/release-proof.mjs <write|check|check-hook>");
146
161
  } catch (error) {
147
162
  fail(error instanceof Error ? error.message : String(error));
148
163
  }
@@ -1 +0,0 @@
1
- .forgerelay-panel{border:1px solid var(--tool-card-border);background:var(--tool-card-header-bg);width:100%;color:var(--color-text-primary,#f5f5f6);border-radius:12px;overflow:hidden}.workspace-panel{background:var(--tool-card-header-bg);width:100%}.workspace-panel-header{grid-template-columns:22px minmax(0,1fr) auto;align-items:center;gap:10px;min-height:58px;padding:9px 12px;display:grid}.workspace-panel-icon{background:color-mix(in srgb, var(--tool-accent) 9%, transparent);width:22px;height:22px;color:color-mix(in srgb, var(--tool-accent) 72%, var(--color-text-tertiary,#a3a3aa));border-radius:6px;place-items:center;display:grid}.workspace-panel-icon-svg{stroke-width:1.8px;width:14px;height:14px}.workspace-panel-title-group{gap:2px;min-width:0;display:grid}.workspace-panel-title{font-size:var(--font-text-sm-size,14px);font-weight:600;line-height:1.3}.workspace-panel-subtitle,.workspace-panel-mode{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,11px);line-height:1.35}.workspace-panel-subtitle{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.workspace-panel-mode{border:1px solid color-mix(in srgb, var(--tool-card-divider) 76%, transparent);white-space:nowrap;border-radius:999px;padding:2px 7px}.workspace-panel .workspace-details{border-top:1px solid var(--tool-card-divider);background:var(--tool-card-body-bg);max-height:none}.workspace-panel-pending-dot{background:var(--color-text-info,#38bdf8);width:8px;height:8px;box-shadow:0 0 0 3px color-mix(in srgb, var(--color-text-info,#38bdf8) 12%, transparent);border-radius:999px;justify-self:center}.activity-panel{border:1px solid var(--tool-card-border);background:var(--tool-card-header-bg);width:100%;color:var(--color-text-primary,#f5f5f6);border-radius:12px;overflow:hidden}.forgerelay-panel .activity-panel{border:0;border-top:1px solid var(--tool-card-divider);border-radius:0}.activity-panel-header{width:100%;min-height:58px;color:inherit;cursor:pointer;font:inherit;text-align:left;background:0 0;border:0;grid-template-columns:14px minmax(0,1fr) auto 20px;align-items:center;gap:10px;padding:9px 12px;display:grid}.activity-panel-header:hover{background:var(--tool-card-hover-bg)}.activity-panel-header:focus-visible{outline:2px solid color-mix(in srgb, var(--color-text-info,#38bdf8) 72%, transparent);outline-offset:-2px}.activity-panel-header-pending{cursor:default}.activity-panel-header-pending:hover{background:0 0}.activity-panel-pending-spacer{width:20px}.activity-panel-status{background:var(--color-text-info,#38bdf8);width:8px;height:8px;box-shadow:0 0 0 3px color-mix(in srgb, var(--color-text-info,#38bdf8) 12%, transparent);border-radius:9999px;justify-self:center}.activity-panel-status.state-done{background:var(--color-success-text,#6fda83);box-shadow:0 0 0 3px color-mix(in srgb, var(--color-success-text,#6fda83) 12%, transparent)}.activity-panel-status.state-error{background:var(--color-danger-text,#ee7676);box-shadow:0 0 0 3px color-mix(in srgb, var(--color-danger-text,#ee7676) 12%, transparent)}.activity-panel-title-group{gap:2px;min-width:0;display:grid}.activity-panel-title{font-size:var(--font-text-sm-size,14px);font-weight:600;line-height:1.3}.activity-panel-subtitle,.activity-panel-count{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,11px);line-height:1.35}.activity-panel-count{white-space:nowrap}.activity-panel-body{border-top:1px solid var(--tool-card-divider);background:var(--tool-card-body-bg);display:grid}.activity-viewport{overscroll-behavior:contain;max-height:420px;overflow:hidden auto}.activity-list{display:grid}.activity-group+.activity-group{border-top:1px solid var(--tool-card-divider)}.activity-group.grouped>.activity-row.parent{background:color-mix(in srgb, var(--color-background-secondary,#272727) 54%, transparent)}.activity-children{border-top:1px solid color-mix(in srgb, var(--tool-card-divider) 72%, transparent);display:grid}.activity-row{--activity-accent:var(--color-text-secondary,#b6b6bd);--activity-phase:var(--color-text-tertiary,#a3a3aa);width:100%;min-height:46px;color:inherit;font:inherit;text-align:left;background:0 0;border:0;grid-template-columns:28px minmax(0,1fr) auto 16px;align-items:center;gap:10px;padding:7px 12px;display:grid}.activity-row.interactive{cursor:pointer}.activity-row.interactive:hover{background:var(--tool-card-hover-bg)}.activity-row.interactive:focus-visible{outline:2px solid color-mix(in srgb, var(--activity-accent) 68%, transparent);outline-offset:-2px}.activity-row.child{padding-left:34px;position:relative}.activity-row.child:before{background:color-mix(in srgb, var(--activity-accent) 26%, var(--tool-card-divider));content:"";width:1px;position:absolute;top:0;bottom:0;left:20px}.activity-row.child+.activity-row.child{border-top:1px solid color-mix(in srgb, var(--tool-card-divider) 52%, transparent)}.activity-row.kind-read{--activity-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 32%, #06b6d4 68%)}.activity-row.kind-write{--activity-accent:var(--color-success-text,#6fda83)}.activity-row.kind-edit,.activity-row.kind-rename{--activity-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 28%, #d99742 72%)}.activity-row.kind-delete{--activity-accent:var(--color-danger-text,#ee7676)}.activity-row.kind-shell{--activity-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 42%, #64748b 58%)}.activity-row.kind-shell-result{--activity-accent:color-mix(in srgb, var(--color-success-text,#6fda83) 72%, var(--color-text-secondary,#b6b6bd))}.activity-row.kind-capability{--activity-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 34%, #3b82f6 66%)}.activity-row.kind-batch{--activity-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 34%, #8b5cf6 66%)}.activity-row.phase-executing{--activity-phase:var(--color-text-info,#38bdf8)}.activity-row.phase-returned{--activity-phase:var(--color-warning-text,#e6b566)}.activity-row.phase-done{--activity-phase:var(--color-success-text,#6fda83)}.activity-row.phase-error{--activity-phase:var(--color-danger-text,#ee7676)}.activity-row.shell-result{box-shadow:inset 2px 0 0 color-mix(in srgb, var(--activity-accent) 68%, transparent)}.activity-icon{border:1px solid color-mix(in srgb, var(--activity-accent) 18%, transparent);background:color-mix(in srgb, var(--activity-accent) 9%, transparent);width:28px;height:28px;color:var(--activity-accent);border-radius:7px;place-items:center;display:grid}.activity-icon-svg{stroke-width:1.8px;width:15px;height:15px}.activity-main{gap:4px;min-width:0;display:grid}.activity-title-line{align-items:baseline;gap:8px;min-width:0;display:flex}.activity-title{color:var(--color-text-primary,#f5f5f6);font-size:var(--font-text-sm-size,12px);flex:none;font-weight:600;line-height:1.35}.activity-member{color:var(--color-text-secondary,#d4d4d8);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,10px);flex:none;line-height:1.4}.activity-target{min-width:0;color:var(--color-text-tertiary,#a3a3aa);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,11px);text-overflow:ellipsis;white-space:nowrap;line-height:1.4;overflow:hidden}.activity-meta{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,10px);font-variant-numeric:tabular-nums;white-space:nowrap;justify-content:flex-end;align-items:center;gap:8px;display:inline-flex}.activity-phase{color:var(--activity-phase);align-items:center;gap:5px;display:inline-flex}.activity-phase:before{content:"";background:currentColor;border-radius:9999px;width:6px;height:6px}.activity-progress-wrap{grid-template-columns:auto minmax(48px,110px);align-items:center;gap:8px;max-width:220px;display:grid}.activity-progress-counts{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,10px);font-variant-numeric:tabular-nums;white-space:nowrap}.activity-progress-track{background:color-mix(in srgb, var(--activity-accent) 14%, var(--tool-card-divider));border-radius:9999px;height:3px;display:block;overflow:hidden}.activity-progress-fill{border-radius:inherit;background:var(--activity-accent);height:100%;display:block}.activity-empty,.activity-refresh-error{color:var(--color-text-secondary,#b7b7bf);font-size:var(--font-text-sm-size,12px);padding:12px}.activity-refresh-error{border-top:1px solid var(--tool-card-divider);color:var(--color-danger-text,#ee7676)}.activity-detail-chevron,.activity-detail-spacer,.activity-detail-chevron.chevron{width:16px;height:16px}.activity-detail-chevron .icon-svg{width:13px;height:13px}.activity-entry.expanded>.activity-row{background:color-mix(in srgb, var(--activity-accent) 6%, transparent)}.activity-detail{border-top:1px solid color-mix(in srgb, var(--tool-card-divider) 72%, transparent);background:color-mix(in srgb, var(--color-background-primary,#101114) 90%, transparent);display:grid}.activity-detail-section+.activity-detail-section{border-top:1px solid color-mix(in srgb, var(--tool-card-divider) 62%, transparent)}.activity-detail-label{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,10px);letter-spacing:.02em;padding:8px 12px 0;font-weight:600}.activity-detail-section.error .activity-detail-label,.activity-detail-section.error .activity-detail-value{color:var(--color-danger-text,#ee7676)}.activity-detail-value{max-height:260px;color:var(--color-text-secondary,#c7c7ce);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,11px);white-space:pre-wrap;overflow-wrap:break-word;margin:0;padding:6px 12px 10px;line-height:1.5;overflow:auto}.activity-detail-status{color:var(--color-text-secondary,#b7b7bf);font-size:var(--font-text-sm-size,12px);padding:10px 12px}.activity-detail-status.error{color:var(--color-danger-text,#ee7676)}.activity-terminal{background:var(--color-background-primary,#101114)}.activity-terminal-command,.activity-terminal-output{color:var(--color-text-primary,#f5f5f6);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,11px);white-space:pre-wrap;overflow-wrap:break-word;background:0 0;border:0;border-radius:0;margin:0;line-height:1.55}.activity-terminal-command{border-bottom:1px solid color-mix(in srgb, var(--tool-card-divider) 74%, transparent);color:var(--color-text-secondary,#c7c7ce);padding:9px 12px}.activity-terminal-output{max-height:320px;padding:10px 12px;overflow:auto}.activity-terminal-meta{border-top:1px solid color-mix(in srgb, var(--tool-card-divider) 74%, transparent);color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-xs-size,10px);font-variant-numeric:tabular-nums;padding:7px 12px}.activity-terminal-meta.status-running{color:var(--color-text-info,#38bdf8)}.activity-terminal-meta.status-done{color:var(--color-success-text,#6fda83)}.activity-terminal-meta.status-failed{color:var(--color-danger-text,#ee7676)}@media (width<=520px){.activity-panel-header{grid-template-columns:12px minmax(0,1fr) auto 18px;gap:8px;min-height:54px;padding:8px 10px}.activity-panel-subtitle,.activity-panel-count{font-size:10px}.activity-row{grid-template-columns:26px minmax(0,1fr) 18px;gap:6px 8px;min-height:48px;padding:8px 10px}.activity-row.child{padding-left:28px}.activity-row.child:before{left:16px}.activity-icon{align-self:start;width:26px;height:26px}.activity-title-line{gap:2px;display:grid}.activity-meta{grid-column:2;justify-content:flex-start}.activity-detail-chevron,.activity-detail-spacer{grid-area:1/3/span 2}.activity-progress-wrap{grid-template-columns:auto minmax(40px,1fr);max-width:none}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif);color:var(--color-text-primary,#f5f5f6);--tool-card-border:color-mix(in srgb, var(--color-border-primary,#414141) 74%, transparent);--tool-card-header-bg:color-mix(in srgb, var(--color-background-secondary,#272727) 88%, transparent);--tool-card-body-bg:color-mix(in srgb, var(--color-background-primary,#181818) 94%, transparent);--tool-card-hover-bg:color-mix(in srgb, var(--color-background-tertiary,#343434) 46%, transparent);--tool-card-divider:color-mix(in srgb, var(--color-border-primary,#414141) 66%, transparent);--tool-accent:var(--color-text-secondary,#b6b6bd);--scrollbar-thumb:color-mix(in srgb, var(--color-text-tertiary,#8a8a8a) 56%, transparent);--scrollbar-thumb-hover:color-mix(in srgb, var(--color-text-secondary,#a8a8a8) 82%, transparent);background:0 0}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}*{box-sizing:border-box}html,body{background:0 0;margin:0;overflow:hidden}.shell{width:100%;padding:0;overflow:hidden}.empty,.tool-card{--tool-accent-soft:color-mix(in srgb, var(--tool-accent) 12%, transparent);border:1px solid var(--tool-card-border);background:var(--tool-card-header-bg);width:100%;box-shadow:none;color:var(--color-text-primary,#f5f5f6);border-radius:12px;overflow:hidden}.tool-card.workspace,.tool-card.directory{--tool-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 34%, #3b82f6 66%)}.tool-card.read,.tool-card.search{--tool-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 32%, #06b6d4 68%)}.tool-card.write{--tool-accent:var(--color-success-text,#6fda83)}.tool-card.edit,.tool-card.review{--tool-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 28%, #d99742 72%)}.tool-card.delete{--tool-accent:var(--color-danger-text,#ee7676)}.tool-card.shell{--tool-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 42%, #64748b 58%)}.tool-card.state-success{--tool-accent:var(--color-success-text,#6fda83)}.tool-card.state-error{--tool-accent:var(--color-danger-text,#ee7676)}.tool-card.state-running{--tool-accent:color-mix(in srgb, var(--color-text-primary,#f5f5f6) 30%, #38bdf8 70%)}@supports selector(::-webkit-scrollbar){.pretty-scrollbar::-webkit-scrollbar{width:12px;height:12px}.pretty-scrollbar::-webkit-scrollbar-button{width:0;height:0;display:none}.pretty-scrollbar::-webkit-scrollbar-track{background:0 0}.pretty-scrollbar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb);background-clip:content-box;border:4px solid #0000;border-radius:9999px}.pretty-scrollbar::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover)}.pretty-scrollbar::-webkit-scrollbar-thumb:active{background-color:var(--scrollbar-thumb-hover)}.pretty-scrollbar::-webkit-scrollbar-corner{background:0 0}}.empty{color:var(--color-text-secondary,#b6b6bd);font-size:var(--font-text-sm-size,13px);padding:14px 16px}.tool-header{width:100%;min-height:64px;color:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:11px;grid-template-columns:40px minmax(0,1fr) auto 20px;align-items:center;gap:12px;padding:10px 12px;display:grid}.tool-header:focus-visible,.review-diff-file-header:focus-visible,.review-more:focus-visible{outline:2px solid color-mix(in srgb, var(--tool-accent) 72%, transparent);outline-offset:-2px}.tool-header:hover:not(:disabled){background:var(--tool-card-hover-bg)}.tool-header:disabled{cursor:default}.tool-icon{border:1px solid color-mix(in srgb, var(--tool-accent) 18%, transparent);background:var(--tool-accent-soft);width:40px;height:40px;color:var(--tool-accent);border-radius:10px;place-items:center;display:grid}.icon-svg{stroke-width:1.8px;width:20px;height:20px;display:block}.tool-main{gap:2px;min-width:0;display:grid}.tool-title{color:var(--color-text-primary,#f5f5f6);font-size:var(--font-text-sm-size,14px);font-weight:550;line-height:1.3}.tool-label{color:var(--color-text-tertiary,#a3a3aa);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,12px);text-overflow:ellipsis;white-space:nowrap;line-height:1.4;overflow:hidden}.stats{font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-xs-size,12px);font-variant-numeric:tabular-nums;white-space:nowrap;align-items:center;gap:5px;display:inline-flex}.header-meta{color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-sm-size,12px);text-align:right;white-space:nowrap;line-height:1.35}.header-meta.empty{width:0}.add{color:var(--color-success-text,#6fda83)}.remove{color:var(--color-danger-text,#ee7676)}.chevron{width:20px;height:20px;color:var(--color-text-tertiary,#a3a3aa);border-radius:7px;place-items:center;transition:background .14s,color .14s,transform .14s;display:grid}.tool-header:hover:not(:disabled) .chevron{color:var(--color-text-primary,#f5f5f6)}.chevron .icon-svg{width:15px;height:15px}.chevron.expanded{transform:rotate(180deg)}.chevron.loading{transform:none}.chevron.loading .icon-svg{fill:none;stroke-linecap:round;stroke-dasharray:38 14;animation:.7s linear infinite payload-spinner}@keyframes payload-spinner{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.chevron.loading .icon-svg{animation:none}}.tool-body{border-top:1px solid var(--tool-card-divider);background:var(--tool-card-body-bg)}.workspace-details{max-height:420px;display:grid;overflow:auto}.workspace-rows{padding:4px 0;display:grid}.workspace-row{grid-template-columns:22px minmax(116px,.24fr) minmax(0,1fr);align-items:center;gap:10px;min-height:40px;padding:7px 12px;display:grid}.workspace-row-icon{background:color-mix(in srgb, var(--tool-accent) 9%, transparent);width:22px;height:22px;color:color-mix(in srgb, var(--tool-accent) 72%, var(--color-text-tertiary,#a3a3aa));border-radius:6px;place-items:center;display:grid}.workspace-row-icon-svg{stroke-width:1.8px;width:14px;height:14px}.workspace-key{min-height:22px;color:var(--color-text-tertiary,#a3a3aa);font-size:var(--font-text-sm-size,12px);align-items:center;font-weight:500;display:flex}.workspace-value{min-width:0;color:var(--color-text-secondary,#c7c7ce);font-size:var(--font-text-sm-size,12px);text-overflow:ellipsis;white-space:nowrap;line-height:1.45;overflow:hidden}.workspace-value.mono{font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace)}.workspace-base-value{align-items:center;gap:7px;min-width:0;display:flex}.workspace-base-value .workspace-value{flex:0 auto}.workspace-base-warning{width:18px;height:18px;color:var(--color-warning-text,#e6b566);cursor:help;flex:none;place-items:center;display:grid}.workspace-base-warning-svg{stroke-width:2px;width:14px;height:14px}.workspace-chip-list{flex-wrap:nowrap;align-items:center;gap:6px;min-width:0;display:flex;overflow:hidden}.workspace-chip{border:1px solid color-mix(in srgb, var(--tool-accent) 16%, var(--tool-card-divider));background:color-mix(in srgb, var(--tool-accent) 7%, transparent);max-width:100%;min-height:24px;color:var(--color-text-secondary,#c7c7ce);text-overflow:ellipsis;white-space:nowrap;border-radius:9999px;flex:none;align-items:center;gap:5px;padding:3px 8px;font-size:11px;line-height:1.25;display:inline-flex;overflow:hidden}.workspace-chip-logo{object-fit:contain;flex:none;width:13px;height:13px;display:block}.workspace-chip-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.workspace-agent-profile{border:0;border-bottom:1px solid color-mix(in srgb, var(--tool-accent) 34%, var(--tool-card-divider));max-width:100%;min-height:24px;color:var(--color-text-secondary,#c7c7ce);white-space:nowrap;background:0 0;border-radius:0;align-items:center;gap:5px;padding:3px 2px 4px;font-size:11px;line-height:1.25;display:inline-flex;overflow:hidden}.workspace-agent-profile-logo{object-fit:contain;flex:none;width:14px;height:14px;display:block}.workspace-agent-profile:hover{border-bottom-color:var(--tool-accent);color:var(--color-text-primary,#f5f5f6)}.workspace-agent-profile.muted{color:var(--color-text-tertiary,#a3a3aa);opacity:.72;border-bottom-style:dashed}.workspace-provider-logo{cursor:help;flex:none;place-items:center;width:20px;height:24px;display:inline-grid}.workspace-provider-logo-image{object-fit:contain;width:16px;height:16px;display:block}.workspace-provider-logo.muted{opacity:.62}.workspace-chip.muted{color:var(--color-text-tertiary,#a3a3aa);opacity:.72;border-style:dashed}.workspace-skills-row,.workspace-instructions-row,.workspace-agents-row{align-items:start}.workspace-skills-list,.workspace-agents-list{flex-wrap:wrap;overflow:visible}.workspace-instruction-status{border-radius:5px;flex:none;place-items:center;width:18px;height:18px;display:grid}.workspace-instruction-status.loaded{background:color-mix(in srgb, var(--color-success-text,#6fda83) 12%, transparent);color:var(--color-success-text,#6fda83)}.workspace-instruction-status.available{background:color-mix(in srgb, var(--color-text-tertiary,#a3a3aa) 9%, transparent);color:var(--color-text-tertiary,#a3a3aa)}.workspace-instruction-status-svg{stroke-width:1.9px;width:12px;height:12px}.workspace-instruction-list{border:1px solid var(--tool-card-divider);background:color-mix(in srgb, var(--tool-card-body-bg) 88%, transparent);border-radius:9px;min-width:0;display:grid;overflow:hidden}.workspace-instructions-content{min-width:0;display:block}.workspace-instructions-toggle{border:0;border-top:1px solid var(--tool-card-divider);background:color-mix(in srgb, var(--tool-card-body-bg) 72%, transparent);width:100%;min-height:32px;color:var(--tool-accent);cursor:pointer;font:inherit;font-size:var(--font-text-sm-size,11px);white-space:nowrap;border-radius:0 0 9px 9px;justify-content:center;align-items:center;padding:6px 10px;font-weight:550;line-height:1.25;display:flex}.workspace-instructions-toggle:hover{background:var(--tool-card-hover-bg)}.workspace-instructions-toggle:focus-visible{outline:2px solid color-mix(in srgb, var(--tool-accent) 72%, transparent);outline-offset:2px}.workspace-instruction-item+.workspace-instruction-item{border-top:1px solid var(--tool-card-divider)}.workspace-instruction-header{width:100%;min-width:0;color:inherit;font:inherit;text-align:left;background:0 0;border:0;grid-template-columns:22px minmax(0,1fr) 18px;align-items:center;gap:9px;padding:8px 10px;display:grid}.workspace-instruction-header.interactive{cursor:pointer}.workspace-instruction-header.interactive:hover{background:var(--tool-card-hover-bg)}.workspace-instruction-header.interactive:focus-visible{outline:2px solid color-mix(in srgb, var(--tool-accent) 72%, transparent);outline-offset:-2px}.workspace-instruction-text{gap:2px;min-width:0;display:grid}.workspace-instruction-name{min-width:0;color:var(--color-text-primary,#f5f5f6);font-size:var(--font-text-sm-size,12px);text-overflow:ellipsis;white-space:nowrap;font-weight:550;overflow:hidden}.workspace-instruction-path{min-width:0;color:var(--color-text-tertiary,#a3a3aa);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:10px;line-height:1.35;overflow:hidden}.workspace-instruction-chevron{width:18px;height:18px;color:var(--color-text-tertiary,#a3a3aa);place-items:center;transition:transform .14s;display:grid}.workspace-instruction-item.expanded .workspace-instruction-chevron{transform:rotate(180deg)}.workspace-instruction-chevron-svg{width:14px;height:14px}.workspace-instruction-preview{border-top:1px solid var(--tool-card-divider);background:color-mix(in srgb, var(--color-background-primary,#101114) 92%, transparent);max-height:300px;color:var(--color-text-secondary,#c7c7ce);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);white-space:pre-wrap;overflow-wrap:break-word;margin:0;padding:10px 12px;font-size:11px;line-height:1.55;overflow:auto}.workspace-instruction-preview[hidden]{display:none}.review-header{grid-template-columns:40px minmax(0,1fr) auto 20px}.review-title-group{gap:3px;min-width:0;display:grid}.review-summary{border-top:1px solid var(--tool-card-divider);background:var(--tool-card-body-bg);display:grid}.review-diff-file-stats{align-items:center;gap:8px;display:flex}.review-empty{color:var(--color-text-secondary,#b7b7bf);font-size:var(--font-text-sm-size,13px)}.review-more{border:0;border-top:1px solid var(--tool-card-divider);width:100%;min-height:40px;color:var(--color-text-tertiary,#a3a3aa);cursor:pointer;font:inherit;font-size:var(--font-text-sm-size,12px);text-align:left;background:0 0;padding:0 12px}.review-more:hover{background:var(--tool-card-hover-bg);color:var(--color-text-primary,#f5f5f6)}.review-diff{max-height:520px;display:grid;overflow:hidden auto}.review-diff-files{gap:0;padding:0;display:grid}.review-diff-file{border:0;border-radius:0;overflow:hidden}.review-diff-file+.review-diff-file{border-top:1px solid var(--tool-card-divider)}.review-diff-file-header{width:100%;min-height:42px;color:var(--color-text-primary,#f5f5f6);cursor:pointer;font:inherit;text-align:left;background:0 0;border:0;grid-template-columns:22px minmax(0,1fr) auto;align-items:center;gap:10px;padding:0 12px;display:grid}.review-file-kind{background:color-mix(in srgb, var(--color-text-tertiary,#a3a3aa) 10%, transparent);width:20px;height:20px;color:var(--color-text-tertiary,#a3a3aa);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);border-radius:6px;align-self:center;place-items:center;font-size:10px;font-weight:700;display:grid}.review-file-kind.added{background:color-mix(in srgb, var(--color-success-text,#6fda83) 12%, transparent);color:var(--color-success-text,#6fda83)}.review-file-kind.edited,.review-file-kind.renamed,.review-file-kind.renamed-edited{background:color-mix(in srgb, var(--color-warning-text,#e6b566) 12%, transparent);color:var(--color-warning-text,#e6b566)}.review-file-kind.deleted{background:color-mix(in srgb, var(--color-danger-text,#ee7676) 12%, transparent);color:var(--color-danger-text,#ee7676)}.review-single-file{overflow:hidden}.review-diff-file-header:hover{background:var(--tool-card-hover-bg)}.review-diff-file-name,.review-diff-file-stats{text-overflow:ellipsis;white-space:nowrap;font-size:13px;line-height:20px;overflow:hidden}.review-diff-file-name{font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace)}.review-diff-file-name.renamed{text-overflow:clip;align-items:center;gap:6px;min-width:0;display:flex}.review-diff-file-path{text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:calc(50% - 10px);overflow:hidden}.review-diff-file-path.previous{color:var(--color-text-tertiary,#a3a3aa)}.review-diff-file-path.current{color:var(--color-text-primary,#f5f5f6)}.review-diff-file-arrow{color:var(--color-text-tertiary,#a3a3aa);font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif);flex:none}.review-diff-file-stats{font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-sm-size,12px);font-variant-numeric:tabular-nums;justify-content:flex-end;overflow:visible}.status{font-size:var(--font-text-sm-size,12px);padding:10px 12px}.status.muted{color:var(--color-text-secondary,#b7b7bf)}.status.error{color:var(--color-danger-text,#ee7676)}.pierre-diff,.pierre-file{--diffs-bg:var(--tool-payload-bg,var(--color-background-primary,#101114));--diffs-light-bg:var(--color-background-primary,#fff);--diffs-dark-bg:var(--tool-payload-bg,var(--color-background-primary,#101114));--diffs-font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);--diffs-header-font-family:var(--font-sans,ui-sans-serif, system-ui, sans-serif);--diffs-font-size:var(--font-text-sm-size,12px);--diffs-line-height:20px;border-bottom-right-radius:8px;border-bottom-left-radius:8px;max-height:420px;display:block;overflow:auto}.text-payload{max-height:420px;color:var(--color-text-secondary,#c7c7ce);font-family:var(--font-mono,ui-monospace, SFMono-Regular, monospace);font-size:var(--font-text-sm-size,12px);white-space:pre-wrap;overflow-wrap:break-word;margin:0;padding:10px 12px;line-height:1.55;overflow:auto}.text-payload.bash{color:var(--color-text-primary,#f5f5f6);background:var(--color-background-primary,#101114)}@media (width<=520px){.tool-header{grid-template-columns:36px minmax(0,1fr) auto 18px;gap:9px;min-height:58px;padding:9px 10px}.tool-icon{border-radius:9px;width:36px;height:36px}.chevron{width:18px;height:18px}.review-header{grid-template-columns:36px minmax(0,1fr) auto 18px}.workspace-row{grid-template-columns:22px minmax(0,1fr);gap:2px 8px;padding-block:8px}.workspace-row-icon{grid-row:1/span 2;align-self:start}.workspace-row>.workspace-key,.workspace-row>.workspace-value,.workspace-row>.workspace-chip-list,.workspace-row>.workspace-instructions-content{grid-column:2}}
@@ -1 +0,0 @@
1
- import"./workspace-app-CwbJnb_w.js";import"./workspace-app-BztEvZIC.js";document.documentElement.dataset.forgerelayApp=`historical-tool-card`;
@@ -1 +0,0 @@
1
- import"./workspace-app-CwbJnb_w.js";import"./workspace-app-BztEvZIC.js";document.documentElement.dataset.forgerelayApp=`workspace-lifecycle-compatibility`;