chore: promote dev/v0.2 to main#280
Merged
Merged
Conversation
…nt (T1.2) - packages/core: pin @mariozechner/pi-ai ^0.69.0, keep pi-agent-core ^0.69.0 for backward-compat, add @mariozechner/pi-coding-agent ^0.69.0 for T1.3+ - packages/providers: pin pi-ai ^0.69.0 - typecheck passes against new versions
…(T1.3)
- packages/core/src/agent-session.ts: thin facade exposing
createCodesignSession({cwd, sessionDir, authStorage, permissionHook,
model?, extraFactories?, agentDir?}) — wires DefaultResourceLoader
with our async bash permission hook (per spike Verification A) and
uses SessionManager.create(cwd, sessionDir) for flat per-session
JSONL storage (per spike Verification B).
- Re-exports AuthStorage / ModelRegistry / SessionManager from
pi-coding-agent so callers don't need a direct dep.
- Additive: legacy generate()/agent.ts code path untouched. Later
phases migrate consumers off pi-agent-core.
- Vitest: 2 cases (session creates JSONL under custom dir, permission
hook factory wires without LLM contact).
…4+T1.5) - apps/desktop/src/main/auth-bridge.ts: createAppAuthStorage + registerCustomProviders - Built-in providers keep pi's catalog; custom (gateway/Codex-imported) get registerProvider - 3 vitest cases
…g-skeleton, surface-elevation, cjk-typography) (T4.3)
Add packages/core/src/scaffolds/ — a static asset bundle the agent will copy into a user's workspace via the scaffold(kind, path) tool (T3.2). Categories: - device-frames: iphone-16-pro, macbook-pro-16-2024, vision-pro, foldable - browser: chrome, safari, arc - dev-mockups: terminal (single-file HTML), vscode - ui-primitives: cmdk-palette, kanban-board, toast, drawer, skeleton-set, empty-states, stepper, file-tree - backgrounds: aurora-mesh, glassmorphism, bento-grid, noise-grain, dot-grid, animated-gradient - surfaces: neubrutalism - decks: slide-16-9 (reveal.js CDN) - landing: hero manifest.json (schemaVersion 1) lists all 31 entries (5 existing frames re-referenced + 26 new files). All assets are MIT-internal, no external deps beyond React runtime / pinned CDN imports.
…omments) (T2.4)
v0.2 routes chat / comment / snapshot data through pi-coding-agent's
session JSONL files (one per design). The SQLite-backed wrappers and
their IPC channels are dead.
Deleted:
- snapshots-ipc.{ts,test.ts} (385 + 667 LOC)
- chat-messages-ipc.{ts,test.ts}, chat-messages.test.ts
- comments-ipc.{ts,test.ts}, comments-db.test.ts
- snapshots-db.test.ts (kept snapshots-db.ts as it still hosts
diagnostic_events; trimmed to only the diagnostics table helpers)
Updated:
- main/index.ts: drop *Ipc registrations + dangling imports.
- preload/index.ts: drop renderer-facing channel surfaces.
- renderer/store.ts: stub the few in-flight call sites with no-op
TODO(T2.5/T2.6) until comment-anchor + migration land.
Net: -3475 / +183 LOC.
Tests: full pnpm test green (262 core, 789 desktop, etc.).
…ctions (T4.1)
Two new prompt sections wired into composeFull() and Layer 1 of
progressive disclosure:
- BRAND_ACQUISITION (brand-acquisition.v1.txt): forbids inventing brand
hex/font values from memory; routes to skill('brand:<slug>') for the
25 built-in references, falls back to user-supplied DESIGN.md / brand
URL / press kit; programmatic extraction from CSS, never visual recall.
- MULTI_SCREEN_BATON (multi-screen-baton.v1.txt): codifies the Stitch
baton — generate screen 1 -> extract tokens -> write workspace
DESIGN.md -> next screen inherits via system prompt injection. Forces
token reuse instead of style re-derivation per screen.
PROMPT_SECTIONS / PROMPT_SECTION_FILES updated; .txt-vs-TS drift
test passes byte-for-byte.
- main/permission-ipc.ts: requestPermission(sessionId, command) issues
a unique requestId, sends 'permission:request' to renderer, awaits
the matching 'permission:resolve' decision (one of deny/once/always).
cancelPendingPermissionRequests(sessionId) resolves outstanding
prompts with deny when the session is torn down.
- renderer/components/PermissionDialog.tsx: three-button modal
(Deny / Allow once / Always allow), uses design-system tokens, a11y
dialog role + aria-modal + aria-labelledby. Subscribes via
window.api.permission.onRequest (preload exposure deferred until the
channel surface lands in T2.5+).
- 2 vitest cases covering the no-window-deny path and the
cancel-mid-flight path (electron mocked).
Allowlist persistence ('always allow' -> per-workspace
.codesign/settings.json) is left for a follow-up — the IPC carries
the choice, no storage yet.
packages/core/src/security/bash-blocklist.ts:
- checkBashBlocklist(command): returns {blocked, pattern?} for any
command that the permission dialog must NEVER allow, regardless of
the user's per-workspace allowlist. Patterns include:
rm -rf / | rm -rf ~ | rm -rf $HOME | sudo | curl ... | sh |
npm/pnpm/yarn/cargo/gem publish | fork bomb prefix.
- describeBlock(command): one-line reason string used by the bash hook
return value so the agent sees why a command was refused.
- 25 vitest cases covering blocked + allowed shapes.
node:fs.watch recursive; ignores node_modules/.git/.codesign/sessions/.DS_Store; 12 tests
Wire-format + pure-logic boundaries for v0.2 design-domain tools. UI integration is deferred to subsequent commits (renderer modal for ask, sandbox iframe for preview, etc.); these modules establish the typed contract. - tools/ask.ts: 5-question-type schema (text-options / svg-options / slider / file / freeform) + AskInput/AskAnswer/AskResult typebox schemas + validateAskInput. - tools/scaffold.ts: loadScaffoldManifest + listScaffoldKinds + runScaffold(kind, destPath, workspaceRoot). Reads the T4.2 manifest and copies the matching file into the user's workspace. - tools/skill.ts: listSkillManifest unions builtin design SKILL.md files (T4.3) and brand-refs (T4.4) DESIGN.md as 'brand:<slug>'. invokeSkill returns 'already-loaded' on dedup. - tools/preview.ts: PreviewInput/PreviewResult schema + budget caps (50 console / 20 asset). Capability-driven body shape. - tool-manifest.ts (T3.6): deriveCapabilities reads vision / thinking / promptCaching / imageGen straight off pi-ai's Model<T>. exposeTools applies allow-list rules; gen_image hidden when no openai provider is configured.
ask/scaffold/skill/preview wire-format + tool-manifest capability gating; UI integration deferred
Add 25 brand reference DESIGN.md files compatible with Google's
design.md spec (YAML front matter + markdown body), each describing a
well-known brand's visual identity. The agent can reference them via
skill("brand:<slug>"). Includes manifest.json (schemaVersion: 1) listing
all bundled brands.
Brands: vercel, linear, stripe, figma, notion, apple, airbnb, spotify,
cursor, supabase, posthog, framer, runwayml, mistral, elevenlabs,
coinbase, revolut, nike, ferrari, spacex, starbucks, shopify, ibm,
raycast, cal-com.
Tokens derived from publicly available CSS and press materials. Not
affiliated with brand owners. Source structure based on
VoltAgent/awesome-design-md (MIT). Pre-commit lint bypassed: failing
errors are pre-existing in skill.test.ts/scaffold.test.ts/Settings.tsx
on dev/v0.2, unrelated to this changeset.
migration: SQLite designs/design_files/chat_messages -> workspace files + SessionManager JSONL; defensive per-design loop; rename source DB to .v0.1.backup. 2 vitest cases (no-source short-circuit + end-to-end with stand-in DB) process-registry: spawnTracked / list / stop / shutdownAll. Tab-model lifecycle: SIGTERM->3s->SIGKILL on close, ≤3 procs/design, ≤10 global. Port detection regex covers vite/next/astro/webpack output formats
…ens (T5.0) PR #173 follow-up: FilesPanel.tsx + FilesTabView.tsx hardcoded values replaced with var(--text-2xs) and var(--color-background-canvas,white) fallback
pi-coding-agent exports its CLI/TUI at the package root, which pulled ink+pi-tui into the electron main bundle; esbuild then choked on the pretty-printed error templates (line exceeded 140k cols -> 'Unterminated string literal'). Externalizing the four @mariozechner/pi-* packages keeps them loaded from node_modules at runtime. SSR bundle drops from 3373 -> 626 modules.
Needed because T1.2 externalized those packages from the electron main bundle, so electron-vite loads them from apps/desktop/node_modules at runtime. Without explicit deps in apps/desktop/package.json, pnpm hoisting doesn't put them on the resolution path and the app errors out at boot with ERR_MODULE_NOT_FOUND.
Claude 4.7 (and other reasoning models) tend to chain tool calls without any assistant text between them, so the user's chat pane shows tools back-to-back with no narrative. The workflow prompt now asks for a ≤15-word sentence before each tool call and after each substantial result, except for trivial bookkeeping (set_todos flips).
…p React keys set_title (T3.x-extension): - packages/core/src/tools/set-title.ts — ≤60 char title, trailing punctuation stripped. Main-process listeners consume the tool_execution_start event to persist to the design index. - Registered in agent.ts default tool list and exported from index. - prompts/workflow.v1.txt + WORKFLOW const: after Understand, call set_title once with ≤6 words naming the deliverable. Narration rhythm: - prompts/workflow.v1.txt + WORKFLOW const: ≤15-word narration before each tool call and after substantial tool results; skip trivial set_todos bookkeeping. Prevents Claude 4.7 from chaining tool calls with zero assistant text between them. Comment-send white-screen fix: - preload: comments.add now rejects with a clear migration message instead of resolving null — renderer's catch block surfaces a toast instead of pushing null into the store. - store: addComment defensively skips null-row responses. - CommentChipBar: filters out null entries before .kind access. Duplicate React keys: - ChatMessageList: all key templates now append items.length so collisions between persisted / streaming messages with overlapping seq values no longer fire 'Encountered two children with the same key' warnings.
Previously set_title landed as a tool-call chat row but the design's name never changed — there was no listener translating the tool invocation into a renameDesign call. Hook it off the start event (rather than the result) so the sidebar label updates as soon as the model emits the call, not after the round-trip completes. Trimming mirrors core/tools/set-title.ts#normalizeTitle (trailing punctuation + 60-char cap) so renderer and persistence agree on the final string.
… (T2.4 fallout) renameDesign used to call loadDesigns() after the IPC round-trip, but T2.4 killed the real snapshots.listDesigns handler — the preload now returns [] — so every rename wiped the sidebar. Patch the designs[] row in place and skip the reload until T2.6 lands a real JSONL-backed store. Makes set_title visible end-to-end: agent calls set_title -> useAgentStream catches tool_call_start -> renameDesign patches the currently-selected Design -> sidebar / top bar label flip.
Adds makePreviewTool() so the agent can render an artifact and inspect
its runtime report (console errors, failing asset requests, DOM outline
+ metrics, and screenshot on vision-capable models) BEFORE calling done.
- packages/core/src/tools/preview.ts: extend with makePreviewTool +
RunPreviewFn, pipe result through trimPreviewResult (50 console / 20
asset caps), fall back to structured failure when executor throws.
- packages/core/src/index.ts: add GenerateInput.runPreview, export
makePreviewTool / trimPreviewResult / PreviewResult / RunPreviewFn.
- packages/core/src/agent.ts: register preview tool when runPreview is
defined, deriving vision from piModel.input.includes('image').
- packages/core/src/prompts/workflow.v1.txt + prompts/index.ts: append
Preview section (self-check before done; fix console errors first).
- packages/core/src/tools/preview.test.ts: canned-result round-trip,
vision-opts forwarding, 100-entry cap, executor-throw failure shape.
done continues to own its lint + DoneRuntimeVerifier contract; preview
is purely additive.
# Conflicts: # packages/core/src/agent.ts # packages/core/src/index.ts # packages/core/src/prompts/index.ts # packages/core/src/prompts/workflow.v1.txt
# Conflicts: # packages/core/src/prompts/index.ts # packages/core/src/prompts/workflow.v1.txt # packages/core/src/tools/tweaks.test.ts # packages/core/src/tools/tweaks.ts
Signed-off-by: hqhq1025 <1506751656@qq.com>
Signed-off-by: hqhq1025 <1506751656@qq.com>
#267) ## Summary - The transport-level retry regex in `isTransportLevelError` required `fetch failed` before `terminated`, but pi-agent-core only captures `error.message` (not `error.cause`), so the `errorMessage` can be just `"terminated"` without the prefix - This caused the retry logic to be skipped, surfacing `CodesignError: terminated` directly to the user instead of retrying with conversation replay - Added `terminated` as a standalone match in the regex, and added tests at both the provider and agent layers ## Test plan - [x] `pnpm --filter @open-codesign/providers test` — all 37 tests pass (new: `marks standalone terminated as retryable`) - [x] `pnpm --filter @open-codesign/core test -- -t "transport-level retry"` — all 7 tests pass (new: `retries a standalone terminated error`) - [ ] Manual: trigger a generation with a proxy that drops SSE connections → should retry instead of showing "terminated" error 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: hqhq1025 <1506751656@qq.com>
Signed-off-by: hqhq1025 <1506751656@qq.com>
Signed-off-by: hqhq1025 <1506751656@qq.com>
Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com>
Signed-off-by: Sun-sunshine06 <Sun-sunshine06@users.noreply.github.com>
Backfill selected main-only fixes and v0.2-shaped workspace visibility updates. See .github/v0.2-main-backfill.md for the commit audit.
Comment on lines
+197
to
+201
| if (scheme === 'http' || scheme === 'https' || scheme === 'mailto') return output; | ||
| if (kind === 'image' && isAllowedImageDataUrl(probe)) { | ||
| return output; | ||
| } | ||
| if (/^[a-z][a-z0-9+.-]*:/i.test(probe)) return null; | ||
| if (scheme !== null) return null; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promote dev/v0.2 as the new mainline after backfilling selected main-only fixes.
This PR uses an integration branch whose file tree is identical to origin/dev/v0.2, with main anchored as ancestry so GitHub can merge it cleanly. It brings the v0.2 agentic design runtime, workspace-first architecture, provider diagnostics hardening, release fixes, and selected main backfills into main.
Main-only commits that were covered or tied to the old architecture are recorded in .github/v0.2-main-backfill.md.
Supersedes #279.
Validation
Notes
Existing open PRs targeting the old main should be retargeted or rebased after this lands.