Merge pull request #458 from alibaba/refactor/ci-and-prettier

refactor(setup): consolidate prettier config and streamline CI
This commit is contained in:
Simon
2026-04-16 17:05:47 +08:00
committed by GitHub
18 changed files with 255 additions and 182 deletions

View File

@@ -1,7 +1,7 @@
--- ---
name: pre-impl-discussion name: pre-impl-discussion
description: "Conduct a thorough pre-implementation discussion before making significant changes. Use when the user wants to discuss, plan, or evaluate a change before implementing it — especially when they say words like 'discuss', 'evaluate', 'plan', or 'let's talk about'." description: "Conduct a thorough pre-implementation discussion before making significant changes. Use when the user wants to discuss, plan, or evaluate a change before implementing it — especially when they say words like 'discuss', 'evaluate', 'plan', or 'let's talk about'."
argument-hint: "Describe the change to evaluate" argument-hint: 'Describe the change to evaluate'
--- ---
# Pre-Implementation Discussion # Pre-Implementation Discussion
@@ -40,6 +40,7 @@ Do NOT skip this step. Do NOT rely on assumptions about what "most projects" do.
- **Search in parallel** to save time — batch independent queries - **Search in parallel** to save time — batch independent queries
Common pitfalls: Common pitfalls:
- Assuming compatibility without checking actual version constraints - Assuming compatibility without checking actual version constraints
- Confusing roadmap/aspirations with actual released state - Confusing roadmap/aspirations with actual released state
- Missing transitive constraints (a dependency of a dependency) - Missing transitive constraints (a dependency of a dependency)
@@ -53,6 +54,7 @@ Share a **brief** assessment. Tables work well for comparisons. Highlight **bloc
Surface the decisions the user needs to make. Present them as clear choices with trade-offs, not as a recommendation monologue. Surface the decisions the user needs to make. Present them as clear choices with trade-offs, not as a recommendation monologue.
For each decision point: For each decision point:
- What are the options? (2-3 max) - What are the options? (2-3 max)
- What does each option cost or give up? - What does each option cost or give up?
- What's your lean and why? (one sentence) - What's your lean and why? (one sentence)
@@ -66,6 +68,7 @@ The user will ask follow-up questions, raise concerns, or challenge assumptions.
- **Update your mental model** based on user feedback - **Update your mental model** based on user feedback
Common mistakes in this phase: Common mistakes in this phase:
- Repeating the full plan after every small clarification - Repeating the full plan after every small clarification
- Answering a narrow question with a broad redesign - Answering a narrow question with a broad redesign
- Treating user questions as confirmation to proceed - Treating user questions as confirmation to proceed
@@ -84,6 +87,7 @@ Keep it terse. Tables over paragraphs. No explanations the user already heard du
### 7. Wait for Confirmation ### 7. Wait for Confirmation
After presenting the final plan, **stop and wait**. The user will either: After presenting the final plan, **stop and wait**. The user will either:
- Confirm → then (and only then) proceed to implementation - Confirm → then (and only then) proceed to implementation
- Ask more questions → go back to step 5 - Ask more questions → go back to step 5
- Modify scope → update the plan and re-present - Modify scope → update the plan and re-present
@@ -91,7 +95,7 @@ After presenting the final plan, **stop and wait**. The user will either:
## Anti-Patterns ## Anti-Patterns
| Don't | Do Instead | | Don't | Do Instead |
|-------|------------| | --------------------------------------------------- | ---------------------------------------- |
| Start implementation "to test" without confirmation | Present findings and wait | | Start implementation "to test" without confirmation | Present findings and wait |
| Repeat the full plan in every response | Answer the specific question asked | | Repeat the full plan in every response | Answer the specific question asked |
| Say "X should work" without checking | Say "I need to verify X" and research it | | Say "X should work" without checking | Say "I need to verify X" and research it |

View File

@@ -1,6 +1,6 @@
name: CI
permissions: permissions:
contents: read contents: read
name: CI
on: on:
push: push:
@@ -17,6 +17,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js ${{ matrix.node-version }} - name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6 uses: actions/setup-node@v6
@@ -24,18 +26,8 @@ jobs:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: 'npm' cache: 'npm'
# test on default version of npm
# - 9.6~10.8 on node@20
# - 11.3~11.6 on node@24
- name: Node and NPM version
run: node --version && npm --version
- name: Install dependencies - name: Install dependencies
run: npm install run: npm ci
- name: Lint - name: CI checks
run: npx eslint . && npx prettier --check **/*.ts run: node scripts/ci.js
- name: Build
run: npm run build

8
.prettierignore Normal file
View File

@@ -0,0 +1,8 @@
# Prompt templates (formatted manually for LLM readability)
*prompt.md
# Generated
packages/extension/.wxt
# Vendored
**/components/ui

View File

@@ -22,7 +22,7 @@
"packages/*/node_modules": true "packages/*/node_modules": true
}, },
"markdownlint.config": { "markdownlint.config": {
// "comment": "Relaxed rules", // Relaxed rules
"default": true, "default": true,
"whitespace": false, "whitespace": false,
"line_length": false, "line_length": false,
@@ -36,6 +36,7 @@
"ol-prefix": false, "ol-prefix": false,
"no-duplicate-heading": false "no-duplicate-heading": false
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode",
"js/ts.tsdk.path": "node_modules/typescript/lib", "js/ts.tsdk.path": "node_modules/typescript/lib",
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true "typescript.enablePromptUseWorkspaceTsdk": true

View File

@@ -16,21 +16,21 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment Examples of behavior that contributes to creating a positive environment
include: include:
* Using welcoming and inclusive language - Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences - Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism - Gracefully accepting constructive criticism
* Focusing on what is best for the community - Focusing on what is best for the community
* Showing empathy towards other community members - Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or - The use of sexualized language or imagery and unwelcome sexual attention or
advances advances
* Trolling, insulting/derogatory comments, and personal or political attacks - Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or electronic - Publishing others' private information, such as a physical or electronic
address, without explicit permission address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Our Responsibilities ## Our Responsibilities
@@ -85,19 +85,19 @@ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.ht
有助于创造正面环境的行为包括但不限于: 有助于创造正面环境的行为包括但不限于:
* 使用友好和包容性语言 - 使用友好和包容性语言
* 尊重不同的观点和经历 - 尊重不同的观点和经历
* 耐心地接受建设性批评 - 耐心地接受建设性批评
* 关注对社区最有利的事情 - 关注对社区最有利的事情
* 友善对待其他社区成员 - 友善对待其他社区成员
身为参与者不能接受的行为包括但不限于: 身为参与者不能接受的行为包括但不限于:
* 使用与性有关的言语或是图像,以及不受欢迎的性骚扰 - 使用与性有关的言语或是图像,以及不受欢迎的性骚扰
* 捣乱/煽动/造谣的行为或进行侮辱/贬损的评论,人身攻击及政治攻击 - 捣乱/煽动/造谣的行为或进行侮辱/贬损的评论,人身攻击及政治攻击
* 公开或私下的骚扰 - 公开或私下的骚扰
* 未经许可地发布他人的个人资料,例如住址或是电子地址 - 未经许可地发布他人的个人资料,例如住址或是电子地址
* 其他可以被合理地认定为不恰当或者违反职业操守的行为 - 其他可以被合理地认定为不恰当或者违反职业操守的行为
## 我们的责任 ## 我们的责任

View File

@@ -106,4 +106,3 @@ this project possible.
--- ---
**⭐ 如果觉得 PageAgent 有用或有趣,请给项目点个星!** **⭐ 如果觉得 PageAgent 有用或有趣,请给项目点个星!**

View File

@@ -36,6 +36,7 @@
"postpublish": "npm run postpublish --workspaces --if-present", "postpublish": "npm run postpublish --workspaces --if-present",
"typecheck": "tsc --noEmit -p tsconfig.typecheck.json && tsc --noEmit -p packages/extension/tsconfig.json", "typecheck": "tsc --noEmit -p tsconfig.typecheck.json && tsc --noEmit -p packages/extension/tsconfig.json",
"lint": "eslint .", "lint": "eslint .",
"ci": "node scripts/ci.js",
"cleanup": "rm -rf packages/*/dist && rm -rf packages/*/.output", "cleanup": "rm -rf packages/*/dist && rm -rf packages/*/.output",
"prepare": "husky || true" "prepare": "husky || true"
}, },

View File

@@ -1 +0,0 @@
system_prompt.md

View File

@@ -1,2 +0,0 @@
.wxt
src/components/ui

View File

@@ -42,12 +42,7 @@ localStorage.setItem('PageAgentExtUserAuthToken', 'your-token')
## Quick Start ## Quick Start
```typescript ```typescript
import type { import type { AgentActivity, AgentStatus, ExecutionResult, HistoricalEvent } from '@page-agent/core'
AgentActivity,
AgentStatus,
ExecutionResult,
HistoricalEvent,
} from '@page-agent/core'
// Wait for extension injection (up to 1 second) // Wait for extension injection (up to 1 second)
async function waitForExtension(timeout = 1000): Promise<boolean> { async function waitForExtension(timeout = 1000): Promise<boolean> {
@@ -91,7 +86,7 @@ Execute one agent task.
Parameters: Parameters:
| Name | Type | Required | Description | | Name | Type | Required | Description |
| ---- | ---- | -------- | ----------- | | -------- | --------------- | -------- | ------------------------------------ |
| `task` | `string` | Yes | Task description | | `task` | `string` | Yes | Task description |
| `config` | `ExecuteConfig` | Yes | LLM settings, options, and callbacks | | `config` | `ExecuteConfig` | Yes | LLM settings, options, and callbacks |
@@ -106,12 +101,7 @@ Stop the current task.
Install `@page-agent/core` for complete types: Install `@page-agent/core` for complete types:
```typescript ```typescript
import type { import type { AgentActivity, AgentStatus, ExecutionResult, HistoricalEvent } from '@page-agent/core'
AgentActivity,
AgentStatus,
ExecutionResult,
HistoricalEvent,
} from '@page-agent/core'
export interface ExecuteConfig { export interface ExecuteConfig {
baseURL: string baseURL: string
@@ -205,12 +195,7 @@ window.PAGE_AGENT_EXT!.stop()
If you are not importing `@page-agent/core`, add: If you are not importing `@page-agent/core`, add:
```typescript ```typescript
import type { import type { AgentActivity, AgentStatus, ExecutionResult, HistoricalEvent } from '@page-agent/core'
AgentActivity,
AgentStatus,
ExecutionResult,
HistoricalEvent,
} from '@page-agent/core'
interface ExecuteConfig { interface ExecuteConfig {
baseURL: string baseURL: string

View File

@@ -1 +0,0 @@
system_prompt.md

View File

@@ -37,7 +37,7 @@ Same format — add the config to the MCP settings of your client.
## MCP Tools ## MCP Tools
| Tool | Input | Description | | Tool | Input | Description |
| -------------- | ------------------ | ---------------------------------------------------- | | -------------- | ------------------ | ----------------------------------------------------- |
| `execute_task` | `{ task: string }` | Execute a browser task in natural language. Blocking. | | `execute_task` | `{ task: string }` | Execute a browser task in natural language. Blocking. |
| `get_status` | — | Returns `{ connected, busy }` | | `get_status` | — | Returns `{ connected, busy }` |
| `stop_task` | — | Stop the currently running task. | | `stop_task` | — | Stop the currently running task. |

View File

@@ -3,7 +3,10 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="https://img.alicdn.com/imgextra/i1/O1CN01mRGret1QrKiu7CFJI_!!6000000002029-2-tps-64-64.png" /> <link
rel="icon"
href="https://img.alicdn.com/imgextra/i1/O1CN01mRGret1QrKiu7CFJI_!!6000000002029-2-tps-64-64.png"
/>
<title>Page Agent MCP Launcher</title> <title>Page Agent MCP Launcher</title>
<style> <style>
* { * {
@@ -172,16 +175,26 @@
If the extension is outdated, please update it to the latest version. If the extension is outdated, please update it to the latest version.
</li> </li>
<li data-i18n="tip_other_browser"> <li data-i18n="tip_other_browser">
If the extension is not installed in this browser, open this page from the If the extension is not installed in this browser, open this page from the browser that
browser that has it installed. has it installed.
</li> </li>
<li data-i18n="tip_refresh">Refresh this page after installing or updating.</li> <li data-i18n="tip_refresh">Refresh this page after installing or updating.</li>
</ul> </ul>
</div> </div>
<div class="links"> <div class="links">
<a href="https://alibaba.github.io/page-agent/docs/introduction/overview" target="_blank" data-i18n="link_docs">Docs</a> <a
<a href="https://github.com/alibaba/page-agent/issues" target="_blank" data-i18n="link_issues">Report an Issue</a> href="https://alibaba.github.io/page-agent/docs/introduction/overview"
target="_blank"
data-i18n="link_docs"
>Docs</a
>
<a
href="https://github.com/alibaba/page-agent/issues"
target="_blank"
data-i18n="link_issues"
>Report an Issue</a
>
</div> </div>
</div> </div>
@@ -197,8 +210,7 @@
install_sub: 'Page Agent 需要安装最新版浏览器插件才能运行。', install_sub: 'Page Agent 需要安装最新版浏览器插件才能运行。',
install_btn: '从 Chrome 应用商店安装', install_btn: '从 Chrome 应用商店安装',
tip_outdated: '如果插件版本过旧,请更新到最新版本。', tip_outdated: '如果插件版本过旧,请更新到最新版本。',
tip_other_browser: tip_other_browser: '如果该浏览器中未安装插件,请从装有插件的浏览器打开此页面。',
'如果该浏览器中未安装插件,请从装有插件的浏览器打开此页面。',
tip_refresh: '安装或更新后,请刷新此页面。', tip_refresh: '安装或更新后,请刷新此页面。',
link_docs: '文档', link_docs: '文档',
link_issues: '问题反馈', link_issues: '问题反馈',
@@ -220,13 +232,9 @@
if (!globalThis.chrome?.runtime?.sendMessage) { if (!globalThis.chrome?.runtime?.sendMessage) {
showInstall() showInstall()
} else { } else {
chrome.runtime.sendMessage( chrome.runtime.sendMessage(EXT_ID, { type: 'OPEN_HUB', wsPort }, (response) => {
EXT_ID,
{ type: 'OPEN_HUB', wsPort },
(response) => {
if (chrome.runtime.lastError || !response?.ok) showInstall() if (chrome.runtime.lastError || !response?.ok) showInstall()
} })
)
} }
} catch { } catch {
showInstall() showInstall()

View File

@@ -49,10 +49,34 @@
<div id="sk"> <div id="sk">
<p class="sk-text" id="sk-text">Loading...</p> <p class="sk-text" id="sk-text">Loading...</p>
<style> <style>
#sk{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(135deg,#eff6ff,#f5f3ff)} #sk {
@media(prefers-color-scheme:dark){#sk{background:linear-gradient(135deg,#111827,#1f2937)}} display: flex;
.sk-text{font:400 14px/1 system-ui,sans-serif;color:#94a3b8;animation:skf 2s ease-in-out infinite} align-items: center;
@keyframes skf{0%,100%{opacity:.6}50%{opacity:.3}} justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #eff6ff, #f5f3ff);
}
@media (prefers-color-scheme: dark) {
#sk {
background: linear-gradient(135deg, #111827, #1f2937);
}
}
.sk-text {
font:
400 14px/1 system-ui,
sans-serif;
color: #94a3b8;
animation: skf 2s ease-in-out infinite;
}
@keyframes skf {
0%,
100% {
opacity: 0.6;
}
50% {
opacity: 0.3;
}
}
</style> </style>
</div> </div>
</div> </div>

55
scripts/ci.js Normal file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env node
/**
* CI check script. Run locally before commit or in GitHub Actions.
*
* Usage:
* node scripts/ci.js # run all checks
* node scripts/ci.js --no-build # skip build step
*/
import chalk from 'chalk'
import { execSync } from 'child_process'
import { parallelTask } from './parallel-task.js'
const args = new Set(process.argv.slice(2))
const skipBuild = args.has('--no-build')
function run(label, command) {
console.log(chalk.bgBlue.white.bold(`${label} `))
execSync(command, { stdio: 'inherit' })
}
function isMainBranch() {
if (process.env.GITHUB_REF) return process.env.GITHUB_REF === 'refs/heads/main'
try {
return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim() === 'main'
} catch {
return true
}
}
// 1. Commitlint — skip on main
if (isMainBranch()) {
console.log(chalk.dim(' ▸ commitlint (skipped on main)'))
} else {
const from = execSync('git merge-base origin/main HEAD', { encoding: 'utf-8' }).trim()
run('commitlint', `npx commitlint --from ${from} --to HEAD`)
}
// 2. Lint + Format + Typecheck in parallel
console.log(chalk.bgBlue.white.bold(' ▸ lint + format + typecheck '))
await parallelTask(
[
{ label: 'lint', command: 'npm run lint' },
{ label: 'format', command: 'npx prettier --check .' },
{ label: 'typecheck', command: 'npm run typecheck' },
],
{ timeoutMs: 120_000 }
)
// 3. Build
if (skipBuild) {
console.log(chalk.dim(' ▸ build (skipped)'))
} else {
run('build', 'npm run build')
}