Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 27 additions & 168 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,171 +1,30 @@
# ScriptCat Development Guide
# ScriptCat — Copilot Instructions

## Code Review

When performing a code review, respond in Chinese.

## Architecture Overview

ScriptCat is a sophisticated browser extension that executes user scripts with a unique multi-process architecture:

### Core Components
- **Service Worker** (`src/service_worker.ts`) - Main background process handling script management, installations, and chrome APIs
- **Offscreen** (`src/offscreen.ts`) - Isolated background environment for running background/scheduled scripts
- **Sandbox** (`src/sandbox.ts`) - Secure execution environment inside offscreen for script isolation
- **Content Scripts** (`src/content.ts`) - Injected into web pages to execute user scripts
- **Inject Scripts** (`src/inject.ts`) - Runs in page context with access to page globals

### Message Passing System
ScriptCat uses a sophisticated message passing architecture (`packages/message/`):
- **ExtensionMessage** - Chrome extension runtime messages between service worker/content/pages
- **WindowMessage** - PostMessage-based communication between offscreen/sandbox
- **CustomEventMessage** - CustomEvent-based communication between content/inject scripts
- **MessageQueue** - Cross-environment event broadcasting system

Key pattern: All communication flows through Service Worker → Offscreen → Sandbox for background scripts, or Service Worker → Content → Inject for page scripts.

### Script Execution Flow
1. **Page Scripts**: Service Worker registers with `chrome.userScripts` → injected into pages
2. **Background Scripts**: Service Worker → Offscreen → Sandbox execution
3. **Scheduled Scripts**: Cron-based execution in Sandbox environment

## Key Development Patterns

### Path Aliases
```typescript
"@App": "./src/"
"@Packages": "./packages/"
"@Tests": "./tests/"
```

### Repository Pattern
All data access uses DAO classes extending `Repo<T>` base class:
```typescript
// Example: ScriptDAO, ResourceDAO, SubscribeDAO
export class ScriptDAO extends Repo<Script> {
public save(val: Script) { return super._save(val.uuid, val); }
}
```

### Service Layer Structure
Services follow a consistent pattern with dependency injection:
```typescript
export class ExampleService {
constructor(
private group: Group, // Message handling group
private messageQueue: IMessageQueue, // Event broadcasting (MessageQueue's interface)
private dataDAO: DataDAO // Data access
) {}

init() {
this.group.on("action", this.handleAction.bind(this));
}
}
```

### Script Compilation & Sandboxing
User scripts are compiled with sandbox context isolation:
- `compileScriptCode()` - Wraps scripts with error handling and context binding
- `compileInjectScript()` - Creates window-mounted functions for inject scripts
- Sandbox uses `with(arguments[0])` for controlled variable access

## Technology Stack

- **React 19** - Component framework with automatic runtime
- **shadcn/ui** - UI component library built on Radix UI
- **Tailwind CSS** - Utility-first CSS framework for styling
- **Rspack** - Fast bundler (Webpack alternative) with SWC
- **TypeScript** - Type-safe development


## Development Workflows

### Build & Development
```bash
pnpm run dev # Development with source maps
pnpm run dev:noMap # Development without source maps (needed for incognito)
pnpm run build # Production build
pnpm run pack # Create browser extension packages
```

### Testing
```bash
pnpm test # Run all tests with Vitest
pnpm run coverage # Generate coverage reports
```
> **This file only holds Copilot-specific behavior and a router.** Architecture, coding conventions, commands,
> and testing mechanics are owned by [`../AGENTS.md`](../AGENTS.md) and the docs it routes to
> (`docs/develop.md`, `docs/architecture.md`, `docs/references/*`, `docs/verification.md`, `docs/design.md`,
> `docs/translation.md`). Read those before reviewing or writing code — don't rely on a second, separately
> maintained copy of them here; when this file and one of those docs disagree, the owning doc wins and this
> file should be corrected to match.

**Testing Patterns:**
- Uses Vitest with happy-dom environment
- Chrome extension APIs mocked via `@Packages/chrome-extension-mock`
- Message system testing with `MockMessage` classes
- Sandbox testing validates script isolation

### Code Organization
- **Monorepo structure** with packages in `packages/` (message, filesystem, etc.)
- **Feature-based organization** in `src/app/service/` by environment
- **Shared utilities** in `src/pkg/` for cross-cutting concerns
- **Type definitions** in `src/types/` with global declarations

### Browser Extension Specifics
- **Manifest V3** with service worker background
- **User Scripts API** for script injection (Chrome/Edge)
- **Offscreen API** for DOM access in background contexts
- **Declarative Net Request** for script installation interception

## Critical Integration Points

### Script Installation Flow
1. URL patterns trigger declarative net request rules
2. Service Worker opens install page with cached script data
3. Install page validates and processes script metadata
4. Scripts registered with appropriate execution environment

### GM API Implementation
- Split across Content, Service Worker, and Offscreen contexts (each a `GMApi` in its own module)
- Permission verification via `PermissionVerify` service
- Value storage abstracted through `ValueService`
- Cross-origin requests handled in service worker context

### Resource Management
- `ResourceService` handles script dependencies (@require, @resource)
- Content Security Policy handling for external resources
- Caching layer via `Cache` class with automatic expiration

## Debug & Development Notes

- Use `pnpm run dev:noMap` for incognito window development
- Background script changes require extension reload
- Message passing debugging available in service worker console
- Sandbox script execution isolated from page context - use `unsafeWindow` for page access

## File Structure Patterns
- Tests co-located with source files (`.test.ts` suffix)
- Template files use `.tpl` extension for build-time processing
- Configuration files use factory pattern for environment-specific setup

## Language
- The code is developed and maintained by developers based in Mainland China.
- Comments should preferably be written in Simplified Chinese.
- The user interface supports multiple languages, with English set as the default for global users.

## PR Review Policy

When performing Pull Request (PR) reviews, Copilot must always conduct a **comprehensive and independent review** of the entire PR content.

- **Full Review Every Time**
Always review **all modified files** in every PR, regardless of previous reviews or user comments. Even during re-reviews, treat the PR as new and **do not rely on prior review states**.

- **No Skipping of Files**
Do not skip or ignore any text-based file types (including `.md`, `.json`, `.yml`, `.toml`, `.ts`, `.js`, `.py`, `.html`, `.css`, `.tsx`, `.vue`, `.sh`, etc.). Every file that is changed must be fully examined.

- **Reference as Context Only**
PR descriptions, commit messages, or user discussions serve only as **reference context**. The review must focus primarily on the **actual code and file changes**.

- **Infer Intent from Code Changes**
Always attempt to **infer the purpose and intent** of the changes directly from the modified content, rather than relying solely on user statements or PR titles.

- **Critical Thinking Requirement**
For each change, Copilot should assess correctness, consistency, and maintainability — ensuring that logic, style, and architectural impact align with project standards.
## Code Review

- **Independent Verification**
Do not assume unchanged files or previously reviewed sections are safe; verify all code paths potentially affected by the modifications.
- Respond in Chinese when performing a code review (用中文回复代码审查意见).
- Conduct a **comprehensive and independent review** of the entire PR every time:
- **Full review every time** — review all modified files regardless of previous reviews or comments; treat
re-reviews as new, not relying on prior review state.
- **No skipping files** — examine every changed file regardless of type (`.md`, `.json`, `.yml`, `.toml`,
`.ts`, `.js`, `.py`, `.html`, `.css`, `.tsx`, `.vue`, `.sh`, etc.).
- **PR descriptions/commit messages/discussion are reference context only** — the review's conclusions must
be grounded in the actual code and file changes, inferring intent from the diff itself.
- **Independent verification** — don't assume an unchanged file or a previously reviewed section is safe;
verify code paths potentially affected by the current changes.

## Minimal fallback (only if this surface can't reliably follow the link above)

ScriptCat is a Manifest V3 browser extension (TypeScript + React 19 + Rspack, pnpm) that runs
Tampermonkey-compatible userscripts across five isolated contexts — Service Worker, Content, Inject, Offscreen,
Sandbox — communicating over `packages/message`. If you cannot load `AGENTS.md`, treat any architecture,
persistence-pattern, or service-shape claim you're tempted to state here as unverified, and prefer asking the
reviewer to confirm against `AGENTS.md` / `docs/architecture.md` over inventing a summary — this file is not
the source of truth for those facts and must not re-accumulate a parallel copy of them.
19 changes: 11 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ This file provides guidance to AI coding agents (Claude Code, etc.) when working
> (`src/locales/<locale>/*.json` namespace files, per-language docs, UI copy, or test snapshots), you must first
> read that guide and follow the matching `docs/references/terminology-<locale>.md` if it exists.

> **Before adding, editing, reorganizing, or reviewing any contributor doc (this file or `docs/*`), read
> **Before adding, editing, reorganizing, or reviewing any tracked agent/contributor Markdown — this file,
> `docs/*`, `.github/*.md`, package-local READMEs, and source-local READMEs — read
> [`docs/DOC-MAINTENANCE.md`](docs/DOC-MAINTENANCE.md)** — keep the doc set organized (links resolve, index
> current, no duplication) and every claim factually true against the current branch (*if you can't grep it on
> this branch, don't claim it*).
> current, no duplication, no cross-document policy conflicts) and every claim factually true against the current
> branch (*if you can't grep it on this branch, don't claim it*). That guide owns the full checklist; don't copy
> it into this always-loaded file.

> **Before opening or updating a pull request, read [`docs/pull-request.md`](docs/pull-request.md)** — this
> repo's PR description structure and evidence rules.
Expand All @@ -53,9 +55,9 @@ isn't universal, that's called out in the item itself.
- **Fix root causes, not symptoms — refactor over patch.** No `as any` / `// @ts-ignore` / try-catch swallow / defensive skips to make errors disappear (宁愿重构也不要打补丁). If a test fails, fix the code, not the test — the narrow exceptions (a wrong test contract; a test that never carried value) are in [`docs/references/develop-testing.md`](docs/references/develop-testing.md#writing-meaningful-tests-what-to-clean-up--not-write).
- **Confirm before you fix.** Before touching a reported bug, reproduce it and confirm it actually exists — never fix from assumption. Capture the reproduction, then fix, **in that order** (确定 bug 存在 → 写测试或记录验证证据 → 修复); how to reproduce and what counts as capture are in [`docs/verification.md`](docs/verification.md) and the TDD entry below.
- **TDD/BDD first, for changes that alter observable behavior.** Write failing tests **before** implementing new or changed behavior, using BDD-style Chinese `describe`/`it` titles. Two narrow exceptions — neither a blanket file/task category — are in [`docs/references/develop-testing.md`](docs/references/develop-testing.md#when-tdd-doesnt-apply). (Runner, mocks, and how to run tests are in `docs/develop.md`.)
- **SOLID, high cohesion & low coupling — applied to the existing extension points.** `Repo<T>` for new entities, `Group.on(...)` for new messages. Inject `Group` / `IMessageQueue` / DAOs via constructor; don't `new` them inside methods. Depend on narrow interfaces (`IMessageQueue`, not `MessageQueue`).
- **SOLID, high cohesion & low coupling — applied to the existing extension points.** Persistence is a small backend taxonomy (`Repo<T>` / `DAO<T>` / `OPFSRepo` / a few custom repos), not one pattern to default to — pick by matching an existing entity with the same needs; see [`docs/references/architecture-data.md`](docs/references/architecture-data.md#adding-an-entity). For messages, use `Group.on(...)`. Not every service takes the same constructor shape — context services vs. the Agent subsystem differ; see [`docs/references/architecture-services.md`](docs/references/architecture-services.md#adding-a-service). Depend on narrow interfaces (`IMessageQueue`, not `MessageQueue`).
- **Direct replacement over adapter sandwiches.** When swapping a backend/library, replace in place — no `interface Foo + LegacyImpl + NewImpl` unless both must coexist at runtime.
- **Scope discipline — stay in your lane.** Bug fix ≠ cleanup PR. Touch only the files the task requires; leave unrelated files untouched (不要动和任务不相干的文件). Don't add helpers, abstractions, validation, or backwards-compat shims you don't need today. Three similar lines beats a premature abstraction.
- **Scope discipline — stay in your lane.** Bug fix ≠ cleanup PR. Touch only the files the task requires; leave unrelated files untouched (不要动和任务不相干的文件). Don't add helpers, abstractions, validation, or backwards-compat shims you don't need today. Three similar lines beats a premature abstraction. Don't remove or narrow currently supported behavior just to simplify a fix — only do so when the task or an already-verified contract explicitly calls for that change.
- **No dead code or `// removed` markers** — git remembers. Delete unused code outright.
- **Comments explain "why", not "what".** Do not use ephemeral review labels such as `finding N` or review-round identifiers in comments or test names. Permanent issue or PR references are allowed when useful, but must supplement—not replace—the explanation. Do not restate code, duplicate enclosing documentation, or leave stale comments after code changes. See [`docs/develop.md`](docs/develop.md#comment-discipline) for the full policy.

Expand Down Expand Up @@ -93,9 +95,10 @@ Execution paths: page scripts → `chrome.userScripts`; background → SW → Of
`ExtensionMessage` (chrome.runtime — SW ↔ Content / Inject / Offscreen), `WindowMessage` (postMessage — Offscreen ↔ Sandbox), `ServiceWorkerMessageSend` (`clients.matchAll()` + `postMessage` — SW → Offscreen on Chrome), `CustomEventMessage` (CustomEvent — Content ↔ Inject), `MessageQueue` (cross-context broadcast).

### Service & Data Layers
- Services in `src/app/service/<context>/` — split by execution context. Constructor-injected `Group`, `IMessageQueue`, DAOs.
- DAOs in `src/app/repo/` extend `Repo<T>` (chrome.storage + cache): `ScriptDAO`, `ValueDAO`, `ResourceDAO`, `PermissionDAO`, `SubscribeDAO`.
- **GM API** split across content / SW / offscreen, each a `GMApi` (content built on `GM_Base`; SW — permission verify, cross-origin; offscreen — DOM-dependent background-script APIs); values via `ValueService`.
- Services live under `src/app/service/` as **context services** (`content/`, `offscreen/`, `sandbox/`, `service_worker/`) plus **cross-cutting subsystems** (`agent/`, `extension/`, `queue.ts`) — not one uniform shape. Details, inventory, "adding a service": [`docs/references/architecture-services.md`](docs/references/architecture-services.md).
- Persistence is a backend taxonomy (`Repo<T>` / `DAO<T>` / `OPFSRepo` / custom), not one pattern. Details, inventory, "adding an entity": [`docs/references/architecture-data.md`](docs/references/architecture-data.md).
- **GM API** split across content / SW / offscreen, each a `GMApi`; values via `ValueService`. Adding a new GM API: [`docs/references/architecture-gm-api.md`](docs/references/architecture-gm-api.md).
- **Agent subsystem** (`src/app/service/agent/`) is an AI-agent layer spanning the existing five contexts, not a sixth. Full write-up: [`docs/references/architecture-agent.md`](docs/references/architecture-agent.md).

### Browser Extension APIs (MV3)
`chrome.userScripts` (page injection), Offscreen API (DOM in background), Declarative Net Request (intercepts `.user.js` URLs to trigger install flow).
Expand Down
Loading
Loading