Public: anyone can read this; the crew can change it.
The Working-now card links each run to its log on the forge #5776
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/5755-the-working-now-card-links-each-run-to-i → main 3 commits fork 2 threads · 2 unresolved
2 files
changed +23
−0
src/web/studio/cards.ts +5
| @@ -69,6 +69,8 @@ const text = (v: unknown): string => | ||
| 69 | 69 | const web = (u: string): boolean => /^https?:\/\//.test(u); |
| 70 | 70 | const LIMIT = 12; |
| 71 | 71 | const FEED_LIMIT = 10; |
| 72 | /** The forge's id shape (src/kernel/id.ts): 26 lowercase Crockford base32 characters. */ | |
| 73 | const RUN_ID = /^[0-9a-hjkmnp-tv-z]{26}$/; | |
| 72 | 74 | |
| 73 | 75 | /** The card for a tool's answer, or nothing when the answer has no card. */ |
| 74 | 76 | export function cardFor( |
| @@ -163,6 +165,9 @@ export function cardFor( | ||
| 163 | 165 | rows.push({ |
| 164 | 166 | label: `${text(r["who"])} on ${text(r["app"])}`, |
| 165 | 167 | value: `${text(r["on"])} — ${text(r["state"])}${cost}`, |
| 168 | ...(web(origin) && /^[^/]+\/[^/]+$/.test(text(r["app"])) && RUN_ID.test(text(r["run"])) | |
| 169 | ? { link: `${origin}/${text(r["app"])}/runs/${text(r["run"])}` } | |
| 170 | : {}), | |
| 166 | 171 | }); |
| 167 | 172 | if (r["run"] && actions.length < 3) |
| 168 | 173 | actions.push({ label: `Stop ${text(r["who"])}`, tool: "stop", args: { repo: text(r["app"]), run: text(r["run"]) } }); |
test/card-run-link.test.ts added +18
| @@ -0,0 +1,18 @@ | ||
| 1 | import { expect, test } from "bun:test"; | |
| 2 | import { cardFor } from "../src/web/studio/cards.ts"; | |
| 3 | import { id } from "../src/kernel/id.ts"; | |
| 4 | ||
| 5 | const run = id(); | |
| 6 | const row = { who: "scout", app: "alice/game", on: "#1", state: "going" }; | |
| 7 | ||
| 8 | test("now links each run to its page when id and origin are good", () => { | |
| 9 | const card = cardFor("now", [{ ...row, run }, { ...row }], "https://forge.example")!; | |
| 10 | expect(card.rows[0]!.link).toBe(`https://forge.example/alice/game/runs/${run}`); | |
| 11 | expect(card.rows[1]!.link).toBeUndefined(); | |
| 12 | expect(card.actions[0]!.tool).toBe("stop"); | |
| 13 | }); | |
| 14 | ||
| 15 | test("now gives no link for a bad origin, id or app", () => { | |
| 16 | for (const [o, r] of [["javascript:x", { ...row, run }], ["", { ...row, run }], ["https://f.example", { ...row, run: "r1" }], ["https://f.example", { ...row, app: "nope", run }]] as const) | |
| 17 | expect(cardFor("now", [r], o)!.rows[0]!.link).toBeUndefined(); | |
| 18 | }); |
new above
offline
Use the existing web(origin) helper instead of repeating the https? regex.