@dsdenes/devboard 0.1.560 → 0.1.563
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/AGENTS.md +59 -0
- package/README.md +2497 -26
- package/bin/devboard.mjs +352 -118
- package/client/App.svelte +523 -0
- package/client/FeedbackOverlay.svelte +1125 -0
- package/client/FlowMode.svelte +1015 -0
- package/client/app.css +3922 -0
- package/client/env.d.ts +23 -0
- package/client/lib/commands.ts +836 -0
- package/client/lib/components/ActivityBar.svelte +295 -0
- package/client/lib/components/AdrTable.svelte +241 -0
- package/client/lib/components/CommandPalette.svelte +198 -0
- package/client/lib/components/ConceptKind.svelte +66 -0
- package/client/lib/components/ConfirmDialog.svelte +62 -0
- package/client/lib/components/DataTable.svelte +243 -0
- package/client/lib/components/DetailSplit.svelte +68 -0
- package/client/lib/components/DiscoverOverview.svelte +898 -0
- package/client/lib/components/DiscoverWorkspace.svelte +437 -0
- package/client/lib/components/DraftsPage.svelte +186 -0
- package/client/lib/components/GoalWorkspace.svelte +1042 -0
- package/client/lib/components/IssuesAgentFocus.svelte +117 -0
- package/client/lib/components/IssuesAgentLog.svelte +50 -0
- package/client/lib/components/IssuesQuestion.svelte +95 -0
- package/client/lib/components/IssuesWorkspace.svelte +577 -0
- package/client/lib/components/MermaidDiagram.svelte +89 -0
- package/client/lib/components/MonacoEditor.svelte +190 -0
- package/client/lib/components/NotificationRegion.svelte +195 -0
- package/client/lib/components/PaneHandle.svelte +25 -0
- package/client/lib/components/ScoutIssues.svelte +215 -0
- package/client/lib/components/ScoutWorkspace.svelte +180 -0
- package/client/lib/components/Sidebar.svelte +622 -0
- package/client/lib/components/StatusBar.svelte +118 -0
- package/client/lib/components/Terminal.svelte +193 -0
- package/client/lib/components/WatchdogWorkspace.svelte +537 -0
- package/client/lib/components/ui/button.svelte +56 -0
- package/client/lib/components/ui/icon-button.svelte +56 -0
- package/client/lib/components/ui/input.svelte +19 -0
- package/client/lib/components/ui/page-header.svelte +120 -0
- package/client/lib/components/ui/stage-track.svelte +141 -0
- package/client/lib/components/watchdog-indicator.svelte +189 -0
- package/client/lib/connection.svelte.ts +210 -0
- package/client/lib/dependency-diagram.test.ts +90 -0
- package/client/lib/dependency-diagram.ts +75 -0
- package/client/lib/discover-format.test.ts +265 -0
- package/client/lib/discover-format.ts +394 -0
- package/client/lib/discover.svelte.ts +412 -0
- package/client/lib/draft-format.test.ts +48 -0
- package/client/lib/draft-format.ts +13 -0
- package/client/lib/flow-save.test.ts +148 -0
- package/client/lib/flow.svelte.ts +445 -0
- package/client/lib/goal-reconnect.test.ts +282 -0
- package/client/lib/goal.svelte.ts +652 -0
- package/client/lib/issues.svelte.ts +439 -0
- package/client/lib/layout.svelte.ts +234 -0
- package/client/lib/notification-issue.test.ts +53 -0
- package/client/lib/notification-issue.ts +27 -0
- package/client/lib/notifications.svelte.ts +62 -0
- package/client/lib/poll-status.test.ts +141 -0
- package/client/lib/poll-status.ts +88 -0
- package/client/lib/record-status.test.ts +19 -0
- package/client/lib/record-status.ts +25 -0
- package/client/lib/scout.svelte.ts +164 -0
- package/client/lib/skill-document.test.ts +77 -0
- package/client/lib/skill-document.ts +57 -0
- package/client/lib/status-tone.test.ts +40 -0
- package/client/lib/status-tone.ts +33 -0
- package/client/lib/types.ts +578 -0
- package/client/lib/utils.ts +6 -0
- package/client/lib/viewport.svelte.ts +20 -0
- package/client/lib/watchdog.svelte.ts +69 -0
- package/client/main.ts +7 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/abnfDiagram-VCTEODGH-CmBSMArZ.js +1 -0
- package/dist/assets/arc-BZgCSX2H.js +1 -0
- package/dist/assets/architecture-7GRP2DOG-CF9MHlfo.js +1 -0
- package/dist/assets/architectureDiagram-5GKGNRK7-DzWB6xiQ.js +36 -0
- package/dist/assets/array-BifhSqXX.js +1 -0
- package/dist/assets/blockDiagram-I7D4REHJ-BtmGJ0hn.js +129 -0
- package/dist/assets/c4Diagram-7LVT6UL2-D5CHrrRX.js +38 -0
- package/dist/assets/channel-CgM4lcUW.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/assets/chunk-4HAMMTFA-DeIufjFl.js +62 -0
- package/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/assets/chunk-75Z2AOVW-DbtzyKUg.js +2 -0
- package/dist/assets/chunk-DU6HZSFF-C0fdbx3K.js +127 -0
- package/dist/assets/chunk-F27PBJKO-HObL2IvF.js +1 -0
- package/dist/assets/chunk-FOHPRMQF-DD4dKubD.js +161 -0
- package/dist/assets/chunk-GMAD6QVW-fg8wvtPY.js +72 -0
- package/dist/assets/chunk-GVQU2GXP-C0TaHOrD.js +1 -0
- package/dist/assets/chunk-IMKFNOWR-BVoIdx20.js +231 -0
- package/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/assets/chunk-L3NEJ4N5-B_kmqfk5.js +1 -0
- package/dist/assets/chunk-OSK3NFVY-DO0vhxHH.js +10 -0
- package/dist/assets/chunk-P2QGCYS3-CjljLvFj.js +1 -0
- package/dist/assets/chunk-POPQ4Y6H-BU0C7tw6.js +1 -0
- package/dist/assets/chunk-PWAF6VOD-Dn0OjBt0.js +1 -0
- package/dist/assets/chunk-SHT3W25Y-CMCZE2xx.js +168 -0
- package/dist/assets/chunk-SVP7TREG-BIRmRy_W.js +88 -0
- package/dist/assets/chunk-TICWLB2K-C1bc2CDE.js +206 -0
- package/dist/assets/chunk-XXDRQBXY-Cc38QUmR.js +1 -0
- package/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/assets/classDiagram-ZZMXUADV-BDh5w6Nc.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-BDh5w6Nc.js +1 -0
- package/dist/assets/cose-bilkent-JH36ORCC-B7pU7qhM.js +1 -0
- package/dist/assets/cynefin-OW5HDTMX-76dswSqS.js +1 -0
- package/dist/assets/cynefinDiagram-5FMLGOSQ-2kS4q01d.js +62 -0
- package/dist/assets/cytoscape.esm-BegBNzOV.js +321 -0
- package/dist/assets/dagre-D7JM2Yhv.js +1 -0
- package/dist/assets/dagre-GXQ25YYZ-B5Y21TQM.js +4 -0
- package/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/assets/diagram-S7CK7UJ4-CY6td7Et.js +30 -0
- package/dist/assets/diagram-UQ7AKVKN-DmDqnGZf.js +41 -0
- package/dist/assets/diagram-VSXAHHWV-KGLWOOcE.js +3 -0
- package/dist/assets/diagram-VX7I27RA-D5syUraJ.js +24 -0
- package/dist/assets/diagram-Z3DM3KII-Dtrbs1Om.js +24 -0
- package/dist/assets/dist-Dce-2YbA.js +1 -0
- package/dist/assets/ebnfDiagram-PWID7BFC-CQpJLtU3.js +1 -0
- package/dist/assets/editor.worker-BmdWdrHZ.js +33 -0
- package/dist/assets/erDiagram-RLTQ6QDP-cMTzKLu_.js +99 -0
- package/dist/assets/eventmodeling-NTZA5JFV-CMzLdNaL.js +1 -0
- package/dist/assets/flowDiagram-HODETNUW-BMUajB-G.js +1 -0
- package/dist/assets/ganttDiagram-EL5Y4UJY-DseBS5Fs.js +292 -0
- package/dist/assets/gitGraph-4MIJSDKK-CUQZRpxJ.js +1 -0
- package/dist/assets/gitGraphDiagram-WWUBYQGX-CfMfsJ3b.js +106 -0
- package/dist/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/assets/index-ByQ-XX38.css +1 -0
- package/dist/assets/index-CIf5TpfY.js +214 -0
- package/dist/assets/info-A6RAGUB7-D3nAKZ8M.js +1 -0
- package/dist/assets/infoDiagram-27XIBGKW-zu1O0WOy.js +2 -0
- package/dist/assets/init-C-OQMol4.js +1 -0
- package/dist/assets/ishikawaDiagram-5VMMS53U-DKC7BO9p.js +70 -0
- package/dist/assets/journeyDiagram-3NMN7TZE-Ld5mXse7.js +139 -0
- package/dist/assets/kanban-definition-UXKFOSKX-CH7_QlHL.js +89 -0
- package/dist/assets/katex-DJhrJSbw.js +257 -0
- package/dist/assets/line-N9XiCREw.js +1 -0
- package/dist/assets/linear-C9hnqmJv.js +1 -0
- package/dist/assets/mermaid-parser.core-DgPwV5Bh.js +7 -0
- package/dist/assets/mermaid.core-BKqynXLR.js +44 -0
- package/dist/assets/mindmap-definition-YA3MSWOX-DkiL-wiW.js +96 -0
- package/dist/assets/monaco-DjpsE8to.css +1 -0
- package/dist/assets/monaco-DqzJaNIe.js +908 -0
- package/dist/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/assets/packet-AYTQ26CC-DuMTvpEJ.js +1 -0
- package/dist/assets/path-fybaL0A-.js +1 -0
- package/dist/assets/pegDiagram-XKGWAZYB-DvMl_xSe.js +1 -0
- package/dist/assets/pie-WAS4IAKB-Da0xPaD8.js +1 -0
- package/dist/assets/pieDiagram-E7YTZNPT-amANNRJY.js +39 -0
- package/dist/assets/quadrantDiagram-AXDQQJYC-BrgvDMnk.js +7 -0
- package/dist/assets/radar-RG4KPBEZ-Dz3Ih5-N.js +1 -0
- package/dist/assets/railroad-74A4TZTK-CKMW-IV2.js +1 -0
- package/dist/assets/railroad-abnf-HS5TGJTU-ChqmSWSF.js +1 -0
- package/dist/assets/railroad-ebnf-LZEXJU2U-V3R4fFdb.js +1 -0
- package/dist/assets/railroad-peg-WCYAUIDC-B-RuhUQW.js +1 -0
- package/dist/assets/railroadDiagram-O6MQD6OU-FjG-6OLu.js +1 -0
- package/dist/assets/requirementDiagram-BXWQKSXE-Cnj8RfE4.js +84 -0
- package/dist/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dist/assets/sankeyDiagram-P5KCCOFB-DMu1fnEh.js +40 -0
- package/dist/assets/sequenceDiagram-WJ2MYXX4-CtCtaRpW.js +162 -0
- package/dist/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/assets/src-CGp3bfio.js +1 -0
- package/dist/assets/stateDiagram-D77RDMKH-xcJbLNhz.js +1 -0
- package/dist/assets/stateDiagram-v2-MP3YSRHH-DYHrQmJJ.js +1 -0
- package/dist/assets/swimlanes-42K2YHIH-BwLln_ga.js +1 -0
- package/dist/assets/swimlanesDiagram-VR7AAH4N-BcDfUQ0A.js +8 -0
- package/dist/assets/timeline-definition-24CTP7MA-ucNGsUUz.js +120 -0
- package/dist/assets/treeView-Q6P3EWNA-3uOomRue.js +1 -0
- package/dist/assets/treemap-WGGIJYW6-iGK7vwID.js +1 -0
- package/dist/assets/vennDiagram-4TSXK5OY-B9LgGe16.js +34 -0
- package/dist/assets/wardley-WFR3VGLG-FupMOf6k.js +1 -0
- package/dist/assets/wardleyDiagram-VM6X3IG4-CGZdEXM2.js +78 -0
- package/dist/assets/xterm-BrP-ENHg.css +1 -0
- package/dist/assets/xterm-C8zLTNGk.js +16 -0
- package/dist/assets/xychartDiagram-S5SC5T6Z-DafZrSBJ.js +7 -0
- package/dist/favicon.ico +0 -0
- package/dist/favicon.svg +6 -0
- package/dist/index.html +34 -0
- package/extensions/implement-goal-issue.ts +368 -0
- package/extensions/implement-next-epic.ts +835 -0
- package/index.html +28 -0
- package/install.sh +111 -0
- package/issues/control.ts +91 -0
- package/issues/guards.ts +12 -0
- package/issues/ledger.ts +122 -0
- package/issues/legacy.ts +68 -0
- package/issues/lock.ts +305 -0
- package/issues/paths.ts +76 -0
- package/issues/preflight.ts +189 -0
- package/issues/repository.ts +203 -0
- package/issues/scout/actions.ts +255 -0
- package/issues/scout/control.ts +80 -0
- package/issues/scout/github.ts +358 -0
- package/issues/scout/paths.ts +129 -0
- package/issues/scout/preflight.ts +277 -0
- package/issues/scout/recommendation.ts +400 -0
- package/issues/scout/scan.ts +143 -0
- package/issues/scout/state.ts +448 -0
- package/issues/scout/worker.ts +1282 -0
- package/issues/state.ts +584 -0
- package/issues/tracker.ts +271 -0
- package/issues/worker.ts +1065 -0
- package/lib/dependencies.ts +61 -0
- package/lib/forge-auth.ts +953 -0
- package/lib/forge.ts +141 -0
- package/lib/gitea.ts +729 -0
- package/lib/github-release.ts +318 -0
- package/lib/inventory.test.ts +79 -0
- package/lib/inventory.ts +53 -0
- package/lib/release.test.ts +269 -0
- package/lib/release.ts +801 -0
- package/omp/commands/adr-resolve.md +8 -0
- package/omp/commands/discover.md +6 -0
- package/omp/commands/epic-next.md +8 -0
- package/omp/commands/flow-change.md +8 -0
- package/omp/commands/flow-goal.md +8 -0
- package/omp/commands/flow-implement.md +8 -0
- package/omp/commands/flow-widget.md +8 -0
- package/omp/commands/goal-draft.md +8 -0
- package/omp/commands/goal-outcome.md +8 -0
- package/omp/commands/implement-issue.md +8 -0
- package/omp/commands/prepare-skills.md +6 -0
- package/omp/commands/scout-recommendations.md +8 -0
- package/omp/commands/setup-devboard.md +24 -0
- package/omp/config.yml +12 -0
- package/omp/extensions/implement-goal-issue.ts +2 -0
- package/omp/extensions/implement-next-epic.ts +2 -0
- package/omp/mcp.json +9 -0
- package/package.json +86 -7
- package/prompts/adr-resolve.md +130 -0
- package/prompts/discover.md +541 -0
- package/prompts/epic-next.md +533 -0
- package/prompts/flow-change.md +76 -0
- package/prompts/flow-goal.md +126 -0
- package/prompts/flow-implement.md +103 -0
- package/prompts/flow-widget.md +54 -0
- package/prompts/goal-draft.md +147 -0
- package/prompts/goal-outcome.md +87 -0
- package/prompts/implement-issue.md +66 -0
- package/prompts/prepare-skills.md +142 -0
- package/prompts/scout-recommendations.md +143 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +6 -0
- package/server/acp.ts +540 -0
- package/server/activity.test.ts +96 -0
- package/server/activity.ts +48 -0
- package/server/app.test.ts +882 -0
- package/server/app.ts +6179 -0
- package/server/ask.test.ts +543 -0
- package/server/ask.ts +589 -0
- package/server/dependencies.test.ts +118 -0
- package/server/discover-remote.test.ts +1602 -0
- package/server/discover-sheet.test.ts +176 -0
- package/server/discover.test.ts +1510 -0
- package/server/discover.ts +3198 -0
- package/server/feedback.test.ts +458 -0
- package/server/feedback.ts +369 -0
- package/server/fixtures/adr-source.ts +71 -0
- package/server/fixtures/hang-download.ts +14 -0
- package/server/fixtures/stub-agent.ts +1870 -0
- package/server/fixtures/stub-forge.ts +141 -0
- package/server/fixtures/stub-gh.ts +57 -0
- package/server/flow-pr.test.ts +976 -0
- package/server/flow.test.ts +1632 -0
- package/server/flow.ts +2655 -0
- package/server/forge-pr.ts +387 -0
- package/server/goal-creation.test.ts +957 -0
- package/server/goal-draft.test.ts +348 -0
- package/server/goal-drafts.ts +449 -0
- package/server/goal-proposal.test.ts +479 -0
- package/server/goal-proposal.ts +232 -0
- package/server/goal-revision.test.ts +613 -0
- package/server/goal-slug.test.ts +56 -0
- package/server/goal-slug.ts +96 -0
- package/server/goal.ts +20 -0
- package/server/index.ts +147 -0
- package/server/issue-close.test.ts +100 -0
- package/server/issue-close.ts +178 -0
- package/server/issues.test.ts +167 -0
- package/server/issues.ts +479 -0
- package/server/journal.test.ts +350 -0
- package/server/journal.ts +329 -0
- package/server/lifecycle-pause.test.ts +1795 -0
- package/server/lifecycle.test.ts +1879 -0
- package/server/parallel-lifecycle.test.ts +1029 -0
- package/server/persistence-restart.test.ts +723 -0
- package/server/persistence.test.ts +1935 -0
- package/server/records.test.ts +180 -0
- package/server/records.ts +99 -0
- package/server/reset-implementation.test.ts +997 -0
- package/server/run.test.ts +611 -0
- package/server/scout.test.ts +877 -0
- package/server/scout.ts +459 -0
- package/server/skills-preparation.test.ts +1073 -0
- package/server/state.ts +249 -0
- package/server/tracker.ts +369 -0
- package/server/updates.test.ts +444 -0
- package/server/updates.ts +198 -0
- package/server/version.test.ts +140 -0
- package/server/version.ts +151 -0
- package/server/watchdog.ts +389 -0
- package/svelte.config.js +5 -0
- package/templates/host-AGENTS.md +235 -0
- package/tsconfig.json +21 -0
- package/vite.config.ts +21 -0
- package/watchdog/cleanup-main.ts +98 -0
- package/watchdog/cleanup.ts +301 -0
- package/watchdog/collect.ts +311 -0
- package/watchdog/coordinator.ts +397 -0
- package/watchdog/delivery.ts +107 -0
- package/watchdog/discovery.ts +209 -0
- package/watchdog/findings.ts +211 -0
- package/watchdog/github.ts +189 -0
- package/watchdog/history.ts +138 -0
- package/watchdog/install.ts +103 -0
- package/watchdog/ledger.ts +188 -0
- package/watchdog/lock.ts +63 -0
- package/watchdog/main.ts +106 -0
- package/watchdog/status.ts +71 -0
- package/watchdog/systemd.ts +96 -0
- package/watchdog/uninstall.ts +30 -0
- package/watchdog/units/devboard-watchdog.service +9 -0
- package/watchdog/units/devboard-watchdog.timer +10 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Marked, type Tokens } from "marked";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The prepared SKILL.md body without its YAML frontmatter. The frontmatter is
|
|
5
|
+
* bookkeeping: the panel header already states the name and the skills list
|
|
6
|
+
* owns the description, so the document starts at the first instruction.
|
|
7
|
+
*/
|
|
8
|
+
export function skillBody(source: string): string {
|
|
9
|
+
const normalized = source.replace(/\r\n?/g, "\n");
|
|
10
|
+
const lines = normalized.split("\n");
|
|
11
|
+
if (lines[0]?.trim() !== "---") return normalized.trim();
|
|
12
|
+
const close = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
|
|
13
|
+
if (close < 0) return normalized.trim();
|
|
14
|
+
return lines.slice(close + 1).join("\n").trim();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function escapeHtml(value: string): string {
|
|
18
|
+
return value
|
|
19
|
+
.replaceAll("&", "&")
|
|
20
|
+
.replaceAll("<", "<")
|
|
21
|
+
.replaceAll(">", ">")
|
|
22
|
+
.replaceAll('"', """)
|
|
23
|
+
.replaceAll("'", "'");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Links may leave the console, but never into a script or data URL. */
|
|
27
|
+
function safeHref(href: string): boolean {
|
|
28
|
+
if (/^\s*(?:javascript|data|vbscript):/i.test(href)) return false;
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const marked = new Marked({ gfm: true });
|
|
33
|
+
|
|
34
|
+
marked.use({
|
|
35
|
+
renderer: {
|
|
36
|
+
// A skill file is host content, not app markup: raw HTML renders as text.
|
|
37
|
+
html({ text }: Tokens.HTML | Tokens.Tag) {
|
|
38
|
+
return escapeHtml(text);
|
|
39
|
+
},
|
|
40
|
+
link({ href, title, tokens }: Tokens.Link) {
|
|
41
|
+
const label = this.parser.parseInline(tokens);
|
|
42
|
+
if (!safeHref(href)) return label;
|
|
43
|
+
const titleAttribute = title == null ? "" : ` title="${escapeHtml(title)}"`;
|
|
44
|
+
return `<a href="${escapeHtml(href)}"${titleAttribute} target="_blank" rel="noreferrer noopener">${label}</a>`;
|
|
45
|
+
},
|
|
46
|
+
image({ text }: Tokens.Image) {
|
|
47
|
+
return escapeHtml(text);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/** Renders the skill body as sanitized HTML for the document panel. */
|
|
53
|
+
export function renderSkillDocument(source: string): string {
|
|
54
|
+
const body = skillBody(source);
|
|
55
|
+
if (body.length === 0) return "";
|
|
56
|
+
return marked.parse(body, { async: false });
|
|
57
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { statusTone } from "./status-tone";
|
|
3
|
+
|
|
4
|
+
describe("status tone", () => {
|
|
5
|
+
test("marks active work as accent", () => {
|
|
6
|
+
expect(statusTone("running")).toBe("accent");
|
|
7
|
+
expect(statusTone("scanning")).toBe("accent");
|
|
8
|
+
expect(statusTone("pausing")).toBe("accent");
|
|
9
|
+
expect(statusTone("retrying")).toBe("accent");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("marks successful completion as success", () => {
|
|
13
|
+
expect(statusTone("succeeded")).toBe("success");
|
|
14
|
+
expect(statusTone("merged")).toBe("success");
|
|
15
|
+
expect(statusTone("handled")).toBe("success");
|
|
16
|
+
expect(statusTone("accepted")).toBe("success");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("marks failures as error", () => {
|
|
20
|
+
expect(statusTone("failed")).toBe("error");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("keeps stopped and paused work neutral instead of the running color", () => {
|
|
24
|
+
for (const status of ["stopped", "paused", "parked", "idle", "closed", "unknown", "none"]) {
|
|
25
|
+
expect(statusTone(status)).toBeUndefined();
|
|
26
|
+
}
|
|
27
|
+
expect(statusTone("stopped")).not.toBe(statusTone("running"));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("normalizes the status word", () => {
|
|
31
|
+
expect(statusTone(" Running ")).toBe("accent");
|
|
32
|
+
expect(statusTone("FAILED")).toBe("error");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("keeps pending and stale distinct", () => {
|
|
36
|
+
expect(statusTone("pending")).toBe("pending");
|
|
37
|
+
expect(statusTone("stale")).toBe("stale");
|
|
38
|
+
expect(statusTone("deferred")).toBeUndefined();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BadgeTone } from "./record-status";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The tone one process status earns, wherever the dashboard renders it.
|
|
5
|
+
*
|
|
6
|
+
* A status word has one color in every surface: active work is `accent`,
|
|
7
|
+
* successful completion is `success`, a failure is `error`, and anything that
|
|
8
|
+
* is neither working nor finished — stopped, paused, parked, idle, closed,
|
|
9
|
+
* unknown — stays neutral. Stopped work therefore never borrows the running
|
|
10
|
+
* color, and a status that changes surface does not change meaning.
|
|
11
|
+
*/
|
|
12
|
+
export function statusTone(status: string): BadgeTone | undefined {
|
|
13
|
+
switch (status.trim().toLowerCase()) {
|
|
14
|
+
case "running":
|
|
15
|
+
case "scanning":
|
|
16
|
+
case "pausing":
|
|
17
|
+
case "retrying":
|
|
18
|
+
return "accent";
|
|
19
|
+
case "succeeded":
|
|
20
|
+
case "merged":
|
|
21
|
+
case "handled":
|
|
22
|
+
case "accepted":
|
|
23
|
+
return "success";
|
|
24
|
+
case "failed":
|
|
25
|
+
return "error";
|
|
26
|
+
case "pending":
|
|
27
|
+
return "pending";
|
|
28
|
+
case "stale":
|
|
29
|
+
return "stale";
|
|
30
|
+
default:
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
export type Mode = "goal" | "issues" | "flow" | "discover";
|
|
2
|
+
export type Theme = "dark" | "light";
|
|
3
|
+
|
|
4
|
+
export interface AdrRecord {
|
|
5
|
+
file: string;
|
|
6
|
+
title: string;
|
|
7
|
+
status: string;
|
|
8
|
+
pending: boolean;
|
|
9
|
+
summary: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface VersionState {
|
|
13
|
+
running: string | null;
|
|
14
|
+
installed: string | null;
|
|
15
|
+
latest: string | null;
|
|
16
|
+
stale: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type IssuesLifecycle = "stopped" | "idle" | "running" | "pausing" | "paused" | "failed";
|
|
20
|
+
export type IssuesRunStatus = "running" | "succeeded" | "failed" | "stopped";
|
|
21
|
+
|
|
22
|
+
export interface IssuesIssue {
|
|
23
|
+
number: number;
|
|
24
|
+
title: string;
|
|
25
|
+
url: string;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
labels: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface QueuedIssue extends IssuesIssue {
|
|
31
|
+
handled: boolean;
|
|
32
|
+
/** The run that last handled this issue, or null. */
|
|
33
|
+
runId: string | null;
|
|
34
|
+
/** The run of the agent currently working this issue, or null. */
|
|
35
|
+
agentRunId: string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface IssuesPollState {
|
|
39
|
+
intervalMs: number;
|
|
40
|
+
lastPollAt: string | null;
|
|
41
|
+
nextPollAt: string | null;
|
|
42
|
+
etag: string | null;
|
|
43
|
+
notModified: boolean;
|
|
44
|
+
rateLimitedUntil: string | null;
|
|
45
|
+
error: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface IssuesWorkerRecord {
|
|
49
|
+
pid: number;
|
|
50
|
+
startedAt: string;
|
|
51
|
+
stateDir: string;
|
|
52
|
+
harnessVersion: string | null;
|
|
53
|
+
argv: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface IssuesRunSummary {
|
|
57
|
+
runId: string;
|
|
58
|
+
status: IssuesRunStatus;
|
|
59
|
+
startedAt: string;
|
|
60
|
+
finishedAt: string | null;
|
|
61
|
+
exitCode: number | null;
|
|
62
|
+
issueNumbers: number[];
|
|
63
|
+
activity: number;
|
|
64
|
+
firstStderrLine: string | null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface IssuesRunDetail extends IssuesRunSummary {
|
|
68
|
+
repo: string;
|
|
69
|
+
argv: string[];
|
|
70
|
+
cwd: string;
|
|
71
|
+
issues: IssuesIssue[];
|
|
72
|
+
workerPid: number;
|
|
73
|
+
harnessVersion: string | null;
|
|
74
|
+
activityLines: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The worker's published snapshot, as the dashboard is allowed to see it. */
|
|
78
|
+
export interface IssuesSnapshot {
|
|
79
|
+
present: boolean;
|
|
80
|
+
repo: string | null;
|
|
81
|
+
root: string;
|
|
82
|
+
lifecycle: IssuesLifecycle;
|
|
83
|
+
enabled: boolean;
|
|
84
|
+
paused: boolean;
|
|
85
|
+
attached: boolean;
|
|
86
|
+
worker: IssuesWorkerRecord | null;
|
|
87
|
+
poll: IssuesPollState | null;
|
|
88
|
+
queue: QueuedIssue[];
|
|
89
|
+
runs: IssuesRunSummary[];
|
|
90
|
+
agents: IssuesAgent[];
|
|
91
|
+
cooldowns: Record<string, string>;
|
|
92
|
+
lastError: string | null;
|
|
93
|
+
lastExitCode: number | null;
|
|
94
|
+
finishedAt: string | null;
|
|
95
|
+
notice: string | null;
|
|
96
|
+
updatedAt: string | null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface IssuesActivityEntry {
|
|
100
|
+
text: string;
|
|
101
|
+
append: boolean;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface RunQuestionOption {
|
|
105
|
+
label: string;
|
|
106
|
+
description?: string;
|
|
107
|
+
recommended: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface RunQuestion {
|
|
111
|
+
id: number | string;
|
|
112
|
+
message: string;
|
|
113
|
+
options: RunQuestionOption[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** One running issue's own concurrent peer. */
|
|
117
|
+
export interface IssuesAgent {
|
|
118
|
+
runId: string;
|
|
119
|
+
issueNumber: number;
|
|
120
|
+
startedAt: string;
|
|
121
|
+
question: RunQuestion | null;
|
|
122
|
+
acp: { pid: number; argv: string[]; cwd: string } | null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface GoalDraftSummary {
|
|
126
|
+
path: string;
|
|
127
|
+
name: string;
|
|
128
|
+
heading: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface GoalDraftDetail extends GoalDraftSummary {
|
|
132
|
+
text: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export type GoalDraftStatus = "idle" | "running" | "succeeded" | "failed" | "stopped";
|
|
136
|
+
|
|
137
|
+
export interface GoalDraftRun {
|
|
138
|
+
status: GoalDraftStatus;
|
|
139
|
+
path: string | null;
|
|
140
|
+
startedAt: string | null;
|
|
141
|
+
finishedAt: string | null;
|
|
142
|
+
error: string | null;
|
|
143
|
+
activity: string[];
|
|
144
|
+
question: RunQuestion | null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export type ScoutLifecycle = "stopped" | "idle" | "scanning" | "failed";
|
|
148
|
+
export type ScoutIssueState = "pending" | "implemented";
|
|
149
|
+
export type ScoutSyncState = "ok" | "error" | "stale";
|
|
150
|
+
|
|
151
|
+
/** One Auto Scout issue, as GitHub last reported it. */
|
|
152
|
+
export interface ScoutIssueRow {
|
|
153
|
+
number: number;
|
|
154
|
+
title: string;
|
|
155
|
+
url: string;
|
|
156
|
+
createdAt: string;
|
|
157
|
+
/** An open issue is `pending`; a closed one is `implemented`. */
|
|
158
|
+
state: ScoutIssueState;
|
|
159
|
+
/** The recommendation's category, the body's `## Category`, or null. */
|
|
160
|
+
category: string | null;
|
|
161
|
+
/** The earliest published release that shipped the closing commit, or null. */
|
|
162
|
+
version: string | null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface ScoutLimits {
|
|
166
|
+
maxPerHour: number;
|
|
167
|
+
maxPending: number;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface ScoutSync {
|
|
171
|
+
state: ScoutSyncState;
|
|
172
|
+
/** The last successful read, or null before one. */
|
|
173
|
+
at: string | null;
|
|
174
|
+
/** Why the last read failed, or null. */
|
|
175
|
+
error: string | null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface ScoutScanRecord {
|
|
179
|
+
scanId: string;
|
|
180
|
+
startedAt: string;
|
|
181
|
+
/** How many recommendations the request asked for. */
|
|
182
|
+
requested: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** The scout worker's published state, as the dashboard is allowed to see it. */
|
|
186
|
+
export interface ScoutSnapshot {
|
|
187
|
+
present: boolean;
|
|
188
|
+
repo: string | null;
|
|
189
|
+
root: string;
|
|
190
|
+
lifecycle: ScoutLifecycle;
|
|
191
|
+
enabled: boolean;
|
|
192
|
+
attached: boolean;
|
|
193
|
+
worker: IssuesWorkerRecord | null;
|
|
194
|
+
limits: ScoutLimits;
|
|
195
|
+
issues: ScoutIssueRow[];
|
|
196
|
+
sync: ScoutSync;
|
|
197
|
+
scan: ScoutScanRecord | null;
|
|
198
|
+
newestScanId: string | null;
|
|
199
|
+
nextAttemptAt: string | null;
|
|
200
|
+
lastError: string | null;
|
|
201
|
+
notice: string | null;
|
|
202
|
+
updatedAt: string | null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface ScoutActivityEntry {
|
|
206
|
+
text: string;
|
|
207
|
+
append: boolean;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export type WatchdogIssueState = "pending" | "implemented";
|
|
211
|
+
export type WatchdogSyncState = "ok" | "error" | "stale";
|
|
212
|
+
|
|
213
|
+
/** One issue the watchdog filed, with what GitHub last reported for it. */
|
|
214
|
+
export interface WatchdogIssue {
|
|
215
|
+
url: string;
|
|
216
|
+
category: string;
|
|
217
|
+
line: string;
|
|
218
|
+
filedAt: string;
|
|
219
|
+
/** `null` until a GitHub read has answered for this issue. */
|
|
220
|
+
state: WatchdogIssueState | null;
|
|
221
|
+
/** The earliest published release that shipped the closing commit, or null. */
|
|
222
|
+
version: string | null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface WatchdogCycleWindow {
|
|
226
|
+
start: string | null;
|
|
227
|
+
end: string | null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** One retained watchdog run directory. */
|
|
231
|
+
export interface WatchdogCycle {
|
|
232
|
+
at: string;
|
|
233
|
+
window: WatchdogCycleWindow;
|
|
234
|
+
action: string;
|
|
235
|
+
findings: number;
|
|
236
|
+
/** The GitHub issues this cycle's findings map to, in finding order. */
|
|
237
|
+
issues: string[];
|
|
238
|
+
reason?: string;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface WatchdogSync {
|
|
242
|
+
state: WatchdogSyncState;
|
|
243
|
+
/** The last successful read, or null before one. */
|
|
244
|
+
at: string | null;
|
|
245
|
+
/** Why the last read failed, or null after a success. */
|
|
246
|
+
error: string | null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** `GET /api/watchdog`, as the page renders it. */
|
|
250
|
+
export interface WatchdogSnapshot {
|
|
251
|
+
cycle: string | null;
|
|
252
|
+
action: string;
|
|
253
|
+
reason?: string;
|
|
254
|
+
findings: number;
|
|
255
|
+
issues: WatchdogIssue[];
|
|
256
|
+
pending: number;
|
|
257
|
+
cycles: WatchdogCycle[];
|
|
258
|
+
sync: WatchdogSync;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface SkillSummary {
|
|
262
|
+
name: string;
|
|
263
|
+
description: string;
|
|
264
|
+
/** Which preparation owns the skill; an older server sends neither field. */
|
|
265
|
+
family?: "prepare" | "discover";
|
|
266
|
+
state?: "generated" | "edited" | "missing";
|
|
267
|
+
/** The SKILL.md text; absent from an older server. */
|
|
268
|
+
content?: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** The issue reporter's overlay phase, shared between the shell and the overlay. */
|
|
272
|
+
export type FeedbackPhase = "idle" | "picking" | "composing" | "sending" | "failed";
|
|
273
|
+
|
|
274
|
+
/** The UI issue action an armed selection mode files. */
|
|
275
|
+
export type FeedbackAction = "report" | "remove" | "redesign";
|
|
276
|
+
|
|
277
|
+
export interface SkillContradiction {
|
|
278
|
+
skills: [string, string];
|
|
279
|
+
directives: [string, string];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export type RunAction = "resolving" | "implementing" | "generating";
|
|
283
|
+
export type LifecycleStage = "goal" | "epic" | "adr" | "implementation" | "finished";
|
|
284
|
+
|
|
285
|
+
export interface LifecycleWork {
|
|
286
|
+
kind: "adr" | "epic";
|
|
287
|
+
id: string;
|
|
288
|
+
url?: string;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface LifecycleState {
|
|
292
|
+
stage: LifecycleStage;
|
|
293
|
+
pass: number;
|
|
294
|
+
work: LifecycleWork | null;
|
|
295
|
+
paused: boolean;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export type LaneKind = "generation" | "implementation" | "adr";
|
|
299
|
+
export type LaneStatus = "running" | "paused" | "closed" | "failed" | "retrying" | "parked";
|
|
300
|
+
|
|
301
|
+
export interface LaneEpic {
|
|
302
|
+
number: number;
|
|
303
|
+
title: string;
|
|
304
|
+
url: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface Lane {
|
|
308
|
+
id: string;
|
|
309
|
+
kind: LaneKind;
|
|
310
|
+
epic: LaneEpic | null;
|
|
311
|
+
record: { file: string; title: string } | null;
|
|
312
|
+
attempt: number;
|
|
313
|
+
status: LaneStatus;
|
|
314
|
+
activity: string[];
|
|
315
|
+
question: RunQuestion | null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export type FlowStatus = "none" | "idle" | "running" | "stopped" | "merged";
|
|
319
|
+
export type FlowCategory =
|
|
320
|
+
| "contract"
|
|
321
|
+
| "entity"
|
|
322
|
+
| "naming"
|
|
323
|
+
| "data"
|
|
324
|
+
| "dependency"
|
|
325
|
+
| "irreversible"
|
|
326
|
+
| "structure";
|
|
327
|
+
export type AnswerTarget = "goal" | "implementation" | "conversation";
|
|
328
|
+
|
|
329
|
+
export interface FlowFile {
|
|
330
|
+
path: string;
|
|
331
|
+
status: "added" | "modified" | "deleted" | "renamed";
|
|
332
|
+
insertions: number;
|
|
333
|
+
deletions: number;
|
|
334
|
+
diff: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export interface FlowWidget {
|
|
338
|
+
id: string;
|
|
339
|
+
category: FlowCategory;
|
|
340
|
+
concept: string;
|
|
341
|
+
summary: string;
|
|
342
|
+
rationale: string;
|
|
343
|
+
files: string[];
|
|
344
|
+
accepted: boolean;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export interface FlowSteeringNote {
|
|
348
|
+
id: string;
|
|
349
|
+
timestamp: string;
|
|
350
|
+
source: string;
|
|
351
|
+
text: string;
|
|
352
|
+
status: "new" | "read";
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface FlowCheckpoint {
|
|
356
|
+
id: string;
|
|
357
|
+
timestamp: string;
|
|
358
|
+
summary: string;
|
|
359
|
+
files: number;
|
|
360
|
+
commit: string;
|
|
361
|
+
verification: "passed" | "failed" | "not-run";
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export interface FlowVerification {
|
|
365
|
+
command: string;
|
|
366
|
+
status: "passed" | "failed" | "not-run";
|
|
367
|
+
timestamp: string;
|
|
368
|
+
output: string;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export interface FlowBlocker {
|
|
372
|
+
id: string;
|
|
373
|
+
timestamp: string;
|
|
374
|
+
text: string;
|
|
375
|
+
dismissed: boolean;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export interface FlowPr {
|
|
379
|
+
forge: "github" | "gitlab";
|
|
380
|
+
number: number;
|
|
381
|
+
url: string;
|
|
382
|
+
state: "none" | "draft" | "live" | "merged" | "closed" | "error";
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface FlowConversationMessage {
|
|
386
|
+
role: "developer" | "agent";
|
|
387
|
+
text: string;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export interface FlowConversation {
|
|
391
|
+
widgetId: string;
|
|
392
|
+
messages: FlowConversationMessage[];
|
|
393
|
+
activity: string[];
|
|
394
|
+
question: RunQuestion | null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export interface FlowGoalCreation {
|
|
398
|
+
activity: string[];
|
|
399
|
+
question: RunQuestion | null;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export interface FlowHistoryEntry {
|
|
403
|
+
sessionId: string;
|
|
404
|
+
goal: string;
|
|
405
|
+
pr: FlowPr | null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export interface FlowSnapshot {
|
|
409
|
+
sessionId: string | null;
|
|
410
|
+
status: FlowStatus;
|
|
411
|
+
goal: string;
|
|
412
|
+
decisions: string;
|
|
413
|
+
worktree: string | null;
|
|
414
|
+
branch: string | null;
|
|
415
|
+
baseRevision: string | null;
|
|
416
|
+
files: FlowFile[];
|
|
417
|
+
widgets: FlowWidget[];
|
|
418
|
+
steering: FlowSteeringNote[];
|
|
419
|
+
checkpoints: FlowCheckpoint[];
|
|
420
|
+
verification: FlowVerification | null;
|
|
421
|
+
blockers: FlowBlocker[];
|
|
422
|
+
pr: FlowPr | null;
|
|
423
|
+
prError: string | null;
|
|
424
|
+
leftover: string | null;
|
|
425
|
+
question: RunQuestion | null;
|
|
426
|
+
goalCreation: FlowGoalCreation | null;
|
|
427
|
+
conversation: FlowConversation | null;
|
|
428
|
+
activity: string[];
|
|
429
|
+
notice: string | null;
|
|
430
|
+
history: FlowHistoryEntry[];
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export type Confidence = "observed" | "declared" | "inferred" | "unknown";
|
|
434
|
+
|
|
435
|
+
export interface Leaf {
|
|
436
|
+
value: unknown;
|
|
437
|
+
evidence: string[];
|
|
438
|
+
confidence: Confidence;
|
|
439
|
+
reason?: string;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export interface Labelled {
|
|
443
|
+
language: string;
|
|
444
|
+
text: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export interface Concept {
|
|
448
|
+
id: string;
|
|
449
|
+
prefLabels: Labelled[];
|
|
450
|
+
altLabels?: Labelled[];
|
|
451
|
+
definitions?: Labelled[];
|
|
452
|
+
status: string;
|
|
453
|
+
origin: string;
|
|
454
|
+
kind: string;
|
|
455
|
+
grounding?: unknown[];
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface Glossary {
|
|
459
|
+
boundedContext: string;
|
|
460
|
+
titles: Labelled[];
|
|
461
|
+
concepts: Concept[];
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** How often one concept is used across the host's documentation and source. */
|
|
465
|
+
export interface ConceptUsage {
|
|
466
|
+
count: number;
|
|
467
|
+
files: number;
|
|
468
|
+
examples: string[];
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** Usage keyed by bounded context, then concept id. */
|
|
472
|
+
export type GlossaryUsage = Record<string, Record<string, ConceptUsage>>;
|
|
473
|
+
|
|
474
|
+
/** The crawl's own judgment of how much a concept matters to the project. */
|
|
475
|
+
export interface ConceptSignificance {
|
|
476
|
+
score: number;
|
|
477
|
+
reason: string;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** Significance keyed by bounded context, then concept id. */
|
|
481
|
+
export type GlossarySignificance = Record<string, Record<string, ConceptSignificance>>;
|
|
482
|
+
|
|
483
|
+
export interface DiscoverSkill {
|
|
484
|
+
name: string;
|
|
485
|
+
state: "generated" | "edited" | "missing";
|
|
486
|
+
baseline: string | null;
|
|
487
|
+
live: string | null;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export interface Freshness {
|
|
491
|
+
project: string;
|
|
492
|
+
commit: string;
|
|
493
|
+
dirty: boolean;
|
|
494
|
+
discoveredAt: string;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/** One remote project whose published bytes the dashboard retains. */
|
|
498
|
+
export interface RetainedRemoteProject {
|
|
499
|
+
url: string;
|
|
500
|
+
owner: string;
|
|
501
|
+
repo: string;
|
|
502
|
+
/** ISO time the discovery that produced the retained bytes completed. */
|
|
503
|
+
completedAt: string;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/** The target Discover reads and writes: this host, or a retained remote project. */
|
|
507
|
+
export type DiscoverTarget =
|
|
508
|
+
| { kind: "host" }
|
|
509
|
+
| {
|
|
510
|
+
kind: "remote";
|
|
511
|
+
url: string;
|
|
512
|
+
owner: string;
|
|
513
|
+
repo: string;
|
|
514
|
+
/** True while the active project's transient clone exists for a run. */
|
|
515
|
+
checkout: boolean;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
export interface DiscoverStatePayload {
|
|
519
|
+
active: boolean;
|
|
520
|
+
runId: string | null;
|
|
521
|
+
startedAt: string | null;
|
|
522
|
+
interrupted: boolean;
|
|
523
|
+
stale: boolean;
|
|
524
|
+
warnings: string[];
|
|
525
|
+
busy: string | null;
|
|
526
|
+
error: string | null;
|
|
527
|
+
/** True only when the dashboard serves a harness source checkout. */
|
|
528
|
+
remoteAvailable: boolean;
|
|
529
|
+
/** Retained remote projects, newest completed discovery first. */
|
|
530
|
+
retained: RetainedRemoteProject[];
|
|
531
|
+
/** `owner/name` of the repository being read, or null outside a GitHub remote. */
|
|
532
|
+
repository: string | null;
|
|
533
|
+
target: DiscoverTarget;
|
|
534
|
+
cloning: { url: string } | null;
|
|
535
|
+
manifest: unknown;
|
|
536
|
+
freshness: Freshness | null;
|
|
537
|
+
sheet: Record<string, unknown> | null;
|
|
538
|
+
/** The manifest's invocations for the commands the sheet recorded. */
|
|
539
|
+
commandAliases?: Array<{ command: string; alias: string }>;
|
|
540
|
+
dependencyRepositories: Record<string, string>;
|
|
541
|
+
glossaries: Glossary[];
|
|
542
|
+
glossaryUsage: GlossaryUsage;
|
|
543
|
+
glossarySignificance: GlossarySignificance;
|
|
544
|
+
decisions: unknown[];
|
|
545
|
+
skills: DiscoverSkill[];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export type DiscoverTabId =
|
|
549
|
+
| "overview"
|
|
550
|
+
| "glossary"
|
|
551
|
+
| "testing-strategy"
|
|
552
|
+
| "naming-conventions"
|
|
553
|
+
| "coding-conventions"
|
|
554
|
+
| "architecture-boundaries"
|
|
555
|
+
| "glossary-skill";
|
|
556
|
+
|
|
557
|
+
export interface DiscoverTab {
|
|
558
|
+
id: DiscoverTabId;
|
|
559
|
+
label: string;
|
|
560
|
+
skill: string | null;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/** One visible turn of the element-scoped Ask conversation. */
|
|
564
|
+
export interface AskTurn {
|
|
565
|
+
role: "developer" | "agent";
|
|
566
|
+
text: string;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/** The captured element an Ask question travels with. */
|
|
570
|
+
export interface AskContext {
|
|
571
|
+
route: string;
|
|
572
|
+
url: string;
|
|
573
|
+
selector: string;
|
|
574
|
+
viewport: string;
|
|
575
|
+
captured_at: string;
|
|
576
|
+
visible_text: string;
|
|
577
|
+
dom_excerpt: string;
|
|
578
|
+
}
|