From 5221f2ebd2959542e0cc2159e79fddbd5aec3e17 Mon Sep 17 00:00:00 2001 From: Jacob Mathison Date: Sat, 18 Jul 2026 10:07:26 -0500 Subject: [PATCH] Add agents and screenshot crop workflow --- AGENTS.md | 6 +- README.md | 2 +- docs/extension-management.md | 5 +- index.html | 4 + llm.txt | 2 +- manifest.llm.json | 7 +- src/main.ts | 205 ++++++++++++++++++++++++++++--- src/store.ts | 225 ++++++++++++++++++++++++++++++++++- src/styles.css | 133 ++++++++++++++++++++- 9 files changed, 559 insertions(+), 30 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 92fb813..5ae7c7f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -44,10 +44,12 @@ Use `.env.local` for local secrets. Keep `.env.local` and any real token-bearing - Runtime API calls are centralized in `src/api.ts`. - Side panel state is centralized in the vanilla Zustand store at `src/store.ts`. - The extension opens as a Chrome side panel. It is not a draggable in-page window. -- The side panel has icon menu sections for Add URL, URLs, Gitea repos, Workspaces, and Add Issue. +- The side panel has icon menu sections for Add URL, URLs, Gitea repos, Workspaces, Agents, and Add Issue. - Add URL is enabled only when the active tab's base URL is not already in the URLs list. The user must pick either a workspace or a Gitea repo; the app infers the linked counterpart from local context. - URLs can be deleted from the URLs list. User-added URLs are removed from storage; generated known URLs are hidden through the stored deleted-base list. -- Add Issue is enabled only when the active tab's base URL is already in the URLs list and has a linked Gitea repo. The issue form must show the target repo, capture visible-tab screenshots, accept Gitea-friendly file attachments, and include `Chrome profile: Silma` in created issue bodies. +- The Agents view lists available agent files. It currently contains one entry: `GLOBAL AGENT` backed by `AGENTS.md`. +- Add Issue is enabled only when the active tab's base URL is already in the URLs list and has a linked Gitea repo. The issue form must show the target repo, let the user select an agent file, capture visible-tab screenshots, accept multiple accumulated Gitea-friendly file attachments, and include `Chrome profile: Silma` plus the selected agent in created issue bodies. +- Clicking a captured screenshot must open an expanded preview with Close, Remove, and Crop controls. - Newly created issues must be created with the `Change Request` label. - If the Ready checkbox is checked, create the issue first, upload screenshots/files as issue assets second, and apply the `ready` label last. - The Add Issue view also lists existing issues for the linked Gitea repo. Selecting an issue must show the original description, issue attachments, and comment chain, followed by a comment form that can add text, take additional screenshots, attach files, upload those files as issue assets, and submit a Gitea comment with attachment links. diff --git a/README.md b/README.md index 95edeab..4792788 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The deployable extension output is `dist/`. Load `dist/` in Chrome as an unpacke Static assets, including the extension icon assets, live in `public/` and are copied into `dist/` during the build. -The app opens in the Chrome side panel. The top icon menu includes Add URL, URLs, Gitea repos, Workspaces, and Add Issue. Add URL is enabled only for an active tab base URL that is not already in the URLs list. URLs can be deleted from the list. Add Issue is enabled when the active tab base URL is already linked to a Gitea repo; it creates an issue with the `Change Request` label, uploads screenshots and files as issue assets, and can apply the `ready` label after uploads. The same view lists existing repo issues; selecting one shows the original description, attachments, comment chain, and a comment form with screenshots and file attachments. Rows can be marked Ready or deleted. +The app opens in the Chrome side panel. The top icon menu includes Add URL, URLs, Gitea repos, Workspaces, Agents, and Add Issue. Add URL is enabled only for an active tab base URL that is not already in the URLs list. URLs can be deleted from the list. The Agents view currently lists `GLOBAL AGENT` from `AGENTS.md`. Add Issue is enabled when the active tab base URL is already linked to a Gitea repo; it creates an issue with the selected agent file and `Change Request` label, uploads accumulated screenshots and files as issue assets, and can apply the `ready` label after uploads. Captured screenshots can be expanded, removed, or cropped. The same view lists existing repo issues; selecting one shows the original description, attachments, comment chain, and a comment form with screenshots and file attachments. Rows can be marked Ready or deleted. Builds generate `public/local-context.json` from `/Users/Tabitha/.openclaw/workspace_Father`. That snapshot links known workspaces to local Gitea repos and is copied into `dist/` so the built extension is self-contained. diff --git a/docs/extension-management.md b/docs/extension-management.md index 2b3ddfa..73edd82 100644 --- a/docs/extension-management.md +++ b/docs/extension-management.md @@ -39,10 +39,13 @@ Required variables: - Add Issue is enabled only when the active tab's base URL is already in the URLs list and that URL is linked to a Gitea repo. - The Add Issue view must show the Gitea repo that will receive the issue. +- The Add Issue form must let the user select the agent file for handoff. The initial agent is `GLOBAL AGENT` backed by `AGENTS.md`. - The Add Issue view intentionally omits the redundant view header title/description and keeps the Ready checkbox label short. - Screenshot capture uses Chrome's visible-tab capture API and requires the extension's `activeTab` permission plus `` host permission so capture still works after the side panel remains open across tab changes. - Captured screenshots should appear immediately in Add Issue as thumbnail rows. -- Created issue bodies must include `Chrome profile: Silma`. +- Captured screenshots can be expanded, closed, removed, or cropped before upload. +- File attachments are accumulated across picker selections and all selected files must be uploaded to Gitea. +- Created issue bodies must include `Chrome profile: Silma` and the selected agent. - Newly created issues must include the `Change Request` label. - When Ready is checked, create the issue, upload screenshots/files as Gitea issue assets, then apply the `ready` label last. - The Add Issue view lists existing issues for the linked Gitea repo. Selecting an issue shows the original description, issue attachments, comment chain, and a comment form for text, additional screenshots, and file attachments. diff --git a/index.html b/index.html index e1a73b7..d7e1a42 100644 --- a/index.html +++ b/index.html @@ -26,6 +26,10 @@ Workspaces + + + ` + ) + .join("")} + `; } +function renderAgentOptions(agents: AgentProfile[], selectedAgentId: string): string { + return agents + .map( + (agent) => + `` + ) + .join(""); +} + function renderBodyText(body: string, emptyText: string): string { const trimmed = body.trim(); if (!trimmed) { @@ -370,6 +413,7 @@ function renderScreenshotList(screenshots: ScreenshotAttachment[], deleteAction: } const attribute = deleteAction === "issue" ? "data-delete-screenshot" : "data-delete-comment-screenshot"; + const previewTarget = deleteAction === "issue" ? "issue" : "comment"; return `
@@ -377,7 +421,9 @@ function renderScreenshotList(screenshots: ScreenshotAttachment[], deleteAction: .map( (screenshot) => `
- ${escapeHtml(screenshot.name)} +
${escapeHtml(screenshot.name)}
@@ -388,6 +434,62 @@ function renderScreenshotList(screenshots: ScreenshotAttachment[], deleteAction: `; } +function getPreviewScreenshot(): ScreenshotAttachment | null { + const state = appStore.getState(); + const preview = state.screenshotPreview; + + if (!preview) { + return null; + } + + const screenshots = preview.target === "issue" ? state.issueDraft.screenshots : state.issueCommentDraft.screenshots; + return screenshots.find((screenshot) => screenshot.id === preview.id) ?? null; +} + +function renderScreenshotPreview(): string { + const state = appStore.getState(); + const preview = state.screenshotPreview; + const screenshot = getPreviewScreenshot(); + + if (!preview || !screenshot) { + return ""; + } + + const crop = preview.crop; + + return ` + + `; +} + function renderIssueRows(issues: GiteaIssueSummary[], selectedIssueNumber: number | null): string { const state = appStore.getState(); @@ -450,10 +552,7 @@ function renderIssueCommentForm(issue: GiteaIssueSummary): string { File attachments - ${renderAttachmentList( - draft.files.map((file) => file.name), - "No files selected." - )} + ${renderFileList(draft.files, "comment")}