mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
64062af9a1
A Guided Review can now leave Plannotator: as a single self-contained HTML file that renders exactly like the in-app guide, as an encrypted-by-default share link on guides.show, or authored by any agent through the new guide CLI. Highlights: packages/guide-viewer extracted from review-editor at the injection seam (read-only host, no third renderer); guides.show Worker with R2-backed share storage, per-IP rate limiting on creation, delete tokens hashed at rest, and 128-bit ids; portable exports pin the viewer by SRI hash with budget and manifest gates in PR CI and at deploy; two-runtime parity across Bun and Pi verified; v0.27.x saved guides load unchanged. Retention is indefinite by explicit decision, to revisit with the lean sharing refactor. Decision record: adr/decisions/007-portable-guided-reviews-20260815.md
74 lines
3.3 KiB
TypeScript
74 lines
3.3 KiB
TypeScript
/** Hard cap on reviewer-supplied extra guide instructions (#1265): the
|
|
* freeform text appended to the organizer methodology at launch. A hygiene
|
|
* bound on prompt size, not a security boundary (the instructions run on the
|
|
* user's own machine against their own agent). Enforced server-side in
|
|
* composeGuideMethodology and mirrored by the launch textarea's maxLength. */
|
|
export const GUIDE_EXTRA_INSTRUCTIONS_MAX_CHARS = 2000;
|
|
|
|
/** Human labels for the engines that can generate a guide, keyed by the id
|
|
* stored in a snapshot's `generator.engine`. The one source of truth for the
|
|
* in-app engine pickers and the portable viewer's "generated by" line. */
|
|
export const GUIDE_ENGINE_LABEL = {
|
|
claude: 'Claude',
|
|
codex: 'Codex',
|
|
cursor: 'Cursor',
|
|
opencode: 'OpenCode',
|
|
pi: 'Pi',
|
|
copilot: 'Copilot',
|
|
} as const;
|
|
|
|
export interface GuideDiffRef {
|
|
/** Repo-relative path; must match a DiffFile.path in the current review patch. */
|
|
file: string;
|
|
/** 1-2 sentence semantic description of what changed in THIS file, written
|
|
* from the diff hunks alone (no investigation). Required by the JSON schema
|
|
* for schema-enforced engines; optional here so a marker engine that omits
|
|
* it still yields a valid guide — the UI simply renders nothing. */
|
|
summary?: string;
|
|
}
|
|
|
|
export interface GuideSection {
|
|
/** Concept-level title, e.g. "Payment localization module" — never a filename paraphrase. */
|
|
title: string;
|
|
/** Markdown prose: what changed, why it exists, and its key implications.
|
|
* Semantic order (core first, consequences next, glue grouped last) is
|
|
* carried by the array position, not by any label field. */
|
|
overview: string;
|
|
/** File references into the provided changeset. Usually 1..n, but a
|
|
* deliberate prose-only context section (no diffs, real overview text) is
|
|
* a valid model output and is preserved as-is rather than dropped. */
|
|
diffs: GuideDiffRef[];
|
|
}
|
|
|
|
export interface CodeGuideOutput {
|
|
/** From the PR title when a PR is given, otherwise derived from the changes. */
|
|
title: string;
|
|
/** 1-2 sentence framing shown under the title: why this changeset exists. */
|
|
intent: string;
|
|
/** Ordered sections: core first, consequence next, support last. */
|
|
sections: GuideSection[];
|
|
/** Changed files the model didn't place — rendered in a trailing "Everything else" section. */
|
|
unplacedFiles?: string[];
|
|
}
|
|
|
|
/** One row of GET /api/guides — a persisted guide for the current repo
|
|
* (#1112). Loaded through the guide endpoints as the `saved:{id}` pseudo
|
|
* job id. Browser-safe (types only); the store lives in guide-store.ts. */
|
|
export interface SavedGuideListEntry {
|
|
id: string;
|
|
/** Review-target label — "PR #1082" or the branch name. */
|
|
label: string;
|
|
title: string;
|
|
/** Epoch ms when the guide was first persisted. */
|
|
savedAt: number;
|
|
progress: { reviewed: number; total: number };
|
|
/** True when the stored head sha differs from the current head. */
|
|
moved: boolean;
|
|
}
|
|
|
|
/** UI-side guide shape: server output extended with persisted per-section reviewed state.
|
|
* `saved` is set when the guide is persisted on disk (autosaved live job, or a
|
|
* `saved:{id}` load); `moved` is set only on `saved:` loads whose stored head
|
|
* sha differs from the head currently under review. */
|
|
export type CodeGuideData = CodeGuideOutput & { reviewed: boolean[]; saved?: boolean; moved?: boolean };
|