mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
aa46dbb29a
* feat(guide): per-file summary on guide diff refs Each diffs[] entry now carries a required (schema-enforced) 1-2 sentence summary of the semantic change in that file, written from the diff hunks alone. Sanitizer passes it through when it's a non-blank string and omits it otherwise -- a missing summary never drops the ref or fails the guide. Rendered as a muted inline-markdown line above each diff in the guide; marker-engine contract and demo data updated to match. * fix(guide): repair prompt must not invent missing summaries The guide schema now requires summary, so a schema-enforced repair of a payload that lacks them (marker-engine output) would force the model to fabricate captions with no diff in sight. Instruct it to fill missing required fields with an empty string instead; the sanitizer already renders nothing for blanks. * feat(agents): GitHub Copilot CLI as a marker engine for review + guide jobs Adds copilot as the fourth marker engine (no schema flag, so it uses the nonce-tagged marker-block contract like Cursor/OpenCode/Pi): - marker-review.ts: COPILOT_ENGINE — 'copilot --output-format json' JSONL stream (assistant.message carries the assembled text; deltas skipped), models discovered from 'copilot help config', live-log formatting for tool.execution_start/complete. Non-interactive posture: --no-ask-user auto-denies unallowed tools, --deny-tool=write, read-only-oriented shell allowlist (git/gh/glab/jj/wc), builtin MCPs and auto-update disabled. - Exported MarkerEngineId and replaced every 'cursor'|'opencode'|'pi' cast with it (Bun server, Pi server mirror, guide-review) so the next engine is a two-edit change. - agent-jobs (both runtimes): copilot in SERVER_BUILT_PROVIDERS; capability entry + model discovery come free from the MARKER_ENGINES loop. - UI: copilot review/guide engine with per-surface model settings (useAgentSettings), AgentsTab launch + config rows, GuideEmptyState launcher, job-detail labels, CopilotIcon (currentColor, official mark). - Tests: argv/read-only flags, help-config model parsing, stream reduction, full marker pipeline; profile-map expectations widened. Verified live: composed review prompt through the real copilot binary, marker block parsed, seeded bug found. * fix(agents): structurally deny high-consequence verbs for Copilot jobs git:*/gh:*/glab:* stay allowed for inspection ergonomics, but Copilot's deny-precedence rules now block the verbs a prompt-injected background job could abuse: git push/reset/clean/checkout/restore (local reviews run in the user's real working tree), and PR/MR/issue comment/create/merge/ close/edit/review on gh and glab. Probe-verified: git log runs, git push --dry-run is denied by the shell(git push) rule. Addresses the one confirmed finding from the PR #997 review round; the other two (untracked-file reads, git -C) were refuted by live probes.
65 lines
3.4 KiB
TypeScript
65 lines
3.4 KiB
TypeScript
/**
|
|
* Demo guide data for development mode.
|
|
*
|
|
* Loaded by useGuideData when jobId === DEMO_GUIDE_ID, so the Guided Review
|
|
* screen renders with realistic content without needing an agent run. Section
|
|
* diffs reference the real file paths from demoData.ts's DEMO_DIFF so the
|
|
* per-section DiffViewers resolve against the actual demo files array instead
|
|
* of hitting the "outdated" chip.
|
|
*/
|
|
|
|
import type { CodeGuideData } from '@plannotator/shared/guide';
|
|
|
|
export const DEMO_GUIDE_ID = 'demo-guide';
|
|
|
|
export const DEMO_GUIDE: CodeGuideData = {
|
|
title: 'Typed API client, resilient auth, and a safer Button',
|
|
intent:
|
|
'Rewrites the auth hook against a typed request layer so login/refresh failures surface as real errors instead of silent nulls, and closes a long-standing bug where Button fired onClick while disabled.',
|
|
sections: [
|
|
{
|
|
title: 'Button respects disabled at both the prop and DOM level',
|
|
overview:
|
|
'The click handler now checks `disabled` before calling `onClick`, and the underlying `<button>` also gets the native `disabled` attribute via a new `variant` prop. Previously only the visual style hinted at disabled state; the handler still fired. This closes the gap that let a slow double-click submit a form twice. The handler is wrapped in `useCallback` so existing callsites that pass inline arrow functions don\'t cause extra re-renders.',
|
|
diffs: [
|
|
{
|
|
file: 'src/components/Button.tsx',
|
|
summary: 'Guards `onClick` behind the `disabled` prop and forwards native `disabled` to the DOM element.',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'Auth hook rewritten against a typed request client',
|
|
overview:
|
|
'useAuth used to fake success/failure with untyped fetch calls; it now delegates to `api.auth.*`, a typed client with a proper `ApiError` class carrying status and code. `login`/`logout`/`refresh` are all `useCallback`-wrapped and the hook now tracks `error` in state so the UI can show why a login failed rather than just spinning. This is the change that made the Button fix visible in the first place: a disabled login button that silently still fired was masking failed-login retries.',
|
|
diffs: [
|
|
{
|
|
file: 'src/hooks/useAuth.ts',
|
|
summary: 'Replaces the untyped fetch calls with `api.auth.*` and adds `error` state so failed logins surface in the UI.',
|
|
},
|
|
{
|
|
file: 'src/services/api.ts',
|
|
summary: 'New typed request client with an `ApiError` class carrying HTTP status and error code.',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: 'Formatting-only cleanup, no behavior change',
|
|
overview:
|
|
'settings.ts picked up a repo-wide indentation pass (2-space to 4-space in the config getters) with no logic changes beyond bumping the production pool max from 20 to a still-20 (no-op) — worth a glance only to confirm the diff really is whitespace. Modal.tsx is a new, self-contained portal-based dialog component added opportunistically; nothing in this changeset wires it up yet.',
|
|
diffs: [
|
|
{
|
|
file: 'src/config/settings.ts',
|
|
summary: 'Indentation-only reformat of the config getters; no behavior change.',
|
|
},
|
|
{
|
|
file: 'src/components/Modal.tsx',
|
|
summary: 'New portal-based dialog component; added but not yet wired up anywhere.',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
unplacedFiles: ['src/utils/helpers.ts'],
|
|
reviewed: [],
|
|
};
|