@polishd/next 0.2.3-dev.4 → 0.2.3-dev.5
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 +37 -39
- package/README.md +7 -5
- package/bin/init.mjs +4 -1
- package/dist/ai/actions.d.ts +1 -7
- package/dist/ai/actions.d.ts.map +1 -1
- package/dist/ai/actions.js +0 -10
- package/dist/ai/actions.js.map +1 -1
- package/dist/ai/guard.d.ts.map +1 -1
- package/dist/ai/guard.js +32 -8
- package/dist/ai/guard.js.map +1 -1
- package/dist/ai/issues.d.ts +0 -12
- package/dist/ai/issues.d.ts.map +1 -1
- package/dist/ai/issues.js +2 -16
- package/dist/ai/issues.js.map +1 -1
- package/dist/ai/types.d.ts +0 -49
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +2 -4
- package/dist/dashboard/index.js.map +1 -1
- package/dist/dashboard/issues.d.ts +2 -31
- package/dist/dashboard/issues.d.ts.map +1 -1
- package/dist/dashboard/issues.js +71 -4
- package/dist/dashboard/issues.js.map +1 -1
- package/dist/dashboard/snapshot-actions.d.ts +15 -5
- package/dist/dashboard/snapshot-actions.d.ts.map +1 -1
- package/dist/dashboard/snapshot-actions.js +102 -25
- package/dist/dashboard/snapshot-actions.js.map +1 -1
- package/dist/dashboard/snapshots.d.ts.map +1 -1
- package/dist/dashboard/snapshots.js +71 -8
- package/dist/dashboard/snapshots.js.map +1 -1
- package/dist/dashboard.css +18 -70
- package/dist/server/snapshots.d.ts +37 -6
- package/dist/server/snapshots.d.ts.map +1 -1
- package/dist/server/snapshots.js +271 -144
- package/dist/server/snapshots.js.map +1 -1
- package/docs/SETUP.md +10 -0
- package/package.json +1 -1
- package/dist/ai/fix.d.ts +0 -14
- package/dist/ai/fix.d.ts.map +0 -1
- package/dist/ai/fix.js +0 -254
- package/dist/ai/fix.js.map +0 -1
- package/dist/dashboard/issue-list.d.ts +0 -11
- package/dist/dashboard/issue-list.d.ts.map +0 -1
- package/dist/dashboard/issue-list.js +0 -159
- package/dist/dashboard/issue-list.js.map +0 -1
- package/dist/dashboard/markdown-parse.d.ts +0 -87
- package/dist/dashboard/markdown-parse.d.ts.map +0 -1
- package/dist/dashboard/markdown-parse.js +0 -244
- package/dist/dashboard/markdown-parse.js.map +0 -1
- package/dist/dashboard/markdown.d.ts +0 -5
- package/dist/dashboard/markdown.d.ts.map +0 -1
- package/dist/dashboard/markdown.js +0 -65
- package/dist/dashboard/markdown.js.map +0 -1
package/dist/ai/fix.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Polishd — filed issue → suggested fix (server only).
|
|
3
|
-
*
|
|
4
|
-
* The Issues tab shows what was reported; this module answers the next
|
|
5
|
-
* question: how would you actually fix it? Only meaningful when the GitHub
|
|
6
|
-
* codebase is connected — the whole point is that the suggestion is grounded
|
|
7
|
-
* in the repository's real source, not in the issue text alone:
|
|
8
|
-
*
|
|
9
|
-
* 1. Recover the analytics evidence behind the issue from the filed log —
|
|
10
|
-
* an issue polishd didn't file is refused, there's no evidence to ground.
|
|
11
|
-
* 2. Pull source: files the issue body already cites (the ones the original
|
|
12
|
-
* verification read), then code-search hits for the evidence.
|
|
13
|
-
* 3. Ask the model to first CLASSIFY the bug — an interaction issue
|
|
14
|
-
* (something users do fails) or a design issue (something users see is
|
|
15
|
-
* wrong) — and then design the fix on the published practice for that
|
|
16
|
-
* class: Nielsen Norman's usability heuristics and the WAI-ARIA
|
|
17
|
-
* Authoring Practices for interaction, WCAG 2.2 and spacing/type-scale
|
|
18
|
-
* rhythm for design. The reply names the guidelines it leaned on, so the
|
|
19
|
-
* owner can judge the advice by its sources.
|
|
20
|
-
* 4. The answer is an implementation path — ordered, file-by-file edits —
|
|
21
|
-
* not just prose, and it's cached per issue number: the issue and the
|
|
22
|
-
* source rarely change under it, and a regenerate is one click away.
|
|
23
|
-
*/
|
|
24
|
-
import { getMeta, setMeta } from "../server/store";
|
|
25
|
-
import { isGithubConnected, readGithubFile, readGithubIssue, searchGithubCode, } from "./github";
|
|
26
|
-
import { evidenceSearchTerms, findFiledIssue } from "./issues";
|
|
27
|
-
import { loadProjectProfile } from "./profile";
|
|
28
|
-
import { callModel } from "./providers";
|
|
29
|
-
import { resolveSettings } from "./settings";
|
|
30
|
-
const FIX_LOG_KEY = "issue_fix_suggestions";
|
|
31
|
-
const MAX_FILES = 4;
|
|
32
|
-
const MAX_CHARS_PER_FILE = 8_000;
|
|
33
|
-
const MAX_BODY_CHARS = 6_000;
|
|
34
|
-
/** The reply carries prose + steps, not one paragraph — give it headroom. */
|
|
35
|
-
const MAX_OUTPUT_TOKENS = 4_096;
|
|
36
|
-
async function loadFixLog() {
|
|
37
|
-
const raw = await getMeta(FIX_LOG_KEY);
|
|
38
|
-
if (!raw)
|
|
39
|
-
return {};
|
|
40
|
-
try {
|
|
41
|
-
return JSON.parse(raw);
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
return {};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Every cached suggestion, keyed by issue number — what the Issues tab loads
|
|
49
|
-
* up front so an already-answered issue opens with its fix in place.
|
|
50
|
-
*/
|
|
51
|
-
export async function listFixSuggestions() {
|
|
52
|
-
const log = await loadFixLog();
|
|
53
|
-
const out = {};
|
|
54
|
-
for (const s of Object.values(log))
|
|
55
|
-
out[s.issueNumber] = s;
|
|
56
|
-
return out;
|
|
57
|
-
}
|
|
58
|
-
// ── The prompt ───────────────────────────────────────────────────────────────
|
|
59
|
-
const FIX_PROMPT = "You are a senior product engineer proposing a concrete fix for a bug that " +
|
|
60
|
-
"a product-analytics tool filed from real user-behavior data. You receive " +
|
|
61
|
-
"the GitHub issue (title and body), the analytics identifier cited as " +
|
|
62
|
-
"evidence, and source files from the site's repository.\n\n" +
|
|
63
|
-
"First classify the bug, then design the fix on the widely adopted practice " +
|
|
64
|
-
"for that class:\n" +
|
|
65
|
-
"- interaction: something users DO fails or frustrates — rage/dead clicks, " +
|
|
66
|
-
"broken or missing handlers, unresponsive or inaccessible controls, " +
|
|
67
|
-
"confusing flows, runtime errors. Ground the fix in Nielsen Norman's " +
|
|
68
|
-
"usability heuristics (visibility of system status, error prevention and " +
|
|
69
|
-
"recovery), the WAI-ARIA Authoring Practices for correct interactive " +
|
|
70
|
-
"semantics and keyboard support, and touch-target guidance (WCAG 2.5.8 / " +
|
|
71
|
-
"the 44px platform minimums).\n" +
|
|
72
|
-
"- design: something users SEE is wrong — contrast, visual hierarchy, " +
|
|
73
|
-
"spacing, typography, layout shift. Ground the fix in WCAG 2.2 (1.4.3 text " +
|
|
74
|
-
"contrast, 1.4.11 non-text contrast), a consistent spacing rhythm and type " +
|
|
75
|
-
"scale, and the web-vitals guidance on layout stability (CLS).\n\n" +
|
|
76
|
-
"Respond with ONLY a JSON object (no markdown fences, no preamble):\n" +
|
|
77
|
-
'{ "bugType": "interaction" | "design", "classification": string, ' +
|
|
78
|
-
'"approach": string, "steps": [{ "path": string, "change": string }], ' +
|
|
79
|
-
'"practices": string[] }\n\n' +
|
|
80
|
-
"bugType: which class this bug falls into.\n" +
|
|
81
|
-
"classification: one sentence on why it's that class.\n" +
|
|
82
|
-
"approach: the fix in 2-5 sentences, written for the developer who will " +
|
|
83
|
-
"implement it, citing the code it changes. Inline markdown (backticked " +
|
|
84
|
-
"identifiers) is welcome; no headings.\n" +
|
|
85
|
-
"steps: the implementation path, in order. Each path MUST be a repository " +
|
|
86
|
-
"file path taken from the source files provided; each change describes the " +
|
|
87
|
-
"exact edit in 1-3 sentences. 1-5 steps.\n" +
|
|
88
|
-
"practices: 1-3 short names of the published guidelines the fix leans on, " +
|
|
89
|
-
'e.g. "WCAG 2.2 §1.4.3 contrast", "ARIA APG disclosure pattern", ' +
|
|
90
|
-
'"NN/g error prevention". Only ones that genuinely informed the fix.';
|
|
91
|
-
// ── Source gathering ─────────────────────────────────────────────────────────
|
|
92
|
-
/** Repo paths the issue body itself cites — `[`src/x.tsx`](…)` and the like. */
|
|
93
|
-
function citedPaths(body) {
|
|
94
|
-
const out = [];
|
|
95
|
-
for (const m of body.matchAll(/`([\w@./-]+\.[a-z]{2,4})`/gi)) {
|
|
96
|
-
if (m[1].includes("/") && !out.includes(m[1]))
|
|
97
|
-
out.push(m[1]);
|
|
98
|
-
}
|
|
99
|
-
return out;
|
|
100
|
-
}
|
|
101
|
-
/** The issue's own citations first, then code-search hits for the evidence. */
|
|
102
|
-
async function collectSource(evidence, body) {
|
|
103
|
-
const paths = citedPaths(body);
|
|
104
|
-
for (const p of await searchGithubCode(evidenceSearchTerms(evidence), MAX_FILES)) {
|
|
105
|
-
if (!paths.includes(p))
|
|
106
|
-
paths.push(p);
|
|
107
|
-
}
|
|
108
|
-
const out = [];
|
|
109
|
-
for (const path of paths.slice(0, MAX_FILES)) {
|
|
110
|
-
const content = await readGithubFile(path);
|
|
111
|
-
if (content)
|
|
112
|
-
out.push({ path, content: content.slice(0, MAX_CHARS_PER_FILE) });
|
|
113
|
-
}
|
|
114
|
-
return out;
|
|
115
|
-
}
|
|
116
|
-
// ── Parsing ──────────────────────────────────────────────────────────────────
|
|
117
|
-
/** Tolerant JSON extraction, same approach as the investigation parser. */
|
|
118
|
-
function parseSuggestion(text) {
|
|
119
|
-
let t = text.trim();
|
|
120
|
-
const fence = t.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
121
|
-
if (fence)
|
|
122
|
-
t = fence[1].trim();
|
|
123
|
-
const start = t.indexOf("{");
|
|
124
|
-
const end = t.lastIndexOf("}");
|
|
125
|
-
if (start < 0 || end <= start)
|
|
126
|
-
return null;
|
|
127
|
-
try {
|
|
128
|
-
const obj = JSON.parse(t.slice(start, end + 1));
|
|
129
|
-
const approach = typeof obj.approach === "string" ? obj.approach.trim() : "";
|
|
130
|
-
if (!approach)
|
|
131
|
-
return null;
|
|
132
|
-
const steps = Array.isArray(obj.steps)
|
|
133
|
-
? obj.steps
|
|
134
|
-
.flatMap((s) => {
|
|
135
|
-
if (typeof s !== "object" || s === null)
|
|
136
|
-
return [];
|
|
137
|
-
const { path, change } = s;
|
|
138
|
-
return typeof path === "string" && typeof change === "string" && path.trim()
|
|
139
|
-
? [{ path: path.trim(), change: change.trim() }]
|
|
140
|
-
: [];
|
|
141
|
-
})
|
|
142
|
-
.slice(0, 5)
|
|
143
|
-
: [];
|
|
144
|
-
return {
|
|
145
|
-
bugType: obj.bugType === "design" ? "design" : "interaction",
|
|
146
|
-
classification: typeof obj.classification === "string" ? obj.classification.trim() : "",
|
|
147
|
-
approach,
|
|
148
|
-
steps,
|
|
149
|
-
practices: Array.isArray(obj.practices)
|
|
150
|
-
? obj.practices
|
|
151
|
-
.filter((p) => typeof p === "string" && p.trim().length > 0)
|
|
152
|
-
.slice(0, 3)
|
|
153
|
-
: [],
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// ── The pipeline ─────────────────────────────────────────────────────────────
|
|
161
|
-
/**
|
|
162
|
-
* Propose (or re-propose, with `force`) a fix for one filed issue. Refuses
|
|
163
|
-
* cleanly when nothing is connected, no model key is set, or the number isn't
|
|
164
|
-
* an issue polishd filed; a model hiccup comes back as `provider-error`, and
|
|
165
|
-
* nothing is cached on failure.
|
|
166
|
-
*/
|
|
167
|
-
export async function suggestIssueFix(issueNumber, force = false) {
|
|
168
|
-
if (!(await isGithubConnected())) {
|
|
169
|
-
return {
|
|
170
|
-
ok: false,
|
|
171
|
-
error: "not-connected",
|
|
172
|
-
message: "Connect a GitHub repository in the settings first.",
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
const { settings } = await resolveSettings();
|
|
176
|
-
if (!settings.apiKey) {
|
|
177
|
-
return {
|
|
178
|
-
ok: false,
|
|
179
|
-
error: "no-key",
|
|
180
|
-
message: "Configure a model API key in the settings first.",
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
const key = String(issueNumber);
|
|
184
|
-
if (!force) {
|
|
185
|
-
const cached = (await loadFixLog())[key];
|
|
186
|
-
if (cached)
|
|
187
|
-
return { ok: true, suggestion: cached, regenerated: false };
|
|
188
|
-
}
|
|
189
|
-
const filed = await findFiledIssue(issueNumber);
|
|
190
|
-
if (!filed) {
|
|
191
|
-
return {
|
|
192
|
-
ok: false,
|
|
193
|
-
error: "not-found",
|
|
194
|
-
message: `Issue #${issueNumber} isn't one polishd filed.`,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
// Live issue text when GitHub will still give it; the stored claim otherwise.
|
|
198
|
-
const detail = await readGithubIssue(issueNumber);
|
|
199
|
-
const title = detail?.title ?? filed.claim ?? `Issue #${issueNumber}`;
|
|
200
|
-
const body = (detail?.body ?? "").slice(0, MAX_BODY_CHARS);
|
|
201
|
-
const files = await collectSource(filed.evidence, body);
|
|
202
|
-
const profile = await loadProjectProfile();
|
|
203
|
-
const sections = [
|
|
204
|
-
`THE ISSUE (#${issueNumber}): ${title}`,
|
|
205
|
-
"",
|
|
206
|
-
"ISSUE BODY:",
|
|
207
|
-
body || filed.claim || "(no body available)",
|
|
208
|
-
"",
|
|
209
|
-
`EVIDENCE (identifier from the analytics data): ${filed.evidence}`,
|
|
210
|
-
];
|
|
211
|
-
if (profile) {
|
|
212
|
-
sections.push("", `PROJECT PROFILE (what this site and its components are):\n${profile.text}`);
|
|
213
|
-
}
|
|
214
|
-
if (files.length > 0) {
|
|
215
|
-
sections.push("", "SOURCE FILES (from the GitHub repository):", ...files.map((f) => `--- ${f.path} ---\n${f.content}`));
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
sections.push("", "SOURCE FILES: none could be located for this evidence — keep steps to " +
|
|
219
|
-
"the paths the issue body cites, or describe where the change belongs.");
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
const reply = await callModel(settings, FIX_PROMPT, sections.join("\n"), {
|
|
223
|
-
maxTokens: MAX_OUTPUT_TOKENS,
|
|
224
|
-
});
|
|
225
|
-
const parsed = reply.text ? parseSuggestion(reply.text) : null;
|
|
226
|
-
if (!parsed) {
|
|
227
|
-
return {
|
|
228
|
-
ok: false,
|
|
229
|
-
error: "provider-error",
|
|
230
|
-
message: "The model's suggestion could not be parsed. Try again.",
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
const suggestion = {
|
|
234
|
-
...parsed,
|
|
235
|
-
issueNumber,
|
|
236
|
-
files: files.map((f) => f.path),
|
|
237
|
-
provider: settings.provider,
|
|
238
|
-
model: settings.model,
|
|
239
|
-
generatedAt: Date.now(),
|
|
240
|
-
};
|
|
241
|
-
const log = await loadFixLog();
|
|
242
|
-
log[key] = suggestion;
|
|
243
|
-
await setMeta(FIX_LOG_KEY, JSON.stringify(log));
|
|
244
|
-
return { ok: true, suggestion, regenerated: true };
|
|
245
|
-
}
|
|
246
|
-
catch (err) {
|
|
247
|
-
return {
|
|
248
|
-
ok: false,
|
|
249
|
-
error: "provider-error",
|
|
250
|
-
message: err instanceof Error ? err.message : "The model call failed.",
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
//# sourceMappingURL=fix.js.map
|
package/dist/ai/fix.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/ai/fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { PolishdFiledIssue, PolishdFixSuggestion } from "../ai/types";
|
|
2
|
-
export default function IssueList({ issues, repo, suggestions: initialSuggestions, canSuggest, }: {
|
|
3
|
-
issues: PolishdFiledIssue[];
|
|
4
|
-
/** The connected repository, "owner/repo". */
|
|
5
|
-
repo?: string;
|
|
6
|
-
/** Cached fix suggestions, keyed by issue number. */
|
|
7
|
-
suggestions: Record<number, PolishdFixSuggestion>;
|
|
8
|
-
/** True when a model API key is configured (fix suggestions need one). */
|
|
9
|
-
canSuggest: boolean;
|
|
10
|
-
}): import("react").JSX.Element;
|
|
11
|
-
//# sourceMappingURL=issue-list.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue-list.d.ts","sourceRoot":"","sources":["../../src/dashboard/issue-list.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAifrB,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,MAAM,EACN,IAAI,EACJ,WAAW,EAAE,kBAAkB,EAC/B,UAAU,GACX,EAAE;IACD,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,OAAO,CAAC;CACrB,+BA0BA"}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Polishd — the filed-issue list and its right-side drawer (client).
|
|
5
|
-
*
|
|
6
|
-
* The Issues tab's rows live here so a click can do something: each row opens
|
|
7
|
-
* a drawer with the full issue — the body rendered as the markdown it is
|
|
8
|
-
* (see `markdown.tsx`), not the raw text — plus the metadata GitHub reports
|
|
9
|
-
* and the analytics context polishd kept. Same drawer pattern as the sampled
|
|
10
|
-
* user journeys: the dashboard stays in view while you drill into one issue.
|
|
11
|
-
*
|
|
12
|
-
* The drawer also carries the "Suggest a fix" panel. With the GitHub codebase
|
|
13
|
-
* connected, one click asks the configured model to classify the bug — an
|
|
14
|
-
* interaction issue or a design issue — and propose a fix grounded in the
|
|
15
|
-
* repository's source and in published practice (NN/g heuristics, the ARIA
|
|
16
|
-
* Authoring Practices, WCAG 2.2), with the file-by-file implementation path.
|
|
17
|
-
* Suggestions arrive pre-loaded from the server cache; generating a new one
|
|
18
|
-
* goes through `suggestIssueFixAction`.
|
|
19
|
-
*/
|
|
20
|
-
import { useEffect, useState, useTransition } from "react";
|
|
21
|
-
import { suggestIssueFixAction } from "../ai/actions";
|
|
22
|
-
import { Markdown } from "./markdown";
|
|
23
|
-
import { border, divider, labelCls as label, SpinnerIcon } from "./ui";
|
|
24
|
-
// ── Formatting helpers ────────────────────────────────────────────────────────
|
|
25
|
-
/** "3 Aug", or "3 Aug 2024" once it's from another year. */
|
|
26
|
-
function shortDate(ms) {
|
|
27
|
-
const d = new Date(ms);
|
|
28
|
-
const sameYear = d.getFullYear() === new Date().getFullYear();
|
|
29
|
-
return d.toLocaleDateString("en-GB", {
|
|
30
|
-
day: "numeric",
|
|
31
|
-
month: "short",
|
|
32
|
-
...(sameYear ? {} : { year: "numeric" }),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
/** Coarse relative age — "2d ago" — for the meta line. */
|
|
36
|
-
function timeAgo(ms) {
|
|
37
|
-
const delta = Date.now() - ms;
|
|
38
|
-
if (delta < 60_000)
|
|
39
|
-
return "just now";
|
|
40
|
-
const mins = Math.floor(delta / 60_000);
|
|
41
|
-
if (mins < 60)
|
|
42
|
-
return `${mins}m ago`;
|
|
43
|
-
const hours = Math.floor(mins / 60);
|
|
44
|
-
if (hours < 24)
|
|
45
|
-
return `${hours}h ago`;
|
|
46
|
-
const days = Math.floor(hours / 24);
|
|
47
|
-
if (days < 30)
|
|
48
|
-
return `${days}d ago`;
|
|
49
|
-
return shortDate(ms);
|
|
50
|
-
}
|
|
51
|
-
/** Open / closed / unreadable — the one thing you look for per row. */
|
|
52
|
-
function StatePill({ detail }) {
|
|
53
|
-
if (!detail) {
|
|
54
|
-
return (_jsx("span", { className: "shrink-0 rounded-full bg-[#1a1a1a] px-2 py-0.5 text-[10px] font-medium text-[#666]", children: "\u25CB unreadable" }));
|
|
55
|
-
}
|
|
56
|
-
if (detail.state === "open") {
|
|
57
|
-
return (_jsx("span", { className: "shrink-0 rounded-full bg-emerald-950 px-2 py-0.5 text-[10px] font-medium text-emerald-400", children: "\u25CF open" }));
|
|
58
|
-
}
|
|
59
|
-
const notPlanned = detail.stateReason === "not_planned";
|
|
60
|
-
return (_jsx("span", { className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${notPlanned ? "bg-[#1a1a1a] text-[#888]" : "bg-[#1e132b] text-[#b083f0]"}`, children: notPlanned ? "✕ not planned" : "✓ closed" }));
|
|
61
|
-
}
|
|
62
|
-
function Chip({ children, tone = "text-[#888]" }) {
|
|
63
|
-
return (_jsx("span", { className: `max-w-full break-all rounded border border-[#2e2e2e] px-1.5 py-0.5 text-[10px] font-medium ${tone}`, children: children }));
|
|
64
|
-
}
|
|
65
|
-
/** Which class of bug the fix suggestion decided this is. */
|
|
66
|
-
function BugTypeChip({ type }) {
|
|
67
|
-
return type === "interaction" ? (_jsx("span", { className: "shrink-0 rounded-full bg-blue-950 px-2 py-0.5 text-[10px] font-medium text-blue-400", children: "interaction issue" })) : (_jsx("span", { className: "shrink-0 rounded-full bg-purple-950 px-2 py-0.5 text-[10px] font-medium text-purple-300", children: "design issue" }));
|
|
68
|
-
}
|
|
69
|
-
/** The dot-separated facts under a row's title, in the order they matter. */
|
|
70
|
-
function metaLine(issue) {
|
|
71
|
-
const { detail } = issue;
|
|
72
|
-
const opened = detail?.createdAt ?? issue.filedAt;
|
|
73
|
-
const bits = [];
|
|
74
|
-
if (opened)
|
|
75
|
-
bits.push(`opened ${timeAgo(opened)}`);
|
|
76
|
-
if (detail?.author)
|
|
77
|
-
bits.push(`by ${detail.author}`);
|
|
78
|
-
if (detail?.closedAt)
|
|
79
|
-
bits.push(`closed ${timeAgo(detail.closedAt)}`);
|
|
80
|
-
// An "updated" that is really just the moment it was filed says nothing.
|
|
81
|
-
else if (detail && detail.updatedAt > (opened ?? 0) + 60_000) {
|
|
82
|
-
bits.push(`updated ${timeAgo(detail.updatedAt)}`);
|
|
83
|
-
}
|
|
84
|
-
if (detail && detail.comments > 0) {
|
|
85
|
-
bits.push(`${detail.comments} ${detail.comments === 1 ? "comment" : "comments"}`);
|
|
86
|
-
}
|
|
87
|
-
if (detail && detail.assignees.length > 0) {
|
|
88
|
-
bits.push(`assigned to ${detail.assignees.join(", ")}`);
|
|
89
|
-
}
|
|
90
|
-
return bits.join(" · ");
|
|
91
|
-
}
|
|
92
|
-
// ── One clickable row ─────────────────────────────────────────────────────────
|
|
93
|
-
function IssueRow({ issue, repo, onOpen, }) {
|
|
94
|
-
const { detail } = issue;
|
|
95
|
-
const title = detail?.title ?? issue.claim ?? `Issue #${issue.number}`;
|
|
96
|
-
return (_jsxs("div", { role: "button", tabIndex: 0, "data-component": "issue-open", onClick: onOpen, onKeyDown: (e) => {
|
|
97
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
98
|
-
e.preventDefault();
|
|
99
|
-
onOpen();
|
|
100
|
-
}
|
|
101
|
-
}, className: `group cursor-pointer px-4 py-4 transition-colors hover:bg-[#111] sm:px-5 ${divider} first:border-t-0`, children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("a", { href: issue.url, target: "_blank", rel: "noreferrer noopener", onClick: (e) => e.stopPropagation(), className: "text-[14px] font-medium leading-snug text-white hover:text-[#8ab4f8]", children: [_jsxs("span", { className: "mr-1.5 font-mono text-[12px] tabular-nums text-[#666]", children: ["#", issue.number] }), title] }), _jsx("p", { className: "mt-1.5 text-[11px] leading-snug text-[#666]", children: metaLine(issue) })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx(StatePill, { detail: detail }), _jsx("span", { className: "text-[#555] transition-colors group-hover:text-[#999]", children: "\u203A" })] })] }), _jsxs("div", { className: "mt-2.5 flex flex-wrap items-center gap-1.5", children: [_jsxs(Chip, { tone: "text-[#aaa]", children: [_jsx("span", { className: "text-[#666]", children: "evidence" }), " ", _jsx("span", { className: "font-mono", children: issue.evidence })] }), issue.verdict === "confirmed" && (_jsx(Chip, { tone: "text-emerald-500", children: "verified against source" })), issue.verdict === "inconclusive" && (_jsx(Chip, { tone: "text-[#f5a623]", children: "filed unverified" })), (detail?.labels ?? []).map((l) => (_jsx(Chip, { children: l }, l)))] }), !detail && (_jsxs("p", { className: "mt-2.5 text-[12px] leading-relaxed text-[#777]", children: ["Polishd filed this issue", issue.filedAt ? ` on ${shortDate(issue.filedAt)}` : "", ", but GitHub won't return it now \u2014 it was deleted or transferred, or the access token no longer covers", repo ? ` ${repo}` : " the repository", "."] }))] }));
|
|
102
|
-
}
|
|
103
|
-
// ── The suggest-a-fix panel (inside the drawer) ───────────────────────────────
|
|
104
|
-
function FixPanel({ issueNumber, repo, suggestion, canSuggest, onSuggested, }) {
|
|
105
|
-
const [pending, startTransition] = useTransition();
|
|
106
|
-
const [error, setError] = useState(null);
|
|
107
|
-
const run = (force) => {
|
|
108
|
-
setError(null);
|
|
109
|
-
startTransition(async () => {
|
|
110
|
-
const res = await suggestIssueFixAction(issueNumber, force);
|
|
111
|
-
if (res.ok)
|
|
112
|
-
onSuggested(res.suggestion);
|
|
113
|
-
else
|
|
114
|
-
setError(res.message);
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
const fileUrl = (path) => repo ? `https://github.com/${repo}/blob/HEAD/${path}` : undefined;
|
|
118
|
-
return (_jsxs("div", { className: `border-t ${border} px-4 py-4 sm:px-5`, children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx("div", { className: "text-[10px] uppercase tracking-[0.08em] text-[#666]", children: "Suggested fix" }), suggestion && _jsx(BugTypeChip, { type: suggestion.bugType })] }), suggestion ? (_jsxs(_Fragment, { children: [suggestion.classification && (_jsx("p", { className: "mb-3 text-[12px] leading-relaxed text-[#888]", children: suggestion.classification })), _jsx(Markdown, { text: suggestion.approach }), suggestion.steps.length > 0 && (_jsxs("div", { className: "mt-4", children: [_jsx("div", { className: "mb-2 text-[10px] uppercase tracking-[0.08em] text-[#666]", children: "Implementation path" }), _jsx("ol", { children: suggestion.steps.map((step, i) => (_jsxs("li", { className: "relative flex gap-3", children: [_jsxs("div", { className: "relative flex w-2.5 shrink-0 justify-center", children: [_jsx("span", { className: "z-10 mt-[5px] h-2.5 w-2.5 shrink-0 rounded-full bg-[#555]" }), i < suggestion.steps.length - 1 && (_jsx("span", { className: "absolute top-[5px] h-full w-px bg-[#2e2e2e]" }))] }), _jsxs("div", { className: "min-w-0 flex-1 pb-3", children: [fileUrl(step.path) ? (_jsx("a", { href: fileUrl(step.path), target: "_blank", rel: "noreferrer noopener", className: "break-all font-mono text-[12px] text-[#8ab4f8] hover:underline", children: step.path })) : (_jsx("span", { className: "break-all font-mono text-[12px] text-[#ccc]", children: step.path })), _jsx("p", { className: "mt-0.5 text-[12px] leading-relaxed text-[#aaa]", children: step.change })] })] }, i))) })] })), suggestion.practices.length > 0 && (_jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "text-[10px] text-[#666]", children: "grounded in" }), suggestion.practices.map((p) => (_jsx(Chip, { tone: "text-[#aaa]", children: p }, p)))] })), _jsxs("div", { className: "mt-3 flex items-center gap-2.5", children: [_jsx("button", { type: "button", "data-component": "issue-suggest-fix", onClick: () => run(true), disabled: pending, className: "rounded-md border border-[#2e2e2e] px-2.5 py-1 text-[11px] text-[#888] transition-colors hover:border-[#555] hover:text-white disabled:opacity-50", children: pending ? "Rethinking…" : "Regenerate" }), _jsxs("span", { className: "text-[10px] text-[#555]", children: [suggestion.model, " \u00B7 ", timeAgo(suggestion.generatedAt)] })] })] })) : canSuggest ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mb-3 text-[12px] leading-relaxed text-[#777]", children: "Ask the configured model to classify this bug \u2014 interaction or design \u2014 and propose a fix grounded in the repository's source, with the files to change." }), _jsxs("button", { type: "button", "data-component": "issue-suggest-fix", onClick: () => run(false), disabled: pending, className: "inline-flex items-center gap-2 rounded-md border border-[#2e2e2e] px-3 py-1.5 text-[12px] text-[#aaa] transition-colors hover:border-[#555] hover:text-white disabled:opacity-50", children: [pending && _jsx(SpinnerIcon, {}), pending ? "Reading the source…" : "Suggest a fix"] })] })) : (_jsx("p", { className: "text-[12px] leading-relaxed text-[#777]", children: "Configure a model API key in the settings and polishd can propose a fix for this issue from your source code." })), error && _jsx("p", { className: "mt-2.5 text-[12px] leading-relaxed text-red-400", children: error })] }));
|
|
119
|
-
}
|
|
120
|
-
// ── Right-side detail drawer ──────────────────────────────────────────────────
|
|
121
|
-
function MetaCell({ label: labelText, value, mono }) {
|
|
122
|
-
return (_jsxs("div", { className: `px-4 py-3 ${border} border-t`, children: [_jsx("div", { className: "text-[10px] uppercase tracking-[0.08em] text-[#666]", children: labelText }), _jsx("div", { className: `mt-1 break-words text-[13px] text-white ${mono ? "font-mono text-[12px]" : ""}`, children: value })] }));
|
|
123
|
-
}
|
|
124
|
-
function IssueDrawer({ issue, repo, suggestion, canSuggest, onClose, onSuggested, }) {
|
|
125
|
-
// Esc to close + lock background scroll while the drawer is open.
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
if (!issue)
|
|
128
|
-
return;
|
|
129
|
-
const onKey = (e) => {
|
|
130
|
-
if (e.key === "Escape")
|
|
131
|
-
onClose();
|
|
132
|
-
};
|
|
133
|
-
document.addEventListener("keydown", onKey);
|
|
134
|
-
const prev = document.body.style.overflow;
|
|
135
|
-
document.body.style.overflow = "hidden";
|
|
136
|
-
return () => {
|
|
137
|
-
document.removeEventListener("keydown", onKey);
|
|
138
|
-
document.body.style.overflow = prev;
|
|
139
|
-
};
|
|
140
|
-
}, [issue, onClose]);
|
|
141
|
-
const open = issue !== null;
|
|
142
|
-
const detail = issue?.detail ?? null;
|
|
143
|
-
return (_jsxs("div", { className: `fixed inset-0 z-50 ${open ? "" : "pointer-events-none"}`, "aria-hidden": !open, children: [_jsx("div", { onClick: onClose, className: `absolute inset-0 bg-black/60 transition-opacity duration-200 ${open ? "opacity-100" : "opacity-0"}` }), _jsx("aside", { role: "dialog", "aria-modal": "true", "aria-label": "Filed issue detail", className: `absolute right-0 top-0 flex h-full w-full max-w-md flex-col border-l ${border} bg-[#0a0a0a] shadow-2xl transition-transform duration-200 ease-out sm:max-w-xl ${open ? "translate-x-0" : "translate-x-full"}`, children: issue && (_jsxs(_Fragment, { children: [_jsxs("div", { className: `flex items-center gap-3 border-b ${border} px-4 py-4 sm:px-5`, children: [_jsxs("span", { className: "font-mono text-[14px] font-semibold text-white", children: ["#", issue.number] }), _jsx(StatePill, { detail: detail }), _jsx("a", { href: issue.url, target: "_blank", rel: "noreferrer noopener", className: "ml-auto whitespace-nowrap text-[11px] text-[#888] transition-colors hover:text-white", children: "GitHub \u2197" }), _jsx("button", { type: "button", "data-component": "issue-close", onClick: onClose, "aria-label": "Close", className: "flex h-7 w-7 items-center justify-center rounded-md border border-[#2e2e2e] text-[#888] transition-colors hover:bg-[#111] hover:text-white", children: "\u2715" })] }), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: [_jsxs("div", { className: "px-4 pt-4 sm:px-5", children: [_jsx("h2", { className: "text-[15px] font-semibold leading-snug text-white", children: detail?.title ?? issue.claim ?? `Issue #${issue.number}` }), issue.claim && issue.claim !== (detail?.title ?? issue.claim) && (_jsxs("p", { className: "mt-2 text-[12px] leading-relaxed text-[#888]", children: [_jsx("span", { className: label, children: "Reported as" }), " ", _jsx("span", { className: "text-[#aaa]", children: issue.claim })] })), (detail?.labels.length ?? 0) > 0 && (_jsx("div", { className: "mt-2.5 flex flex-wrap gap-1.5 pb-1", children: detail?.labels.map((l) => _jsx(Chip, { children: l }, l)) })), _jsx("div", { className: "pb-4" })] }), _jsxs("div", { className: "grid grid-cols-2", children: [_jsx(MetaCell, { label: "Opened", value: detail?.createdAt
|
|
144
|
-
? shortDate(detail.createdAt)
|
|
145
|
-
: issue.filedAt
|
|
146
|
-
? shortDate(issue.filedAt)
|
|
147
|
-
: "—" }), _jsx(MetaCell, { label: "Author", value: detail?.author ?? "—" }), _jsx(MetaCell, { label: "Evidence", value: issue.evidence, mono: true }), _jsx(MetaCell, { label: "Verification", value: issue.verdict === "confirmed"
|
|
148
|
-
? "verified against source"
|
|
149
|
-
: issue.verdict === "inconclusive"
|
|
150
|
-
? "filed unverified"
|
|
151
|
-
: "—" })] }), _jsxs("div", { className: `border-t ${border} px-4 py-4 sm:px-5`, children: [_jsx("div", { className: "mb-3 text-[10px] uppercase tracking-[0.08em] text-[#666]", children: "Issue body" }), detail ? (detail.body.trim().length > 0 ? (_jsx(Markdown, { text: detail.body })) : (_jsx("p", { className: "text-[12px] italic text-[#555]", children: "This issue has no body." }))) : (_jsxs("p", { className: "text-[12px] leading-relaxed text-[#777]", children: ["GitHub won't return this issue any more \u2014 it was deleted or transferred, or the access token no longer covers", repo ? ` ${repo}` : " the repository", "."] }))] }), _jsx(FixPanel, { issueNumber: issue.number, repo: repo, suggestion: suggestion, canSuggest: canSuggest, onSuggested: onSuggested })] })] })) })] }));
|
|
152
|
-
}
|
|
153
|
-
// ── Exported list + drawer ────────────────────────────────────────────────────
|
|
154
|
-
export default function IssueList({ issues, repo, suggestions: initialSuggestions, canSuggest, }) {
|
|
155
|
-
const [selected, setSelected] = useState(null);
|
|
156
|
-
const [suggestions, setSuggestions] = useState(initialSuggestions);
|
|
157
|
-
return (_jsxs(_Fragment, { children: [issues.map((issue) => (_jsx(IssueRow, { issue: issue, repo: repo, onOpen: () => setSelected(issue) }, issue.evidence))), _jsx(IssueDrawer, { issue: selected, repo: repo, suggestion: selected ? suggestions[selected.number] : undefined, canSuggest: canSuggest, onClose: () => setSelected(null), onSuggested: (s) => setSuggestions((prev) => ({ ...prev, [s.issueNumber]: s })) })] }));
|
|
158
|
-
}
|
|
159
|
-
//# sourceMappingURL=issue-list.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue-list.js","sourceRoot":"","sources":["../../src/dashboard/issue-list.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAC;AAE3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,IAAI,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAEvE,iFAAiF;AAEjF,4DAA4D;AAC5D,SAAS,SAAS,CAAC,EAAU;IAC3B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9D,OAAO,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;QACnC,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,OAAO;QACd,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KACzC,CAAC,CAAC;AACL,CAAC;AAED,0DAA0D;AAC1D,SAAS,OAAO,CAAC,EAAU;IACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IAC9B,IAAI,KAAK,GAAG,MAAM;QAAE,OAAO,UAAU,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IACxC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,OAAO,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,OAAO,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,OAAO,CAAC;IACrC,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,uEAAuE;AACvE,SAAS,SAAS,CAAC,EAAE,MAAM,EAAyC;IAClE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CACL,eAAM,SAAS,EAAC,oFAAoF,kCAE7F,CACR,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CACL,eAAM,SAAS,EAAC,2FAA2F,4BAEpG,CACR,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,KAAK,aAAa,CAAC;IACxD,OAAO,CACL,eACE,SAAS,EAAE,6DACT,UAAU,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,6BAC5C,EAAE,YAED,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,GACrC,CACR,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,aAAa,EAA0C;IACtF,OAAO,CACL,eACE,SAAS,EAAE,8FAA8F,IAAI,EAAE,YAE9G,QAAQ,GACJ,CACR,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,SAAS,WAAW,CAAC,EAAE,IAAI,EAA6C;IACtE,OAAO,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,CAC9B,eAAM,SAAS,EAAC,qFAAqF,kCAE9F,CACR,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,yFAAyF,6BAElG,CACR,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,QAAQ,CAAC,KAAwB;IACxC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,EAAE,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC;IAClD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,MAAM,EAAE,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,IAAI,MAAM,EAAE,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACtE,yEAAyE;SACpE,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,iFAAiF;AAEjF,SAAS,QAAQ,CAAC,EAChB,KAAK,EACL,IAAI,EACJ,MAAM,GAKP;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,UAAU,KAAK,CAAC,MAAM,EAAE,CAAC;IAEvE,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,oBACI,YAAY,EAC3B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;YACf,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBACvC,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC,EACD,SAAS,EAAE,4EAA4E,OAAO,mBAAmB,aAEjH,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,SAAS,aACtB,aACE,IAAI,EAAE,KAAK,CAAC,GAAG,EACf,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,EACnC,SAAS,EAAC,sEAAsE,aAEhF,gBAAM,SAAS,EAAC,uDAAuD,kBACnE,KAAK,CAAC,MAAM,IACT,EACN,KAAK,IACJ,EAEJ,YAAG,SAAS,EAAC,6CAA6C,YAAE,QAAQ,CAAC,KAAK,CAAC,GAAK,IAC5E,EACN,eAAK,SAAS,EAAC,kCAAkC,aAC/C,KAAC,SAAS,IAAC,MAAM,EAAE,MAAM,GAAI,EAC7B,eAAM,SAAS,EAAC,uDAAuD,uBAAS,IAC5E,IACF,EAGN,eAAK,SAAS,EAAC,4CAA4C,aACzD,MAAC,IAAI,IAAC,IAAI,EAAC,aAAa,aACtB,eAAM,SAAS,EAAC,aAAa,yBAAgB,EAAC,GAAG,EACjD,eAAM,SAAS,EAAC,WAAW,YAAE,KAAK,CAAC,QAAQ,GAAQ,IAC9C,EACN,KAAK,CAAC,OAAO,KAAK,WAAW,IAAI,CAChC,KAAC,IAAI,IAAC,IAAI,EAAC,kBAAkB,wCAA+B,CAC7D,EACA,KAAK,CAAC,OAAO,KAAK,cAAc,IAAI,CACnC,KAAC,IAAI,IAAC,IAAI,EAAC,gBAAgB,iCAAwB,CACpD,EACA,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACjC,KAAC,IAAI,cAAU,CAAC,IAAL,CAAC,CAAY,CACzB,CAAC,IACE,EAEL,CAAC,MAAM,IAAI,CACV,aAAG,SAAS,EAAC,gDAAgD,yCAClC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iHAE9D,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,SACpD,CACL,IACG,CACP,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF,SAAS,QAAQ,CAAC,EAChB,WAAW,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,GAQZ;IACC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,GAAG,GAAG,CAAC,KAAc,EAAE,EAAE;QAC7B,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,eAAe,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAC5D,IAAI,GAAG,CAAC,EAAE;gBAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;;gBACnC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAC/B,IAAI,CAAC,CAAC,CAAC,sBAAsB,IAAI,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,OAAO,CACL,eAAK,SAAS,EAAE,YAAY,MAAM,oBAAoB,aACpD,eAAK,SAAS,EAAC,8BAA8B,aAC3C,cAAK,SAAS,EAAC,qDAAqD,8BAAoB,EACvF,UAAU,IAAI,KAAC,WAAW,IAAC,IAAI,EAAE,UAAU,CAAC,OAAO,GAAI,IACpD,EAEL,UAAU,CAAC,CAAC,CAAC,CACZ,8BACG,UAAU,CAAC,cAAc,IAAI,CAC5B,YAAG,SAAS,EAAC,8CAA8C,YACxD,UAAU,CAAC,cAAc,GACxB,CACL,EAED,KAAC,QAAQ,IAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,GAAI,EAEtC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAC9B,eAAK,SAAS,EAAC,MAAM,aACnB,cAAK,SAAS,EAAC,0DAA0D,oCAEnE,EACN,uBACG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACjC,cAAY,SAAS,EAAC,qBAAqB,aACzC,eAAK,SAAS,EAAC,6CAA6C,aAC1D,eAAM,SAAS,EAAC,2DAA2D,GAAG,EAC7E,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,eAAM,SAAS,EAAC,6CAA6C,GAAG,CACjE,IACG,EACN,eAAK,SAAS,EAAC,qBAAqB,aACjC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACpB,YACE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EACxB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,SAAS,EAAC,gEAAgE,YAEzE,IAAI,CAAC,IAAI,GACR,CACL,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,6CAA6C,YAC1D,IAAI,CAAC,IAAI,GACL,CACR,EACD,YAAG,SAAS,EAAC,gDAAgD,YAC1D,IAAI,CAAC,MAAM,GACV,IACA,KAzBC,CAAC,CA0BL,CACN,CAAC,GACC,IACD,CACP,EAEA,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,eAAK,SAAS,EAAC,0CAA0C,aACvD,eAAM,SAAS,EAAC,yBAAyB,4BAAmB,EAC3D,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAC/B,KAAC,IAAI,IAAS,IAAI,EAAC,aAAa,YAC7B,CAAC,IADO,CAAC,CAEL,CACR,CAAC,IACE,CACP,EAED,eAAK,SAAS,EAAC,gCAAgC,aAC7C,iBACE,IAAI,EAAC,QAAQ,oBACE,mBAAmB,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EACxB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAC,mJAAmJ,YAE5J,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,GAChC,EACT,gBAAM,SAAS,EAAC,yBAAyB,aACtC,UAAU,CAAC,KAAK,cAAK,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,IAChD,IACH,IACL,CACJ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CACf,8BACE,YAAG,SAAS,EAAC,8CAA8C,mLAGvD,EACJ,kBACE,IAAI,EAAC,QAAQ,oBACE,mBAAmB,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EACzB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAC,kLAAkL,aAE3L,OAAO,IAAI,KAAC,WAAW,KAAG,EAC1B,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,IAC3C,IACR,CACJ,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,yCAAyC,8HAGlD,CACL,EAEA,KAAK,IAAI,YAAG,SAAS,EAAC,iDAAiD,YAAE,KAAK,GAAK,IAChF,CACP,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF,SAAS,QAAQ,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAoD;IACnG,OAAO,CACL,eAAK,SAAS,EAAE,aAAa,MAAM,WAAW,aAC5C,cAAK,SAAS,EAAC,qDAAqD,YAAE,SAAS,GAAO,EACtF,cAAK,SAAS,EAAE,2CAA2C,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,EAAE,YAC7F,KAAK,GACF,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,KAAK,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,OAAO,EACP,WAAW,GAQZ;IACC,kEAAkE;IAClE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YACjC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC;IAC5B,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC;IAErC,OAAO,CACL,eAAK,SAAS,EAAE,sBAAsB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,EAAE,iBAAe,CAAC,IAAI,aAE3F,cACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,gEACT,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WACzB,EAAE,GACF,EAEF,gBACE,IAAI,EAAC,QAAQ,gBACF,MAAM,gBACN,oBAAoB,EAC/B,SAAS,EAAE,wEAAwE,MAAM,mFACvF,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,kBAC3B,EAAE,YAED,KAAK,IAAI,CACR,8BAEE,eAAK,SAAS,EAAE,oCAAoC,MAAM,oBAAoB,aAC5E,gBAAM,SAAS,EAAC,gDAAgD,kBAC5D,KAAK,CAAC,MAAM,IACT,EACP,KAAC,SAAS,IAAC,MAAM,EAAE,MAAM,GAAI,EAC7B,YACE,IAAI,EAAE,KAAK,CAAC,GAAG,EACf,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,SAAS,EAAC,sFAAsF,8BAG9F,EACJ,iBACE,IAAI,EAAC,QAAQ,oBACE,aAAa,EAC5B,OAAO,EAAE,OAAO,gBACL,OAAO,EAClB,SAAS,EAAC,4IAA4I,uBAG/I,IACL,EAGN,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,mBAAmB,aAChC,aAAI,SAAS,EAAC,mDAAmD,YAC9D,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,UAAU,KAAK,CAAC,MAAM,EAAE,GACtD,EACJ,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAChE,aAAG,SAAS,EAAC,8CAA8C,aACzD,eAAM,SAAS,EAAE,KAAK,4BAAoB,EAAC,GAAG,EAC9C,eAAM,SAAS,EAAC,aAAa,YAAE,KAAK,CAAC,KAAK,GAAQ,IAChD,CACL,EACA,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CACnC,cAAK,SAAS,EAAC,oCAAoC,YAChD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAC,IAAI,cAAU,CAAC,IAAL,CAAC,CAAY,CAAC,GAChD,CACP,EACD,cAAK,SAAS,EAAC,MAAM,GAAG,IACpB,EAGN,eAAK,SAAS,EAAC,kBAAkB,aAC/B,KAAC,QAAQ,IACP,KAAK,EAAC,QAAQ,EACd,KAAK,EACH,MAAM,EAAE,SAAS;gDACf,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC;gDAC7B,CAAC,CAAC,KAAK,CAAC,OAAO;oDACb,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;oDAC1B,CAAC,CAAC,GAAG,GAEX,EACF,KAAC,QAAQ,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,GAAI,EACzD,KAAC,QAAQ,IAAC,KAAK,EAAC,UAAU,EAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,SAAG,EACzD,KAAC,QAAQ,IACP,KAAK,EAAC,cAAc,EACpB,KAAK,EACH,KAAK,CAAC,OAAO,KAAK,WAAW;gDAC3B,CAAC,CAAC,yBAAyB;gDAC3B,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,cAAc;oDAChC,CAAC,CAAC,kBAAkB;oDACpB,CAAC,CAAC,GAAG,GAEX,IACE,EAGN,eAAK,SAAS,EAAE,YAAY,MAAM,oBAAoB,aACpD,cAAK,SAAS,EAAC,0DAA0D,2BAEnE,EACL,MAAM,CAAC,CAAC,CAAC,CACR,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC9B,KAAC,QAAQ,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAI,CAChC,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAC,gCAAgC,wCAA4B,CAC1E,CACF,CAAC,CAAC,CAAC,CACF,aAAG,SAAS,EAAC,yCAAyC,mIAGnD,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,SACpC,CACL,IACG,EAEN,KAAC,QAAQ,IACP,WAAW,EAAE,KAAK,CAAC,MAAM,EACzB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,GACxB,IACE,IACL,CACJ,GACK,IACJ,CACP,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,MAAM,EACN,IAAI,EACJ,WAAW,EAAE,kBAAkB,EAC/B,UAAU,GASX;IACC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAEnE,OAAO,CACL,8BACG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACrB,KAAC,QAAQ,IAEP,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAH3B,KAAK,CAAC,QAAQ,CAInB,CACH,CAAC,EACF,KAAC,WAAW,IACV,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAC/D,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAChC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CACjB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAE7D,IACD,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Polishd — a small GitHub-flavored-markdown parser (pure, no dependencies).
|
|
3
|
-
*
|
|
4
|
-
* The Issues tab shows issue bodies that are real markdown: polishd writes
|
|
5
|
-
* them (`issueBody` in `src/ai/issues.ts` emits headings, bold, code, link
|
|
6
|
-
* lists, blockquotes) and humans edit them on GitHub afterwards. Rendering
|
|
7
|
-
* that as a raw `<pre>` wastes the structure — but the package's rule is zero
|
|
8
|
-
* runtime dependencies, so `react-markdown` and friends are off the table.
|
|
9
|
-
*
|
|
10
|
-
* This module is the answer: a bounded, hand-written parser for the subset of
|
|
11
|
-
* GFM that actually appears in issues — headings, paragraphs, fenced code,
|
|
12
|
-
* blockquotes, ordered/unordered/task lists (nested), tables, rules, and the
|
|
13
|
-
* inline set (bold, italic, strikethrough, code, links, images, autolinks).
|
|
14
|
-
* One GitHub-ism matters: inside a paragraph a single newline is a hard
|
|
15
|
-
* break, the way issue comments render. Anything the parser doesn't
|
|
16
|
-
* recognize degrades to plain paragraph text — never a crash, never dropped
|
|
17
|
-
* content.
|
|
18
|
-
*
|
|
19
|
-
* Parsing is kept apart from rendering (`markdown.tsx`) so the grammar can be
|
|
20
|
-
* pinned down by plain node:test files with no React in sight.
|
|
21
|
-
*/
|
|
22
|
-
export type MdInline = {
|
|
23
|
-
kind: "text";
|
|
24
|
-
text: string;
|
|
25
|
-
} | {
|
|
26
|
-
kind: "break";
|
|
27
|
-
} | {
|
|
28
|
-
kind: "code";
|
|
29
|
-
text: string;
|
|
30
|
-
} | {
|
|
31
|
-
kind: "strong";
|
|
32
|
-
children: MdInline[];
|
|
33
|
-
} | {
|
|
34
|
-
kind: "em";
|
|
35
|
-
children: MdInline[];
|
|
36
|
-
} | {
|
|
37
|
-
kind: "del";
|
|
38
|
-
children: MdInline[];
|
|
39
|
-
} | {
|
|
40
|
-
kind: "link";
|
|
41
|
-
href: string;
|
|
42
|
-
children: MdInline[];
|
|
43
|
-
} | {
|
|
44
|
-
kind: "image";
|
|
45
|
-
alt: string;
|
|
46
|
-
src: string;
|
|
47
|
-
};
|
|
48
|
-
export interface MdListItem {
|
|
49
|
-
/** Set only on task-list items: `- [x]` / `- [ ]`. */
|
|
50
|
-
checked?: boolean;
|
|
51
|
-
children: MdInline[];
|
|
52
|
-
/** A nested list, when the item has deeper-indented list lines under it. */
|
|
53
|
-
sub?: MdList;
|
|
54
|
-
}
|
|
55
|
-
export interface MdList {
|
|
56
|
-
ordered: boolean;
|
|
57
|
-
items: MdListItem[];
|
|
58
|
-
}
|
|
59
|
-
export type MdBlock = {
|
|
60
|
-
kind: "heading";
|
|
61
|
-
level: number;
|
|
62
|
-
children: MdInline[];
|
|
63
|
-
} | {
|
|
64
|
-
kind: "paragraph";
|
|
65
|
-
children: MdInline[];
|
|
66
|
-
} | {
|
|
67
|
-
kind: "codeBlock";
|
|
68
|
-
lang: string;
|
|
69
|
-
text: string;
|
|
70
|
-
} | {
|
|
71
|
-
kind: "quote";
|
|
72
|
-
children: MdBlock[];
|
|
73
|
-
} | {
|
|
74
|
-
kind: "list";
|
|
75
|
-
list: MdList;
|
|
76
|
-
} | {
|
|
77
|
-
kind: "rule";
|
|
78
|
-
} | {
|
|
79
|
-
kind: "table";
|
|
80
|
-
header: MdInline[][];
|
|
81
|
-
rows: MdInline[][][];
|
|
82
|
-
};
|
|
83
|
-
/** Parse one run of inline markdown into a token list. */
|
|
84
|
-
export declare function parseInline(text: string): MdInline[];
|
|
85
|
-
/** Parse a whole markdown document into blocks. */
|
|
86
|
-
export declare function parseMarkdown(md: string): MdBlock[];
|
|
87
|
-
//# sourceMappingURL=markdown-parse.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-parse.d.ts","sourceRoot":"","sources":["../../src/dashboard/markdown-parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;CAAE,CAAC;AAmDlE,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAoBpD;AAgED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAyGnD"}
|