diff --git a/.agents/skills/AGENTS.md b/.agents/skills/AGENTS.md index 516225c..77fc695 100644 --- a/.agents/skills/AGENTS.md +++ b/.agents/skills/AGENTS.md @@ -2,10 +2,10 @@ ## OVERVIEW ###### Skill catalog for writing and workflow automation - -The `.agents/skills/` directory contains the reusable skill library shipped with VibePaper. + +The `.agents/skills/` directory contains the reusable skill library shipped with CoPaper. Each skill is a self-contained module that extends the agent's capabilities for a specific academic task or workflow-management task. -These skills are bundled into initialized projects by `vibe init`. +These skills are bundled into initialized projects by `copaper init`. ## STRUCTURE ###### Standardized skill module organization @@ -18,9 +18,9 @@ These skills are bundled into initialized projects by `vibe init`. ## WHERE TO LOOK ###### Important skills in the current catalog -- `vibepaper-manage`: Teaches agents how to use OpenCode plugin tools for dashboard, initialization, artifact readiness, workflow status, phase updates, and workflow log inspection. +- `copaper-manage`: Teaches agents how to use OpenCode plugin tools for dashboard, initialization, artifact readiness, workflow status, phase updates, and workflow log inspection. - `human-comment-helper`: Adds structured reviewer feedback and synthetic examples. -- `latex2markdown`: Imports content from LaTeX files into the VibePaper structure. +- `latex2markdown`: Imports content from LaTeX files into the CoPaper structure. - `markdown-helper`: Interactive assistance for writing and improving `paper.md`. - `markdown-review`: Quality assurance check for novelty, importance, and correctness. - `markdown2latex`: High-quality export from `paper.md` to conference-ready LaTeX. @@ -40,19 +40,19 @@ These skills are bundled into initialized projects by `vibe init`. - **Quality Gates**: Use `markdown-review` to validate content before final export. - **Format Mapping**: Conversion skills must maintain semantic meaning across formats. - **Math Support**: Preserve `$...$` and `$$...$$` during all transformations. -- **OpenCode Plugin Tools**: When available, skills MUST use `vibepaper_dashboard`, `vibepaper_init_apply`, `vibepaper_artifact_status`, `vibepaper_artifact_record`, `vibepaper_workflow_status`, `vibepaper_workflow_log`, and `vibepaper_workflow_set_phase` instead of shell `vibe` commands or manual `.agents/state.json` / `.agents/events.jsonl` edits. -- **Project Initialization**: After explicit user confirmation and collection of project `name` and `domain`, call `vibepaper_init_apply` to initialize OpenCode-managed VibePaper core files. Do not describe initialization as a prompt-only action or manually create the core files when the plugin tool is available. -- **Workflow Status Queries**: For read-only workflow phase status, current phase, phase table, and next-step recommendation, call `vibepaper_workflow_status`. Do not read `.agents/state.json` directly for phase state when the plugin tool is available. -- **Paper Structure Queries**: For read-only `paper.md` Level 2-5 completion, Level 5 writing targets, next writing target, and structural issues, call `vibepaper_paper_structure_status`. Do not reimplement this as prompt-only heading scans or shell parsing when the plugin tool is available. -- **Storyline Structure Queries**: For read-only `storyline.md` `#####` section readiness, TODO coverage, and next storyline target, call `vibepaper_storyline_structure_status`. Do not reimplement this as prompt-only section scans when the plugin tool is available. -- **Import Extraction**: For user-specified PDF and PPTX imports, call `vibepaper_pdf_extract` or `vibepaper_ppt_extract`. These tools are read-only and require an explicit user-provided absolute or relative path; do not run separate shell existence checks, scan directories, glob for candidates, or guess source files. -- **Checker Status Queries**: For read-only checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence, call `vibepaper_checker_status`. Do not read `.agents/state.json` or `.agents/precheck_report.md` directly just to infer checker status when the plugin tool is available. -- **Reviewer Boundary**: Route checker review, checker-result summarization, and issue explanation to `@vibepaper-reviewer` when available. The reviewer is read-only and must not edit `paper.md` or write checker records directly. -- **Phase Updates**: After explicit user confirmation, call `vibepaper_workflow_set_phase`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe this as a prompt-only action. -- **Workflow Log Queries**: For read-only inspection of `.agents/events.jsonl`, call `vibepaper_workflow_log` with optional `lastN`, `phase`, and `operator` filters. Do not read the event log file directly when the plugin tool is available. -- **Artifact Readiness Queries**: For read-only artifact readiness, evidence, confidence, and recommendation, call `vibepaper_artifact_status`. Do not manually infer readiness from files or `.agents/state.json` when the plugin tool is available. -- **Artifact Readiness Records**: After explicit user confirmation, route artifact readiness recording to `@vibepaper-recorder`; the recorder calls `vibepaper_artifact_record`, which writes the `artifacts` area in `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe readiness recording as a prompt-only action. -- **Recorder Boundary**: `vibepaper_artifact_record` must be invoked through `@vibepaper-recorder`; other agents should route the recording action rather than calling it directly. +- **OpenCode Plugin Tools**: When available, skills MUST use `copaper_dashboard`, `copaper_init_apply`, `copaper_artifact_status`, `copaper_artifact_record`, `copaper_workflow_status`, `copaper_workflow_log`, and `copaper_workflow_set_phase` instead of shell `copaper` commands or manual `.agents/state.json` / `.agents/events.jsonl` edits. +- **Project Initialization**: After explicit user confirmation and collection of project `name` and `domain`, call `copaper_init_apply` to initialize OpenCode-managed CoPaper core files. Do not describe initialization as a prompt-only action or manually create the core files when the plugin tool is available. +- **Workflow Status Queries**: For read-only workflow phase status, current phase, phase table, and next-step recommendation, call `copaper_workflow_status`. Do not read `.agents/state.json` directly for phase state when the plugin tool is available. +- **Paper Structure Queries**: For read-only `paper.md` Level 2-5 completion, Level 5 writing targets, next writing target, and structural issues, call `copaper_paper_structure_status`. Do not reimplement this as prompt-only heading scans or shell parsing when the plugin tool is available. +- **Storyline Structure Queries**: For read-only `storyline.md` `#####` section readiness, TODO coverage, and next storyline target, call `copaper_storyline_structure_status`. Do not reimplement this as prompt-only section scans when the plugin tool is available. +- **Import Extraction**: For user-specified PDF and PPTX imports, call `copaper_pdf_extract` or `copaper_ppt_extract`. These tools are read-only and require an explicit user-provided absolute or relative path; do not run separate shell existence checks, scan directories, glob for candidates, or guess source files. +- **Checker Status Queries**: For read-only checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence, call `copaper_checker_status`. Do not read `.agents/state.json` or `.agents/precheck_report.md` directly just to infer checker status when the plugin tool is available. +- **Reviewer Boundary**: Route checker review, checker-result summarization, and issue explanation to `@copaper-reviewer` when available. The reviewer is read-only and must not edit `paper.md` or write checker records directly. +- **Phase Updates**: After explicit user confirmation, call `copaper_workflow_set_phase`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe this as a prompt-only action. +- **Workflow Log Queries**: For read-only inspection of `.agents/events.jsonl`, call `copaper_workflow_log` with optional `lastN`, `phase`, and `operator` filters. Do not read the event log file directly when the plugin tool is available. +- **Artifact Readiness Queries**: For read-only artifact readiness, evidence, confidence, and recommendation, call `copaper_artifact_status`. Do not manually infer readiness from files or `.agents/state.json` when the plugin tool is available. +- **Artifact Readiness Records**: After explicit user confirmation, route artifact readiness recording to `@copaper-recorder`; the recorder calls `copaper_artifact_record`, which writes the `artifacts` area in `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe readiness recording as a prompt-only action. +- **Recorder Boundary**: `copaper_artifact_record` must be invoked through `@copaper-recorder`; other agents should route the recording action rather than calling it directly. - **Unsupported Tool Gaps**: If the OpenCode plugin does not yet expose a needed capability, state the gap explicitly instead of inventing a plugin tool or falling back silently. - **Scaffold Sync**: New or changed skills must be mirrored into the packaged scaffold. diff --git a/.agents/skills/auto-init/SKILL.md b/.agents/skills/auto-init/SKILL.md index 6967354..2f849ff 100644 --- a/.agents/skills/auto-init/SKILL.md +++ b/.agents/skills/auto-init/SKILL.md @@ -1,11 +1,11 @@ --- name: auto-init -description: Detect when the user wants to start a new VibePaper paper project or initialize a workspace, run `vibe --root . init` when needed, then inspect the current workflow phase and immediately begin the appropriate next phase work. +description: Detect when the user wants to start a new CoPaper paper project or initialize a workspace, run `copaper --root . init` when needed, then inspect the current workflow phase and immediately begin the appropriate next phase work. --- # Auto Init -This skill initializes a VibePaper project when the user expresses intent to start a new paper or workspace. +This skill initializes a CoPaper project when the user expresses intent to start a new paper or workspace. ## Input Files @@ -18,7 +18,7 @@ This skill initializes a VibePaper project when the user expresses intent to sta ## Triggers -Use this skill when the user asks to start or initialize a VibePaper paper project, including phrases such as: +Use this skill when the user asks to start or initialize a CoPaper paper project, including phrases such as: - "start working" - "start writing paper" @@ -38,7 +38,7 @@ Use this skill when the user asks to start or initialize a VibePaper paper proje 5. Run: ```bash -vibe --root . init --name "" --domain "" +copaper --root . init --name "" --domain "" ``` 6. After initialization succeeds, tell the user where the scaffold was created. @@ -54,14 +54,14 @@ Only run `git init` when `command -v git` succeeds and `git rev-parse --is-insid 8. Continue immediately by checking status: ```bash -vibe --root . status --json +copaper --root . status --json ``` 9. Read `current_phase` from the JSON output and begin that phase's work without waiting for another user command. ## Phase Continuation -After `vibe --root . status --json`, use this routing: +After `copaper --root . status --json`, use this routing: | Current Phase | Begin This Work | |---------------|-----------------| @@ -80,5 +80,5 @@ If the phase requires information the user has not provided, ask only for the mi - Keep `--root` before the `init` subcommand. - Use the CLI for initialization instead of manually creating `.agents/state.json`. - Do not run `git init` when the current folder is already inside an existing Git work tree. -- Do not require Git; if it is unavailable, continue the VibePaper workflow. +- Do not require Git; if it is unavailable, continue the CoPaper workflow. - Do not stop after initialization when status can be read; continue into the current phase workflow. diff --git a/.agents/skills/bogus-data-helper/SKILL.md b/.agents/skills/bogus-data-helper/SKILL.md index 4bbd05f..2e74286 100644 --- a/.agents/skills/bogus-data-helper/SKILL.md +++ b/.agents/skills/bogus-data-helper/SKILL.md @@ -28,7 +28,7 @@ You are an AI assistant helping create placeholder evaluation data. Your generat ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for inserting placeholder content: +The paper follows CoPaper structure. Key rules for inserting placeholder content: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). diff --git a/.agents/skills/clarity-checker/SKILL.md b/.agents/skills/clarity-checker/SKILL.md index 0aed245..c61285c 100644 --- a/.agents/skills/clarity-checker/SKILL.md +++ b/.agents/skills/clarity-checker/SKILL.md @@ -5,7 +5,7 @@ description: Detects undefined terms, unclear descriptions, and clarity issues i # Clarity Checker Skill -This skill identifies clarity issues in academic paper drafts following the VibePaper structure, including undefined terms, vague descriptions, ambiguous references, and insufficient explanations that hinder reader comprehension. +This skill identifies clarity issues in academic paper drafts following the CoPaper structure, including undefined terms, vague descriptions, ambiguous references, and insufficient explanations that hinder reader comprehension. ## When to Use This Skill @@ -239,7 +239,7 @@ For each clarity issue found: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. diff --git a/.agents/skills/vibepaper-manage/SKILL.md b/.agents/skills/copaper-manage/SKILL.md similarity index 55% rename from .agents/skills/vibepaper-manage/SKILL.md rename to .agents/skills/copaper-manage/SKILL.md index 3b5eb77..8383c20 100644 --- a/.agents/skills/vibepaper-manage/SKILL.md +++ b/.agents/skills/copaper-manage/SKILL.md @@ -1,11 +1,11 @@ --- -name: vibepaper-manage -description: Teaches agents how to manage a VibePaper project through the OpenCode plugin tools, including dashboard, initialization, artifact readiness, workflow status, event log inspection, and phase updates. Use this skill whenever the task is about workflow/state management rather than direct paper writing. +name: copaper-manage +description: Teaches agents how to manage a CoPaper project through the OpenCode plugin tools, including dashboard, initialization, artifact readiness, workflow status, event log inspection, and phase updates. Use this skill whenever the task is about workflow/state management rather than direct paper writing. --- -# VibePaper-Manage Skill +# CoPaper-Manage Skill -This skill tells an agent how to manage a VibePaper project through the OpenCode plugin tools instead of shell commands, prompt-only instructions, or manual edits to workflow files. +This skill tells an agent how to manage a CoPaper project through the OpenCode plugin tools instead of shell commands, prompt-only instructions, or manual edits to workflow files. Use this skill when the task is about project lifecycle management, initialization, workflow status, phase control, artifact readiness, or event log inspection. @@ -13,7 +13,7 @@ Use this skill when the task is about project lifecycle management, initializati Use this skill when the user asks to: -- initialize a VibePaper project from OpenCode +- initialize a CoPaper project from OpenCode - check current workflow status - inspect recent workflow history - mark a phase as `not_started`, `in_progress`, `complete`, or `skipped` @@ -21,12 +21,12 @@ Use this skill when the user asks to: - record artifact readiness after confirmation - check checker status, severity counts, stale signals, and precheck evidence - record checker run summaries after confirmation -- understand what to do next in the VibePaper workflow +- understand what to do next in the CoPaper workflow Typical triggers: - `check workflow status` -- `show VibePaper dashboard` +- `show CoPaper dashboard` - `skip experiments for this project` - `record artifact readiness` - `manage this paper with OpenCode` @@ -36,13 +36,13 @@ Typical triggers: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `.agents/state.json` | Tool-managed | Status, phase, artifact-record, and initialization flows | Access only through plugin tools when possible; contains workflow phases and artifact records | -| `.agents/events.jsonl` | Tool-managed | Workflow history inspection | Access through `vibepaper_workflow_log`; do not read or append directly | -| `storyline.md` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `paper.md` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `relatedwork/` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `.agents/cross_index.json` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| Checker status | Optional | Checker inspection | Access through `vibepaper_checker_status`; do not inspect `.agents/state.json` directly just to infer checker status | -| Relatedwork status | Optional | Literature workflow inspection | Access through `vibepaper_relatedwork_status`; do not run CLI status or read `literature.json` directly just to summarize progress | +| `.agents/events.jsonl` | Tool-managed | Workflow history inspection | Access through `copaper_workflow_log`; do not read or append directly | +| `storyline.md` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `paper.md` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `relatedwork/` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `.agents/cross_index.json` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| Checker status | Optional | Checker inspection | Access through `copaper_checker_status`; do not inspect `.agents/state.json` directly just to infer checker status | +| Relatedwork status | Optional | Literature workflow inspection | Access through `copaper_relatedwork_status`; do not run CLI status or read `literature.json` directly just to summarize progress | ## OpenCode Plugin Tools @@ -50,16 +50,16 @@ Prefer these plugin tools whenever they are available: | User intent | Plugin tool | |---|---| -| Show project dashboard / init preview | `vibepaper_dashboard` | -| Initialize core VibePaper files after confirmation | `vibepaper_init_apply` | -| Read artifact readiness | `vibepaper_artifact_status` | -| Record artifact readiness after confirmation | `vibepaper_artifact_record` | -| Read workflow phase status and next step | `vibepaper_workflow_status` | -| Read recent workflow events | `vibepaper_workflow_log` | -| Update a workflow phase after confirmation | `vibepaper_workflow_set_phase` | -| Read checker run status and stale signals | `vibepaper_checker_status` | -| Record checker run summary after confirmation | `vibepaper_checker_record` | -| Read relatedwork catalog, PDF, summary, BibTeX, and cross-index status | `vibepaper_relatedwork_status` | +| Show project dashboard / init preview | `copaper_dashboard` | +| Initialize core CoPaper files after confirmation | `copaper_init_apply` | +| Read artifact readiness | `copaper_artifact_status` | +| Record artifact readiness after confirmation | `copaper_artifact_record` | +| Read workflow phase status and next step | `copaper_workflow_status` | +| Read recent workflow events | `copaper_workflow_log` | +| Update a workflow phase after confirmation | `copaper_workflow_set_phase` | +| Read checker run status and stale signals | `copaper_checker_status` | +| Record checker run summary after confirmation | `copaper_checker_record` | +| Read relatedwork catalog, PDF, summary, BibTeX, and cross-index status | `copaper_relatedwork_status` | Do not hand-edit: @@ -86,25 +86,25 @@ When a requested action needs one of those missing capabilities, state that no p ## Initialization Workflow -Use `vibepaper_dashboard` first to check whether initialization is needed. +Use `copaper_dashboard` first to check whether initialization is needed. If initialization is needed: 1. Ask for the project name and research domain. 2. Restate the initialization target, project name, and domain. 3. Wait for explicit confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`. +4. Call `copaper_init_apply` with `name` and `domain`. 5. Show the tool output to the user. -The tool call, not a prompt-only instruction, initializes the OpenCode-managed VibePaper core files and refuses conflicts. Do not manually create those core files when the plugin tool is available. +The tool call, not a prompt-only instruction, initializes the OpenCode-managed CoPaper core files and refuses conflicts. Do not manually create those core files when the plugin tool is available. The plugin initialization writes only the core files defined by the plugin, such as `paper.md`, `storyline.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, and `.agents/events.jsonl`. Do not claim it installs `.agents/skills/` unless the tool output says so. ## Status and Inspection -Use `vibepaper_workflow_status` for read-only inspection of workflow phase status, current phase, phase table, and next-step recommendation. Do not read `.agents/state.json` directly for phase state when this plugin tool is available. +Use `copaper_workflow_status` for read-only inspection of workflow phase status, current phase, phase table, and next-step recommendation. Do not read `.agents/state.json` directly for phase state when this plugin tool is available. -Use `vibepaper_workflow_log` for read-only inspection of `.agents/events.jsonl`. Do not read the event log file directly when this plugin tool is available. +Use `copaper_workflow_log` for read-only inspection of `.agents/events.jsonl`. Do not read the event log file directly when this plugin tool is available. Supported filters: @@ -112,19 +112,19 @@ Supported filters: - `phase` - `operator` -Use `vibepaper_artifact_status` for read-only inspection of artifact readiness, evidence, confidence, and recommendation. Do not manually infer readiness from files or `.agents/state.json` when this plugin tool is available. +Use `copaper_artifact_status` for read-only inspection of artifact readiness, evidence, confidence, and recommendation. Do not manually infer readiness from files or `.agents/state.json` when this plugin tool is available. It inspects artifacts such as `storyline.md`, `paper.md`, `relatedwork/`, `.agents/skills/`, `.agents/cross_index.json`, and checker results. -Use `vibepaper_checker_status` for read-only inspection of checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence. This tool does not run checkers, write checker results, mark issues resolved, update workflow phases, or record artifact readiness. +Use `copaper_checker_status` for read-only inspection of checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence. This tool does not run checkers, write checker results, mark issues resolved, update workflow phases, or record artifact readiness. -Use `vibepaper_checker_record` only after a checker has actually run and the user explicitly confirms the summary to persist. This tool writes the `checkers` area in `.agents/state.json` and appends a `record_checker_result` event to `.agents/events.jsonl`. It does not run checker skills, mark individual issues resolved, update workflow phases, or record artifact readiness. +Use `copaper_checker_record` only after a checker has actually run and the user explicitly confirms the summary to persist. This tool writes the `checkers` area in `.agents/state.json` and appends a `record_checker_result` event to `.agents/events.jsonl`. It does not run checker skills, mark individual issues resolved, update workflow phases, or record artifact readiness. -Use `vibepaper_relatedwork_status` for read-only inspection of relatedwork catalog, BibTeX, PDF files, paper summaries, search cache, queries, aggregate summary, and `.agents/cross_index.json`. This tool does not run `relatedwork search`, `import`, `sync-bib`, `download`, `summarize`, `register-summary`, or `build-index`; it also does not write `.agents/state.json` or append events. +Use `copaper_relatedwork_status` for read-only inspection of relatedwork catalog, BibTeX, PDF files, paper summaries, search cache, queries, aggregate summary, and `.agents/cross_index.json`. This tool does not run `relatedwork search`, `import`, `sync-bib`, `download`, `summarize`, `register-summary`, or `build-index`; it also does not write `.agents/state.json` or append events. ## Phase Control -Use `vibepaper_workflow_set_phase` when a phase should be explicitly marked as: +Use `copaper_workflow_set_phase` when a phase should be explicitly marked as: - `not_started` - `in_progress` @@ -140,7 +140,7 @@ Before calling the tool: Then call: ```text -vibepaper_workflow_set_phase({ +copaper_workflow_set_phase({ phase: "", status: "", reason: "" @@ -149,7 +149,7 @@ vibepaper_workflow_set_phase({ The tool call, not a prompt-only instruction, updates `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Valid phase names are project-defined and should come from `vibepaper_workflow_status`. Common defaults are: +Valid phase names are project-defined and should come from `copaper_workflow_status`. Common defaults are: - `storyline` - `literature` @@ -162,14 +162,14 @@ Do not use stage letters such as `A`, `B`, or `D`. ## Artifact Readiness -Use `vibepaper_artifact_status` for read-only readiness, evidence, confidence, and recommendation before deciding whether an artifact should be recorded. This tool does not modify files or workflow state. +Use `copaper_artifact_status` for read-only readiness, evidence, confidence, and recommendation before deciding whether an artifact should be recorded. This tool does not modify files or workflow state. When the user explicitly asks to record readiness: 1. Restate artifact, status, confidence, evidence, and reason. 2. Wait for explicit confirmation. -3. Route the confirmed record action to `@vibepaper-recorder`. -4. The recorder calls `vibepaper_artifact_record`. +3. Route the confirmed record action to `@copaper-recorder`. +4. The recorder calls `copaper_artifact_record`. The tool call, not a prompt-only instruction, writes the `artifacts` area in `.agents/state.json` and appends the readiness event to `.agents/events.jsonl`. It records artifact readiness only. It does not automatically advance phases. @@ -185,15 +185,15 @@ Use only plugin-supported record values: ## Checker Result Recording -Use `vibepaper_checker_status` first when you need to inspect existing checker freshness or counts. +Use `copaper_checker_status` first when you need to inspect existing checker freshness or counts. When the user explicitly asks to record a checker result: 1. Verify the result came from actual checker output, such as `markdown-review` or an individual checker skill. 2. Restate checker, status, Critical/Major/Minor counts, summary, evidence, issue list if provided, and reason. 3. Wait for explicit confirmation. -4. Route the confirmed record action to `@vibepaper-recorder`. -5. The recorder calls `vibepaper_checker_record`. +4. Route the confirmed record action to `@copaper-recorder`. +5. The recorder calls `copaper_checker_record`. Use only plugin-supported checker record values: @@ -209,15 +209,15 @@ Use only plugin-supported checker record values: ### Pattern 1: Dashboard -1. Call `vibepaper_dashboard`. -2. If ready, call `vibepaper_artifact_status` to inspect artifact readiness, evidence, confidence, and recommendation. -3. Then call `vibepaper_workflow_status`. -4. Optionally call `vibepaper_workflow_log`. +1. Call `copaper_dashboard`. +2. If ready, call `copaper_artifact_status` to inspect artifact readiness, evidence, confidence, and recommendation. +3. Then call `copaper_workflow_status`. +4. Optionally call `copaper_workflow_log`. ### Pattern 2: Safe Workflow Inspection -1. Call `vibepaper_workflow_status` to get the current phase, phase table, and next-step recommendation. -2. Call `vibepaper_workflow_log` with `lastN` or optional `phase`/`operator` filters to query `.agents/events.jsonl` read-only. +1. Call `copaper_workflow_status` to get the current phase, phase table, and next-step recommendation. +2. Call `copaper_workflow_log` with `lastN` or optional `phase`/`operator` filters to query `.agents/events.jsonl` read-only. 3. Decide the next action from the returned state. ### Pattern 3: Skip a Non-Applicable Phase @@ -225,18 +225,18 @@ Use only plugin-supported checker record values: 1. Confirm the phase is genuinely not needed. 2. Ask for or restate the skip reason. 3. Wait for confirmation. -4. Call `vibepaper_workflow_set_phase` with `status: "skipped"`. -5. Call `vibepaper_workflow_status` to verify the result. +4. Call `copaper_workflow_set_phase` with `status: "skipped"`. +5. Call `copaper_workflow_status` to verify the result. ## Must NOT Do - **NEVER** hand-edit `.agents/state.json` for actions covered by plugin tools. - **NEVER** append to `.agents/events.jsonl` for workflow phase changes covered by plugin tools. -- **NEVER** read `.agents/events.jsonl` directly for workflow history when `vibepaper_workflow_log` is available. +- **NEVER** read `.agents/events.jsonl` directly for workflow history when `copaper_workflow_log` is available. - **NEVER** update phases without explicit user confirmation. -- **NEVER** use shell `vibe` commands when an equivalent plugin tool exists. +- **NEVER** use shell `copaper` commands when an equivalent plugin tool exists. - **NEVER** claim unsupported plugin capabilities exist. -- **NEVER** read `.agents/state.json` directly just to infer checker status when `vibepaper_checker_status` is available. +- **NEVER** read `.agents/state.json` directly just to infer checker status when `copaper_checker_status` is available. ## End Condition diff --git a/.agents/skills/data-checker/SKILL.md b/.agents/skills/data-checker/SKILL.md index 31494e0..5a591b1 100644 --- a/.agents/skills/data-checker/SKILL.md +++ b/.agents/skills/data-checker/SKILL.md @@ -289,7 +289,7 @@ Generate comprehensive data authenticity assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. diff --git a/.agents/skills/evaluation-protocol-checker/SKILL.md b/.agents/skills/evaluation-protocol-checker/SKILL.md index cea6bc3..6da3ad2 100644 --- a/.agents/skills/evaluation-protocol-checker/SKILL.md +++ b/.agents/skills/evaluation-protocol-checker/SKILL.md @@ -318,7 +318,7 @@ Generate a comprehensive evaluation protocol assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. diff --git a/.agents/skills/experiment-analyzer/SKILL.md b/.agents/skills/experiment-analyzer/SKILL.md index 601f637..883633a 100644 --- a/.agents/skills/experiment-analyzer/SKILL.md +++ b/.agents/skills/experiment-analyzer/SKILL.md @@ -104,7 +104,7 @@ This mode is for users who already have experimental data and want to skip the e 1. **Confirm intent**: Ask the user to confirm they want to skip the experiment phase. Warn them that skipping means no code understanding, result analysis, or protocol review will be performed. 2. **Collect data path**: Ask the user for the path to their existing data file(s). These will be referenced in `paper.md` but not analyzed by this skill. -3. **Update workflow phase**: Restate the skip reason and wait for explicit user confirmation. Then call `vibepaper_workflow_set_phase` with `phase: "experiments"`, `status: "skipped"`, and the confirmed `reason`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. +3. **Update workflow phase**: Restate the skip reason and wait for explicit user confirmation. Then call `copaper_workflow_set_phase` with `phase: "experiments"`, `status: "skipped"`, and the confirmed `reason`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. 4. **Inform user**: Tell the user that the experiment phase has been marked as skipped. Suggest that they may still want to use Result Analysis mode later if they need help interpreting their data. ### Step 3: Update Workflow State @@ -113,7 +113,7 @@ After completing any mode (except Skip, which updates workflow state in Step 2d) 1. Restate the intended phase update to the user. 2. Wait for explicit confirmation. -3. Call `vibepaper_workflow_set_phase` with `phase: "experiments"` and `status: "complete"` after code/result/protocol analysis is complete; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. +3. Call `copaper_workflow_set_phase` with `phase: "experiments"` and `status: "complete"` after code/result/protocol analysis is complete; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. 4. Do not manually edit `.agents/state.json` when the plugin tool is available. 5. The current plugin does not expose a dedicated tool for storing experiment metadata such as `mode_used`, `last_updated`, or `data_files`; mention this limitation instead of writing those fields directly. @@ -123,7 +123,7 @@ After completing any mode (except Skip, which updates workflow state in Step 2d) |------|----------|-------------|---------| | `storyline.md` | **Required** | Step 2a/2b (mapping experiments to RQs) | Research narrative for mapping code/results to research questions | | `paper.md` | **Required** | Step 2a/2b (understanding evaluation needs) | Paper structure and evaluation section requirements | -| `.agents/state.json` | Tool-managed | Step 3 (end) and Step 2d (skip mode) | Update experiment phase via `vibepaper_workflow_set_phase`; do not edit directly | +| `.agents/state.json` | Tool-managed | Step 3 (end) and Step 2d (skip mode) | Update experiment phase via `copaper_workflow_set_phase`; do not edit directly | | User-provided experiment code path | Conditional | Step 2a (Code Understanding mode) | Directory of experiment code to analyze | | User-provided result file paths | Conditional | Step 2b (Result Analysis mode) | CSV/JSON/TXT/log files with experimental results | @@ -136,7 +136,7 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules - **NEVER** modify user code. Analysis is read-only; suggest changes but do not apply them. - **NEVER** fabricate or invent experimental results. Only report what exists in the data files. - **NEVER** skip the mode selection step. Always ask the user which mode they need first. -- **NEVER** bypass VibePaper structure constraints when suggesting content for `paper.md` (Level 6 title ≤50 chars, body ≤500 chars, do not modify Level 2-5 headers). +- **NEVER** bypass CoPaper structure constraints when suggesting content for `paper.md` (Level 6 title ≤50 chars, body ≤500 chars, do not modify Level 2-5 headers). - **NEVER** insert content into `paper.md` without the user explicitly reviewing and accepting it. - **NEVER** modify Level 1-5 headers in `paper.md`. Only suggest Level 6 content additions. @@ -145,6 +145,6 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules 1. **Read-only analysis**: This skill reads code and data but never modifies them. All suggestions are presented to the user for review. 2. **RQ alignment is critical**: Every analysis mode should cross-reference results or code with the stated research questions in `storyline.md` and `paper.md`. 3. **Protocol review delegates to evaluation-protocol-checker**: The Protocol Review mode does not duplicate the checker's logic. It invokes the checker and then discusses results with the user. -4. **State tracking**: Use `vibepaper_workflow_set_phase` after completing a mode to maintain workflow continuity. +4. **State tracking**: Use `copaper_workflow_set_phase` after completing a mode to maintain workflow continuity. 5. **Bilingual support**: Trigger words and user-facing prompts should accommodate both English and Chinese inputs. 6. **Data formats**: Result Analysis mode supports CSV, JSON, TXT, and common log file formats. If the user provides an unsupported format, ask them to convert it first. diff --git a/.agents/skills/humanizer/SKILL.md b/.agents/skills/humanizer/SKILL.md index 1dfd5e8..5d6b05b 100644 --- a/.agents/skills/humanizer/SKILL.md +++ b/.agents/skills/humanizer/SKILL.md @@ -475,7 +475,7 @@ Avoiding AI patterns is only half the job. Sterile, voiceless writing is just as ## Action Logging The current OpenCode plugin does not expose a generic `humanize_text` event logger or arbitrary tool-event writer. Do not append to `.agents/toolevents.jsonl` manually in plugin-based workflows. -If the user explicitly asks to record artifact readiness after humanization, restate the artifact, status, confidence, evidence, and reason, wait for confirmation, then route the record action to `@vibepaper-recorder` so it can call `vibepaper_artifact_record`. +If the user explicitly asks to record artifact readiness after humanization, restate the artifact, status, confidence, evidence, and reason, wait for confirmation, then route the record action to `@copaper-recorder` so it can call `copaper_artifact_record`. The recorder tool call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only readiness text. Otherwise, summarize the processed target and changes in the response. diff --git a/.agents/skills/latex-final-writer/SKILL.md b/.agents/skills/latex-final-writer/SKILL.md index 2467ca8..57aac99 100644 --- a/.agents/skills/latex-final-writer/SKILL.md +++ b/.agents/skills/latex-final-writer/SKILL.md @@ -21,13 +21,13 @@ Do not use this skill for converting an existing LaTeX paper back into `paper.md The LaTeX final draft must be a faithful, technically precise expansion of the already established research content. The agent may improve structure, wording, LaTeX formatting, and claim boundaries, but must not invent new experiments, numbers, citations, assumptions, or research claims. -## Required Inputs +## Input Files | File/Directory | Required | Purpose | |---|---:|---| | `paper.md` | Required | Canonical paper content and claim source. | | `storyline.md` | Strongly recommended | High-level problem, insight, design, and evaluation plan. | -| `writingrules.md` | Required | VibePaper structure and content constraints. | +| `writingrules.md` | Required | CoPaper structure and content constraints. | | `relatedwork/literature.json` | Conditional | Canonical related-work metadata. | | `relatedwork/papers/*.md` | Conditional | Paper summaries used to write Related Work accurately. | | `.agents/cross_index.json` | Conditional | Concept-to-literature map, if available. | diff --git a/.agents/skills/latex2markdown/SKILL.md b/.agents/skills/latex2markdown/SKILL.md index 3ec48b4..47e4f2e 100644 --- a/.agents/skills/latex2markdown/SKILL.md +++ b/.agents/skills/latex2markdown/SKILL.md @@ -1,21 +1,21 @@ --- name: latex2markdown -description: Extracts content from LaTeX files to fill in paper.md. Use this skill when the user wants to import content from existing LaTeX papers into the VibePaper structure. +description: Extracts content from LaTeX files to fill in paper.md. Use this skill when the user wants to import content from existing LaTeX papers into the CoPaper structure. --- # LaTeX to Markdown Conversion Skill -This skill extracts content from LaTeX academic papers and fills it into the VibePaper markdown structure. +This skill extracts content from LaTeX academic papers and fills it into the CoPaper markdown structure. ## When to Use This Skill - User requests to convert LaTeX to paper.md (e.g., "convert LaTeX to paper.md", "import my LaTeX paper") - User wants to extract content from existing LaTeX files to fill paper.md -- User needs to migrate LaTeX content to the VibePaper structure +- User needs to migrate LaTeX content to the CoPaper structure ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1-5** (`#` to `#####`): Structural headings only — do NOT modify these in `paper.md`. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. @@ -25,7 +25,7 @@ The paper follows VibePaper structure. Key rules for this skill: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `paper.md` | **Required** | Step 1 (start) | Target framework file whose existing structure guides the conversion | -| `writingrules.md` | **Required** | Step 1 (start) | Full structure and content constraints for mapping LaTeX content into VibePaper markdown | +| `writingrules.md` | **Required** | Step 1 (start) | Full structure and content constraints for mapping LaTeX content into CoPaper markdown | | User-provided LaTeX files | **Required** | Step 1 (start) | Source material to extract and map into `paper.md` | | `fig/` | Conditional | During special-element handling | Destination for user-provided figure assets referenced from the LaTeX source | diff --git a/.agents/skills/logic-checker/SKILL.md b/.agents/skills/logic-checker/SKILL.md index 646fbe5..bb678b0 100644 --- a/.agents/skills/logic-checker/SKILL.md +++ b/.agents/skills/logic-checker/SKILL.md @@ -5,7 +5,7 @@ description: Detects logical discrepancies and inconsistencies in academic paper # Logic Checker Skill -This skill detects logical discrepancies, inconsistencies, and argumentation flaws in academic paper drafts following the VibePaper structure. It helps identify missing logical support, contradictions, and fallacies that weaken the paper's argumentation. +This skill detects logical discrepancies, inconsistencies, and argumentation flaws in academic paper drafts following the CoPaper structure. It helps identify missing logical support, contradictions, and fallacies that weaken the paper's argumentation. ## When to Use This Skill @@ -186,7 +186,7 @@ For each discrepancy found: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. diff --git a/.agents/skills/mad-writer/SKILL.md b/.agents/skills/mad-writer/SKILL.md index ba8532f..21bcfad 100644 --- a/.agents/skills/mad-writer/SKILL.md +++ b/.agents/skills/mad-writer/SKILL.md @@ -38,7 +38,7 @@ This skill operates in a continuous loop: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -53,13 +53,13 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov | `paper.md` | **Required** | Phase 1 (initialization) and every rewrite iteration | Current paper content; scan for empty sections, assess state, write content | | `storyline.md` | Conditional | Phase 1 (if exists) | Research narrative for grounding content | | `relatedwork/summary.md` | Conditional | Phase 0-1 (if literature exists) | Context from related work for citations | -| Checker status | Conditional | Phase 3 (checker loop) | Use `vibepaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence | +| Checker status | Conditional | Phase 3 (checker loop) | Use `copaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence | | `.agents/state.json` | Tool gap / optional fallback | Phase 6 (progress tracking) | Read experiment context only when needed; the OpenCode plugin does not expose arbitrary progress metadata writes | When writing content, refer to the Paper Structure Reference above instead of reading `writingrules.md`. -For checker status summaries, call `vibepaper_checker_status`; do not read `.agents/state.json` directly just to infer checker run status when the plugin tool is available. -If the user wants durable checker summaries after an actual checker run, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason; wait for explicit confirmation; then route to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. -For phase-level workflow updates, use `vibepaper_workflow_set_phase` after restating the intended phase/status and waiting for explicit confirmation. The tool writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. Do not hand-edit `.agents/state.json` for checker results, progress counters, or experiment metadata in plugin-based workflows. +For checker status summaries, call `copaper_checker_status`; do not read `.agents/state.json` directly just to infer checker run status when the plugin tool is available. +If the user wants durable checker summaries after an actual checker run, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason; wait for explicit confirmation; then route to `@copaper-recorder` so it can call `copaper_checker_record`. +For phase-level workflow updates, use `copaper_workflow_set_phase` after restating the intended phase/status and waiting for explicit confirmation. The tool writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. Do not hand-edit `.agents/state.json` for checker results, progress counters, or experiment metadata in plugin-based workflows. ## Work Loop @@ -253,7 +253,7 @@ Aggregate feedback from all 7 checkers by severity: - **Minor issues**: Good to address - **Data issues**: Check if `⚠️ [BOGUS]` markers need replacement -After running the checker loop, call `vibepaper_checker_status` to inspect checker run status, severity counts, stale signals, and precheck evidence. Use the actual checker outputs for issue details; the status tool is a read-only summary and freshness check, not an issue-detail store. If the user confirms recording a run summary, use `vibepaper_checker_record` through `@vibepaper-recorder`; do not write checker state by hand. +After running the checker loop, call `copaper_checker_status` to inspect checker run status, severity counts, stale signals, and precheck evidence. Use the actual checker outputs for issue details; the status tool is a read-only summary and freshness check, not an issue-detail store. If the user confirms recording a run summary, use `copaper_checker_record` through `@copaper-recorder`; do not write checker state by hand. **Step 3.3: Filter Fixable Issues** @@ -520,7 +520,7 @@ To prevent infinite loops, the skill has these limits: ## Output Tracking -The skill maintains an in-session progress log in the response. The current OpenCode plugin can record confirmed checker run summaries through `vibepaper_checker_record`, but it has no generic progress-log tool. Do not write hidden progress data into `.agents/state.json` or `.agents/events.jsonl`. +The skill maintains an in-session progress log in the response. The current OpenCode plugin can record confirmed checker run summaries through `copaper_checker_record`, but it has no generic progress-log tool. Do not write hidden progress data into `.agents/state.json` or `.agents/events.jsonl`. ```markdown ` guide what each section should contain. diff --git a/.agents/skills/pdf2paper/SKILL.md b/.agents/skills/pdf2paper/SKILL.md index 7249f49..1699396 100644 --- a/.agents/skills/pdf2paper/SKILL.md +++ b/.agents/skills/pdf2paper/SKILL.md @@ -12,7 +12,7 @@ It is designed for cases where the PDF already contains most of the technical na - User asks to import an existing PDF draft into `paper.md` - User wants section-by-section conversion instead of one-shot rewrite -- User wants to preserve claims from PDF while adapting to VibePaper structure +- User wants to preserve claims from PDF while adapting to CoPaper structure Typical triggers: - `convert pdf to paper.md` @@ -24,7 +24,7 @@ Typical triggers: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1-5** (`#` to `#####`): Structural headings only — do NOT modify these in `paper.md`. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. @@ -33,9 +33,9 @@ The paper follows VibePaper structure. Key rules for this skill: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | Conditional | Step 1 and Step 8 | Target framework; inspect through `vibepaper_paper_structure_status` if present | -| `*.pdf` | **Required** | Step 2 | Source draft content; extract and validate through `vibepaper_pdf_extract` | -| `.agents/state.json` | Optional | Step 9 | Updated only through `vibepaper_workflow_set_phase` | +| `paper.md` | Conditional | Step 1 and Step 8 | Target framework; inspect through `copaper_paper_structure_status` if present | +| `*.pdf` | **Required** | Step 2 | Source draft content; extract and validate through `copaper_pdf_extract` | +| `.agents/state.json` | Optional | Step 9 | Updated only through `copaper_workflow_set_phase` | | `fig/` | Optional | Step 5 | Keep references to figure files mentioned in PDF | Preferred source example: @@ -61,12 +61,12 @@ Path safety rule: ## Supported Formats -- Text-based `pdf`: supported through `vibepaper_pdf_extract` -- Scanned/image-only `pdf`: not OCRed by this skill; if `vibepaper_pdf_extract` reports low confidence or little/no text, stop and ask the user for a text-based PDF or extracted text +- Text-based `pdf`: supported through `copaper_pdf_extract` +- Scanned/image-only `pdf`: not OCRed by this skill; if `copaper_pdf_extract` reports low confidence or little/no text, stop and ask the user for a text-based PDF or extracted text ## Extraction Strategy -Call `vibepaper_pdf_extract` for source extraction when the OpenCode plugin tool is available. +Call `copaper_pdf_extract` for source extraction when the OpenCode plugin tool is available. This tool is read-only and requires an explicit `.pdf` path. It validates path safety, file existence, supported extension, file size, and readable text operators. It does not scan directories, guess source files, write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -77,7 +77,7 @@ Use the tool output to capture: - extraction confidence - source hash for traceability -If the tool reports low confidence or no text operators, disclose that limitation to the user and ask for a better source. Do not replace `vibepaper_pdf_extract` with prompt-only extraction instructions, shell existence checks, shell `pdftotext`, OCR, or directory scans when the plugin tool is available. +If the tool reports low confidence or no text operators, disclose that limitation to the user and ask for a better source. Do not replace `copaper_pdf_extract` with prompt-only extraction instructions, shell existence checks, shell `pdftotext`, OCR, or directory scans when the plugin tool is available. ## Mapping Rules (PDF -> paper.md) @@ -102,14 +102,14 @@ If one PDF paragraph supports multiple destinations, split conservatively and ke - `请提供要转换的 PDF 文件路径(例如:target/example_project/draft.pdf)。` 3. Do not scan the filesystem for PDF candidates when the path is missing. 4. Wait for user-provided absolute or relative path. -5. Do not run a separate shell/file existence check for the `.pdf`; `vibepaper_pdf_extract` performs this validation in Step 2. -6. Check whether `paper.md` exists through `vibepaper_paper_structure_status` in Step 3: +5. Do not run a separate shell/file existence check for the `.pdf`; `copaper_pdf_extract` performs this validation in Step 2. +6. Check whether `paper.md` exists through `copaper_paper_structure_status` in Step 3: - if yes, continue normal mapping and in-place update flow - if no, continue conversion in draft mode and initialize project at Step 8 before final write ### Step 2: Extract PDF content -1. Call `vibepaper_pdf_extract` with the explicit user-provided `.pdf` path. +1. Call `copaper_pdf_extract` with the explicit user-provided `.pdf` path. 2. If the tool returns an error, stop and report the error; do not retry by scanning directories, running `pdftotext`, or doing OCR. 3. Use the returned text, page count, confidence, warnings, and source hash. 4. Build an intermediate traceable note with available page information. @@ -120,7 +120,7 @@ If one PDF paragraph supports multiple destinations, split conservatively and ke ### Step 3: Scan target framework -1. Call `vibepaper_paper_structure_status` to inspect `paper.md` structure and Level 5 writing targets. +1. Call `copaper_paper_structure_status` to inspect `paper.md` structure and Level 5 writing targets. 2. If the tool reports missing `paper.md`, keep accepted conversion content in draft mode and initialize project at Step 8 before final write. 3. If the tool reports an unsafe path or unreadable file, stop and report the tool error. 4. Use the embedded Paper Structure Reference above for structure constraints. @@ -177,12 +177,12 @@ If `paper.md` is missing: - project `domain` 2. Restate the project directory, project `name`, and project `domain`. 3. Wait for explicit user confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed VibePaper core files and refuses conflicts. +4. Call `copaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed CoPaper core files and refuses conflicts. 5. Then apply the accepted converted content into initialized `paper.md`. -Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `vibepaper_init_apply` is available. +Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `copaper_init_apply` is available. -If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `vibepaper_init_apply` can repair missing skills. Continue only if `paper.md` exists and the current skill instructions are available in the active agent context. +If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `copaper_init_apply` can repair missing skills. Continue only if `paper.md` exists and the current skill instructions are available in the active agent context. ### Step 9: Update workflow status @@ -190,9 +190,9 @@ After accepted edits: - If at least one writing section is filled, set `writing` phase to `in_progress`. - If all intended conversion sections are materially filled, set `writing` phase to `complete`. -Use `vibepaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. +Use `copaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. +Do not run `copaper set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. ## Output Requirements @@ -208,7 +208,7 @@ Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when t Each inserted paragraph should be: - faithful to PDF content -- structurally compliant with VibePaper rules +- structurally compliant with CoPaper rules - concise and readable - traceable to source pages @@ -218,7 +218,7 @@ Each inserted paragraph should be: - **NEVER** invent experiment numbers, datasets, or baselines - **NEVER** modify Level 1-5 structure in `paper.md` - **NEVER** rewrite the full paper in one blind pass -- **NEVER** pretend OCR was performed by this skill; disclose low-confidence or missing text from `vibepaper_pdf_extract` +- **NEVER** pretend OCR was performed by this skill; disclose low-confidence or missing text from `copaper_pdf_extract` - **NEVER** treat this as autonomous writing without user confirmation ## Recommended Default Invocation diff --git a/.agents/skills/phase-navigation/SKILL.md b/.agents/skills/phase-navigation/SKILL.md index 5286a11..f1a7db6 100644 --- a/.agents/skills/phase-navigation/SKILL.md +++ b/.agents/skills/phase-navigation/SKILL.md @@ -1,17 +1,17 @@ --- name: phase-navigation -description: Inspect the current VibePaper workflow phase, move forward, move backward, or jump to a named phase when the user asks to view, advance, return, roll back, or switch phases in OpenCode, then invoke the skill for the active phase. Uses `vibe status --json` and `vibe set-phase` instead of editing state files. +description: Inspect the current CoPaper workflow phase, move forward, move backward, or jump to a named phase when the user asks to view, advance, return, roll back, or switch phases in OpenCode, then invoke the skill for the active phase. Uses `copaper status --json` and `copaper set-phase` instead of editing state files. --- # Phase Navigation -This skill inspects and moves a VibePaper project between workflow phases through the `vibe` CLI. +This skill inspects and moves a CoPaper project between workflow phases through the `copaper` CLI. ## Input Files | File | Required | When Used | Purpose | |------|----------|-----------|---------| -| `.agents/state.json` | Required | Start | Read workflow state through `vibe status --json` | +| `.agents/state.json` | Required | Start | Read workflow state through `copaper status --json` | | `.agents/events.jsonl` | Optional | After phase change | CLI appends phase transition events | ## Triggers @@ -49,7 +49,7 @@ Accept clear aliases such as "latex", "review", "paper writing", or "related wor 1. Check current project status: ```bash -vibe --root . status --json +copaper --root . status --json ``` 2. If the user only asked to view or check the current phase, report `current_phase`, summarize the phase statuses briefly, and suggest the active phase's next work. Do not mutate state. @@ -57,7 +57,7 @@ vibe --root . status --json 3. If the user asked for the next phase, read `current_phase` and advance by marking the current phase complete: ```bash -vibe --root . set-phase --status complete +copaper --root . set-phase --status complete ``` The phase order is: @@ -73,9 +73,9 @@ storyline -> literature -> discussion -> experiments -> writing -> latex_review 6. To return to a previous phase, set the target phase to `in_progress`, then reset every later phase to `not_started`: ```bash -vibe --root . set-phase --status in_progress -vibe --root . set-phase --status not_started -vibe --root . set-phase --status not_started +copaper --root . set-phase --status in_progress +copaper --root . set-phase --status not_started +copaper --root . set-phase --status not_started ``` Run one `set-phase` command for each phase after the target. This preserves earlier completed work while making the returned phase the active workflow point. @@ -83,18 +83,18 @@ Run one `set-phase` command for each phase after the target. This preserves earl 7. If the user asked for a specific phase without rollback language, set that phase to `in_progress`: ```bash -vibe --root . set-phase --status in_progress +copaper --root . set-phase --status in_progress ``` 8. If the user asks to skip a phase, use: ```bash -vibe --root . skip --reason "" +copaper --root . skip --reason "" ``` If no reason is provided, ask for a short reason before skipping. -9. After any successful phase change, run `vibe --root . status --json` again and hand off to the active phase skill. Do not rely on OpenCode to auto-trigger another skill; explicitly open that skill's `SKILL.md` and continue its workflow. +9. After any successful phase change, run `copaper --root . status --json` again and hand off to the active phase skill. Do not rely on OpenCode to auto-trigger another skill; explicitly open that skill's `SKILL.md` and continue its workflow. ## Skill Invocation @@ -113,7 +113,7 @@ Important: skill chaining is manual. The agent must directly read the target `SK If the invoked skill needs missing inputs, ask only for the minimum information needed by that skill. For example, after entering `literature`, ask for topic constraints or seed papers only if they are not already available. -If the target skill file is missing, say which file is missing and fall back to `vibepaper-manage` only for workflow-state inspection. Do not stop silently. +If the target skill file is missing, say which file is missing and fall back to `copaper-manage` only for workflow-state inspection. Do not stop silently. ## Constraints @@ -125,5 +125,5 @@ If the target skill file is missing, say which file is missing and fall back to - Do not invent phase names outside the valid phase list. - If already at `latex_review` and the user asks for the next phase, explain that it is the final phase and show the current status. - If already at `storyline` and the user asks for the previous phase, explain that it is the first phase and show the current status. -- Do not use `vibe rollback` for phase navigation unless the user explicitly asks to restore a Git commit; this skill changes workflow phase state, not repository contents. -- If `vibe status --json` fails because the project is not initialized, use `auto-init` first. +- Do not use `copaper rollback` for phase navigation unless the user explicitly asks to restore a Git commit; this skill changes workflow phase state, not repository contents. +- If `copaper status --json` fails because the project is not initialized, use `auto-init` first. diff --git a/.agents/skills/ppt2storyline/SKILL.md b/.agents/skills/ppt2storyline/SKILL.md index 032cf75..a084e38 100644 --- a/.agents/skills/ppt2storyline/SKILL.md +++ b/.agents/skills/ppt2storyline/SKILL.md @@ -28,9 +28,9 @@ Typical triggers: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | Conditional | Step 1, Step 3, and Step 7 | Target template and section structure; inspect through `vibepaper_storyline_structure_status` | -| `*.pptx` | **Required** | Step 2 | Source research content; extract through `vibepaper_ppt_extract` | -| `.agents/state.json` | Optional | Step 8 | Updated only through `vibepaper_workflow_set_phase` | +| `storyline.md` | Conditional | Step 1, Step 3, and Step 7 | Target template and section structure; inspect through `copaper_storyline_structure_status` | +| `*.pptx` | **Required** | Step 2 | Source research content; extract through `copaper_ppt_extract` | +| `.agents/state.json` | Optional | Step 8 | Updated only through `copaper_workflow_set_phase` | | `relatedwork/` | Optional | Step 4 | Cross-check paper names/citations if needed | Preferred source example for this project: @@ -58,7 +58,7 @@ Path safety rule: ## Extraction Strategy -Call `vibepaper_ppt_extract` for source extraction when the OpenCode plugin tool is available. +Call `copaper_ppt_extract` for source extraction when the OpenCode plugin tool is available. This tool is read-only and requires an explicit `.pptx` path. It validates path safety, file existence, supported extension, file size, and readable slide content. It does not scan directories, guess source files, write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -69,9 +69,9 @@ Use the tool output to capture: - source hash for traceability - speaker notes only if explicitly requested through the tool argument -Do not replace `vibepaper_ppt_extract` with prompt-only extraction instructions, shell existence checks, shell unzip commands, `python-pptx`, or directory scans when the plugin tool is available. +Do not replace `copaper_ppt_extract` with prompt-only extraction instructions, shell existence checks, shell unzip commands, `python-pptx`, or directory scans when the plugin tool is available. -For target structure, call `vibepaper_storyline_structure_status`. This tool is read-only and reports whether `storyline.md` is present, safe, and structurally fillable. Do not manually infer storyline section readiness from prompt-only scans when the plugin tool is available. +For target structure, call `copaper_storyline_structure_status`. This tool is read-only and reports whether `storyline.md` is present, safe, and structurally fillable. Do not manually infer storyline section readiness from prompt-only scans when the plugin tool is available. ## Mapping Rules (Slide -> Storyline) @@ -98,15 +98,15 @@ If one slide supports multiple sections, split its points conservatively. - `请提供要转换的 PPTX 文件路径(例如:target/example_project/research_slides.pptx)。` 3. Do not scan the filesystem for PPT/PPTX candidates when the path is missing. 4. Wait for user-provided absolute or relative path. -5. Do not run a separate shell/file existence check for the `.pptx`; `vibepaper_ppt_extract` performs this validation in Step 2. -6. Call `vibepaper_storyline_structure_status` to check whether `storyline.md` exists and is structurally safe: +5. Do not run a separate shell/file existence check for the `.pptx`; `copaper_ppt_extract` performs this validation in Step 2. +6. Call `copaper_storyline_structure_status` to check whether `storyline.md` exists and is structurally safe: - if the tool succeeds, continue normal mapping and in-place update flow - if the tool reports missing `storyline.md`, continue conversion in draft mode and initialize project at Step 7 before final write - if the tool reports an unsafe path or unreadable file, stop and report the tool error ### Step 2: Extract slide text -1. Call `vibepaper_ppt_extract` with the explicit user-provided `.pptx` path. +1. Call `copaper_ppt_extract` with the explicit user-provided `.pptx` path. 2. If the tool returns an error, stop and report the error; do not retry by scanning directories or using shell/Python extraction. 3. Use the returned slides in order. 4. Build an intermediate note like: @@ -116,7 +116,7 @@ If one slide supports multiple sections, split its points conservatively. ### Step 3: Build section evidence map -1. Use the `vibepaper_storyline_structure_status` result from Step 1, or call it again if `storyline.md` was initialized or changed. +1. Use the `copaper_storyline_structure_status` result from Step 1, or call it again if `storyline.md` was initialized or changed. 2. Use the returned `sections`, `nextSection`, and `summary`; do not manually scan `storyline.md` to decide section readiness. 3. For each section, attach supporting slide snippets. 4. Mark section status: @@ -166,12 +166,12 @@ If `storyline.md` is missing: - project `domain` 2. Restate the project directory, project `name`, and project `domain`. 3. Wait for explicit user confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed VibePaper core files and refuses conflicts. +4. Call `copaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed CoPaper core files and refuses conflicts. 5. Then apply the accepted converted content into the initialized `storyline.md`. -Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `vibepaper_init_apply` is available. +Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `copaper_init_apply` is available. -If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `vibepaper_init_apply` can repair missing skills. Continue only if `storyline.md` exists and the current skill instructions are available in the active agent context. +If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `copaper_init_apply` can repair missing skills. Continue only if `storyline.md` exists and the current skill instructions are available in the active agent context. ### Step 8: Update workflow status @@ -179,9 +179,9 @@ After accepted edits: - If at least one storyline section is filled, set storyline phase to `in_progress`. - If all storyline sections are materially filled, set storyline phase to `complete`. -Use `vibepaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. +Use `copaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. +Do not run `copaper set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. ## Output Requirements diff --git a/.agents/skills/problem-checker/SKILL.md b/.agents/skills/problem-checker/SKILL.md index 016ac8e..577d5fd 100644 --- a/.agents/skills/problem-checker/SKILL.md +++ b/.agents/skills/problem-checker/SKILL.md @@ -361,7 +361,7 @@ Generate a comprehensive problem definition assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `` guide what each section should contain. diff --git a/.agents/skills/relatedwork-finder/SKILL.md b/.agents/skills/relatedwork-finder/SKILL.md index 6734f99..49131a7 100644 --- a/.agents/skills/relatedwork-finder/SKILL.md +++ b/.agents/skills/relatedwork-finder/SKILL.md @@ -5,7 +5,7 @@ description: Find the related work papers in the relatedwork folder based on sto # Related Work Finder Skill -This skill automatically finds related-work papers. Every substantive step (keyword extraction, Semantic Scholar search, BibTeX sync, PDF download) is delegated to a `vibe` CLI subcommand, so the skill never calls MCP search tools or spawns subagents. The skill's job is to orchestrate the CLI calls and interact with the user. +This skill automatically finds related-work papers. Every substantive step (keyword extraction, Semantic Scholar search, BibTeX sync, PDF download) is delegated to a `copaper` CLI subcommand, so the skill never calls MCP search tools or spawns subagents. The skill's job is to orchestrate the CLI calls and interact with the user. ## When to Use This Skill @@ -15,20 +15,20 @@ This skill automatically finds related-work papers. Every substantive step (keyw | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | Required if present | Step 1 (input to CLI) | Primary source for keyword extraction by `vibe relatedwork keywords` | +| `storyline.md` | Required if present | Step 1 (input to CLI) | Primary source for keyword extraction by `copaper relatedwork keywords` | | `paper.md` | Fallback | Step 1 (auto-fallback) | Used by the CLI when `storyline.md` is missing | -| `relatedwork/queries.txt` | Read/write | Steps 1-2 | One query per line; written by `vibe relatedwork keywords`, consumed by `vibe relatedwork search --queries-file` | -| `relatedwork/search_cache.json` | Read/write | Steps 2-3 | Cache for search metadata (paper_id, title, authors, year, venue, bibtex, arxiv_id, pdf_url, source_queries) — written by `vibe relatedwork search` | +| `relatedwork/queries.txt` | Read/write | Steps 1-2 | One query per line; written by `copaper relatedwork keywords`, consumed by `copaper relatedwork search --queries-file` | +| `relatedwork/search_cache.json` | Read/write | Steps 2-3 | Cache for search metadata (paper_id, title, authors, year, venue, bibtex, arxiv_id, pdf_url, source_queries) — written by `copaper relatedwork search` | | `relatedwork/paper_list.bib` | Required | Step 3 | BibTeX entries for formalizing the reference list | -| Relatedwork status | Optional | Steps 3-4 | Call `vibepaper_relatedwork_status` for read-only catalog, BibTeX, PDF, summary, and cross-index counts | -| `relatedwork/literature.json` | Required after managed import | Steps 2-6 (after import) | Canonical metadata catalog; inspect progress through `vibepaper_relatedwork_status` when the plugin tool is available | +| Relatedwork status | Optional | Steps 3-4 | Call `copaper_relatedwork_status` for read-only catalog, BibTeX, PDF, summary, and cross-index counts | +| `relatedwork/literature.json` | Required after managed import | Steps 2-6 (after import) | Canonical metadata catalog; inspect progress through `copaper_relatedwork_status` when the plugin tool is available | | `.agents/skills/relatedwork-finder/template.md` | Required | Step 5 | Template for PDF summary generation; passed to subagent | Do NOT read `writingrules.md` — this skill does not need paper structure rules. ## Search & Caching Strategy -1. **Single Backend (Semantic Scholar)**: All searches go through the `vibe relatedwork search` CLI, which queries the Semantic Scholar Graph API. S2's index covers arXiv preprints, major CS/AI venues (CVPR, NeurIPS, ICML, ACL, etc.), and most journals. Do NOT call `serper_google_search_scholar`, `websearch_web_search_exa`, or any other external search tool from this skill — the CLI is the single source of truth. +1. **Single Backend (Semantic Scholar)**: All searches go through the `copaper relatedwork search` CLI, which queries the Semantic Scholar Graph API. S2's index covers arXiv preprints, major CS/AI venues (CVPR, NeurIPS, ICML, ACL, etc.), and most journals. Do NOT call `serper_google_search_scholar`, `websearch_web_search_exa`, or any other external search tool from this skill — the CLI is the single source of truth. 2. **Stateful Cache**: The CLI writes `relatedwork/search_cache.json` (envelope: `{"papers": [...]}`) with one entry per deduplicated paper, including: - `paper_id` (extracted from S2's BibTeX key, or generated as ``) - `title`, `authors`, `year`, `venue` @@ -38,7 +38,7 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules - `source_queries` (which CLI `--query` arguments returned this paper) - `tldr` (S2 model-generated one-sentence summary, when present — useful for filtering) 3. **API Key (optional but recommended)**: Set `SEMANTIC_SCHOLAR_API_KEY` in the environment before running this skill to lift the shared anonymous rate limit (~100 req / 5 min) up to 1 req/sec. The CLI auto-detects the env var; without it the CLI still works but may hit 429s on busy days (it retries with exponential backoff up to 4 attempts). -4. **Canonical Catalog**: After `relatedwork/search_cache.json` is reviewed and trimmed by the user, you MUST import it into `relatedwork/literature.json` via `vibe --root . relatedwork import --input relatedwork/search_cache.json`. `relatedwork/literature.json` is the canonical metadata store used by BibTeX sync, downloads, and summary tracking. +4. **Canonical Catalog**: After `relatedwork/search_cache.json` is reviewed and trimmed by the user, you MUST import it into `relatedwork/literature.json` via `copaper --root . relatedwork import --input relatedwork/search_cache.json`. `relatedwork/literature.json` is the canonical metadata store used by BibTeX sync, downloads, and summary tracking. ## PDF Download @@ -49,14 +49,14 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules ## Action Logging Use OpenCode plugin tools for workflow/artifact events when available. The current plugin does not expose a generic tool-call event logger or relatedwork event writer; do not append logs manually in plugin-based workflows. -If the user asks to inspect workflow event history, call `vibepaper_workflow_log` for read-only querying of `.agents/events.jsonl` instead of reading the file directly. +If the user asks to inspect workflow event history, call `copaper_workflow_log` for read-only querying of `.agents/events.jsonl` instead of reading the file directly. ## Instructions (STRICT INTERACTIVE WORKFLOW) You MUST follow this step-by-step interactive workflow. **STOP and wait for user confirmation after each step marked with [WAIT FOR CONFIRMATION].** ### Step 1: Extract Keywords [WAIT FOR CONFIRMATION] -- Run `vibe --root . relatedwork keywords --count 8` (adjust `--count` if the storyline is unusually broad/narrow). The CLI reads `storyline.md` (falling back to `paper.md`), calls the configured LLM via `VIBEPAPER_MODEL`, and writes the queries one-per-line to `relatedwork/queries.txt`. +- Run `copaper --root . relatedwork keywords --count 8` (adjust `--count` if the storyline is unusually broad/narrow). The CLI reads `storyline.md` (falling back to `paper.md`), calls the configured LLM via `COPAPER_MODEL`, and writes the queries one-per-line to `relatedwork/queries.txt`. - Do NOT extract keywords yourself in this context. Do NOT call any MCP search tool. The CLI is the single source of truth. - After the CLI finishes, `cat relatedwork/queries.txt` and present the list to the user. - **STOP**: Ask "These are the queries the CLI extracted. Do you want to edit `relatedwork/queries.txt` (add/remove/replace lines) before I run the search?" @@ -66,7 +66,7 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Run the search CLI consuming the queries file from Step 1: ```bash - vibe --root . relatedwork search \ + copaper --root . relatedwork search \ --queries-file relatedwork/queries.txt \ --limit 20 \ --year 2022-2026 @@ -83,15 +83,15 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user ### Step 3: Formalize BibTeX List [WAIT FOR CONFIRMATION] - If the user dropped any entries, rewrite `relatedwork/search_cache.json` keeping only the selected papers (preserve the `{"papers": [...]}` envelope). -- Run `vibe --root . relatedwork import --input relatedwork/search_cache.json` to merge the kept entries into `relatedwork/literature.json`. -- If `paper_list.bib` already contains papers missing from `relatedwork/literature.json`, you MAY rerun `vibe --root . relatedwork search --query ""` to enrich them, then re-import. -- Run `vibe --root . relatedwork sync-bib` to write metadata-backed entries into `relatedwork/paper_list.bib` and to import any remaining bib-only entries into `relatedwork/literature.json`. -- Call `vibepaper_relatedwork_status` to inspect catalog and BibTeX counts. This tool is read-only; do not replace it with prompt-only status text or a manual `.agents/state.json` update. +- Run `copaper --root . relatedwork import --input relatedwork/search_cache.json` to merge the kept entries into `relatedwork/literature.json`. +- If `paper_list.bib` already contains papers missing from `relatedwork/literature.json`, you MAY rerun `copaper --root . relatedwork search --query "<title>"` to enrich them, then re-import. +- Run `copaper --root . relatedwork sync-bib` to write metadata-backed entries into `relatedwork/paper_list.bib` and to import any remaining bib-only entries into `relatedwork/literature.json`. +- Call `copaper_relatedwork_status` to inspect catalog and BibTeX counts. This tool is read-only; do not replace it with prompt-only status text or a manual `.agents/state.json` update. - **ACTION**: Show the final BibTeX entries and the relatedwork status summary to the user. - **STOP**: Ask "I have formalized the BibTeX entries in paper_list.bib. Should I proceed to download PDFs and write summaries?" ### Step 4: Download PDFs [WAIT FOR CONFIRMATION] - PDF download status must be recorded by a managed relatedwork operation. The current OpenCode plugin has no `relatedwork download` or retry tool; do not hand-write download results into JSON. Ask before using any CLI fallback. -- After the download command finishes, call `vibepaper_relatedwork_status` to inspect PDF download status, failures, and summary readiness. This tool is read-only and must not be used to fake download success. +- After the download command finishes, call `copaper_relatedwork_status` to inspect PDF download status, failures, and summary readiness. This tool is read-only and must not be used to fake download success. - **ACTION**: Present the status of downloaded PDFs to the user from the tool output. - **STOP AND TERMINATE**: This skill's responsibility strictly ENDS HERE. You MUST STOP execution. Ask the user: "I have finished finding the related work and downloading the PDFs. Would you like to continue and switch to the `relatedwork-summarizer` skill to generate summaries now?" diff --git a/.agents/skills/relatedwork-summarizer/SKILL.md b/.agents/skills/relatedwork-summarizer/SKILL.md index 5479acd..85ee001 100644 --- a/.agents/skills/relatedwork-summarizer/SKILL.md +++ b/.agents/skills/relatedwork-summarizer/SKILL.md @@ -5,7 +5,7 @@ description: Drive the relatedwork summarization CLI, build the literature cross # Related Work Summarizer Skill -This skill orchestrates per-paper summarization for downloaded PDFs by calling the `vibe relatedwork summarize` CLI, builds the literature cross-index via `vibe relatedwork build-index`, and produces a coverage report comparing summaries to `storyline.md`. The skill itself does not read PDFs, spawn subagents, or call MCP tools — all heavy lifting lives in the CLI. +This skill orchestrates per-paper summarization for downloaded PDFs by calling the `copaper relatedwork summarize` CLI, builds the literature cross-index via `copaper relatedwork build-index`, and produces a coverage report comparing summaries to `storyline.md`. The skill itself does not read PDFs, spawn subagents, or call MCP tools — all heavy lifting lives in the CLI. ## When to Use This Skill @@ -16,20 +16,20 @@ This skill orchestrates per-paper summarization for downloaded PDFs by calling t | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| Relatedwork status | Required | Steps 1, 2, 4 | Call `vibepaper_relatedwork_status` for read-only catalog, download, summary, BibTeX, and cross-index state | -| `relatedwork/literature.json` | Required | Steps 1, 4 | Canonical catalog used by the CLI; inspect queue state through `vibepaper_relatedwork_status` when available | +| Relatedwork status | Required | Steps 1, 2, 4 | Call `copaper_relatedwork_status` for read-only catalog, download, summary, BibTeX, and cross-index state | +| `relatedwork/literature.json` | Required | Steps 1, 4 | Canonical catalog used by the CLI; inspect queue state through `copaper_relatedwork_status` when available | | `storyline.md` | Required | Steps 2, 3 | Passed to the CLI as context for the "relation to our work" section, and used by the coverage report | | `.agents/skills/relatedwork-finder/template.md` | Required | Step 2 | Summary template; passed to the CLI | | `relatedwork/papers/<paper_id>.md` | Read/write | Steps 2-3 | Per-paper summary files written by the CLI | | `relatedwork/summary.md` | Read/write | Step 3 | Aggregated multi-paper summary (skill maintains this file) | -| `.agents/cross_index.json` | Read/write | Step 4 | Built by `vibe relatedwork build-index` | +| `.agents/cross_index.json` | Read/write | Step 4 | Built by `copaper relatedwork build-index` | ## Required Environment The summarization CLI uses an OpenAI-compatible LLM. Before running this skill, confirm the following are set (typically in `.env`): - `OPENAI_API_KEY` — required -- `VIBEPAPER_MODEL` — required (e.g. `gpt-4o-mini`) +- `COPAPER_MODEL` — required (e.g. `gpt-4o-mini`) - `OPENAI_BASE_URL` — optional, only if using a proxy endpoint If any of these are missing the CLI will fail loudly; do NOT try to summarize by reading the PDFs yourself. @@ -46,7 +46,7 @@ After invoking any tool, append a structured JSON log to `.agents/events.jsonl`. You MUST follow this step-by-step interactive workflow. **STOP and wait for user confirmation after each step marked with [WAIT FOR CONFIRMATION].** ### Step 1: Target Scope Parsing [WAIT FOR CONFIRMATION] -- Call `vibepaper_relatedwork_status` first. This tool is read-only and reports which papers are downloaded and which already have summaries; do not replace it with prompt-only status text or manual state inspection. +- Call `copaper_relatedwork_status` first. This tool is read-only and reports which papers are downloaded and which already have summaries; do not replace it with prompt-only status text or manual state inspection. - Check if the user requested a specific paper (by title or `paper_id`): - If yes: verify the paper exists in the tool output and its `downloadStatus` is `downloaded` with `pdfExists=true`. If not, REFUSE the request and explain why. The target queue contains ONLY this paper. - If no: the target queue contains every paper with `downloadStatus=downloaded`, `pdfExists=true`, and `summaryExists=false`. @@ -57,16 +57,16 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Run the summarize CLI. For the full queue: ```bash - vibe --root . relatedwork summarize + copaper --root . relatedwork summarize ``` For a single paper (when the user specified one in Step 1): ```bash - vibe --root . relatedwork summarize --paper-id <paper_id> + copaper --root . relatedwork summarize --paper-id <paper_id> ``` - Add `--force` if the user wants to re-summarize already-summarized papers. Other useful flags: `--qps 16` (default), `--concurrency 8` (default; worker threads), `--model <name>` (override `VIBEPAPER_MODEL`). + Add `--force` if the user wants to re-summarize already-summarized papers. Other useful flags: `--qps 16` (default), `--concurrency 8` (default; worker threads), `--model <name>` (override `COPAPER_MODEL`). - The CLI: 1. Extracts PDF text with `pypdf` 2. Sends `storyline.md` + the template + the PDF text to the configured LLM @@ -75,12 +75,12 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Do NOT spawn subagents. Do NOT use any `multimodal-looker` agent type. Do NOT read PDFs yourself. The CLI handles parallelism, rate limiting, and oversized-PDF failures internally. - After the CLI finishes, parse its stdout. For each `[ok]` line: open the new `relatedwork/papers/<paper_id>.md` and synthesize its key points (technical mechanism, methodology, empirical results, limitations) into `relatedwork/summary.md` under a `## <paper_id>: <Title>` heading. If a section for that `paper_id` already exists in `summary.md`, REPLACE it; otherwise APPEND it. - For each `[fail]` line, leave the paper alone. Surface the error to the user. -- Call `vibepaper_relatedwork_status` again to verify summary counts after the CLI updates `literature.json`. +- Call `copaper_relatedwork_status` again to verify summary counts after the CLI updates `literature.json`. - **ACTION**: Tell the user "Summarized X papers via the CLI (Y succeeded, Z failed). I have updated `relatedwork/summary.md` with the new sections." List any failures. - **STOP**: Ask "Should I proceed to build the cross-index and generate the coverage report?" ### Step 3: Build Cross-Index & Coverage Report [WAIT FOR CONFIRMATION] -- Run `vibe --root . relatedwork build-index`. The CLI scans `relatedwork/papers/*.md`, updates `.agents/cross_index.json`, and emits a coverage report (covered points, gaps, ratio) against `storyline.md`. +- Run `copaper --root . relatedwork build-index`. The CLI scans `relatedwork/papers/*.md`, updates `.agents/cross_index.json`, and emits a coverage report (covered points, gaps, ratio) against `storyline.md`. - Do NOT spawn task agents to "improve" the index in this skill — the CLI is authoritative. (If LLM-augmented technical-point extraction is added later it will be exposed as a `--use-llm` flag on the same CLI.) - **ACTION**: Present the coverage report verbatim: - Covered technical points (with paper references) @@ -91,6 +91,6 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user ### Step 4: Finalize Summary Document - Read `relatedwork/summary.md` end-to-end and reorganize entries into thematic groups if the user requested it (e.g., by method family, by problem setting). Otherwise leave the order unchanged. - Keep `relatedwork/literature.json` as the canonical metadata artifact. Do NOT delete it. -- Call `vibepaper_relatedwork_status` before the final response if you need to report final literature, summary, BibTeX, or cross-index counts. +- Call `copaper_relatedwork_status` before the final response if you need to report final literature, summary, BibTeX, or cross-index counts. - If `relatedwork/search_cache.json` is no longer needed, ask the user before removing it. - Respond with "I have finalized `relatedwork/summary.md`." diff --git a/.agents/skills/review-revise/SKILL.md b/.agents/skills/review-revise/SKILL.md index de96a3b..168d3e8 100644 --- a/.agents/skills/review-revise/SKILL.md +++ b/.agents/skills/review-revise/SKILL.md @@ -3,8 +3,8 @@ name: review-revise description: Conducts multi-round Review-Revise cycles based on 7-checker output to systematically improve paper quality. Each issue requires user confirmation before modification. Use this skill when the user wants to review and revise their paper. --- # Review-Revise Skill -This skill runs a controlled Review-Revise loop over checker findings. In plugin-based workflows, read-only checker status is available through `vibepaper_checker_status`, and confirmed checker run summaries can be recorded through `vibepaper_checker_record`; full issue-resolution writes are still a tool gap. -Use `@vibepaper-reviewer` when available to explain checker findings, severity, and likely reviewer concerns before any writing revision is proposed. The reviewer is read-only and must not edit `paper.md`. +This skill runs a controlled Review-Revise loop over checker findings. In plugin-based workflows, read-only checker status is available through `copaper_checker_status`, and confirmed checker run summaries can be recorded through `copaper_checker_record`; full issue-resolution writes are still a tool gap. +Use `@copaper-reviewer` when available to explain checker findings, severity, and likely reviewer concerns before any writing revision is proposed. The reviewer is read-only and must not edit `paper.md`. It is the repair layer after diagnosis: the seven checkers identify issues, then this skill helps the user process them in a severity-first order, propose fixes one issue at a time, and apply changes only after explicit confirmation. Its purpose is not to auto-rewrite the paper. Its purpose is to convert checker output into careful, auditable, multi-round improvement while keeping the user in control of every modification. @@ -41,7 +41,7 @@ Never process Minor issues ahead of unresolved Critical or Major issues unless t | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `paper.md` | **Required** | Step 1 (start) | Primary analysis target; read to understand current paper content | -| Checker status | Optional | Step 1 (start) | Call `vibepaper_checker_status` to inspect existing checker runs, severity counts, stale signals, and precheck evidence | +| Checker status | Optional | Step 1 (start) | Call `copaper_checker_status` to inspect existing checker runs, severity counts, stale signals, and precheck evidence | | `storyline.md` | Optional | Step 5b (when revising narrative/claim alignment) | Research narrative for grounding revisions | | `.agents/cross_index.json` | Optional but preferred | Step 5b (before reading relatedwork summaries) | Cross-reference index; consult FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current issue | | `relatedwork/papers/*.md` | Optional | Step 5b (only the summaries identified through cross-index) | Individual literature summaries; read ONLY the specific files identified through `.agents/cross_index.json` or when the issue clearly depends on prior work | @@ -51,10 +51,10 @@ If some files do not exist yet, continue with the available context instead of b ## Workflow ### Step 1: Read Paper and Checker State 1. Read `paper.md`. -2. Call `vibepaper_checker_status` to determine whether previous checker results exist and whether they are stale. +2. Call `copaper_checker_status` to determine whether previous checker results exist and whether they are stale. 3. Use the current `markdown-review` output as the authoritative source for issue details. The status tool gives summary and freshness, not full issue text. 4. Extract checker name, issue ID, severity, description, suggestion, status, and any checker-generated HTML comment text from the fresh review output when available. -5. If `@vibepaper-reviewer` is available, ask it to summarize and explain the issue set without editing files. +5. If `@copaper-reviewer` is available, ask it to summarize and explain the issue set without editing files. 6. Build a working list of unresolved issues. Goal: understand what the paper says now and what the seven checkers still consider problematic. If checker results are not available, do not fabricate them and do not create state entries manually. @@ -64,8 +64,8 @@ If checker results do not exist yet, or the `checkers` field is missing or empty 1. Invoke the `markdown-review` skill first. 2. Run all seven checkers in the standard order. 3. Use the returned checker report as the working issue queue. -4. Call `vibepaper_checker_status` after the review to inspect status/freshness if checker summaries or precheck evidence were produced. -5. If the user wants durable checker summaries, restate the actual checker output summary and route the confirmed record action to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. +4. Call `copaper_checker_status` after the review to inspect status/freshness if checker summaries or precheck evidence were produced. +5. If the user wants durable checker summaries, restate the actual checker output summary and route the confirmed record action to `@copaper-recorder` so it can call `copaper_checker_record`. Do not invent checker findings. This skill must be driven by actual checker output from state or from the immediately returned review report. @@ -145,7 +145,7 @@ If and only if the user confirms: 1. Apply the approved modification to `paper.md`. 2. Keep the change tightly scoped to the current issue. 3. Avoid unrelated edits. -4. Preserve the existing VibePaper structure and heading hierarchy. +4. Preserve the existing CoPaper structure and heading hierarchy. If the user asks for a modified suggestion first, revise the suggestion and ask again. Do not silently merge user intent into the paper without another confirmation point. @@ -181,7 +181,7 @@ Recommended tracked fields, if a future dedicated review-revise history tool exi - current round number - stopped_by (`user_satisfied`, `max_rounds`, `no_critical_or_major`, `user_stopped`) - optional review-revise history summary -Do not update `.agents/state.json` directly in plugin-based workflows. The current OpenCode plugin exposes `vibepaper_workflow_set_phase` for phase status, `vibepaper_artifact_record` for artifact readiness, and `vibepaper_checker_record` for confirmed checker run summaries. It does not expose checker issue-resolution or review-revise history persistence. +Do not update `.agents/state.json` directly in plugin-based workflows. The current OpenCode plugin exposes `copaper_workflow_set_phase` for phase status, `copaper_artifact_record` for artifact readiness, and `copaper_checker_record` for confirmed checker run summaries. It does not expose checker issue-resolution or review-revise history persistence. ## Safety Valves This skill must enforce all of the following: @@ -210,16 +210,16 @@ Required interaction pattern: ## Checker Integration Notes This skill depends on actual checker output, either from a fresh `markdown-review` run or from already persisted checker data. Current OpenCode plugin tool coverage: -- Supported: `vibepaper_workflow_status`, `vibepaper_workflow_log`, `vibepaper_workflow_set_phase`, `vibepaper_artifact_status`, `vibepaper_artifact_record` -- Supported for read-only checker summaries: `vibepaper_checker_status` -- Supported for confirmed checker run summaries: `vibepaper_checker_record` +- Supported: `copaper_workflow_status`, `copaper_workflow_log`, `copaper_workflow_set_phase`, `copaper_artifact_status`, `copaper_artifact_record` +- Supported for read-only checker summaries: `copaper_checker_status` +- Supported for confirmed checker run summaries: `copaper_checker_record` - Not supported: full `get_unresolved_issues()` with issue text, `mark_issue_resolved()`, review-revise history persistence When an unsupported operation is needed, state the tool gap instead of editing `.agents/state.json` manually. -Use `vibepaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. -If the user asks to record a checker result, route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_checker_record`; do not directly edit checker state or use prompt-only persistence text. -Use `vibepaper_artifact_status` for read-only artifact readiness, evidence, confidence, and recommendation; do not infer readiness manually when the plugin tool is available. -Use `vibepaper_workflow_log` for read-only workflow event history queries; do not read `.agents/events.jsonl` directly when the plugin tool is available. -If the user asks to record artifact readiness, route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_artifact_record`; do not directly edit artifact state or use prompt-only readiness text. +Use `copaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. +If the user asks to record a checker result, route the confirmed action to `@copaper-recorder` so it can call `copaper_checker_record`; do not directly edit checker state or use prompt-only persistence text. +Use `copaper_artifact_status` for read-only artifact readiness, evidence, confidence, and recommendation; do not infer readiness manually when the plugin tool is available. +Use `copaper_workflow_log` for read-only workflow event history queries; do not read `.agents/events.jsonl` directly when the plugin tool is available. +If the user asks to record artifact readiness, route the confirmed action to `@copaper-recorder` so it can call `copaper_artifact_record`; do not directly edit artifact state or use prompt-only readiness text. ## Must NOT Do - **NEVER** auto-apply modifications diff --git a/.agents/skills/socratic-discussion/SKILL.md b/.agents/skills/socratic-discussion/SKILL.md index 75445b7..99afd5e 100644 --- a/.agents/skills/socratic-discussion/SKILL.md +++ b/.agents/skills/socratic-discussion/SKILL.md @@ -3,7 +3,7 @@ name: socratic-discussion description: Conducts Socratic research discussions to help users critically examine their insights, methods, and claims. Integrates with 7 checker dimensions for targeted questioning. Use this skill when the user wants to discuss or analyze their research. --- # Socratic Discussion Skill -This is the core value skill in VibePaper. It helps researchers think more deeply about their own work through structured Socratic questioning instead of letting the system provide answers directly. It operates over the 57 discussion dimensions defined in `vibepaper/dimensions.py`, aligned with the 7 checker families used across the project. +This is the core value skill in CoPaper. It helps researchers think more deeply about their own work through structured Socratic questioning instead of letting the system provide answers directly. It operates over the 57 discussion dimensions defined in `copaper/dimensions.py`, aligned with the 7 checker families used across the project. Its purpose is not to draft faster. Its purpose is to improve judgment: clearer problem definition, better novelty boundaries, stronger technical depth, tighter logic, clearer expression, sounder evaluation design, and more trustworthy evidence. ## When to Use This Skill @@ -46,7 +46,7 @@ Do not reorder the sequence unless the user explicitly asks to jump. ## Core Discussion Principles - Ask one main question at a time. - Discuss exactly one dimension at a time. -- Prefer the predefined question bank in `vibepaper/dimensions.py`. +- Prefer the predefined question bank in `copaper/dimensions.py`. - If checker issues exist, use them to sharpen the first question. - If the user's answer is weak, ask a narrower follow-up instead of changing dimensions. - Never fabricate evidence, references, experiments, or prior work. @@ -58,11 +58,11 @@ Do not reorder the sequence unless the user explicitly asks to jump. |------|----------|-------------|---------| | `storyline.md` | **Required** | Step 1 (start) | Research narrative, insight, method outline | | `paper.md` | **Required** | Step 1 (start) | Current paper state and claim wording | -| Checker status | Optional | Step 2 (if checker-driven discussion) | Use `vibepaper_checker_status` for read-only checker family status, severity counts, stale signals, and precheck evidence | +| Checker status | Optional | Step 2 (if checker-driven discussion) | Use `copaper_checker_status` for read-only checker family status, severity counts, stale signals, and precheck evidence | | `relatedwork/papers/*.md` | Optional | Step 1 (as needed) | Prior-work summaries for contrast questions | | `.agents/cross_index.json` | Optional | Step 1 (as needed) | Paper-technique mappings for targeted questioning | | `.agents/discussion_log.json` | Optional | Step 3 (to find covered dimensions) | Prior discussion history | -| `vibepaper/dimensions.py` | **Required** | Step 1 (start) | 57 dimensions and question bank | +| `copaper/dimensions.py` | **Required** | Step 1 (start) | 57 dimensions and question bank | If some files do not exist yet, continue with the available context instead of blocking the workflow. @@ -72,12 +72,12 @@ If some files do not exist yet, continue with the available context instead of b 2. Read `paper.md`. 3. Read relevant summaries from `relatedwork/papers/`. 4. Read `.agents/cross_index.json` if available. -5. Read `vibepaper/dimensions.py`. +5. Read `copaper/dimensions.py`. Goal: understand the user's problem, insight, method, and evidence situation before asking questions. ### Step 2: Integrate Checker Results -1. Call `vibepaper_workflow_status` if workflow phase status, current phase, phase table, or next-step recommendation is needed. -2. Call `vibepaper_checker_status` to detect which of the 7 checker families have run, whether results are stale, and the Critical/Major/Minor counts. +1. Call `copaper_workflow_status` if workflow phase status, current phase, phase table, or next-step recommendation is needed. +2. Call `copaper_checker_status` to detect which of the 7 checker families have run, whether results are stale, and the Critical/Major/Minor counts. 3. Use the tool output to prioritize checker families with stale or non-clean statuses. 4. If detailed issue text is needed and is not present in the current conversation, ask the user to run or provide `markdown-review`; do not read `.agents/state.json` directly just to infer checker status. 5. Map available unresolved issues to dimensions using `checker_name` and issue meaning. @@ -92,7 +92,7 @@ If checker results exist, explicitly tell the user that checker-flagged dimensio 5. Sort uncovered dimensions in this order: - checker-flagged dimensions first - then by checker family - - then by registry order in `vibepaper/dimensions.py` + - then by registry order in `copaper/dimensions.py` ### Step 4: Present a Dimension Menu Present the uncovered dimensions grouped by checker family. @@ -117,7 +117,7 @@ For the selected dimension: 2. Reset the per-dimension round counter. 3. Load the five question types in order. 4. Start with Clarification. -5. Use the predefined question text from `vibepaper/dimensions.py` when available. +5. Use the predefined question text from `copaper/dimensions.py` when available. 6. If this dimension has checker issues, incorporate the issue wording into the first question. ### Step 6: Delegate Deep Question Preparation @@ -193,7 +193,7 @@ Write the result to `.agents/discussion_log.json`. If the file does not exist, create it. Preserve old records and append new session entries. ### Step 13: Workflow State -Use `vibepaper_workflow_set_phase` only for phase-level updates such as marking `discussion` as `in_progress` or `complete`, and only after explicit user confirmation. +Use `copaper_workflow_set_phase` only for phase-level updates such as marking `discussion` as `in_progress` or `complete`, and only after explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`; do not substitute a prompt-only note or manual file edit. The current OpenCode plugin does not expose a dedicated tool for discussion metadata or checker issue resolution status. Do not manually edit `.agents/state.json` for those fields in plugin-based workflows; report the limitation instead. @@ -288,7 +288,7 @@ Required summary fields: `key_points`, `strengths`, `weaknesses`, `open_question - **NEVER** erase prior history from `.agents/discussion_log.json` ## Important Notes -1. This skill is the core value of VibePaper because it improves thinking, not just writing speed. +1. This skill is the core value of CoPaper because it improves thinking, not just writing speed. 2. The checkers provide the issue map; this skill provides the interactive reasoning layer. 3. Checker integration is optional, but much more powerful when checker results exist. 4. Every completed dimension should leave behind a reusable summary and concrete suggestions. diff --git a/.agents/skills/state-machine-markdown-helper/SKILL.md b/.agents/skills/state-machine-markdown-helper/SKILL.md index 5cb8152..6f6f60c 100644 --- a/.agents/skills/state-machine-markdown-helper/SKILL.md +++ b/.agents/skills/state-machine-markdown-helper/SKILL.md @@ -5,7 +5,7 @@ description: Helps users write and improve markdown academic paper content using # State Machine Markdown Helper Skill -This skill helps users write markdown content for computer science research papers following the VibePaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. +This skill helps users write markdown content for computer science research papers following the CoPaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. ## When to Use This Skill @@ -15,7 +15,7 @@ This skill helps users write markdown content for computer science research pape ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -27,11 +27,11 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `vibepaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | +| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `copaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | | `storyline.md` | **Required** | State 0 (outline) and State 2 (subagent prompt) | Core research narrative, insights, and method for grounding | | `.agents/cross_index.json` | Optional but preferred | State 1 (before reading relatedwork summaries) | Cross-reference index; consult FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current section | | `relatedwork/papers/*.md` | Optional | State 1 (only the summaries identified via cross-index) | Individual literature summaries; read ONLY the specific files identified through `.agents/cross_index.json` lookup | -| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `vibepaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | +| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `copaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | | `fig/` | Conditional | State 2 (when writing sections that reference visuals) | Available figures; list paths so the subagent can reference them | When the orchestrator needs literature context in State 1, it MUST: @@ -53,17 +53,17 @@ You must explicitly announce your current state to the user in every message (e. 4. **STOP AND WAIT**. Once approved, continue to State 1. ### State 1: Context & Literature Gathering (READ) -1. Call `vibepaper_paper_structure_status` to locate the next incomplete Level 5 writing target. Use the tool's `nextTarget`, `level5Targets`, `summary`, and `violations` instead of manually scanning `paper.md`. +1. Call `copaper_paper_structure_status` to locate the next incomplete Level 5 writing target. Use the tool's `nextTarget`, `level5Targets`, `summary`, and `violations` instead of manually scanning `paper.md`. 2. **Retrieve RAG Data:** - Search `.agents/cross_index.json` first to identify papers relevant to this section's technical points. - Read snippets from `relatedwork/summary.md`. - If deeper details are needed, use `read_file` on the specific `.md` files in `relatedwork/papers/`. - - If writing experiments, call `vibepaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool. + - If writing experiments, call `copaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool. 3. **Output Fact Sheet:** Generate a strictly formatted "**Fact & Citation Sheet**" containing the core claims to be written and their exact citation tags (e.g., `[@author2024]`). 4. **Announce and Ask**: Show the target section and Fact Sheet to the user. Ask: *"Target section: **[Level 5 Title]**. Shall I launch the writing subagent using this Fact Sheet?"* 5. **STOP AND WAIT** for confirmation. Don't proceed. -`vibepaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. +`copaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. ### State 2: Fresh Subagent Drafting (WRITE) 1. Once confirmed, launch an independent subagent (`runSubagent` or `task`). **CRITICAL: Ensure it operates in a fresh context.** Do not pass your entire chat history. @@ -94,10 +94,10 @@ You must explicitly announce your current state to the user in every message (e. ## Action Logging -Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `vibepaper_workflow_set_phase` and `vibepaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. +Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `copaper_workflow_set_phase` and `copaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. Do not append to `.agents/events.jsonl` manually when using the plugin-based workflow. Report this limitation if the user asks for paragraph-level event logging. -If the user asks to inspect workflow event history, call `vibepaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. +If the user asks to inspect workflow event history, call `copaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. ## Crucial Anti-Patterns - **NEVER** write multiple paragraphs at once without user interactive review. diff --git a/.agents/skills/storyline-helper/SKILL.md b/.agents/skills/storyline-helper/SKILL.md index 2d61772..0f3aed5 100644 --- a/.agents/skills/storyline-helper/SKILL.md +++ b/.agents/skills/storyline-helper/SKILL.md @@ -18,9 +18,9 @@ This skill guides users through constructing their research storyline in `storyl | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | **Required** | Step 1 (structure status) | Primary target file; inspect through `vibepaper_storyline_structure_status` for empty/partial/filled sections | +| `storyline.md` | **Required** | Step 1 (structure status) | Primary target file; inspect through `copaper_storyline_structure_status` for empty/partial/filled sections | | `paper.md` | Conditional | Reverse-extraction mode only | Source for reverse-extracting storyline content when `storyline.md` is sparse | -| `.agents/state.json` | Tool-managed | Step 5 (after applying edits) | Update storyline phase through `vibepaper_workflow_set_phase`; do not edit the file directly | +| `.agents/state.json` | Tool-managed | Step 5 (after applying edits) | Update storyline phase through `copaper_workflow_set_phase`; do not edit the file directly | Do NOT read `writingrules.md` — this skill works with the existing `storyline.md` structure directly. @@ -53,7 +53,7 @@ Do NOT read `writingrules.md` — this skill works with the existing `storyline. ## Section Detection Logic -Use `vibepaper_storyline_structure_status` for section readiness whenever the plugin tool is available. The tool is read-only and validates that `storyline.md` is present, safe, and structurally readable. It does not write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. +Use `copaper_storyline_structure_status` for section readiness whenever the plugin tool is available. The tool is read-only and validates that `storyline.md` is present, safe, and structurally readable. It does not write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. The tool classifies sections using this logic: @@ -64,16 +64,16 @@ A section is considered **empty** if, after its `#####` header line, the content A section is considered **filled** if it contains substantive content beyond TODO placeholders and instructional text. -Do not replace `vibepaper_storyline_structure_status` with prompt-only section scans, shell existence checks, shell parsing, or manual completion inference when the plugin tool is available. +Do not replace `copaper_storyline_structure_status` with prompt-only section scans, shell existence checks, shell parsing, or manual completion inference when the plugin tool is available. ## State Management This skill updates workflow progress through the OpenCode plugin tool: -- When the first section is filled: call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"`. -- When all sections are filled: call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "complete"`. +- When the first section is filled: call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"`. +- When all sections are filled: call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "complete"`. - Before calling the tool, restate the phase/status update and wait for explicit user confirmation. - The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -- Do not call `vibe set-phase`, use `StateManager.set_phase_status`, or manually edit `.agents/state.json` when the plugin tool is available. +- Do not call `copaper set-phase`, use `StateManager.set_phase_status`, or manually edit `.agents/state.json` when the plugin tool is available. ## Reverse Extraction Mode (`paper.md` → `storyline.md`) @@ -102,7 +102,7 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N ### Step 1: Scan & Present (WAIT FOR USER) -1. Call `vibepaper_storyline_structure_status`. +1. Call `copaper_storyline_structure_status`. 2. If the tool reports missing, unsafe, or unreadable `storyline.md`, stop and report the tool error instead of manually scanning files. 3. Use the returned `sections`, `nextSection`, and `summary` to identify empty, partial, and filled storyline sections. 4. Compile a list of empty or partial sections with their section numbers and titles. @@ -148,9 +148,9 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N ### Step 5: Apply or Iterate - If **Accept**: The Orchestrator uses the `Edit` tool to replace the section content in `storyline.md` under the correct `#####` header. Then: - 1. Call `vibepaper_storyline_structure_status` again to check whether all sections are now filled. + 1. Call `copaper_storyline_structure_status` again to check whether all sections are now filled. 2. Restate the intended workflow update and wait for user confirmation. - 3. Call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"` if any section is filled, or `status: "complete"` if all sections are filled. + 3. Call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"` if any section is filled, or `status: "complete"` if all sections are filled. 4. Treat the tool output as the audit record because it writes state and appends the workflow event. 5. Ask the user: *"Section **[Section Title]** has been filled. Would you like to continue with the next empty section?"* If yes, loop back to Step 2 with the next empty section. - If **Modify/Rewrite**: Launch the subagent again (use `session_id` to continue its context), passing the user's feedback. Repeat Step 4. diff --git a/.agents/skills/submission-precheck/SKILL.md b/.agents/skills/submission-precheck/SKILL.md index 7125f79..0a266c6 100644 --- a/.agents/skills/submission-precheck/SKILL.md +++ b/.agents/skills/submission-precheck/SKILL.md @@ -23,7 +23,7 @@ This skill performs a comprehensive pre-submission check on `paper.md` before su | `writingrules.md` | **Required** | Step 1 (start) | Format constraints and structural rules; needed for Check 1 (Format) and Check 5 (Completeness) | | `relatedwork/paper_list.bib` | Conditional | Step 2 (Citation Check) | BibTeX references; needed for Check 2 (Citations) | | `fig/` | Conditional | Step 2 (Figure/Table Check) | Figure assets directory; needed for Check 3 (Figures/Tables) | -| Checker status | Conditional | Step 4 and Step 6 | Use `vibepaper_checker_status` for read-only checker summary, stale signals, and precheck evidence | +| Checker status | Conditional | Step 4 and Step 6 | Use `copaper_checker_status` for read-only checker summary, stale signals, and precheck evidence | | `.agents/state.json` | Conditional | Step 1 (start) | Project state for fields not exposed by plugin tools, such as `latex_template` config for Check 4 | | `.agents/cross_index.json` | Conditional | Step 1 (start) | Cross-reference index; used for completeness verification | @@ -33,7 +33,7 @@ If some files do not exist (e.g., `paper_list.bib`, `.agents/cross_index.json`), ### Check 1: Format Check (格式检查) -Verify that `paper.md` conforms to VibePaper structural rules defined in `writingrules.md`. +Verify that `paper.md` conforms to CoPaper structural rules defined in `writingrules.md`. **Sub-checks:** @@ -201,8 +201,8 @@ Invoke the `markdown-review` skill. Collect the comprehensive review report and - Number of Major issues - Number of Minor issues - Overall assessment -Then call `vibepaper_checker_status` to read any persisted checker summary, stale signal, and precheck evidence. Use this tool for status/freshness; do not read `.agents/state.json` directly just to infer checker status. -If the user asks to persist the precheck checker summaries, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason for each actual checker result; wait for explicit confirmation; then route to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. +Then call `copaper_checker_status` to read any persisted checker summary, stale signal, and precheck evidence. Use this tool for status/freshness; do not read `.agents/state.json` directly just to infer checker status. +If the user asks to persist the precheck checker summaries, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason for each actual checker result; wait for explicit confirmation; then route to `@copaper-recorder` so it can call `copaper_checker_record`. ### Step 5: Generate Precheck Report @@ -211,7 +211,7 @@ Compile all findings into `.agents/precheck_report.md` following the output form ### Step 6: Present Summary to User Display a concise summary of the precheck results. Highlight any FAIL items that block submission. Provide actionable recommendations. -Call `vibepaper_checker_status` before presenting the final summary if you need to mention checker freshness or compare the precheck report against `paper.md`. +Call `copaper_checker_status` before presenting the final summary if you need to mention checker freshness or compare the precheck report against `paper.md`. ## Output Format @@ -374,7 +374,7 @@ Based on the 7 checks above: - **NEVER** modify `paper.md`, `writingrules.md`, `paper_list.bib`, or any other source file - **NEVER** skip any of the 7 checks — all checks must be performed regardless of earlier results - **NEVER** fabricate checker results — always invoke the actual `data-checker` and `markdown-review` skills for Checks 6 and 7 -- **NEVER** read `.agents/state.json` directly just to summarize checker run status when `vibepaper_checker_status` is available +- **NEVER** read `.agents/state.json` directly just to summarize checker run status when `copaper_checker_status` is available - **NEVER** delete or overwrite an existing `.agents/precheck_report.md` without preserving its content — append a timestamp or version if needed ## Important Notes diff --git a/.agents/skills/technical-depth-checker/SKILL.md b/.agents/skills/technical-depth-checker/SKILL.md index dbee846..ae154fc 100644 --- a/.agents/skills/technical-depth-checker/SKILL.md +++ b/.agents/skills/technical-depth-checker/SKILL.md @@ -298,7 +298,7 @@ Generate a comprehensive technical depth assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/.agents/skills/template-latex-export/SKILL.md b/.agents/skills/template-latex-export/SKILL.md index 374797e..ba19a8b 100644 --- a/.agents/skills/template-latex-export/SKILL.md +++ b/.agents/skills/template-latex-export/SKILL.md @@ -1,6 +1,6 @@ --- name: template-latex-export -description: Convert `paper.md` into a final LaTeX paper project using a user-provided conference or journal template placed under `templates/latex/`. Use when the user asks to generate the final LaTeX paper from the VibePaper markdown draft with a local template. +description: Convert `paper.md` into a final LaTeX paper project using a user-provided conference or journal template placed under `templates/latex/`. Use when the user asks to generate the final LaTeX paper from the CoPaper markdown draft with a local template. --- # Template LaTeX Export @@ -11,8 +11,8 @@ This skill converts `paper.md` into a final LaTeX paper using a template that th | File | Required | When Used | Purpose | |------|----------|-----------|---------| -| `paper.md` | Required | Start | Source VibePaper draft to convert | -| `writingrules.md` | Required | Start | Interpret VibePaper heading and paragraph structure | +| `paper.md` | Required | Start | Source CoPaper draft to convert | +| `writingrules.md` | Required | Start | Interpret CoPaper heading and paragraph structure | | `templates/latex/` | Required | Start | User-provided LaTeX template directory | | `relatedwork/paper_list.bib` | Optional | Bibliography step | BibTeX entries to copy or reference | | `fig/` | Optional | Asset step | Figures referenced by the paper | diff --git a/.agents/skills/writing-orchestrator/SKILL.md b/.agents/skills/writing-orchestrator/SKILL.md index ad1ee31..51faf02 100644 --- a/.agents/skills/writing-orchestrator/SKILL.md +++ b/.agents/skills/writing-orchestrator/SKILL.md @@ -5,7 +5,7 @@ description: Orchestrates structured paper framework writing by scanning paper.m # Writing-Orchestrator Skill -This skill is the human-led writing coordinator for VibePaper. +This skill is the human-led writing coordinator for CoPaper. It inspects `paper.md`, shows what is complete or still empty, recommends the next section based on logical dependency, and routes the user to `markdown-helper`, `state-machine-markdown-helper`, or `mad-writer` while treating `markdown-review` as the mandatory review gate. ## When to Use This Skill @@ -32,10 +32,10 @@ This skill is an orchestrator, not a direct replacement for drafting or revision | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | **Required** | Step 1 (structure status) | Primary target; inspect through `vibepaper_paper_structure_status` for Level 2-5 completion and Level 5 writing targets | +| `paper.md` | **Required** | Step 1 (structure status) | Primary target; inspect through `copaper_paper_structure_status` for Level 2-5 completion and Level 5 writing targets | | `storyline.md` | Conditional | When recommending writing order | Research narrative for dependency-aware section ordering | -| Checker status | Conditional | Step 6 and Step 7 | Use `vibepaper_checker_status` for read-only checker run status, stale signals, and severity counts | -| `.agents/state.json` | Conditional | Step 8 (progress tracking) | Workflow phase status via `vibepaper_workflow_set_phase`; arbitrary writing metadata only if a dedicated tool exists | +| Checker status | Conditional | Step 6 and Step 7 | Use `copaper_checker_status` for read-only checker run status, stale signals, and severity counts | +| `.agents/state.json` | Conditional | Step 8 (progress tracking) | Workflow phase status via `copaper_workflow_set_phase`; arbitrary writing metadata only if a dedicated tool exists | | `.agents/cross_index.json` | Conditional | When routing to markdown-helper or mad-writer | Paper-technique mappings; pass to downstream skills for literature context | | `relatedwork/papers/*.md` | Conditional | When routing to markdown-helper or mad-writer | Individual literature summaries; pass to downstream skills, not read directly by orchestrator | | `fig/` | Conditional | When routing to markdown-helper or mad-writer | Available figures; pass to downstream skills for visual references | @@ -46,7 +46,7 @@ If some sources are missing, continue with available context and state what is m ## Completion Scan Rules -The orchestrator must call `vibepaper_paper_structure_status` to inspect `paper.md` completion instead of manually scanning headings when the plugin tool is available. +The orchestrator must call `copaper_paper_structure_status` to inspect `paper.md` completion instead of manually scanning headings when the plugin tool is available. This tool is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -63,9 +63,9 @@ Reporting refinement: ## Workflow -### Step 1: Call `vibepaper_paper_structure_status` +### Step 1: Call `copaper_paper_structure_status` -1. Call `vibepaper_paper_structure_status`. +1. Call `copaper_paper_structure_status`. 2. Use the returned `headings`, `level5Targets`, `nextTarget`, `summary`, and `violations`. 3. If the tool reports missing or invalid `paper.md`, stop and tell the user the framework file is required first. 4. Do not reproduce this scan manually, shell out to parse markdown, or infer completion from ad hoc file reads when the plugin tool is available. @@ -158,7 +158,7 @@ Requirements: After the selected section is complete, automatically invoke `markdown-review`. This review is mandatory after every completed section. -When `@vibepaper-reviewer` is available, route checker-result summarization and issue explanation to that read-only subagent. It must not edit `paper.md`; writing fixes still go through the normal confirmed writing/revision path. +When `@copaper-reviewer` is available, route checker-result summarization and issue explanation to that read-only subagent. It must not edit `paper.md`; writing fixes still go through the normal confirmed writing/revision path. The required checker order is: 1. `problem-checker` @@ -174,23 +174,23 @@ Never skip this review stage. ### Step 6: Show seven-checker results and suggest revision path After review: -1. call `vibepaper_checker_status` to read the current checker status, severity counts, stale signals, and precheck evidence -2. use `@vibepaper-reviewer` when available to produce a compact seven-checker summary from the review output plus the tool status +1. call `copaper_checker_status` to read the current checker status, severity counts, stale signals, and precheck evidence +2. use `@copaper-reviewer` when available to produce a compact seven-checker summary from the review output plus the tool status 3. separate Critical, Major, and Minor issues 4. explain which issues matter most for the finished section -5. if the user wants durable checker summaries, restate the checker record details and route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_checker_record` +5. if the user wants durable checker summaries, restate the checker record details and route the confirmed action to `@copaper-recorder` so it can call `copaper_checker_record` 6. ask whether modifications are needed 7. if yes, suggest `review-revise` Do not fabricate checker results. -Use real review output or `vibepaper_checker_status`; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. +Use real review output or `copaper_checker_status`; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. ### Step 7: Run a final full review after all sections are complete When the scan shows no incomplete writing targets remain: 1. announce that the framework is fully populated 2. run one final full `markdown-review` -3. call `vibepaper_checker_status` to verify status freshness and severity counts +3. call `copaper_checker_status` to verify status freshness and severity counts 4. present the final seven-checker summary 5. suggest `review-revise` if unresolved issues remain @@ -200,13 +200,13 @@ This final pass checks whole-paper consistency instead of only local section qua At the end of each cycle, update workflow phase status through the OpenCode plugin tool when appropriate. -Use `vibepaper_workflow_set_phase`: +Use `copaper_workflow_set_phase`: - after accepted writing edits, set `phase: "writing"` and `status: "in_progress"` - after all writing targets and the final full review are complete, set `phase: "writing"` and `status: "complete"` -Before calling the tool, restate the phase/status update and wait for explicit user confirmation. The `vibepaper_workflow_set_phase` call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. +Before calling the tool, restate the phase/status update and wait for explicit user confirmation. The `copaper_workflow_set_phase` call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. -The current OpenCode plugin does not expose a dedicated tool for arbitrary writing metadata such as current mode, selected section path, completion snapshot, or review-revise history. It can record confirmed checker run summaries through `vibepaper_checker_record`. Do not manually edit `.agents/state.json` for unsupported fields when using the plugin-based workflow; report the limitation instead. +The current OpenCode plugin does not expose a dedicated tool for arbitrary writing metadata such as current mode, selected section path, completion snapshot, or review-revise history. It can record confirmed checker run summaries through `copaper_checker_record`. Do not manually edit `.agents/state.json` for unsupported fields when using the plugin-based workflow; report the limitation instead. ## Writing Order Recommendation @@ -241,7 +241,7 @@ Use this comparison when the user is choosing a mode. Mode guidance: Fine Mode is best for fluid paragraph-by-paragraph arguments; Strict Mode is essential for rigorous, RAG-heavy writing where hallucination must be zero; Fast Mode is better for large baseline sections where structural bulk drafting is acceptable. -The interaction loop must remain section-by-section: scan, summarize, recommend, let the user pick a section and mode, invoke the downstream skill, run `markdown-review`, report results, update workflow phase through `vibepaper_workflow_set_phase` when appropriate, and return to the overview. Do not silently expand into full-paper auto-writing. +The interaction loop must remain section-by-section: scan, summarize, recommend, let the user pick a section and mode, invoke the downstream skill, run `markdown-review`, report results, update workflow phase through `copaper_workflow_set_phase` when appropriate, and return to the overview. Do not silently expand into full-paper auto-writing. ## Must NOT Do @@ -251,7 +251,7 @@ The interaction loop must remain section-by-section: scan, summarize, recommend, - **NEVER** modify Level 2-5 framework headings during orchestration - **NEVER** fabricate completion state without reading `paper.md` - **NEVER** fabricate checker results instead of invoking or reading `markdown-review` -- **NEVER** manually edit `.agents/state.json` for workflow phase updates when `vibepaper_workflow_set_phase` is available +- **NEVER** manually edit `.agents/state.json` for workflow phase updates when `copaper_workflow_set_phase` is available ## End Condition diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..9218e5f --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,50 @@ +name: Deploy Docs + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install docs dependencies + run: pip install -r docs/requirements.txt + + - name: Build site + run: mkdocs build + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index eb5bb22..6207d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ bun.lock package.json .pytest_cache/ plan.md +usage.md +usage-en.md diff --git a/.slim/codemap.json b/.slim/codemap.json index 91a8e5f..382ad48 100644 --- a/.slim/codemap.json +++ b/.slim/codemap.json @@ -2,9 +2,9 @@ "metadata": { "version": "1.0.0", "last_run": "2026-05-19T03:32:47.576Z", - "root": "/mnt/d/Research/vibepaper/new1/VibePaper-OpenCode/.worktrees/opencode-plugin-mvp", + "root": "/mnt/d/Research/copaper/new1/CoPaper-OpenCode/.worktrees/opencode-plugin-mvp", "include_patterns": [ - "vibepaper/**/*.py", + "copaper/**/*.py", "packages/opencode-plugin/src/**/*.ts", "packages/opencode-plugin/package.json", "packages/opencode-plugin/tsconfig.json", @@ -55,37 +55,37 @@ "packages/opencode-plugin/src/storyline-structure.ts": "215011f775899a523715811d8de5a292", "packages/opencode-plugin/src/templates.ts": "4791c45a9c435aacd66ec463f086fec9", "packages/opencode-plugin/src/types.ts": "546c75b56ee49a4dda9d9b9c623a3479", - "packages/opencode-plugin/src/vibepaper-config.ts": "4bd339f618e8d49e75e12788fb555494", + "packages/opencode-plugin/src/copaper-config.ts": "4bd339f618e8d49e75e12788fb555494", "packages/opencode-plugin/src/workflow.ts": "b14ced4eaa97c04d05fc9aa3ac0e495e", "packages/opencode-plugin/tsconfig.json": "fe438b0308fab29aafff50e90e811d7c", "pyproject.toml": "daadaa97bd0c2394862786a06249d971", - "vibepaper/__init__.py": "c5d002281765846d572e037dfb9ee4ac", - "vibepaper/__main__.py": "daa5447ff8ad4abf656aa6dc78fbcc43", - "vibepaper/checker_integration.py": "2b701153a5d709cbe78c88e4ba3bf21e", - "vibepaper/cli.py": "8f05100a8675939fe7bc4c247418024c", - "vibepaper/constants.py": "0bebd1a927ea49cc2f5bd0904c291135", - "vibepaper/crossindex.py": "e86f36746393815fb7c7104d72093f99", - "vibepaper/dimensions.py": "a7e1d1e5fbd1f93dd6258c0833b5c4d6", - "vibepaper/eventlog.py": "ff531a20e0126b95cf68578bc91bcb87", - "vibepaper/git_ops.py": "037fe6c81bfc52fc15b076221d6b7b3c", - "vibepaper/identity.py": "c2a150054506cecbcd8a43aad32dd686", - "vibepaper/literature.py": "e38a29c852e96af9867e554c259adecc", - "vibepaper/llm_client.py": "960abf46229e4160f2a7f93573d4e157", - "vibepaper/relatedwork_clean.py": "900a9794017b30607c189132b95c4466", - "vibepaper/relatedwork_download.py": "bccfa6ffd670cb5274a9824ded1a88fd", - "vibepaper/relatedwork_keywords.py": "146b60c697254c7bb232678274ad4351", - "vibepaper/relatedwork_search.py": "9151bb4264676e439090e9986c833fe1", - "vibepaper/relatedwork_summarize.py": "7c2888d6d5ea0720dd60350fe28bd78f", - "vibepaper/report.py": "a4108b9955ba6b613208921d2faf5030", - "vibepaper/scaffold.py": "59ff7bb4f657a0652d2c27f23adb773d", - "vibepaper/schema.py": "2b991d4146059077524b50a1534c402a", - "vibepaper/state.py": "3004860353f5900b43b10e1bcb8628d9" + "copaper/__init__.py": "c5d002281765846d572e037dfb9ee4ac", + "copaper/__main__.py": "daa5447ff8ad4abf656aa6dc78fbcc43", + "copaper/checker_integration.py": "2b701153a5d709cbe78c88e4ba3bf21e", + "copaper/cli.py": "8f05100a8675939fe7bc4c247418024c", + "copaper/constants.py": "0bebd1a927ea49cc2f5bd0904c291135", + "copaper/crossindex.py": "e86f36746393815fb7c7104d72093f99", + "copaper/dimensions.py": "a7e1d1e5fbd1f93dd6258c0833b5c4d6", + "copaper/eventlog.py": "ff531a20e0126b95cf68578bc91bcb87", + "copaper/git_ops.py": "037fe6c81bfc52fc15b076221d6b7b3c", + "copaper/identity.py": "c2a150054506cecbcd8a43aad32dd686", + "copaper/literature.py": "e38a29c852e96af9867e554c259adecc", + "copaper/llm_client.py": "960abf46229e4160f2a7f93573d4e157", + "copaper/relatedwork_clean.py": "900a9794017b30607c189132b95c4466", + "copaper/relatedwork_download.py": "bccfa6ffd670cb5274a9824ded1a88fd", + "copaper/relatedwork_keywords.py": "146b60c697254c7bb232678274ad4351", + "copaper/relatedwork_search.py": "9151bb4264676e439090e9986c833fe1", + "copaper/relatedwork_summarize.py": "7c2888d6d5ea0720dd60350fe28bd78f", + "copaper/report.py": "a4108b9955ba6b613208921d2faf5030", + "copaper/scaffold.py": "59ff7bb4f657a0652d2c27f23adb773d", + "copaper/schema.py": "2b991d4146059077524b50a1534c402a", + "copaper/state.py": "3004860353f5900b43b10e1bcb8628d9" }, "folder_hashes": { ".": "ce494c2a0b0efbb89dfedabd73cf70f1", "packages": "5e36d0a7d854def99b241030fe1af3db", "packages/opencode-plugin": "5e36d0a7d854def99b241030fe1af3db", "packages/opencode-plugin/src": "e1fb4b7e59033474d9ede11e793b3c77", - "vibepaper": "b15fe34e3c917db42bb6edb0288e58f5" + "copaper": "b15fe34e3c917db42bb6edb0288e58f5" } } diff --git a/AGENTS.md b/AGENTS.md index 24ac6fd..aab03a4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,17 +1,17 @@ # AGENTS.md ## OVERVIEW -###### VibePaper: CLI + skills for structured paper workflows +###### CoPaper: CLI + skills for structured paper workflows <!-- description: Project purpose and core value proposition --> -VibePaper combines a Python CLI with specialized agent skills for structured academic paper writing. +CoPaper combines a Python CLI with specialized agent skills for structured academic paper writing. It manages a six-phase workflow, persists shared project state in `.agents/state.json`, and scaffolds reusable writing assets into any target project directory. The system prioritizes structural integrity, reproducible workflow state, and skill-guided execution over raw AI generation. ## STRUCTURE ###### Runtime package, scaffold bundle, and skill assets <!-- description: File organization and structural rules --> -- `vibepaper/`: Python package implementing CLI, state management, event logs, git integration, reports, and scaffold copy logic. -- `vibepaper/scaffold/`: Bundled package data copied into new projects by `vibe init`. +- `copaper/`: Python package implementing CLI, state management, event logs, git integration, reports, and scaffold copy logic. +- `copaper/scaffold/`: Bundled package data copied into new projects by `copaper init`. - `.agents/skills/`: Source skill library tracked in this repository. - `storyline.md`: Research storyline starter template copied into new projects. - `paper.md`: Paper framework starter template copied into new projects. @@ -23,13 +23,13 @@ The system prioritizes structural integrity, reproducible workflow state, and sk ## WHERE TO LOOK ###### Key implementation entry points <!-- description: Critical paths for development and usage --> -- `vibepaper/cli.py`: Click entry point for `vibe` and `python -m vibepaper`. -- `vibepaper/scaffold.py`: Copies bundled skills and starter files into new project roots. -- `vibepaper/state.py`: Reads and writes `.agents/state.json`. -- `vibepaper/eventlog.py`: Appends and queries `.agents/events.jsonl`. -- `vibepaper/git_ops.py`: Phase-aware commit and rollback helpers. +- `copaper/cli.py`: Click entry point for `copaper` and `python -m copaper`. +- `copaper/scaffold.py`: Copies bundled skills and starter files into new project roots. +- `copaper/state.py`: Reads and writes `.agents/state.json`. +- `copaper/eventlog.py`: Appends and queries `.agents/events.jsonl`. +- `copaper/git_ops.py`: Phase-aware commit and rollback helpers. - `workflow-dataflow.md`: Current artifact flow, reverse workflows, and structural gaps. -- `.agents/skills/vibepaper-manage/`: Guidance for automating project management through the `vibe` CLI. +- `.agents/skills/copaper-manage/`: Guidance for automating project management through the `copaper` CLI. - `tests/test_cli.py` and `tests/test_scaffold.py`: Fastest way to verify workflow behavior. ## CONVENTIONS @@ -54,19 +54,19 @@ The system prioritizes structural integrity, reproducible workflow state, and sk - Do not place `--root` after subcommands such as `init` or `status`. - Do not assume `commit`, `rollback`, or `diff` work outside a Git repository. - Do not assume `report` requires Git; it runs without Git and reports the missing repository in the output. -- Do not hand-edit scaffolded skills when the same change must also exist in `vibepaper/scaffold/`. +- Do not hand-edit scaffolded skills when the same change must also exist in `copaper/scaffold/`. ## COMMANDS ###### Current CLI behaviors agents should rely on <!-- description: Essential commands for agent interaction --> -- `vibe --root <project-dir> init --name "<project>" --domain "<domain>"`: Initializes a project in any directory and scaffolds `.agents/skills/`, `storyline.md`, `paper.md`, `writingrules.md`, and `AGENTS.md`. -- `vibe --root <project-dir> status [--json]`: Reads workflow status from `.agents/state.json` and recomputes `current_phase` from actual phase statuses. -- `vibe --root <project-dir> set-phase <phase> --status <status> [--reason <reason>]`: Explicitly sets a phase status and recomputes `current_phase`. -- `vibe --root <project-dir> skip <phase> --reason "<reason>"`: Marks a phase as skipped. -- `vibe --root <project-dir> log [--phase ...] [--operator ...] [--last N]`: Queries the event log. -- `vibe --root <project-dir> report [--since YYYY-MM-DD] [--output file]`: Generates a progress report. -- `vibe --root <project-dir> relatedwork status|import|sync-bib|download|register-summary|build-index ...`: Manages canonical literature metadata in `relatedwork/literature.json`, synchronizes `relatedwork/paper_list.bib`, downloads PDFs, registers summaries, and rebuilds `.agents/cross_index.json`. -- `vibe --root <project-dir> commit -m "<message>" [--phase <phase>]`, `vibe --root <project-dir> rollback <phase>`, and `vibe --root <project-dir> diff <phase-a> <phase-b>`: Git-backed phase management commands. +- `copaper --root <project-dir> init --name "<project>" --domain "<domain>"`: Initializes a project in any directory and scaffolds `.agents/skills/`, `storyline.md`, `paper.md`, `writingrules.md`, and `AGENTS.md`. +- `copaper --root <project-dir> status [--json]`: Reads workflow status from `.agents/state.json` and recomputes `current_phase` from actual phase statuses. +- `copaper --root <project-dir> set-phase <phase> --status <status> [--reason <reason>]`: Explicitly sets a phase status and recomputes `current_phase`. +- `copaper --root <project-dir> skip <phase> --reason "<reason>"`: Marks a phase as skipped. +- `copaper --root <project-dir> log [--phase ...] [--operator ...] [--last N]`: Queries the event log. +- `copaper --root <project-dir> report [--since YYYY-MM-DD] [--output file]`: Generates a progress report. +- `copaper --root <project-dir> relatedwork status|import|sync-bib|download|register-summary|build-index ...`: Manages canonical literature metadata in `relatedwork/literature.json`, synchronizes `relatedwork/paper_list.bib`, downloads PDFs, registers summaries, and rebuilds `.agents/cross_index.json`. +- `copaper --root <project-dir> commit -m "<message>" [--phase <phase>]`, `copaper --root <project-dir> rollback <phase>`, and `copaper --root <project-dir> diff <phase-a> <phase-b>`: Git-backed phase management commands. ## NOTES ###### Current version notes @@ -74,10 +74,10 @@ The system prioritizes structural integrity, reproducible workflow state, and sk - LaTeX support: Use `$...$` for inline and `$$...$$` for block formulas. - Node expansion: Nodes ending in numbers (e.g., "Challenge 1") can be duplicated. - Image handling: JPG/PNG/GIF supported, max 5MB, stored in `fig/`. -- `vibe init` is intentionally non-destructive for existing `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, and already-present skill directories in the target project. +- `copaper init` is intentionally non-destructive for existing `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, and already-present skill directories in the target project. - `current_phase` is derived from actual phase statuses during CLI status updates instead of staying fixed at the init-time default. - Canonical per-paper literature metadata now lives in `relatedwork/literature.json`; `.agents/state.json` keeps only aggregate literature progress counters. -- The packaged scaffold lives in `vibepaper/scaffold/` and must stay synchronized with the source assets in this repository. +- The packaged scaffold lives in `copaper/scaffold/` and must stay synchronized with the source assets in this repository. ## Repository Map ###### Project architecture index diff --git a/README.md b/README.md index fe7afa2..37828c8 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# VibePaper 使用与测试手册 +# CoPaper 使用与测试手册 > 版本:0.1.0 | 本文档描述当前实际实现,而非理想愿景。 ## 项目概述 -VibePaper 是一个 AI 辅助学术论文写作框架,由以下三部分组成: +CoPaper 是一个 AI 辅助学术论文写作框架,由以下三部分组成: -1. **Python 包 (`vibepaper/`)**:提供六阶段流水线的状态管理、事件日志、Git 操作、周报生成和 7-checker 集成。 +1. **Python 包 (`copaper/`)**:提供六阶段流水线的状态管理、事件日志、Git 操作、周报生成和 7-checker 集成。 2. **Agent Skills (`.agents/skills/`)**:多个 OpenCode/Sisyphus 技能,通过自然语言触发,覆盖从研究主线构建到 LaTeX 转换,再到文本去 AI 痕迹润色的完整流程。 -3. **CLI (`vibe` 命令)**:基于 Click 的命令行工具,用于项目初始化、状态查询、显式阶段状态更新、阶段跳过、Git 提交/回滚、周报和差异对比。 +3. **CLI (`copaper` 命令)**:基于 Click 的命令行工具,用于项目初始化、状态查询、显式阶段状态更新、阶段跳过、Git 提交/回滚、周报和差异对比。 核心理念:**结构与模板优先,AI 辅助优化**。AI 基于你提供的 Insight 和实验数据组织语言、优化文字,而非自由发挥;对成稿可结合 `humanizer` 做“去 AI 味”润色,保持原意同时提升自然度。 @@ -41,10 +41,10 @@ pip install -e .[dev] ```bash # 方式一:通过 console script -vibe --help +copaper --help # 方式二:通过 Python 模块 -python -m vibepaper --help +python -m copaper --help ``` ### 依赖说明 @@ -61,12 +61,12 @@ python -m vibepaper --help ## 仓库结构 ``` -VibePaper-Skill/ -├── vibepaper/ # Python 包:状态管理、CLI、Git 操作等 +CoPaper-Skill/ +├── copaper/ # Python 包:状态管理、CLI、Git 操作等 │ ├── __init__.py # 版本号与公共 API -│ ├── __main__.py # python -m vibepaper 入口 +│ ├── __main__.py # python -m copaper 入口 │ ├── cli.py # Click CLI 命令定义 -│ ├── scaffold/ # `vibe init` 复制到新项目的脚手架资源 +│ ├── scaffold/ # `copaper init` 复制到新项目的脚手架资源 │ ├── constants.py # 六阶段定义、状态枚举、依赖图 │ ├── schema.py # state.json 的 schema 与默认值 │ ├── state.py # StateManager:读写 state.json @@ -104,7 +104,7 @@ VibePaper-Skill/ │ │ ├── human-comment-helper/ # 人工评审注释 │ │ ├── humanizer/ # 去 AI 痕迹润色 │ │ ├── mad-writer/ # 自动写作循环 -│ │ └── vibepaper-manage/ # CLI 工作流管理 +│ │ └── copaper-manage/ # CLI 工作流管理 │ ├── state.json # 项目状态文件(init 后生成) │ └── events.jsonl # 事件日志(追加式 JSON Lines) ├── relatedwork/ # 文献存储目录 @@ -131,13 +131,13 @@ VibePaper-Skill/ ├── pyproject.toml # 包配置 ├── workflow-dataflow.md # storyline.md / paper.md / skills 数据流分析 ├── writingrules.md # 写作规范 -├── paper.md # 论文主文档模板(`vibe init` 会复制) -└── storyline.md # 研究主线模板(`vibe init` 会复制) +├── paper.md # 论文主文档模板(`copaper init` 会复制) +└── storyline.md # 研究主线模板(`copaper init` 会复制) ``` ## 六阶段流水线 -VibePaper 定义了六个写作阶段,按顺序推进: +CoPaper 定义了六个写作阶段,按顺序推进: | 阶段 | 名称 | 说明 | 推荐前置 | 工具层面可跳过 | |------|------|------|----------|----------------| @@ -148,15 +148,15 @@ VibePaper 定义了六个写作阶段,按顺序推进: | 5 | `writing` | 逐节撰写 paper.md | discussion | 是 | | 6 | `latex_review` | 转换为 LaTeX 并审查 | writing | 是 | -**依赖关系**:`vibepaper/constants.py` 中的 `PHASE_DEPENDENCIES` 定义的是**推荐正向推进顺序**,用于状态检查与默认流程编排;它不是对内容工作的硬禁止。实际技能层面允许重入、补跑与部分逆向工作流。 +**依赖关系**:`copaper/constants.py` 中的 `PHASE_DEPENDENCIES` 定义的是**推荐正向推进顺序**,用于状态检查与默认流程编排;它不是对内容工作的硬禁止。实际技能层面允许重入、补跑与部分逆向工作流。 **当前阶段语义**:`current_phase` 不再只是初始化时的默认值。CLI 现在会根据真实 phase 状态自动重算它:优先选择 `in_progress` 的 phase;如果没有,则选择第一个既不是 `complete` 也不是 `skipped` 的 phase。 -**跳过规则**:CLI 当前允许对任意有效阶段名执行 `vibe skip <phase>`;`--reason` 是**可选**参数,但强烈建议填写,便于后续追踪。实践上最常跳过的是 `experiments`,但其它阶段在工具层面也都可以跳过、回退后重做或在必要时补做。 +**跳过规则**:CLI 当前允许对任意有效阶段名执行 `copaper skip <phase>`;`--reason` 是**可选**参数,但强烈建议填写,便于后续追踪。实践上最常跳过的是 `experiments`,但其它阶段在工具层面也都可以跳过、回退后重做或在必要时补做。 ## 文档与 Skill 数据流 -VibePaper 的核心不是“阶段本身”,而是几个关键工件之间的数据流:`storyline.md`、`paper.md`、`relatedwork/`、`.agents/state.json`。 +CoPaper 的核心不是“阶段本身”,而是几个关键工件之间的数据流:`storyline.md`、`paper.md`、`relatedwork/`、`.agents/state.json`。 推荐正向路径是: @@ -184,38 +184,38 @@ VibePaper 的核心不是“阶段本身”,而是几个关键工件之间的 ```bash # ✅ 正确 -vibe --root /path/to/project status -vibe --root ./my-paper init --name "My Paper" --domain SE +copaper --root /path/to/project status +copaper --root ./my-paper init --name "My Paper" --domain SE # ❌ 错误——--root 在子命令之后会被忽略 -vibe init --root /path/to/project --name "My Paper" --domain SE +copaper init --root /path/to/project --name "My Paper" --domain SE ``` ### 命令一览 -#### `vibe init` — 初始化项目 +#### `copaper init` — 初始化项目 ```bash # 交互式(会提示输入 name 和 domain) -vibe init +copaper init # 非交互式 -vibe init --name "My Paper" --domain "software engineering" +copaper init --name "My Paper" --domain "software engineering" # 指定项目根目录 -vibe --root /path/to/project init --name "My Paper" --domain SE +copaper --root /path/to/project init --name "My Paper" --domain SE ``` 创建 `.agents/` 目录、`state.json`、`events.jsonl`,并复制 `.agents/skills/`、`storyline.md`、`paper.md`、`writingrules.md`、`AGENTS.md`。如果 `state.json` 已存在,会提示确认是否重新初始化。 -#### `vibe status` — 查看项目状态 +#### `copaper status` — 查看项目状态 ```bash # 人类可读格式 -vibe status +copaper status # JSON 格式(适合脚本解析) -vibe status --json +copaper status --json ``` 输出示例: @@ -234,72 +234,72 @@ writing [ ] not_started latex_review [ ] not_started ``` -#### `vibe skip` — 跳过阶段 +#### `copaper skip` — 跳过阶段 ```bash # 推荐写法:带原因 -vibe skip experiments --reason "纯理论论文,无需实验" +copaper skip experiments --reason "纯理论论文,无需实验" # 也可省略原因(不推荐) -vibe skip experiments +copaper skip experiments ``` **注意**:`skip` 的参数是阶段名称(如 `experiments`),不是阶段字母(如 `D`)。有效名称为:`storyline`、`literature`、`discussion`、`experiments`、`writing`、`latex_review`。 -#### `vibe set-phase` — 显式设置阶段状态 +#### `copaper set-phase` — 显式设置阶段状态 ```bash # 将 storyline 标为完成,并自动推进 current_phase -vibe set-phase storyline --status complete +copaper set-phase storyline --status complete # 将 discussion 标为进行中;如果推荐前置阶段未完成,会给出 warning 但不会硬阻止 -vibe set-phase discussion --status in_progress +copaper set-phase discussion --status in_progress # 将 experiments 标为 skipped -vibe set-phase experiments --status skipped --reason "纯理论论文" +copaper set-phase experiments --status skipped --reason "纯理论论文" ``` 支持的状态值:`not_started`、`in_progress`、`complete`、`skipped`。 这个命令适合 agent/脚本在不手改 `.agents/state.json` 的前提下,显式推进或回退工作流状态。 -#### `vibe log` — 查询操作日志 +#### `copaper log` — 查询操作日志 ```bash # 查看所有日志 -vibe log +copaper log # 按阶段过滤 -vibe log --phase storyline +copaper log --phase storyline # 按操作者过滤 -vibe log --operator user +copaper log --operator user # 查看最近 10 条 -vibe log --last 10 +copaper log --last 10 # 按日期过滤 -vibe log --since 2026-04-01 +copaper log --since 2026-04-01 ``` -#### `vibe report` — 生成周报 +#### `copaper report` — 生成周报 ```bash # 输出到终端 -vibe report +copaper report # 指定起始日期 -vibe report --since 2026-04-01 +copaper report --since 2026-04-01 # 输出到文件 -vibe report --output report.md +copaper report --output report.md ``` 周报包含:阶段进度、Git 提交摘要(按作者分组)、事件日志统计。如果不在 Git 仓库中,Git 部分会显示 "Git repository not available"。 -#### `vibe relatedwork` — 管理论文元数据、BibTeX 与 PDF +#### `copaper relatedwork` — 管理论文元数据、BibTeX 与 PDF -literature 阶段的所有步骤都封装成 `vibe relatedwork *` 子命令。检索走 Semantic Scholar Graph API;关键词抽取与单篇摘要走任意 OpenAI 兼容的 LLM 端点(默认从 `.env` 读取配置)。 +literature 阶段的所有步骤都封装成 `copaper relatedwork *` 子命令。检索走 Semantic Scholar Graph API;关键词抽取与单篇摘要走任意 OpenAI 兼容的 LLM 端点(默认从 `.env` 读取配置)。 ##### 必需环境变量(写到项目根的 `.env`,启动时自动加载) @@ -310,7 +310,7 @@ S2_API_BASE="..." # 可选:走中转代理时填,未 # LLM(keywords + summarize 需要) OPENAI_API_KEY="..." # 必填 -VIBEPAPER_MODEL="gpt-4o-mini" # 必填,建议先用便宜模型 smoke +COPAPER_MODEL="gpt-4o-mini" # 必填,建议先用便宜模型 smoke OPENAI_BASE_URL="https://proxy/v1" # 可选:走中转代理时填 ``` @@ -320,75 +320,75 @@ OPENAI_BASE_URL="https://proxy/v1" # 可选:走中转代理时填 ```bash # Step 1 · LLM 从 storyline.md 抽 query → relatedwork/queries.txt -vibe relatedwork keywords --count 6 +copaper relatedwork keywords --count 6 # Step 2 · Semantic Scholar 检索 → relatedwork/search_cache.json -vibe relatedwork search --queries-file relatedwork/queries.txt --limit 5 +copaper relatedwork search --queries-file relatedwork/queries.txt --limit 5 # Step 3 · 灌进 canonical catalog → relatedwork/literature.json -vibe relatedwork import --input relatedwork/search_cache.json +copaper relatedwork import --input relatedwork/search_cache.json # Step 4 · 同步 BibTeX → relatedwork/paper_list.bib -vibe relatedwork sync-bib +copaper relatedwork sync-bib # Step 5 · 下载 OA PDF → relatedwork/pdfs/<paper_id>.pdf -vibe relatedwork download +copaper relatedwork download # Step 6 · LLM 单篇 summary → relatedwork/papers/<paper_id>.md -vibe relatedwork summarize --concurrency 4 +copaper relatedwork summarize --concurrency 4 # Step 7 · 交叉索引 + 覆盖报告 → .agents/cross_index.json -vibe relatedwork build-index +copaper relatedwork build-index # 任意时刻看状态 -vibe relatedwork status +copaper relatedwork status ``` ##### 每个子命令的常用 flag ```bash # keywords —— 从 storyline.md / paper.md 抽搜索短语 -vibe relatedwork keywords --count 8 --model gpt-4o-mini --out relatedwork/queries.txt +copaper relatedwork keywords --count 8 --model gpt-4o-mini --out relatedwork/queries.txt # search —— S2 检索 + BibTeX/arXiv/PDF URL/TLDR 自动归一化 # 默认过滤(可覆盖):--fields-of-study "Computer Science" 默认开启,--open-access 默认关闭 -vibe relatedwork search --queries-file relatedwork/queries.txt \ +copaper relatedwork search --queries-file relatedwork/queries.txt \ --limit 20 --year 2022-2026 \ --venue "CVPR,NeurIPS" # 只要有 OA PDF 的论文(便于后续 download) -vibe relatedwork search --queries-file relatedwork/queries.txt --open-access +copaper relatedwork search --queries-file relatedwork/queries.txt --open-access # 跨学科搜索(关掉默认的 CS 限定) -vibe relatedwork search --queries-file relatedwork/queries.txt --fields-of-study "" +copaper relatedwork search --queries-file relatedwork/queries.txt --fields-of-study "" # 也可不写 queries-file,直接传 query -vibe relatedwork search --query "streaming vla" --query "robot policy" +copaper relatedwork search --query "streaming vla" --query "robot policy" # import / sync-bib —— 元数据双向同步 -vibe relatedwork import --input relatedwork/search_cache.json -vibe relatedwork sync-bib +copaper relatedwork import --input relatedwork/search_cache.json +copaper relatedwork sync-bib # download —— urllib + 3 次重试 + %PDF 头校验 -vibe relatedwork download -vibe relatedwork download --retry-failed -vibe relatedwork download --paper-id song2025ceed +copaper relatedwork download +copaper relatedwork download --retry-failed +copaper relatedwork download --paper-id song2025ceed # summarize —— pypdf 抽文本 + LLM,内部 ThreadPool + 16 QPS token bucket -vibe relatedwork summarize # 全部 downloaded 且无 summary 的 -vibe relatedwork summarize --paper-id <id> # 只一篇 -vibe relatedwork summarize --force # 重新做已有 summary -vibe relatedwork summarize --concurrency 8 --qps 16 --max-pdf-bytes 52428800 +copaper relatedwork summarize # 全部 downloaded 且无 summary 的 +copaper relatedwork summarize --paper-id <id> # 只一篇 +copaper relatedwork summarize --force # 重新做已有 summary +copaper relatedwork summarize --concurrency 8 --qps 16 --max-pdf-bytes 52428800 # build-index —— 解析 papers/*.md 生成交叉索引 + 覆盖报告 -vibe relatedwork build-index +copaper relatedwork build-index # register-summary —— 手动登记一篇外部生成的 summary(summarize CLI 已自动调,通常不需要手动) -vibe relatedwork register-summary --paper-id <id> --summary-path relatedwork/papers/<id>.md +copaper relatedwork register-summary --paper-id <id> --summary-path relatedwork/papers/<id>.md # status —— 总表 -vibe relatedwork status -vibe relatedwork status --json +copaper relatedwork status +copaper relatedwork status --json ``` ##### 关键产物 @@ -404,37 +404,37 @@ vibe relatedwork status --json | `.agents/cross_index.json` | `build-index` | storyline 技术点 ↔ 论文 反向索引 + 覆盖率 | | `.agents/state.json` literature phase | 上述所有命令自动同步 | 聚合计数(`papers_found` / `papers_downloaded` / `download_failures` / `summaries_done` / `cross_index_built`) | -#### `vibe diff` — 阶段间差异对比 +#### `copaper diff` — 阶段间差异对比 ```bash -vibe diff storyline literature +copaper diff storyline literature ``` 显示两个阶段最后一次提交之间的 Git diff。如果某个阶段没有提交,会提示无 diff 可用。 -#### `vibe commit` — 阶段化 Git 提交 +#### `copaper commit` — 阶段化 Git 提交 ```bash # 自动检测当前阶段 -vibe commit -m "完成研究主线初稿" +copaper commit -m "完成研究主线初稿" # 指定阶段 -vibe commit --phase storyline -m "完成研究主线初稿" +copaper commit --phase storyline -m "完成研究主线初稿" # 强制提交(即使没有暂存变更) -vibe commit -m "空提交标记" --force +copaper commit -m "空提交标记" --force ``` -提交消息格式为 `[phase] message`,并自动添加 `Co-authored-by: VibePaper AI <ai@vibepaper>` 尾部。**必须在 Git 仓库中运行**。 +提交消息格式为 `[phase] message`,并自动添加 `Co-authored-by: CoPaper AI <ai@copaper>` 尾部。**必须在 Git 仓库中运行**。 -#### `vibe rollback` — 回滚到某阶段的提交 +#### `copaper rollback` — 回滚到某阶段的提交 ```bash # 交互式确认 -vibe rollback storyline +copaper rollback storyline # 跳过确认 -vibe rollback storyline -y +copaper rollback storyline -y ``` 使用 `git reset --soft` 回滚到指定阶段的最后一次提交,同时将 `state.json` 中该阶段状态重置为 `not_started`。**必须在 Git 仓库中运行**。 @@ -443,7 +443,7 @@ vibe rollback storyline -y | 错误信息 | 原因 | 解决方法 | |----------|------|----------| -| `No project found. Run 'vibe init' first.` | 当前目录没有 `.agents/state.json` | 先运行 `vibe init` | +| `No project found. Run 'copaper init' first.` | 当前目录没有 `.agents/state.json` | 先运行 `copaper init` | | `--root` 选项不生效 | `--root` 放在了子命令之后 | 将 `--root` 移到子命令之前 | | `skip` 报错无效阶段名 | 使用了字母标签如 `A`/`B` 而非阶段名 | 使用完整名称如 `storyline`、`experiments` | | `report` 显示 "Git repository not available" | 不在 Git 仓库中 | 在 Git 仓库内运行,或忽略此部分 | @@ -454,7 +454,7 @@ vibe rollback storyline -y ### `.agents/state.json` -项目初始化后由 `vibe init` 创建,是项目进度的唯一真实来源。结构如下: +项目初始化后由 `copaper init` 创建,是项目进度的唯一真实来源。结构如下: ```json { @@ -503,8 +503,8 @@ vibe rollback storyline -y "auto_commit": false, "identity": { "role": "assistant", - "git_name": "VibePaper Bot", - "git_email": "bot@vibepaper.dev" + "git_name": "CoPaper Bot", + "git_email": "bot@copaper.dev" } }, "checkers": {} @@ -556,9 +556,9 @@ vibe rollback storyline -y 可以使用 checker harness 从 `paper.md` 中的标准 AI comment 收集结果并写入状态: ```bash -vibe --root <project-dir> checkers collect -vibe --root <project-dir> checkers collect --checker logic --checker clarity -vibe --root <project-dir> checkers status +copaper --root <project-dir> checkers collect +copaper --root <project-dir> checkers collect --checker logic --checker clarity +copaper --root <project-dir> checkers status ``` harness 只解析 checker skills 已插入的 `<!-- AI Comments: ... -->` 块,不会伪装成自动执行 AI 审稿。带有 `Checker: <name>` 标记的评论会归档到对应 checker;没有标记时,评论会归入本次指定收集的 checker。 @@ -579,11 +579,11 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 **触发**:`"find related work"` -- 编排 `vibe relatedwork keywords / search / import / sync-bib / download` 7 步流水线 -- 关键词抽取与 Semantic Scholar 检索都委派给 `vibe` CLI,**不再调用任何 MCP 搜索工具** +- 编排 `copaper relatedwork keywords / search / import / sync-bib / download` 7 步流水线 +- 关键词抽取与 Semantic Scholar 检索都委派给 `copaper` CLI,**不再调用任何 MCP 搜索工具** - 与 `relatedwork-summarizer` 配合完成 PDF 下载 → 单篇 summary → 交叉索引 -详见 `vibe relatedwork` 章节。 +详见 `copaper relatedwork` 章节。 ### socratic-discussion — 苏格拉底式讨论 @@ -648,7 +648,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 - 从已有 `.pdf` 初稿提取内容,按语义映射到 `paper.md` 的既有 section - 可以从已有的论文初稿转变为paper.md进行审稿 - 严格按 section 逐步转换,并在每节写入前走用户确认 -- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `paper.md`,先执行 `vibe --root <project-dir> init ...` 再更新 `writing` phase +- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `paper.md`,先执行 `copaper --root <project-dir> init ...` 再更新 `writing` phase ### ppt2storyline — PPT/PPTX 转 Storyline @@ -657,7 +657,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 - 从 `.pptx` 提取幻灯片文本并映射到 `storyline.md` 既有 section - 可以从小组会ppt直接转变成storyline.md并进行完整的工作流程 - 以“忠实原文 + 轻量润色”为原则,不新增未在 PPT 出现的研究结论 -- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `storyline.md`,先执行 `vibe --root <project-dir> init ...` 再更新 phase +- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `storyline.md`,先执行 `copaper --root <project-dir> init ...` 再更新 phase ### humanizer — 去 AI 痕迹润色 @@ -671,11 +671,11 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 **触发**:`"show current phase"`、`"go to next phase"`、`"go back to previous phase"`、`"jump to writing"`、`"查看当前阶段"`、`"进入下一阶段"`、`"回到上一个阶段"`、`"跳到 experiments 阶段"` -- 通过 `vibe --root . status --json` 读取当前阶段 +- 通过 `copaper --root . status --json` 读取当前阶段 - 查看当前阶段时只读状态,不修改 workflow - “下一阶段”会把当前 phase 标记为 `complete`,让 CLI 自动推进 - “回到上一阶段/前面某阶段”会把目标 phase 设为 `in_progress`,并把后续 phase 重置为 `not_started` -- “跳到某阶段”会用 `vibe --root . set-phase <phase> --status in_progress` +- “跳到某阶段”会用 `copaper --root . set-phase <phase> --status in_progress` - 跳转后在同一轮直接打开该阶段对应的 `SKILL.md` 并继续执行,例如 `writing` 打开 `writing-orchestrator`,`literature` 打开 `relatedwork-finder` ## 人工测试指南 @@ -687,7 +687,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 python -m pytest tests/ -v # 运行测试并查看覆盖率 -python -m pytest tests/ --cov=vibepaper --cov-report=term +python -m pytest tests/ --cov=copaper --cov-report=term ``` 当前测试状态:**全部通过,覆盖率约 90%**。 @@ -723,32 +723,32 @@ python -m pytest tests/ --cov=vibepaper --cov-report=term ```bash # 1. 初始化项目 -vibe init --name "Test Paper" --domain SE +copaper init --name "Test Paper" --domain SE # 2. 查看状态 -vibe status -vibe status --json +copaper status +copaper status --json # 3. 提交 -vibe commit -m "draft" +copaper commit -m "draft" # 4. 查看日志 -vibe log -vibe log --phase storyline +copaper log +copaper log --phase storyline # 5. 回滚 -vibe rollback storyline +copaper rollback storyline # 6. 生成报告 -vibe report -vibe report --since 2026-04-01 -vibe report --output report.md +copaper report +copaper report --since 2026-04-01 +copaper report --output report.md # 7. 阶段差异 -vibe diff storyline literature +copaper diff storyline literature # 8. 跳过阶段 -vibe skip literature --reason "not needed" +copaper skip literature --reason "not needed" ``` **Git 集成验收**: @@ -764,11 +764,11 @@ vibe skip literature --reason "not needed" ## 故障排除 -### `No project found. Run 'vibe init' first.` +### `No project found. Run 'copaper init' first.` 当前目录(或 `--root` 指定目录)下没有 `.agents/state.json` 文件。 -**解决**:在目标目录运行 `vibe init --name "项目名" --domain "领域"`。 +**解决**:在目标目录运行 `copaper init --name "项目名" --domain "领域"`。 ### `--root` 位置错误 @@ -776,10 +776,10 @@ vibe skip literature --reason "not needed" ```bash # ✅ 正确 -vibe --root /path/to/project status +copaper --root /path/to/project status # ❌ 错误——Click 不会识别子命令之后的全局选项 -vibe status --root /path/to/project +copaper status --root /path/to/project ``` ### `skip` 命令需要有效阶段名 @@ -788,10 +788,10 @@ vibe status --root /path/to/project ```bash # ✅ 正确 -vibe skip experiments --reason "纯理论论文" +copaper skip experiments --reason "纯理论论文" # ❌ 错误——D 不是有效阶段名 -vibe skip D --reason "纯理论论文" +copaper skip D --reason "纯理论论文" ``` 有效阶段名:`storyline`、`literature`、`discussion`、`experiments`、`writing`、`latex_review`。 @@ -811,10 +811,10 @@ vibe skip D --reason "纯理论论文" ```bash # 会提示输入 Project name 和 Research domain -vibe init +copaper init # 非交互式——适合脚本 -vibe init --name "My Paper" --domain "SE" +copaper init --name "My Paper" --domain "SE" ``` ## 建议的首次运行流程 @@ -828,20 +828,20 @@ pip install -e .[dev] # 2. 初始化项目(在 Git 仓库中) cd /path/to/your/paper-project git init # 如果还不是 Git 仓库 -vibe init --name "My Research" --domain "software engineering" +copaper init --name "My Research" --domain "software engineering" # 3. 构建研究主线 # 在 OpenCode 中触发:"help me write storyline" # 或手动编辑 storyline.md -# 4. 检索文献(纯 CLI 流水线,需先在 .env 中配 OPENAI_API_KEY / VIBEPAPER_MODEL / S2_API_KEY) -vibe relatedwork keywords --count 6 -vibe relatedwork search --queries-file relatedwork/queries.txt --limit 5 -vibe relatedwork import --input relatedwork/search_cache.json -vibe relatedwork sync-bib -vibe relatedwork download -vibe relatedwork summarize --concurrency 4 -vibe relatedwork build-index +# 4. 检索文献(纯 CLI 流水线,需先在 .env 中配 OPENAI_API_KEY / COPAPER_MODEL / S2_API_KEY) +copaper relatedwork keywords --count 6 +copaper relatedwork search --queries-file relatedwork/queries.txt --limit 5 +copaper relatedwork import --input relatedwork/search_cache.json +copaper relatedwork sync-bib +copaper relatedwork download +copaper relatedwork summarize --concurrency 4 +copaper relatedwork build-index # 也可以在 OpenCode 中触发 "find related work" 让 skill 编排上述命令 # 5. 苏格拉底式讨论 @@ -850,7 +850,7 @@ vibe relatedwork build-index # 6. 实验分析(或跳过) # 在 OpenCode 中触发:"analyze experiments" -# 或跳过:vibe skip experiments --reason "纯理论论文无需实验" +# 或跳过:copaper skip experiments --reason "纯理论论文无需实验" # 7. 写作 # 在 OpenCode 中触发:"write the paper" @@ -869,9 +869,9 @@ vibe relatedwork build-index # 生成最终投稿版本 # 全程可用 CLI 跟踪进度 -vibe status -vibe log -vibe report +copaper status +copaper log +copaper report ``` ## 写作规范 diff --git a/codemap.md b/codemap.md index 9122e2f..c23043a 100644 --- a/codemap.md +++ b/codemap.md @@ -1,4 +1,4 @@ -# Repository Atlas: VibePaper +# Repository Atlas: CoPaper <!-- description: Master architecture map for the repository. --> @@ -8,7 +8,7 @@ ###### Structured academic workflow platform -VibePaper combines a Python `vibe` CLI, scaffolded agent skills, project-state files, related-work automation, and an OpenCode plugin so researchers can manage a six-phase paper workflow with reproducible state and explicit artifact readiness. +CoPaper combines a Python `copaper` CLI, scaffolded agent skills, project-state files, related-work automation, and an OpenCode plugin so researchers can manage a six-phase paper workflow with reproducible state and explicit artifact readiness. ###### Dual runtime architecture @@ -20,11 +20,11 @@ The Python package owns canonical workflow operations and scaffold data. The Typ ###### Python CLI runtime -`vibepaper/cli.py` defines the `vibe` command tree, including project init, status, phase updates, event logs, reports, Git-backed phase commands, and `relatedwork` subcommands. +`copaper/cli.py` defines the `copaper` command tree, including project init, status, phase updates, event logs, reports, Git-backed phase commands, and `relatedwork` subcommands. ###### OpenCode plugin runtime -`packages/opencode-plugin/src/index.ts` exports the OpenCode plugin, injects VibePaper subagents, and registers `vibepaper_*` tools for dashboards, artifact status, workflow updates, checker records, related-work operations, and import extraction. +`packages/opencode-plugin/src/index.ts` exports the OpenCode plugin, injects CoPaper subagents, and registers `copaper_*` tools for dashboards, artifact status, workflow updates, checker records, related-work operations, and import extraction. ###### Package metadata @@ -32,19 +32,19 @@ The Python package owns canonical workflow operations and scaffold data. The Typ ###### Agent-facing guidance -`AGENTS.md` defines repository conventions. `.agents/skills/` is the source skill library; `vibepaper/scaffold/skills/` is the packaged mirror copied by `vibe init`. +`AGENTS.md` defines repository conventions. `.agents/skills/` is the source skill library; `copaper/scaffold/skills/` is the packaged mirror copied by `copaper init`. ## Repository Directory Map <!-- description: Aggregated folder responsibilities. --> -###### `vibepaper/` +###### `copaper/` -Python runtime package for CLI commands, state persistence, event logs, scaffold copying, literature metadata, related-work LLM/search/download/summarization, checker tracking, cross-indexing, Git operations, and reports. Detailed map: [vibepaper/codemap.md](vibepaper/codemap.md). +Python runtime package for CLI commands, state persistence, event logs, scaffold copying, literature metadata, related-work LLM/search/download/summarization, checker tracking, cross-indexing, Git operations, and reports. Detailed map: [copaper/codemap.md](copaper/codemap.md). ###### `packages/` -Integration package workspace. It currently contains the OpenCode integration package published as `@vibepaper/opencode`. Detailed map: [packages/codemap.md](packages/codemap.md). +Integration package workspace. It currently contains the OpenCode integration package published as `@copaper/opencode`. Detailed map: [packages/codemap.md](packages/codemap.md). ###### `packages/opencode-plugin/` @@ -56,7 +56,7 @@ TypeScript source for plugin registration, tool handlers, config parsing, projec ###### `.agents/skills/` -Source skill library for storyline, literature, discussion, experiments, writing, review, conversion, checkers, submission, humanization, and VibePaper management. Tests enforce mirrored `SKILL.md` files in `vibepaper/scaffold/skills/`. +Source skill library for storyline, literature, discussion, experiments, writing, review, conversion, checkers, submission, humanization, and CoPaper management. Tests enforce mirrored `SKILL.md` files in `copaper/scaffold/skills/`. ###### `tests/` @@ -72,7 +72,7 @@ Pytest suite for Python CLI behavior, state/event persistence, scaffold copying, ###### Project bootstrap -`vibe init` or the plugin's `vibepaper_init_apply` creates project artifacts, `.agents/state.json`, `.agents/events.jsonl`, and skill assets. The Python scaffold copies bundled files; the plugin templates write a TypeScript-managed equivalent for OpenCode workflows. +`copaper init` or the plugin's `copaper_init_apply` creates project artifacts, `.agents/state.json`, `.agents/events.jsonl`, and skill assets. The Python scaffold copies bundled files; the plugin templates write a TypeScript-managed equivalent for OpenCode workflows. ###### Workflow state loop @@ -80,11 +80,11 @@ Both runtimes read and write `.agents/state.json` and `.agents/events.jsonl`. Py ###### Literature pipeline -The Python CLI owns Semantic Scholar search, BibTeX sync, PDF download, LLM keyword extraction, LLM summarization, and cross-index construction. The plugin exposes those operations through `relatedwork-tools.ts`, which executes `vibe relatedwork ...` via `python-bridge.ts`. +The Python CLI owns Semantic Scholar search, BibTeX sync, PDF download, LLM keyword extraction, LLM summarization, and cross-index construction. The plugin exposes those operations through `relatedwork-tools.ts`, which executes `copaper relatedwork ...` via `python-bridge.ts`. ###### Agent workflow loop -OpenCode loads the plugin, receives VibePaper subagent profiles, and uses permission profiles to separate read-only coordination from storyline edits, paper edits, state recording, and literature writes. Skills guide agents to prefer plugin tools over direct state edits. +OpenCode loads the plugin, receives CoPaper subagent profiles, and uses permission profiles to separate read-only coordination from storyline edits, paper edits, state recording, and literature writes. Skills guide agents to prefer plugin tools over direct state edits. ## Design Constraints @@ -104,7 +104,7 @@ Levels 1-5 are structural, Level 6 headings carry paragraph topics, and body tex ###### Source and scaffold sync -Changes to `.agents/skills/` must be mirrored to `vibepaper/scaffold/skills/`; scaffold tests compare source and packaged skill files byte-for-byte. +Changes to `.agents/skills/` must be mirrored to `copaper/scaffold/skills/`; scaffold tests compare source and packaged skill files byte-for-byte. ## Quality Gates diff --git a/vibepaper.egg-info/PKG-INFO b/copaper.egg-info/PKG-INFO similarity index 68% rename from vibepaper.egg-info/PKG-INFO rename to copaper.egg-info/PKG-INFO index 17be0fc..7cf452a 100644 --- a/vibepaper.egg-info/PKG-INFO +++ b/copaper.egg-info/PKG-INFO @@ -1,8 +1,8 @@ Metadata-Version: 2.4 -Name: vibepaper +Name: copaper Version: 0.1.0 Summary: AI-assisted academic writing framework with structured phase management -Author: VibePaper Team +Author: CoPaper Team License: MIT Requires-Python: >=3.10 Description-Content-Type: text/markdown @@ -15,17 +15,17 @@ Provides-Extra: dev Requires-Dist: pytest>=7.0; extra == "dev" Requires-Dist: pytest-cov>=4.0; extra == "dev" -# VibePaper 使用与测试手册 +# CoPaper 使用与测试手册 > 版本:0.1.0 | 本文档描述当前实际实现,而非理想愿景。 ## 项目概述 -VibePaper 是一个 AI 辅助学术论文写作框架,由以下三部分组成: +CoPaper 是一个 AI 辅助学术论文写作框架,由以下三部分组成: -1. **Python 包 (`vibepaper/`)**:提供六阶段流水线的状态管理、事件日志、Git 操作、周报生成和 7-checker 集成。 +1. **Python 包 (`copaper/`)**:提供六阶段流水线的状态管理、事件日志、Git 操作、周报生成和 7-checker 集成。 2. **Agent Skills (`.agents/skills/`)**:多个 OpenCode/Sisyphus 技能,通过自然语言触发,覆盖从研究主线构建到 LaTeX 转换,再到文本去 AI 痕迹润色的完整流程。 -3. **CLI (`vibe` 命令)**:基于 Click 的命令行工具,用于项目初始化、状态查询、显式阶段状态更新、阶段跳过、Git 提交/回滚、周报和差异对比。 +3. **CLI (`copaper` 命令)**:基于 Click 的命令行工具,用于项目初始化、状态查询、显式阶段状态更新、阶段跳过、Git 提交/回滚、周报和差异对比。 核心理念:**结构与模板优先,AI 辅助优化**。AI 基于你提供的 Insight 和实验数据组织语言、优化文字,而非自由发挥;对成稿可结合 `humanizer` 做“去 AI 味”润色,保持原意同时提升自然度。 @@ -58,10 +58,10 @@ pip install -e .[dev] ```bash # 方式一:通过 console script -vibe --help +copaper --help # 方式二:通过 Python 模块 -python -m vibepaper --help +python -m copaper --help ``` ### 依赖说明 @@ -78,12 +78,12 @@ python -m vibepaper --help ## 仓库结构 ``` -VibePaper-Skill/ -├── vibepaper/ # Python 包:状态管理、CLI、Git 操作等 +CoPaper-Skill/ +├── copaper/ # Python 包:状态管理、CLI、Git 操作等 │ ├── __init__.py # 版本号与公共 API -│ ├── __main__.py # python -m vibepaper 入口 +│ ├── __main__.py # python -m copaper 入口 │ ├── cli.py # Click CLI 命令定义 -│ ├── scaffold/ # `vibe init` 复制到新项目的脚手架资源 +│ ├── scaffold/ # `copaper init` 复制到新项目的脚手架资源 │ ├── constants.py # 六阶段定义、状态枚举、依赖图 │ ├── schema.py # state.json 的 schema 与默认值 │ ├── state.py # StateManager:读写 state.json @@ -120,7 +120,7 @@ VibePaper-Skill/ │ │ ├── human-comment-helper/ # 人工评审注释 │ │ ├── humanizer/ # 去 AI 痕迹润色 │ │ ├── mad-writer/ # 自动写作循环 -│ │ └── vibepaper-manage/ # CLI 工作流管理 +│ │ └── copaper-manage/ # CLI 工作流管理 │ ├── state.json # 项目状态文件(init 后生成) │ └── events.jsonl # 事件日志(追加式 JSON Lines) ├── relatedwork/ # 文献存储目录 @@ -145,13 +145,13 @@ VibePaper-Skill/ ├── pyproject.toml # 包配置 ├── workflow-dataflow.md # storyline.md / paper.md / skills 数据流分析 ├── writingrules.md # 写作规范 -├── paper.md # 论文主文档模板(`vibe init` 会复制) -└── storyline.md # 研究主线模板(`vibe init` 会复制) +├── paper.md # 论文主文档模板(`copaper init` 会复制) +└── storyline.md # 研究主线模板(`copaper init` 会复制) ``` ## 六阶段流水线 -VibePaper 定义了六个写作阶段,按顺序推进: +CoPaper 定义了六个写作阶段,按顺序推进: | 阶段 | 名称 | 说明 | 推荐前置 | 工具层面可跳过 | |------|------|------|----------|----------------| @@ -162,15 +162,15 @@ VibePaper 定义了六个写作阶段,按顺序推进: | 5 | `writing` | 逐节撰写 paper.md | discussion | 是 | | 6 | `latex_review` | 转换为 LaTeX 并审查 | writing | 是 | -**依赖关系**:`vibepaper/constants.py` 中的 `PHASE_DEPENDENCIES` 定义的是**推荐正向推进顺序**,用于状态检查与默认流程编排;它不是对内容工作的硬禁止。实际技能层面允许重入、补跑与部分逆向工作流。 +**依赖关系**:`copaper/constants.py` 中的 `PHASE_DEPENDENCIES` 定义的是**推荐正向推进顺序**,用于状态检查与默认流程编排;它不是对内容工作的硬禁止。实际技能层面允许重入、补跑与部分逆向工作流。 **当前阶段语义**:`current_phase` 不再只是初始化时的默认值。CLI 现在会根据真实 phase 状态自动重算它:优先选择 `in_progress` 的 phase;如果没有,则选择第一个既不是 `complete` 也不是 `skipped` 的 phase。 -**跳过规则**:CLI 当前允许对任意有效阶段名执行 `vibe skip <phase>`;`--reason` 是**可选**参数,但强烈建议填写,便于后续追踪。实践上最常跳过的是 `experiments`,但其它阶段在工具层面也都可以跳过、回退后重做或在必要时补做。 +**跳过规则**:CLI 当前允许对任意有效阶段名执行 `copaper skip <phase>`;`--reason` 是**可选**参数,但强烈建议填写,便于后续追踪。实践上最常跳过的是 `experiments`,但其它阶段在工具层面也都可以跳过、回退后重做或在必要时补做。 ## 文档与 Skill 数据流 -VibePaper 的核心不是“阶段本身”,而是几个关键工件之间的数据流:`storyline.md`、`paper.md`、`relatedwork/`、`.agents/state.json`。 +CoPaper 的核心不是“阶段本身”,而是几个关键工件之间的数据流:`storyline.md`、`paper.md`、`relatedwork/`、`.agents/state.json`。 推荐正向路径是: @@ -198,38 +198,38 @@ VibePaper 的核心不是“阶段本身”,而是几个关键工件之间的 ```bash # ✅ 正确 -vibe --root /path/to/project status -vibe --root ./my-paper init --name "My Paper" --domain SE +copaper --root /path/to/project status +copaper --root ./my-paper init --name "My Paper" --domain SE # ❌ 错误——--root 在子命令之后会被忽略 -vibe init --root /path/to/project --name "My Paper" --domain SE +copaper init --root /path/to/project --name "My Paper" --domain SE ``` ### 命令一览 -#### `vibe init` — 初始化项目 +#### `copaper init` — 初始化项目 ```bash # 交互式(会提示输入 name 和 domain) -vibe init +copaper init # 非交互式 -vibe init --name "My Paper" --domain "software engineering" +copaper init --name "My Paper" --domain "software engineering" # 指定项目根目录 -vibe --root /path/to/project init --name "My Paper" --domain SE +copaper --root /path/to/project init --name "My Paper" --domain SE ``` 创建 `.agents/` 目录、`state.json`、`events.jsonl`,并复制 `.agents/skills/`、`storyline.md`、`paper.md`、`writingrules.md`、`AGENTS.md`。如果 `state.json` 已存在,会提示确认是否重新初始化。 -#### `vibe status` — 查看项目状态 +#### `copaper status` — 查看项目状态 ```bash # 人类可读格式 -vibe status +copaper status # JSON 格式(适合脚本解析) -vibe status --json +copaper status --json ``` 输出示例: @@ -248,124 +248,207 @@ writing [ ] not_started latex_review [ ] not_started ``` -#### `vibe skip` — 跳过阶段 +#### `copaper skip` — 跳过阶段 ```bash # 推荐写法:带原因 -vibe skip experiments --reason "纯理论论文,无需实验" +copaper skip experiments --reason "纯理论论文,无需实验" # 也可省略原因(不推荐) -vibe skip experiments +copaper skip experiments ``` **注意**:`skip` 的参数是阶段名称(如 `experiments`),不是阶段字母(如 `D`)。有效名称为:`storyline`、`literature`、`discussion`、`experiments`、`writing`、`latex_review`。 -#### `vibe set-phase` — 显式设置阶段状态 +#### `copaper set-phase` — 显式设置阶段状态 ```bash # 将 storyline 标为完成,并自动推进 current_phase -vibe set-phase storyline --status complete +copaper set-phase storyline --status complete # 将 discussion 标为进行中;如果推荐前置阶段未完成,会给出 warning 但不会硬阻止 -vibe set-phase discussion --status in_progress +copaper set-phase discussion --status in_progress # 将 experiments 标为 skipped -vibe set-phase experiments --status skipped --reason "纯理论论文" +copaper set-phase experiments --status skipped --reason "纯理论论文" ``` 支持的状态值:`not_started`、`in_progress`、`complete`、`skipped`。 这个命令适合 agent/脚本在不手改 `.agents/state.json` 的前提下,显式推进或回退工作流状态。 -#### `vibe log` — 查询操作日志 +#### `copaper log` — 查询操作日志 ```bash # 查看所有日志 -vibe log +copaper log # 按阶段过滤 -vibe log --phase storyline +copaper log --phase storyline # 按操作者过滤 -vibe log --operator user +copaper log --operator user # 查看最近 10 条 -vibe log --last 10 +copaper log --last 10 # 按日期过滤 -vibe log --since 2026-04-01 +copaper log --since 2026-04-01 ``` -#### `vibe report` — 生成周报 +#### `copaper report` — 生成周报 ```bash # 输出到终端 -vibe report +copaper report # 指定起始日期 -vibe report --since 2026-04-01 +copaper report --since 2026-04-01 # 输出到文件 -vibe report --output report.md +copaper report --output report.md ``` 周报包含:阶段进度、Git 提交摘要(按作者分组)、事件日志统计。如果不在 Git 仓库中,Git 部分会显示 "Git repository not available"。 -#### `vibe relatedwork` — 管理论文元数据、BibTeX 与 PDF +#### `copaper relatedwork` — 管理论文元数据、BibTeX 与 PDF + +literature 阶段的所有步骤都封装成 `copaper relatedwork *` 子命令。检索走 Semantic Scholar Graph API;关键词抽取与单篇摘要走任意 OpenAI 兼容的 LLM 端点(默认从 `.env` 读取配置)。 + +##### 必需环境变量(写到项目根的 `.env`,启动时自动加载) + +```bash +# Semantic Scholar +S2_API_KEY="..." # 推荐配置;不配也能跑(共享匿名池易 429) +S2_API_BASE="..." # 可选:走中转代理时填,未填走官方 https://api.semanticscholar.org/graph/v1 + +# LLM(keywords + summarize 需要) +OPENAI_API_KEY="..." # 必填 +COPAPER_MODEL="gpt-4o-mini" # 必填,建议先用便宜模型 smoke +OPENAI_BASE_URL="https://proxy/v1" # 可选:走中转代理时填 +``` + +> `.env` 已加入 `.gitignore`;密钥不会被提交。 + +##### 端到端 7 步流水线 + +```bash +# Step 1 · LLM 从 storyline.md 抽 query → relatedwork/queries.txt +copaper relatedwork keywords --count 6 + +# Step 2 · Semantic Scholar 检索 → relatedwork/search_cache.json +copaper relatedwork search --queries-file relatedwork/queries.txt --limit 5 + +# Step 3 · 灌进 canonical catalog → relatedwork/literature.json +copaper relatedwork import --input relatedwork/search_cache.json + +# Step 4 · 同步 BibTeX → relatedwork/paper_list.bib +copaper relatedwork sync-bib + +# Step 5 · 下载 OA PDF → relatedwork/pdfs/<paper_id>.pdf +copaper relatedwork download + +# Step 6 · LLM 单篇 summary → relatedwork/papers/<paper_id>.md +copaper relatedwork summarize --concurrency 4 + +# Step 7 · 交叉索引 + 覆盖报告 → .agents/cross_index.json +copaper relatedwork build-index + +# 任意时刻看状态 +copaper relatedwork status +``` + +##### 每个子命令的常用 flag ```bash -# 查看元数据总表状态 -vibe relatedwork status -vibe relatedwork status --json +# keywords —— 从 storyline.md / paper.md 抽搜索短语 +copaper relatedwork keywords --count 8 --model gpt-4o-mini --out relatedwork/queries.txt + +# search —— S2 检索 + BibTeX/arXiv/PDF URL/TLDR 自动归一化 +# 默认过滤(可覆盖):--fields-of-study "Computer Science" 默认开启,--open-access 默认关闭 +copaper relatedwork search --queries-file relatedwork/queries.txt \ + --limit 20 --year 2022-2026 \ + --venue "CVPR,NeurIPS" + +# 只要有 OA PDF 的论文(便于后续 download) +copaper relatedwork search --queries-file relatedwork/queries.txt --open-access -# 将 serper/arXiv 搜索结果导入 canonical catalog -vibe relatedwork import --input relatedwork/search_cache.json +# 跨学科搜索(关掉默认的 CS 限定) +copaper relatedwork search --queries-file relatedwork/queries.txt --fields-of-study "" -# 同步 literature.json 与 paper_list.bib -vibe relatedwork sync-bib +# 也可不写 queries-file,直接传 query +copaper relatedwork search --query "streaming vla" --query "robot policy" -# 下载全部待下载 PDF,或重试失败项 -vibe relatedwork download -vibe relatedwork download --retry-failed +# import / sync-bib —— 元数据双向同步 +copaper relatedwork import --input relatedwork/search_cache.json +copaper relatedwork sync-bib -# 注册单篇论文摘要并重建交叉索引 -vibe relatedwork register-summary --paper-id song2025ceed --summary-path relatedwork/papers/song2025ceed.md -vibe relatedwork build-index +# download —— urllib + 3 次重试 + %PDF 头校验 +copaper relatedwork download +copaper relatedwork download --retry-failed +copaper relatedwork download --paper-id song2025ceed + +# summarize —— pypdf 抽文本 + LLM,内部 ThreadPool + 16 QPS token bucket +copaper relatedwork summarize # 全部 downloaded 且无 summary 的 +copaper relatedwork summarize --paper-id <id> # 只一篇 +copaper relatedwork summarize --force # 重新做已有 summary +copaper relatedwork summarize --concurrency 8 --qps 16 --max-pdf-bytes 52428800 + +# build-index —— 解析 papers/*.md 生成交叉索引 + 覆盖报告 +copaper relatedwork build-index + +# register-summary —— 手动登记一篇外部生成的 summary(summarize CLI 已自动调,通常不需要手动) +copaper relatedwork register-summary --paper-id <id> --summary-path relatedwork/papers/<id>.md + +# status —— 总表 +copaper relatedwork status +copaper relatedwork status --json ``` -`relatedwork/literature.json` 是 canonical metadata catalog。它记录:论文题目、作者、发表 venue/journal、arXiv ID、BibTeX、PDF 下载链接、下载状态、PDF 路径、摘要路径等。`.agents/state.json` 只保留 literature phase 的聚合计数,如 `papers_found`、`papers_downloaded`、`download_failures`、`summaries_done`。 +##### 关键产物 + +| 文件 | 写入者 | 内容 | +|---|---|---| +| `relatedwork/queries.txt` | `keywords` | 一行一条搜索短语;可手动编辑后再喂 search | +| `relatedwork/search_cache.json` | `search` | S2 去重 + 归一化后的 paper 列表 | +| `relatedwork/literature.json` | `import` / `download` / `summarize` 等 | **canonical metadata catalog**(题目、作者、venue、arXiv ID、BibTeX、PDF 路径、summary 路径、状态) | +| `relatedwork/paper_list.bib` | `sync-bib` | 与 catalog 双向同步的 BibTeX | +| `relatedwork/pdfs/<paper_id>.pdf` | `download` | OA PDF 原件 | +| `relatedwork/papers/<paper_id>.md` | `summarize` | 单篇 markdown 总结(按 `.agents/skills/relatedwork-finder/template.md` 模板) | +| `.agents/cross_index.json` | `build-index` | storyline 技术点 ↔ 论文 反向索引 + 覆盖率 | +| `.agents/state.json` literature phase | 上述所有命令自动同步 | 聚合计数(`papers_found` / `papers_downloaded` / `download_failures` / `summaries_done` / `cross_index_built`) | -#### `vibe diff` — 阶段间差异对比 +#### `copaper diff` — 阶段间差异对比 ```bash -vibe diff storyline literature +copaper diff storyline literature ``` 显示两个阶段最后一次提交之间的 Git diff。如果某个阶段没有提交,会提示无 diff 可用。 -#### `vibe commit` — 阶段化 Git 提交 +#### `copaper commit` — 阶段化 Git 提交 ```bash # 自动检测当前阶段 -vibe commit -m "完成研究主线初稿" +copaper commit -m "完成研究主线初稿" # 指定阶段 -vibe commit --phase storyline -m "完成研究主线初稿" +copaper commit --phase storyline -m "完成研究主线初稿" # 强制提交(即使没有暂存变更) -vibe commit -m "空提交标记" --force +copaper commit -m "空提交标记" --force ``` -提交消息格式为 `[phase] message`,并自动添加 `Co-authored-by: VibePaper AI <ai@vibepaper>` 尾部。**必须在 Git 仓库中运行**。 +提交消息格式为 `[phase] message`,并自动添加 `Co-authored-by: CoPaper AI <ai@copaper>` 尾部。**必须在 Git 仓库中运行**。 -#### `vibe rollback` — 回滚到某阶段的提交 +#### `copaper rollback` — 回滚到某阶段的提交 ```bash # 交互式确认 -vibe rollback storyline +copaper rollback storyline # 跳过确认 -vibe rollback storyline -y +copaper rollback storyline -y ``` 使用 `git reset --soft` 回滚到指定阶段的最后一次提交,同时将 `state.json` 中该阶段状态重置为 `not_started`。**必须在 Git 仓库中运行**。 @@ -374,7 +457,7 @@ vibe rollback storyline -y | 错误信息 | 原因 | 解决方法 | |----------|------|----------| -| `No project found. Run 'vibe init' first.` | 当前目录没有 `.agents/state.json` | 先运行 `vibe init` | +| `No project found. Run 'copaper init' first.` | 当前目录没有 `.agents/state.json` | 先运行 `copaper init` | | `--root` 选项不生效 | `--root` 放在了子命令之后 | 将 `--root` 移到子命令之前 | | `skip` 报错无效阶段名 | 使用了字母标签如 `A`/`B` 而非阶段名 | 使用完整名称如 `storyline`、`experiments` | | `report` 显示 "Git repository not available" | 不在 Git 仓库中 | 在 Git 仓库内运行,或忽略此部分 | @@ -385,7 +468,7 @@ vibe rollback storyline -y ### `.agents/state.json` -项目初始化后由 `vibe init` 创建,是项目进度的唯一真实来源。结构如下: +项目初始化后由 `copaper init` 创建,是项目进度的唯一真实来源。结构如下: ```json { @@ -434,8 +517,8 @@ vibe rollback storyline -y "auto_commit": false, "identity": { "role": "assistant", - "git_name": "VibePaper Bot", - "git_email": "bot@vibepaper.dev" + "git_name": "CoPaper Bot", + "git_email": "bot@copaper.dev" } }, "checkers": {} @@ -487,9 +570,9 @@ vibe rollback storyline -y 可以使用 checker harness 从 `paper.md` 中的标准 AI comment 收集结果并写入状态: ```bash -vibe --root <project-dir> checkers collect -vibe --root <project-dir> checkers collect --checker logic --checker clarity -vibe --root <project-dir> checkers status +copaper --root <project-dir> checkers collect +copaper --root <project-dir> checkers collect --checker logic --checker clarity +copaper --root <project-dir> checkers status ``` harness 只解析 checker skills 已插入的 `<!-- AI Comments: ... -->` 块,不会伪装成自动执行 AI 审稿。带有 `Checker: <name>` 标记的评论会归档到对应 checker;没有标记时,评论会归入本次指定收集的 checker。 @@ -510,9 +593,11 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 **触发**:`"find related work"` -- 根据 `storyline.md` 生成关键词,调用 Serper MCP 检索相关文献 -- 下载 PDF 并启动独立的多模态上下文窗口逐篇阅读 -- 生成结构化摘要到 `relatedwork/papers/`,构建交叉索引 +- 编排 `copaper relatedwork keywords / search / import / sync-bib / download` 7 步流水线 +- 关键词抽取与 Semantic Scholar 检索都委派给 `copaper` CLI,**不再调用任何 MCP 搜索工具** +- 与 `relatedwork-summarizer` 配合完成 PDF 下载 → 单篇 summary → 交叉索引 + +详见 `copaper relatedwork` 章节。 ### socratic-discussion — 苏格拉底式讨论 @@ -568,7 +653,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 - 从已有 `.pdf` 初稿提取内容,按语义映射到 `paper.md` 的既有 section - 可以从已有的论文初稿转变为paper.md进行审稿 - 严格按 section 逐步转换,并在每节写入前走用户确认 -- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `paper.md`,先执行 `vibe --root <project-dir> init ...` 再更新 `writing` phase +- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `paper.md`,先执行 `copaper --root <project-dir> init ...` 再更新 `writing` phase ### ppt2storyline — PPT/PPTX 转 Storyline @@ -577,7 +662,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 - 从 `.pptx` 提取幻灯片文本并映射到 `storyline.md` 既有 section - 可以从小组会ppt直接转变成storyline.md并进行完整的工作流程 - 以“忠实原文 + 轻量润色”为原则,不新增未在 PPT 出现的研究结论 -- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `storyline.md`,先执行 `vibe --root <project-dir> init ...` 再更新 phase +- 在项目早期可先检查项目目录;若缺少 `.agents/skills` 或 `storyline.md`,先执行 `copaper --root <project-dir> init ...` 再更新 phase ### humanizer — 去 AI 痕迹润色 @@ -596,7 +681,7 @@ Agent Skills 通过自然语言触发,OpenCode 会自动发现并加载对应 python -m pytest tests/ -v # 运行测试并查看覆盖率 -python -m pytest tests/ --cov=vibepaper --cov-report=term +python -m pytest tests/ --cov=copaper --cov-report=term ``` 当前测试状态:**全部通过,覆盖率约 90%**。 @@ -632,32 +717,32 @@ python -m pytest tests/ --cov=vibepaper --cov-report=term ```bash # 1. 初始化项目 -vibe init --name "Test Paper" --domain SE +copaper init --name "Test Paper" --domain SE # 2. 查看状态 -vibe status -vibe status --json +copaper status +copaper status --json # 3. 提交 -vibe commit -m "draft" +copaper commit -m "draft" # 4. 查看日志 -vibe log -vibe log --phase storyline +copaper log +copaper log --phase storyline # 5. 回滚 -vibe rollback storyline +copaper rollback storyline # 6. 生成报告 -vibe report -vibe report --since 2026-04-01 -vibe report --output report.md +copaper report +copaper report --since 2026-04-01 +copaper report --output report.md # 7. 阶段差异 -vibe diff storyline literature +copaper diff storyline literature # 8. 跳过阶段 -vibe skip literature --reason "not needed" +copaper skip literature --reason "not needed" ``` **Git 集成验收**: @@ -673,11 +758,11 @@ vibe skip literature --reason "not needed" ## 故障排除 -### `No project found. Run 'vibe init' first.` +### `No project found. Run 'copaper init' first.` 当前目录(或 `--root` 指定目录)下没有 `.agents/state.json` 文件。 -**解决**:在目标目录运行 `vibe init --name "项目名" --domain "领域"`。 +**解决**:在目标目录运行 `copaper init --name "项目名" --domain "领域"`。 ### `--root` 位置错误 @@ -685,10 +770,10 @@ vibe skip literature --reason "not needed" ```bash # ✅ 正确 -vibe --root /path/to/project status +copaper --root /path/to/project status # ❌ 错误——Click 不会识别子命令之后的全局选项 -vibe status --root /path/to/project +copaper status --root /path/to/project ``` ### `skip` 命令需要有效阶段名 @@ -697,10 +782,10 @@ vibe status --root /path/to/project ```bash # ✅ 正确 -vibe skip experiments --reason "纯理论论文" +copaper skip experiments --reason "纯理论论文" # ❌ 错误——D 不是有效阶段名 -vibe skip D --reason "纯理论论文" +copaper skip D --reason "纯理论论文" ``` 有效阶段名:`storyline`、`literature`、`discussion`、`experiments`、`writing`、`latex_review`。 @@ -720,10 +805,10 @@ vibe skip D --reason "纯理论论文" ```bash # 会提示输入 Project name 和 Research domain -vibe init +copaper init # 非交互式——适合脚本 -vibe init --name "My Paper" --domain "SE" +copaper init --name "My Paper" --domain "SE" ``` ## 建议的首次运行流程 @@ -737,15 +822,21 @@ pip install -e .[dev] # 2. 初始化项目(在 Git 仓库中) cd /path/to/your/paper-project git init # 如果还不是 Git 仓库 -vibe init --name "My Research" --domain "software engineering" +copaper init --name "My Research" --domain "software engineering" # 3. 构建研究主线 # 在 OpenCode 中触发:"help me write storyline" # 或手动编辑 storyline.md -# 4. 检索文献 -# 在 OpenCode 中触发:"find related work" -# 检查 relatedwork/papers/ 目录 +# 4. 检索文献(纯 CLI 流水线,需先在 .env 中配 OPENAI_API_KEY / COPAPER_MODEL / S2_API_KEY) +copaper relatedwork keywords --count 6 +copaper relatedwork search --queries-file relatedwork/queries.txt --limit 5 +copaper relatedwork import --input relatedwork/search_cache.json +copaper relatedwork sync-bib +copaper relatedwork download +copaper relatedwork summarize --concurrency 4 +copaper relatedwork build-index +# 也可以在 OpenCode 中触发 "find related work" 让 skill 编排上述命令 # 5. 苏格拉底式讨论 # 在 OpenCode 中触发:"discuss my research" @@ -753,7 +844,7 @@ vibe init --name "My Research" --domain "software engineering" # 6. 实验分析(或跳过) # 在 OpenCode 中触发:"analyze experiments" -# 或跳过:vibe skip experiments --reason "纯理论论文无需实验" +# 或跳过:copaper skip experiments --reason "纯理论论文无需实验" # 7. 写作 # 在 OpenCode 中触发:"write the paper" @@ -772,9 +863,9 @@ vibe init --name "My Research" --domain "software engineering" # 生成最终投稿版本 # 全程可用 CLI 跟踪进度 -vibe status -vibe log -vibe report +copaper status +copaper log +copaper report ``` ## 写作规范 diff --git a/copaper.egg-info/SOURCES.txt b/copaper.egg-info/SOURCES.txt new file mode 100644 index 0000000..59f0339 --- /dev/null +++ b/copaper.egg-info/SOURCES.txt @@ -0,0 +1,90 @@ +README.md +pyproject.toml +copaper/__init__.py +copaper/__main__.py +copaper/checker_integration.py +copaper/cli.py +copaper/constants.py +copaper/crossindex.py +copaper/dimensions.py +copaper/eventlog.py +copaper/git_ops.py +copaper/identity.py +copaper/literature.py +copaper/llm_client.py +copaper/relatedwork_clean.py +copaper/relatedwork_download.py +copaper/relatedwork_keywords.py +copaper/relatedwork_search.py +copaper/relatedwork_summarize.py +copaper/report.py +copaper/scaffold.py +copaper/schema.py +copaper/state.py +copaper.egg-info/PKG-INFO +copaper.egg-info/SOURCES.txt +copaper.egg-info/dependency_links.txt +copaper.egg-info/entry_points.txt +copaper.egg-info/requires.txt +copaper.egg-info/top_level.txt +copaper/scaffold/AGENTS.md +copaper/scaffold/paper.md +copaper/scaffold/storyline.md +copaper/scaffold/writingrules.md +copaper/scaffold/skills/AGENTS.md +copaper/scaffold/skills/bogus-data-helper/SKILL.md +copaper/scaffold/skills/clarity-checker/SKILL.md +copaper/scaffold/skills/clarity-checker/examples.md +copaper/scaffold/skills/copaper-manage/SKILL.md +copaper/scaffold/skills/data-checker/SKILL.md +copaper/scaffold/skills/data-checker/examples.md +copaper/scaffold/skills/evaluation-protocol-checker/SKILL.md +copaper/scaffold/skills/evaluation-protocol-checker/examples.md +copaper/scaffold/skills/experiment-analyzer/SKILL.md +copaper/scaffold/skills/human-comment-helper/SKILL.md +copaper/scaffold/skills/humanizer/LICENSE +copaper/scaffold/skills/humanizer/README.md +copaper/scaffold/skills/humanizer/SKILL.md +copaper/scaffold/skills/humanizer/WARP.md +copaper/scaffold/skills/latex-final-writer/SKILL.md +copaper/scaffold/skills/latex2markdown/SKILL.md +copaper/scaffold/skills/logic-checker/SKILL.md +copaper/scaffold/skills/logic-checker/examples.md +copaper/scaffold/skills/mad-writer/SKILL.md +copaper/scaffold/skills/markdown-helper/SKILL.md +copaper/scaffold/skills/markdown-review/SKILL.md +copaper/scaffold/skills/markdown2latex/SKILL.md +copaper/scaffold/skills/novelty-checker/SKILL.md +copaper/scaffold/skills/novelty-checker/examples.md +copaper/scaffold/skills/pdf2paper/SKILL.md +copaper/scaffold/skills/ppt2storyline/SKILL.md +copaper/scaffold/skills/problem-checker/SKILL.md +copaper/scaffold/skills/problem-checker/examples.md +copaper/scaffold/skills/relatedwork-finder/SKILL.md +copaper/scaffold/skills/relatedwork-finder/template.md +copaper/scaffold/skills/relatedwork-summarizer/SKILL.md +copaper/scaffold/skills/relatedwork-summarizer/template.md +copaper/scaffold/skills/review-revise/SKILL.md +copaper/scaffold/skills/socratic-discussion/SKILL.md +copaper/scaffold/skills/state-machine-markdown-helper/SKILL.md +copaper/scaffold/skills/storyline-helper/SKILL.md +copaper/scaffold/skills/submission-precheck/SKILL.md +copaper/scaffold/skills/technical-depth-checker/SKILL.md +copaper/scaffold/skills/technical-depth-checker/examples.md +copaper/scaffold/skills/writing-orchestrator/SKILL.md +tests/test_checker_integration.py +tests/test_checker_main.py +tests/test_cli.py +tests/test_crossindex.py +tests/test_dimensions.py +tests/test_eventlog.py +tests/test_git_ops.py +tests/test_identity.py +tests/test_literature.py +tests/test_relatedwork_clean.py +tests/test_relatedwork_llm.py +tests/test_relatedwork_search.py +tests/test_report.py +tests/test_scaffold.py +tests/test_skill_conventions.py +tests/test_state.py \ No newline at end of file diff --git a/vibepaper.egg-info/dependency_links.txt b/copaper.egg-info/dependency_links.txt similarity index 100% rename from vibepaper.egg-info/dependency_links.txt rename to copaper.egg-info/dependency_links.txt diff --git a/copaper.egg-info/entry_points.txt b/copaper.egg-info/entry_points.txt new file mode 100644 index 0000000..de8ea31 --- /dev/null +++ b/copaper.egg-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +copaper = copaper.cli:main diff --git a/vibepaper.egg-info/requires.txt b/copaper.egg-info/requires.txt similarity index 100% rename from vibepaper.egg-info/requires.txt rename to copaper.egg-info/requires.txt diff --git a/copaper.egg-info/top_level.txt b/copaper.egg-info/top_level.txt new file mode 100644 index 0000000..b5152ae --- /dev/null +++ b/copaper.egg-info/top_level.txt @@ -0,0 +1 @@ +copaper diff --git a/copaper/__init__.py b/copaper/__init__.py new file mode 100644 index 0000000..983aa40 --- /dev/null +++ b/copaper/__init__.py @@ -0,0 +1,15 @@ +"""CoPaper - AI-assisted academic writing framework.""" + +__version__ = "0.1.0" + +from copaper.constants import Phase, PhaseStatus, PHASE_ORDER, PHASE_DEPENDENCIES +from copaper.schema import STATE_SCHEMA + +__all__ = [ + "__version__", + "Phase", + "PhaseStatus", + "PHASE_ORDER", + "PHASE_DEPENDENCIES", + "STATE_SCHEMA", +] diff --git a/copaper/__main__.py b/copaper/__main__.py new file mode 100644 index 0000000..512c9c5 --- /dev/null +++ b/copaper/__main__.py @@ -0,0 +1,6 @@ +"""Entry point for `python -m copaper`.""" + +from copaper.cli import main + +if __name__ == "__main__": + main() diff --git a/vibepaper/checker_integration.py b/copaper/checker_integration.py similarity index 99% rename from vibepaper/checker_integration.py rename to copaper/checker_integration.py index b144ece..0372296 100644 --- a/vibepaper/checker_integration.py +++ b/copaper/checker_integration.py @@ -13,7 +13,7 @@ from pathlib import Path from typing import Any -from vibepaper.eventlog import EventLogger +from copaper.eventlog import EventLogger # The 7 checker names @@ -266,7 +266,7 @@ def _stable_issue_id(checker: str, issue: dict[str, Any], index: int) -> str: class CheckerHarness: - """Collect checker issues from a VibePaper paper into project state. + """Collect checker issues from a CoPaper paper into project state. The harness does not execute AI skills itself. It consumes the standardized ``<!-- AI Comments: ... -->`` blocks that checker skills diff --git a/vibepaper/cli.py b/copaper/cli.py similarity index 94% rename from vibepaper/cli.py rename to copaper/cli.py index 7c5195a..6f4af12 100644 --- a/vibepaper/cli.py +++ b/copaper/cli.py @@ -1,4 +1,4 @@ -"""CLI entry point for the `vibe` command.""" +"""CLI entry point for the `copaper` command.""" from __future__ import annotations @@ -10,12 +10,12 @@ import click -import vibepaper -from vibepaper.constants import PHASE_ORDER, PhaseStatus -from vibepaper.eventlog import EventLogger -from vibepaper.literature import LiteratureCatalog, LiteratureCatalogError -from vibepaper.scaffold import scaffold_project -from vibepaper.state import StateFileError, StateManager +import copaper +from copaper.constants import PHASE_ORDER, PhaseStatus +from copaper.eventlog import EventLogger +from copaper.literature import LiteratureCatalog, LiteratureCatalogError +from copaper.scaffold import scaffold_project +from copaper.state import StateFileError, StateManager _STATUS_DISPLAY = { PhaseStatus.COMPLETE: "[done]", @@ -63,7 +63,7 @@ def _load_state_manager_or_exit(root: str) -> StateManager: try: sm.load() except StateFileError: - click.echo("Error: No project found. Run 'vibe init' first.", err=True) + click.echo("Error: No project found. Run 'copaper init' first.", err=True) sys.exit(1) return sm @@ -110,10 +110,10 @@ def _load_relatedwork_records(input_path: Path) -> list[dict[str, Any]]: help="Project root directory.", show_default=True, ) -@click.version_option(version=vibepaper.__version__) +@click.version_option(version=copaper.__version__) @click.pass_context def main(ctx: click.Context, root: str) -> None: - """VibePaper - AI-assisted academic writing framework.""" + """CoPaper - AI-assisted academic writing framework.""" ctx.ensure_object(dict) ctx.obj["root"] = root @@ -132,7 +132,7 @@ def main(ctx: click.Context, root: str) -> None: ) @click.pass_context def init(ctx: click.Context, name: str, domain: str) -> None: - """Initialise a new VibePaper project.""" + """Initialise a new CoPaper project.""" root = ctx.obj["root"] sm = StateManager(root) @@ -170,7 +170,7 @@ def status(ctx: click.Context, as_json: bool) -> None: state = sm._state except StateFileError as exc: click.echo(f"Error: {exc}", err=True) - click.echo("No project found. Run 'vibe init' first.", err=True) + click.echo("No project found. Run 'copaper init' first.", err=True) sys.exit(1) if as_json: @@ -229,7 +229,7 @@ def checkers_collect( log_path = str(sm.project_root / ".agents" / "events.jsonl") el = EventLogger(log_path) - from vibepaper.checker_integration import CheckerHarness + from copaper.checker_integration import CheckerHarness harness = CheckerHarness(root, paper_path=paper_path, event_logger=el) try: @@ -265,7 +265,7 @@ def checkers_status(ctx: click.Context, as_json: bool) -> None: root = ctx.obj["root"] _ = _load_state_manager_or_exit(root) - from vibepaper.checker_integration import CheckerTracker, format_checker_results + from copaper.checker_integration import CheckerTracker, format_checker_results tracker = CheckerTracker(root) results = tracker.get_checker_status() @@ -405,7 +405,7 @@ def relatedwork_search_cmd( root = ctx.obj["root"] sm = _load_state_manager_or_exit(root) - from vibepaper.relatedwork_search import ( + from copaper.relatedwork_search import ( SemanticScholarError, _read_queries_file, resolve_api_key, @@ -468,7 +468,7 @@ def relatedwork_search_cmd( click.echo(f"Cache written to {outcome.cache_path}") click.echo(f"Endpoint: {base_url}") click.echo( - f"Next: vibe --root {root} relatedwork import --input {outcome.cache_path}" + f"Next: copaper --root {root} relatedwork import --input {outcome.cache_path}" ) if not outcome.api_key_used: click.echo( @@ -569,7 +569,7 @@ def relatedwork_download_cmd( root = ctx.obj["root"] sm = _load_state_manager_or_exit(root) - from vibepaper.relatedwork_download import download_papers + from copaper.relatedwork_download import download_papers outcome = download_papers(root, paper_id=paper_id, retry_failed=retry_failed) @@ -707,7 +707,7 @@ def relatedwork_build_index(ctx: click.Context) -> None: @click.option( "--model", default=None, - help="Override VIBEPAPER_MODEL.", + help="Override COPAPER_MODEL.", ) @click.pass_context def relatedwork_keywords_cmd( @@ -721,8 +721,8 @@ def relatedwork_keywords_cmd( root = ctx.obj["root"] sm = _load_state_manager_or_exit(root) - from vibepaper.llm_client import LLMConfigError - from vibepaper.relatedwork_keywords import extract_keywords + from copaper.llm_client import LLMConfigError + from copaper.relatedwork_keywords import extract_keywords try: outcome = extract_keywords( @@ -758,7 +758,7 @@ def relatedwork_keywords_cmd( for query in outcome.queries: click.echo(f" - {query}") click.echo( - f"Next: vibe --root {root} relatedwork search " + f"Next: copaper --root {root} relatedwork search " f"--queries-file {outcome.output_path}" ) @@ -777,7 +777,7 @@ def relatedwork_keywords_cmd( type=click.Path(dir_okay=False, path_type=Path), help="Summary template (default: .agents/skills/relatedwork-finder/template.md).", ) -@click.option("--model", default=None, help="Override VIBEPAPER_MODEL.") +@click.option("--model", default=None, help="Override COPAPER_MODEL.") @click.option( "--qps", type=float, @@ -820,8 +820,8 @@ def relatedwork_summarize_cmd( root = ctx.obj["root"] sm = _load_state_manager_or_exit(root) - from vibepaper.llm_client import LLMConfigError - from vibepaper.relatedwork_summarize import summarize_papers + from copaper.llm_client import LLMConfigError + from copaper.relatedwork_summarize import summarize_papers try: outcome = summarize_papers( @@ -900,7 +900,7 @@ def relatedwork_clean_cmd( root = ctx.obj["root"] sm = _load_state_manager_or_exit(root) - from vibepaper.relatedwork_clean import clean_relatedwork, plan_targets + from copaper.relatedwork_clean import clean_relatedwork, plan_targets targets = [path for path in plan_targets(root) if path.exists()] if not targets: @@ -968,7 +968,7 @@ def set_phase_cmd(ctx: click.Context, phase: str, new_status: str, reason: str) try: sm.load() except StateFileError: - click.echo("Error: No project found. Run 'vibe init' first.", err=True) + click.echo("Error: No project found. Run 'copaper init' first.", err=True) sys.exit(1) if new_status in (PhaseStatus.IN_PROGRESS, PhaseStatus.COMPLETE): @@ -1019,13 +1019,13 @@ def commit(ctx, phase, message, force): sm.save() phase = sm.get_current_phase() except StateFileError: - click.echo("Error: No project found. Run 'vibe init' first.", err=True) + click.echo("Error: No project found. Run 'copaper init' first.", err=True) sys.exit(1) log_path = str(sm.project_root / ".agents" / "events.jsonl") el = EventLogger(log_path) - from vibepaper.git_ops import GitManager + from copaper.git_ops import GitManager gm = GitManager(root, event_logger=el) @@ -1056,7 +1056,7 @@ def rollback(ctx, phase, yes): log_path = str(sm.project_root / ".agents" / "events.jsonl") el = EventLogger(log_path) - from vibepaper.git_ops import GitManager + from copaper.git_ops import GitManager gm = GitManager(root, event_logger=el) @@ -1138,7 +1138,7 @@ def skip(ctx, phase, reason): try: sm.load() except StateFileError: - click.echo("Error: No project found. Run 'vibe init' first.", err=True) + click.echo("Error: No project found. Run 'copaper init' first.", err=True) sys.exit(1) sm.skip_phase(phase, reason=reason) @@ -1168,7 +1168,7 @@ def report(ctx: click.Context, since: str | None, output: str | None) -> None: """Generate a weekly progress report.""" root = ctx.obj["root"] - from vibepaper.report import generate_weekly_report + from copaper.report import generate_weekly_report try: md = generate_weekly_report(repo_path=root, since_date=since) @@ -1191,7 +1191,7 @@ def diff_cmd(ctx: click.Context, phase_a: str, phase_b: str) -> None: """Show diff between two phases.""" root = ctx.obj["root"] - from vibepaper.report import generate_diff_report + from copaper.report import generate_diff_report try: result = generate_diff_report(root, phase_a, phase_b) diff --git a/vibepaper/codemap.md b/copaper/codemap.md similarity index 50% rename from vibepaper/codemap.md rename to copaper/codemap.md index 8d761dc..5418cb6 100644 --- a/vibepaper/codemap.md +++ b/copaper/codemap.md @@ -1,4 +1,4 @@ -# vibepaper/ +# copaper/ <!-- description: Runtime package architecture map. --> @@ -8,7 +8,7 @@ ###### CLI-centered workflow runtime -`vibepaper/` implements the `vibe` command, project state persistence, append-only event logging, scaffold copying, related-work automation, checker status tracking, Git-backed phase operations, reports, and OpenAI-compatible LLM helpers for structured paper workflows. +`copaper/` implements the `copaper` command, project state persistence, append-only event logging, scaffold copying, related-work automation, checker status tracking, Git-backed phase operations, reports, and OpenAI-compatible LLM helpers for structured paper workflows. ###### Six-phase project coordinator @@ -20,15 +20,15 @@ The package models the workflow as `storyline`, `literature`, `discussion`, `exp ###### Click command facade -`vibepaper/cli.py` is the command facade. It keeps user I/O, validation, and exit behavior at the boundary while delegating durable state to `StateManager`, event writes to `EventLogger`, related-work storage to `LiteratureCatalog`, and specialized jobs to small pipeline modules. +`copaper/cli.py` is the command facade. It keeps user I/O, validation, and exit behavior at the boundary while delegating durable state to `StateManager`, event writes to `EventLogger`, related-work storage to `LiteratureCatalog`, and specialized jobs to small pipeline modules. ###### Manager objects over JSON files -`vibepaper/state.py`, `vibepaper/eventlog.py`, `vibepaper/literature.py`, `vibepaper/git_ops.py`, and `vibepaper/checker_integration.py` wrap individual storage or integration concerns. State and literature writes use atomic replace patterns; the event log uses append-only JSON Lines plus simple rotation. +`copaper/state.py`, `copaper/eventlog.py`, `copaper/literature.py`, `copaper/git_ops.py`, and `copaper/checker_integration.py` wrap individual storage or integration concerns. State and literature writes use atomic replace patterns; the event log uses append-only JSON Lines plus simple rotation. ###### Lazy external dependencies -CLI commands import costly or optional integrations only when invoked. Semantic Scholar calls live in `vibepaper/relatedwork_search.py`, OpenAI client creation in `vibepaper/llm_client.py`, PDF parsing in `vibepaper/relatedwork_summarize.py`, and GitPython access in `vibepaper/git_ops.py`. +CLI commands import costly or optional integrations only when invoked. Semantic Scholar calls live in `copaper/relatedwork_search.py`, OpenAI client creation in `copaper/llm_client.py`, PDF parsing in `copaper/relatedwork_summarize.py`, and GitPython access in `copaper/git_ops.py`. ###### Dataclass job results @@ -40,7 +40,7 @@ Batch-style operations return structured outcomes instead of printing internally ###### Project initialization -`vibe --root <dir> init` creates `.agents/state.json` through `StateManager.init_project`, copies bundled assets through `scaffold_project`, creates `.agents/skills/`, starter markdown files, and `AGENTS.md`, then logs an `init_project` event. +`copaper --root <dir> init` creates `.agents/state.json` through `StateManager.init_project`, copies bundled assets through `scaffold_project`, creates `.agents/skills/`, starter markdown files, and `AGENTS.md`, then logs an `init_project` event. ###### State and event updates @@ -68,7 +68,7 @@ Checker skills can be tracked through `CheckerTracker`, which stores latest seve ###### Command-line entry points -`vibepaper/cli.py` exposes the Click command tree used by the installed `vibe` command. `vibepaper/__main__.py` forwards `python -m vibepaper` to the same command group, and `vibepaper/__init__.py` exports version, phase enums, phase order, dependencies, and state schema. +`copaper/cli.py` exposes the Click command tree used by the installed `copaper` command. `copaper/__main__.py` forwards `python -m copaper` to the same command group, and `copaper/__init__.py` exports version, phase enums, phase order, dependencies, and state schema. ###### Filesystem contract @@ -76,11 +76,11 @@ The runtime expects project artifacts relative to `--root`: `.agents/state.json` ###### External services and libraries -Semantic Scholar integration uses `S2_API_KEY`, `SEMANTIC_SCHOLAR_API_KEY`, and optional `S2_API_BASE`. LLM integration uses `OPENAI_API_KEY`, optional `OPENAI_BASE_URL`, and `VIBEPAPER_MODEL`. PDF summarization depends on `pypdf`; Git operations and identity detection depend on GitPython. +Semantic Scholar integration uses `S2_API_KEY`, `SEMANTIC_SCHOLAR_API_KEY`, and optional `S2_API_BASE`. LLM integration uses `OPENAI_API_KEY`, optional `OPENAI_BASE_URL`, and `COPAPER_MODEL`. PDF summarization depends on `pypdf`; Git operations and identity detection depend on GitPython. ###### Scaffold and skills -`vibepaper/scaffold.py` copies package data from `vibepaper/scaffold/` into target projects. It is intentionally non-destructive for existing starter files and skill directories, but refreshes the skills-level `AGENTS.md` so scaffolded skill guidance stays current. +`copaper/scaffold.py` copies package data from `copaper/scaffold/` into target projects. It is intentionally non-destructive for existing starter files and skill directories, but refreshes the skills-level `AGENTS.md` so scaffolded skill guidance stays current. ## Key Files @@ -88,24 +88,24 @@ Semantic Scholar integration uses `S2_API_KEY`, `SEMANTIC_SCHOLAR_API_KEY`, and ###### CLI and workflow schema -`vibepaper/cli.py` defines all `vibe` commands and subcommands. `vibepaper/constants.py` defines phase enums, statuses, order, and dependencies. `vibepaper/schema.py` defines the JSON-shaped state schema and default project state. +`copaper/cli.py` defines all `copaper` commands and subcommands. `copaper/constants.py` defines phase enums, statuses, order, and dependencies. `copaper/schema.py` defines the JSON-shaped state schema and default project state. ###### Persistence modules -`vibepaper/state.py` owns `.agents/state.json` lifecycle and phase helpers. `vibepaper/eventlog.py` owns append/query/export for `.agents/events.jsonl`. `vibepaper/literature.py` owns canonical related-work metadata, BibTeX sync, artifact status refresh, summary registration, and cross-index delegation. +`copaper/state.py` owns `.agents/state.json` lifecycle and phase helpers. `copaper/eventlog.py` owns append/query/export for `.agents/events.jsonl`. `copaper/literature.py` owns canonical related-work metadata, BibTeX sync, artifact status refresh, summary registration, and cross-index delegation. ###### Related-work modules -`vibepaper/relatedwork_keywords.py` extracts search queries with the LLM. `vibepaper/relatedwork_search.py` queries Semantic Scholar and caches normalized records. `vibepaper/relatedwork_download.py` downloads and validates PDFs. `vibepaper/relatedwork_summarize.py` extracts PDF text and writes LLM summaries. `vibepaper/relatedwork_clean.py` resets related-work artifacts. +`copaper/relatedwork_keywords.py` extracts search queries with the LLM. `copaper/relatedwork_search.py` queries Semantic Scholar and caches normalized records. `copaper/relatedwork_download.py` downloads and validates PDFs. `copaper/relatedwork_summarize.py` extracts PDF text and writes LLM summaries. `copaper/relatedwork_clean.py` resets related-work artifacts. ###### Index, checkers, and discussion -`vibepaper/crossindex.py` builds and queries paper-to-topic mappings. `vibepaper/checker_integration.py` records checker outcomes and parses AI comments. `vibepaper/dimensions.py` defines checker-aligned discussion dimensions and Socratic question banks. +`copaper/crossindex.py` builds and queries paper-to-topic mappings. `copaper/checker_integration.py` records checker outcomes and parses AI comments. `copaper/dimensions.py` defines checker-aligned discussion dimensions and Socratic question banks. ###### Git, reporting, and LLM -`vibepaper/git_ops.py` wraps GitPython for phase commits, rollback, diffs, and committer lookup. `vibepaper/report.py` builds weekly progress and phase diff reports. `vibepaper/identity.py` detects Git identity and roles. `vibepaper/llm_client.py` resolves OpenAI-compatible config and rate limits batch LLM calls. +`copaper/git_ops.py` wraps GitPython for phase commits, rollback, diffs, and committer lookup. `copaper/report.py` builds weekly progress and phase diff reports. `copaper/identity.py` detects Git identity and roles. `copaper/llm_client.py` resolves OpenAI-compatible config and rate limits batch LLM calls. ###### Package entry and scaffold -`vibepaper/scaffold.py` copies bundled project assets from `vibepaper/scaffold/`. `vibepaper/__main__.py` enables module execution. `vibepaper/__init__.py` exposes the public package constants used by callers and tests. +`copaper/scaffold.py` copies bundled project assets from `copaper/scaffold/`. `copaper/__main__.py` enables module execution. `copaper/__init__.py` exposes the public package constants used by callers and tests. diff --git a/vibepaper/constants.py b/copaper/constants.py similarity index 93% rename from vibepaper/constants.py rename to copaper/constants.py index 3c58237..4bd6f91 100644 --- a/vibepaper/constants.py +++ b/copaper/constants.py @@ -1,4 +1,4 @@ -"""Phase and status constants for VibePaper pipeline. +"""Phase and status constants for CoPaper pipeline. Defines the 6-phase writing pipeline, status values, phase ordering, and dependency graph. Modeled after AutoResearchClaw's Stage/StageStatus pattern. @@ -10,7 +10,7 @@ class Phase(str, Enum): - """The 6 phases of the VibePaper writing pipeline. + """The 6 phases of the CoPaper writing pipeline. Each phase corresponds to a major workflow stage: storyline - Define research storyline and core insight diff --git a/vibepaper/crossindex.py b/copaper/crossindex.py similarity index 100% rename from vibepaper/crossindex.py rename to copaper/crossindex.py diff --git a/vibepaper/dimensions.py b/copaper/dimensions.py similarity index 100% rename from vibepaper/dimensions.py rename to copaper/dimensions.py diff --git a/vibepaper/eventlog.py b/copaper/eventlog.py similarity index 98% rename from vibepaper/eventlog.py rename to copaper/eventlog.py index bf31cf3..b7f6c97 100644 --- a/vibepaper/eventlog.py +++ b/copaper/eventlog.py @@ -1,6 +1,6 @@ """Event log (.agents/events.jsonl) append and query. -EventLogger provides append-only JSON Lines logging for the VibePaper +EventLogger provides append-only JSON Lines logging for the CoPaper pipeline. Each event is a single JSON object on one line, enabling concurrent-safe appends and simple line-by-line querying. """ diff --git a/vibepaper/git_ops.py b/copaper/git_ops.py similarity index 94% rename from vibepaper/git_ops.py rename to copaper/git_ops.py index 174ab59..e09ecb0 100644 --- a/vibepaper/git_ops.py +++ b/copaper/git_ops.py @@ -1,8 +1,8 @@ """Git operations: phase-based commits, rollback, diffs, and identity management. GitManager wraps GitPython to provide structured git operations aligned with -the VibePaper pipeline phases. Each commit is tagged with a phase prefix -(e.g. ``[storyline]``) and includes a VibePaper co-author trailer. +the CoPaper pipeline phases. Each commit is tagged with a phase prefix +(e.g. ``[storyline]``) and includes a CoPaper co-author trailer. """ from __future__ import annotations @@ -13,11 +13,11 @@ import git if TYPE_CHECKING: - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger class GitManager: - """Manage git operations for the VibePaper pipeline. + """Manage git operations for the CoPaper pipeline. Parameters: repo_path: Path to the git repository (default ``"."``). @@ -77,7 +77,7 @@ def commit_phase( ) formatted_message = ( - f"[{phase}] {message}\n\nCo-authored-by: VibePaper AI <ai@vibepaper>" + f"[{phase}] {message}\n\nCo-authored-by: CoPaper AI <ai@copaper>" ) if self.event_logger is not None: diff --git a/vibepaper/identity.py b/copaper/identity.py similarity index 100% rename from vibepaper/identity.py rename to copaper/identity.py diff --git a/vibepaper/literature.py b/copaper/literature.py similarity index 99% rename from vibepaper/literature.py rename to copaper/literature.py index aec38b4..0d5f8d8 100644 --- a/vibepaper/literature.py +++ b/copaper/literature.py @@ -447,7 +447,7 @@ def iter_download_candidates( return candidates def build_cross_index(self) -> dict[str, Any]: - from vibepaper.crossindex import CrossIndex + from copaper.crossindex import CrossIndex index = CrossIndex( index_path=str(self.project_root / ".agents" / "cross_index.json") diff --git a/vibepaper/llm_client.py b/copaper/llm_client.py similarity index 90% rename from vibepaper/llm_client.py rename to copaper/llm_client.py index fbafbac..836260a 100644 --- a/vibepaper/llm_client.py +++ b/copaper/llm_client.py @@ -1,7 +1,7 @@ """Shared OpenAI-compatible client helpers for related-work tasks. Reads ``OPENAI_API_KEY``, ``OPENAI_BASE_URL`` (optional, for proxies), and -``VIBEPAPER_MODEL`` from the environment. The ``TokenBucket`` rate limiter +``COPAPER_MODEL`` from the environment. The ``TokenBucket`` rate limiter keeps batch jobs (e.g. per-paper summarization) under a configurable QPS ceiling. """ @@ -26,17 +26,17 @@ class LLMConfig: def resolve_model(override: str | None = None) -> str: - """Pick the model name: explicit override > ``VIBEPAPER_MODEL`` env.""" + """Pick the model name: explicit override > ``COPAPER_MODEL`` env.""" if override: candidate = override.strip() if candidate: return candidate - env_value = (os.environ.get("VIBEPAPER_MODEL") or "").strip() + env_value = (os.environ.get("COPAPER_MODEL") or "").strip() if not env_value: raise LLMConfigError( - "VIBEPAPER_MODEL is not set. Configure it in .env, e.g. " - "VIBEPAPER_MODEL=gpt-4o-mini." + "COPAPER_MODEL is not set. Configure it in .env, e.g. " + "COPAPER_MODEL=gpt-4o-mini." ) return env_value diff --git a/vibepaper/relatedwork_clean.py b/copaper/relatedwork_clean.py similarity index 96% rename from vibepaper/relatedwork_clean.py rename to copaper/relatedwork_clean.py index 50d071c..0491e2f 100644 --- a/vibepaper/relatedwork_clean.py +++ b/copaper/relatedwork_clean.py @@ -4,7 +4,7 @@ ``Path.unlink``) the entire ``relatedwork/`` tree and ``.agents/cross_index.json``, then zeros out the literature-phase counters in ``.agents/state.json``. -The intent is to undo every artifact produced by ``vibe relatedwork`` so the +The intent is to undo every artifact produced by ``copaper relatedwork`` so the user can rerun the pipeline from scratch. PDFs and per-paper summaries are included — there is no partial mode here. """ @@ -18,8 +18,8 @@ from pathlib import Path from typing import Callable -from vibepaper.constants import PhaseStatus -from vibepaper.state import StateFileError, StateManager +from copaper.constants import PhaseStatus +from copaper.state import StateFileError, StateManager RELATEDWORK_DIR = "relatedwork" diff --git a/vibepaper/relatedwork_download.py b/copaper/relatedwork_download.py similarity index 97% rename from vibepaper/relatedwork_download.py rename to copaper/relatedwork_download.py index 22e33b2..9c635eb 100644 --- a/vibepaper/relatedwork_download.py +++ b/copaper/relatedwork_download.py @@ -10,7 +10,7 @@ from urllib.error import HTTPError, URLError from urllib.request import Request, urlopen -from vibepaper.literature import DownloadStatus, LiteratureCatalog +from copaper.literature import DownloadStatus, LiteratureCatalog _CHUNK_SIZE = 8192 _PDF_MAGIC = b"%PDF" @@ -73,7 +73,7 @@ def download_pdf( request = Request( url, headers={ - "User-Agent": "VibePaper/0.1 (+https://vibepaper.local)", + "User-Agent": "CoPaper/0.1 (+https://copaper.local)", "Accept": "application/pdf,application/octet-stream;q=0.9,*/*;q=0.5", }, ) diff --git a/vibepaper/relatedwork_keywords.py b/copaper/relatedwork_keywords.py similarity index 97% rename from vibepaper/relatedwork_keywords.py rename to copaper/relatedwork_keywords.py index 34d314f..cb121a2 100644 --- a/vibepaper/relatedwork_keywords.py +++ b/copaper/relatedwork_keywords.py @@ -1,10 +1,10 @@ """Extract related-work search queries from storyline.md via an LLM. -The CLI subcommand ``vibe relatedwork keywords`` reads the project's +The CLI subcommand ``copaper relatedwork keywords`` reads the project's ``storyline.md`` (or ``paper.md`` as fallback), asks the model for N distinct search queries, and writes them one-per-line to ``relatedwork/queries.txt``. The output file is the input expected by -``vibe relatedwork search --queries-file ...``. +``copaper relatedwork search --queries-file ...``. """ from __future__ import annotations @@ -16,7 +16,7 @@ from dataclasses import dataclass from pathlib import Path -from vibepaper.llm_client import ( +from copaper.llm_client import ( LLMConfigError, build_client, load_config, @@ -213,7 +213,7 @@ def main() -> None: parser.add_argument( "--model", default=None, - help="Override VIBEPAPER_MODEL.", + help="Override COPAPER_MODEL.", ) args = parser.parse_args() diff --git a/vibepaper/relatedwork_search.py b/copaper/relatedwork_search.py similarity index 98% rename from vibepaper/relatedwork_search.py rename to copaper/relatedwork_search.py index ac3e8c5..496390e 100644 --- a/vibepaper/relatedwork_search.py +++ b/copaper/relatedwork_search.py @@ -2,9 +2,9 @@ Hits the Semantic Scholar Graph API ``/paper/search`` endpoint for each query, deduplicates results, normalizes them into the schema accepted by -:class:`vibepaper.literature.LiteratureCatalog`, and writes them to a cache +:class:`copaper.literature.LiteratureCatalog`, and writes them to a cache file (default ``relatedwork/search_cache.json``) ready to be imported via -``vibe relatedwork import``. +``copaper relatedwork import``. """ from __future__ import annotations @@ -22,7 +22,7 @@ from urllib.parse import urlencode from urllib.request import Request, urlopen -from vibepaper.literature import ( +from copaper.literature import ( _generate_paper_id, _normalize_authors, extract_bibtex_key, @@ -51,7 +51,7 @@ MAX_LIMIT = 100 DEFAULT_TIMEOUT = 30 DEFAULT_RETRIES = 4 -USER_AGENT = "VibePaper/0.1 (+https://vibepaper.local)" +USER_AGENT = "CoPaper/0.1 (+https://copaper.local)" class SemanticScholarError(Exception): diff --git a/vibepaper/relatedwork_summarize.py b/copaper/relatedwork_summarize.py similarity index 98% rename from vibepaper/relatedwork_summarize.py rename to copaper/relatedwork_summarize.py index 39e2c38..5880b2a 100644 --- a/vibepaper/relatedwork_summarize.py +++ b/copaper/relatedwork_summarize.py @@ -20,8 +20,8 @@ from pathlib import Path from typing import Any -from vibepaper.literature import LiteratureCatalog -from vibepaper.llm_client import ( +from copaper.literature import LiteratureCatalog +from copaper.llm_client import ( LLMConfig, TokenBucket, build_client, @@ -198,7 +198,7 @@ def _summarize_single( return SummaryResult( paper_id=paper_id, success=False, - error="No pdf_path recorded; run `vibe relatedwork download` first.", + error="No pdf_path recorded; run `copaper relatedwork download` first.", ) pdf_path = project_root / pdf_relative @@ -375,7 +375,7 @@ def main() -> None: "--template", default=None, help="Summary template (default scaffold path)." ) parser.add_argument( - "--model", default=None, help="Override VIBEPAPER_MODEL." + "--model", default=None, help="Override COPAPER_MODEL." ) parser.add_argument( "--qps", type=float, default=DEFAULT_QPS, help="Requests per second cap." diff --git a/vibepaper/report.py b/copaper/report.py similarity index 94% rename from vibepaper/report.py rename to copaper/report.py index 17b16f9..05f0ca5 100644 --- a/vibepaper/report.py +++ b/copaper/report.py @@ -5,11 +5,11 @@ from datetime import datetime from typing import Any -from vibepaper.constants import PHASE_ORDER -from vibepaper.eventlog import EventLogger -from vibepaper.git_ops import GitManager -from vibepaper.identity import IdentityManager -from vibepaper.state import StateManager +from copaper.constants import PHASE_ORDER +from copaper.eventlog import EventLogger +from copaper.git_ops import GitManager +from copaper.identity import IdentityManager +from copaper.state import StateManager def generate_weekly_report( diff --git a/vibepaper/scaffold.py b/copaper/scaffold.py similarity index 97% rename from vibepaper/scaffold.py rename to copaper/scaffold.py index 9d7d3c6..e60b2f0 100644 --- a/vibepaper/scaffold.py +++ b/copaper/scaffold.py @@ -1,7 +1,7 @@ -"""Scaffold logic for `vibe init`. +"""Scaffold logic for `copaper init`. Copies bundled skills and starter documents into a new project directory. -The scaffold templates live under ``vibepaper/scaffold/`` as package data. +The scaffold templates live under ``copaper/scaffold/`` as package data. """ from __future__ import annotations diff --git a/vibepaper/scaffold/AGENTS.md b/copaper/scaffold/AGENTS.md similarity index 82% rename from vibepaper/scaffold/AGENTS.md rename to copaper/scaffold/AGENTS.md index 0a9ee11..1309f47 100644 --- a/vibepaper/scaffold/AGENTS.md +++ b/copaper/scaffold/AGENTS.md @@ -1,10 +1,10 @@ # AGENTS.md ## OVERVIEW -###### VibePaper: structured academic paper writing +###### CoPaper: structured academic paper writing <!-- description: What this project is and how it works --> -This is a VibePaper paper-writing project. -VibePaper uses a six-phase workflow, 22 agent skills, and a CLI (`vibe`) to guide you from research storyline to submission-ready LaTeX. +This is a CoPaper paper-writing project. +CoPaper uses a six-phase workflow, 22 agent skills, and a CLI (`copaper`) to guide you from research storyline to submission-ready LaTeX. The core philosophy is structure-first, human-led, AI-assisted: AI polishes your expression and checks your logic, but never invents research content. Your insight is the soul of the paper; the system helps you express it clearly and defend it rigorously. @@ -31,7 +31,7 @@ Your insight is the soul of the paper; the system helps you express it clearly a ## SIX-PHASE WORKFLOW ###### From storyline to submission <!-- description: The six phases, their purpose, and flexibility --> -VibePaper organizes work into six phases. The recommended forward order is: +CoPaper organizes work into six phases. The recommended forward order is: | Phase | Name | Purpose | Key Skill(s) | |-------|------|---------|--------------| @@ -43,7 +43,7 @@ VibePaper organizes work into six phases. The recommended forward order is: | 6 | `latex_review` | Convert to LaTeX, review, and prepare for submission | `markdown2latex`, `submission-precheck` | Flexibility rules: -- Any phase can be skipped via `vibe skip <phase> --reason "..."`. +- Any phase can be skipped via `copaper skip <phase> --reason "..."`. - Any phase can be re-entered and repeated. - Reverse paths are supported: `paper.md` can backfill `storyline.md`; LaTeX can be imported into `paper.md`. - The CLI tracks `current_phase` automatically based on actual phase statuses. @@ -59,10 +59,10 @@ The system revolves around a few key artifacts rather than the phases themselves |----------|-------------|-------------| | `storyline.md` | `storyline-helper`, user, reverse extraction from `paper.md` | `relatedwork-finder`, `socratic-discussion`, `experiment-analyzer`, `markdown-helper`, `writing-orchestrator` | | `paper.md` | `markdown-helper`, `mad-writer`, `latex2markdown`, user | `writing-orchestrator`, `markdown-review`, 7 checkers, `review-revise`, `submission-precheck`, `markdown2latex` | -| `relatedwork/literature.json` | `relatedwork-finder` + `vibe relatedwork` CLI | `markdown-helper`, `markdown-review`, `review-revise`, `mad-writer` | +| `relatedwork/literature.json` | `relatedwork-finder` + `copaper relatedwork` CLI | `markdown-helper`, `markdown-review`, `review-revise`, `mad-writer` | | `relatedwork/papers/*.md` | `relatedwork-finder` (multimodal subagents) | `markdown-helper`, `writing-orchestrator`, `review-revise` | -| `.agents/state.json` | `vibe` CLI, skills | `vibe status`, `writing-orchestrator`, `review-revise`, `socratic-discussion`, `experiment-analyzer` | -| `.agents/cross_index.json` | `vibe relatedwork build-index` | `markdown-helper`, `writing-orchestrator`, `review-revise` | +| `.agents/state.json` | `copaper` CLI, skills | `copaper status`, `writing-orchestrator`, `review-revise`, `socratic-discussion`, `experiment-analyzer` | +| `.agents/cross_index.json` | `copaper relatedwork build-index` | `markdown-helper`, `writing-orchestrator`, `review-revise` | **Supported data flow paths:** @@ -132,7 +132,7 @@ The system revolves around a few key artifacts rather than the phases themselves ### Workflow Management | Skill | Trigger | Purpose | |-------|---------|---------| -| `vibepaper-manage` | "manage this paper with vibe cli" | Teaches agents how to use the `vibe` CLI for project lifecycle management. | +| `copaper-manage` | "manage this paper with copaper cli" | Teaches agents how to use the `copaper` CLI for project lifecycle management. | ## RECOMMENDED WORKFLOW ###### Step-by-step guide for writing a paper @@ -140,11 +140,11 @@ The system revolves around a few key artifacts rather than the phases themselves ### Standard Forward Path -1. **Initialize**: `vibe init --name "Paper Title" --domain "research area"` +1. **Initialize**: `copaper init --name "Paper Title" --domain "research area"` 2. **Storyline** (trigger: "help me write storyline"): Fill in `storyline.md` section by section. Define problem, importance, insight, design, evaluation plan. 3. **Literature** (trigger: "find related work"): Search, download, summarize related papers. Build cross-index. 4. **Discussion** (trigger: "discuss my research"): Socratic questioning to sharpen arguments before writing. -5. **Experiments** (trigger: "analyze experiments" or `vibe skip experiments --reason "..."`): Run experiments or skip if theoretical. +5. **Experiments** (trigger: "analyze experiments" or `copaper skip experiments --reason "..."`): Run experiments or skip if theoretical. 6. **Writing** (trigger: "write the paper"): Use orchestrator to draft `paper.md` section by section. Each section gets 7-checker review. 7. **Review-Revise** (trigger: "review and revise"): Multi-round checker-driven revision until quality is satisfactory. 8. **Pre-submission** (trigger: "submission precheck"): Final quality gate before export. @@ -162,13 +162,13 @@ The system revolves around a few key artifacts rather than the phases themselves - Starting a new paper → `storyline.md` (fill this first) - Writing paper content → `paper.md` (the main document) - Understanding writing rules → `writingrules.md` -- Checking project progress → `vibe status` or `.agents/state.json` +- Checking project progress → `copaper status` or `.agents/state.json` - Finding related work metadata → `relatedwork/literature.json` - Reading paper summaries → `relatedwork/papers/*.md` - Checking quality issues → `.agents/state.json` → `checkers` field - Finding technical concept coverage → `.agents/cross_index.json` -- Reviewing operation history → `vibe log` or `.agents/events.jsonl` -- CLI automation guidance → `.agents/skills/vibepaper-manage/SKILL.md` +- Reviewing operation history → `copaper log` or `.agents/events.jsonl` +- CLI automation guidance → `.agents/skills/copaper-manage/SKILL.md` ## CONVENTIONS ###### Writing and CLI rules @@ -185,7 +185,7 @@ The system revolves around a few key artifacts rather than the phases themselves - Nodes ending in numbers (e.g., "Challenge 1") can be duplicated by incrementing the number. ### CLI Rules -- `--root` is a global option and must appear before the subcommand: `vibe --root <dir> status`, not `vibe status --root <dir>`. +- `--root` is a global option and must appear before the subcommand: `copaper --root <dir> status`, not `copaper status --root <dir>`. - Use full phase names: `storyline`, `literature`, `discussion`, `experiments`, `writing`, `latex_review`. - Prefer the CLI over hand-editing `.agents/state.json` or `.agents/events.jsonl`. @@ -213,27 +213,27 @@ The system revolves around a few key artifacts rather than the phases themselves ## COMMANDS ###### CLI commands for paper workflow management -<!-- description: Essential vibe commands --> -- `vibe init --name "<project>" --domain "<domain>"`: Initialize project, scaffold skills and starter files. -- `vibe status [--json]`: View phase statuses and current phase. -- `vibe set-phase <phase> --status <status> [--reason <reason>]`: Explicitly set a phase status (`not_started`, `in_progress`, `complete`, `skipped`). -- `vibe skip <phase> --reason "<reason>"`: Skip a phase. -- `vibe log [--phase ...] [--operator ...] [--last N] [--since YYYY-MM-DD]`: Query operation history. -- `vibe report [--since YYYY-MM-DD] [--output file]`: Generate progress report. -- `vibe commit -m "<message>" [--phase <phase>]`: Create a phase-aware Git commit. -- `vibe rollback <phase> [-y]`: Rollback to the latest commit of a phase. -- `vibe diff <phase-a> <phase-b>`: Compare two phase snapshots. -- `vibe relatedwork status [--json]`: View literature metadata catalog status. -- `vibe relatedwork import --input <json>`: Import search results into canonical catalog. -- `vibe relatedwork sync-bib`: Synchronize `literature.json` and `paper_list.bib` bidirectionally. -- `vibe relatedwork download [--paper-id ...] [--retry-failed]`: Download PDFs with validation. -- `vibe relatedwork register-summary --paper-id <id> --summary-path <path>`: Register a completed paper summary. -- `vibe relatedwork build-index`: Rebuild `.agents/cross_index.json` from paper summaries. +<!-- description: Essential copaper commands --> +- `copaper init --name "<project>" --domain "<domain>"`: Initialize project, scaffold skills and starter files. +- `copaper status [--json]`: View phase statuses and current phase. +- `copaper set-phase <phase> --status <status> [--reason <reason>]`: Explicitly set a phase status (`not_started`, `in_progress`, `complete`, `skipped`). +- `copaper skip <phase> --reason "<reason>"`: Skip a phase. +- `copaper log [--phase ...] [--operator ...] [--last N] [--since YYYY-MM-DD]`: Query operation history. +- `copaper report [--since YYYY-MM-DD] [--output file]`: Generate progress report. +- `copaper commit -m "<message>" [--phase <phase>]`: Create a phase-aware Git commit. +- `copaper rollback <phase> [-y]`: Rollback to the latest commit of a phase. +- `copaper diff <phase-a> <phase-b>`: Compare two phase snapshots. +- `copaper relatedwork status [--json]`: View literature metadata catalog status. +- `copaper relatedwork import --input <json>`: Import search results into canonical catalog. +- `copaper relatedwork sync-bib`: Synchronize `literature.json` and `paper_list.bib` bidirectionally. +- `copaper relatedwork download [--paper-id ...] [--retry-failed]`: Download PDFs with validation. +- `copaper relatedwork register-summary --paper-id <id> --summary-path <path>`: Register a completed paper summary. +- `copaper relatedwork build-index`: Rebuild `.agents/cross_index.json` from paper summaries. ## NOTES ###### Additional information <!-- description: Miscellaneous important details --> -- `vibe init` is non-destructive: it will not overwrite existing `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, or already-present skill directories. +- `copaper init` is non-destructive: it will not overwrite existing `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, or already-present skill directories. - `current_phase` is automatically derived from actual phase statuses — it is not a static value. - `relatedwork/literature.json` is the canonical metadata store; `.agents/state.json` only keeps aggregate counters (`papers_found`, `papers_downloaded`, `download_failures`, `summaries_done`). - `report` works without Git but will note the missing repository. `commit`, `rollback`, and `diff` require Git. diff --git a/vibepaper/scaffold/paper.md b/copaper/scaffold/paper.md similarity index 100% rename from vibepaper/scaffold/paper.md rename to copaper/scaffold/paper.md diff --git a/vibepaper/scaffold/skills/AGENTS.md b/copaper/scaffold/skills/AGENTS.md similarity index 60% rename from vibepaper/scaffold/skills/AGENTS.md rename to copaper/scaffold/skills/AGENTS.md index 516225c..77fc695 100644 --- a/vibepaper/scaffold/skills/AGENTS.md +++ b/copaper/scaffold/skills/AGENTS.md @@ -2,10 +2,10 @@ ## OVERVIEW ###### Skill catalog for writing and workflow automation -<!-- description: Purpose of the skills directory and its role in VibePaper --> -The `.agents/skills/` directory contains the reusable skill library shipped with VibePaper. +<!-- description: Purpose of the skills directory and its role in CoPaper --> +The `.agents/skills/` directory contains the reusable skill library shipped with CoPaper. Each skill is a self-contained module that extends the agent's capabilities for a specific academic task or workflow-management task. -These skills are bundled into initialized projects by `vibe init`. +These skills are bundled into initialized projects by `copaper init`. ## STRUCTURE ###### Standardized skill module organization @@ -18,9 +18,9 @@ These skills are bundled into initialized projects by `vibe init`. ## WHERE TO LOOK ###### Important skills in the current catalog <!-- description: Catalog of skills in this directory --> -- `vibepaper-manage`: Teaches agents how to use OpenCode plugin tools for dashboard, initialization, artifact readiness, workflow status, phase updates, and workflow log inspection. +- `copaper-manage`: Teaches agents how to use OpenCode plugin tools for dashboard, initialization, artifact readiness, workflow status, phase updates, and workflow log inspection. - `human-comment-helper`: Adds structured reviewer feedback and synthetic examples. -- `latex2markdown`: Imports content from LaTeX files into the VibePaper structure. +- `latex2markdown`: Imports content from LaTeX files into the CoPaper structure. - `markdown-helper`: Interactive assistance for writing and improving `paper.md`. - `markdown-review`: Quality assurance check for novelty, importance, and correctness. - `markdown2latex`: High-quality export from `paper.md` to conference-ready LaTeX. @@ -40,19 +40,19 @@ These skills are bundled into initialized projects by `vibe init`. - **Quality Gates**: Use `markdown-review` to validate content before final export. - **Format Mapping**: Conversion skills must maintain semantic meaning across formats. - **Math Support**: Preserve `$...$` and `$$...$$` during all transformations. -- **OpenCode Plugin Tools**: When available, skills MUST use `vibepaper_dashboard`, `vibepaper_init_apply`, `vibepaper_artifact_status`, `vibepaper_artifact_record`, `vibepaper_workflow_status`, `vibepaper_workflow_log`, and `vibepaper_workflow_set_phase` instead of shell `vibe` commands or manual `.agents/state.json` / `.agents/events.jsonl` edits. -- **Project Initialization**: After explicit user confirmation and collection of project `name` and `domain`, call `vibepaper_init_apply` to initialize OpenCode-managed VibePaper core files. Do not describe initialization as a prompt-only action or manually create the core files when the plugin tool is available. -- **Workflow Status Queries**: For read-only workflow phase status, current phase, phase table, and next-step recommendation, call `vibepaper_workflow_status`. Do not read `.agents/state.json` directly for phase state when the plugin tool is available. -- **Paper Structure Queries**: For read-only `paper.md` Level 2-5 completion, Level 5 writing targets, next writing target, and structural issues, call `vibepaper_paper_structure_status`. Do not reimplement this as prompt-only heading scans or shell parsing when the plugin tool is available. -- **Storyline Structure Queries**: For read-only `storyline.md` `#####` section readiness, TODO coverage, and next storyline target, call `vibepaper_storyline_structure_status`. Do not reimplement this as prompt-only section scans when the plugin tool is available. -- **Import Extraction**: For user-specified PDF and PPTX imports, call `vibepaper_pdf_extract` or `vibepaper_ppt_extract`. These tools are read-only and require an explicit user-provided absolute or relative path; do not run separate shell existence checks, scan directories, glob for candidates, or guess source files. -- **Checker Status Queries**: For read-only checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence, call `vibepaper_checker_status`. Do not read `.agents/state.json` or `.agents/precheck_report.md` directly just to infer checker status when the plugin tool is available. -- **Reviewer Boundary**: Route checker review, checker-result summarization, and issue explanation to `@vibepaper-reviewer` when available. The reviewer is read-only and must not edit `paper.md` or write checker records directly. -- **Phase Updates**: After explicit user confirmation, call `vibepaper_workflow_set_phase`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe this as a prompt-only action. -- **Workflow Log Queries**: For read-only inspection of `.agents/events.jsonl`, call `vibepaper_workflow_log` with optional `lastN`, `phase`, and `operator` filters. Do not read the event log file directly when the plugin tool is available. -- **Artifact Readiness Queries**: For read-only artifact readiness, evidence, confidence, and recommendation, call `vibepaper_artifact_status`. Do not manually infer readiness from files or `.agents/state.json` when the plugin tool is available. -- **Artifact Readiness Records**: After explicit user confirmation, route artifact readiness recording to `@vibepaper-recorder`; the recorder calls `vibepaper_artifact_record`, which writes the `artifacts` area in `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe readiness recording as a prompt-only action. -- **Recorder Boundary**: `vibepaper_artifact_record` must be invoked through `@vibepaper-recorder`; other agents should route the recording action rather than calling it directly. +- **OpenCode Plugin Tools**: When available, skills MUST use `copaper_dashboard`, `copaper_init_apply`, `copaper_artifact_status`, `copaper_artifact_record`, `copaper_workflow_status`, `copaper_workflow_log`, and `copaper_workflow_set_phase` instead of shell `copaper` commands or manual `.agents/state.json` / `.agents/events.jsonl` edits. +- **Project Initialization**: After explicit user confirmation and collection of project `name` and `domain`, call `copaper_init_apply` to initialize OpenCode-managed CoPaper core files. Do not describe initialization as a prompt-only action or manually create the core files when the plugin tool is available. +- **Workflow Status Queries**: For read-only workflow phase status, current phase, phase table, and next-step recommendation, call `copaper_workflow_status`. Do not read `.agents/state.json` directly for phase state when the plugin tool is available. +- **Paper Structure Queries**: For read-only `paper.md` Level 2-5 completion, Level 5 writing targets, next writing target, and structural issues, call `copaper_paper_structure_status`. Do not reimplement this as prompt-only heading scans or shell parsing when the plugin tool is available. +- **Storyline Structure Queries**: For read-only `storyline.md` `#####` section readiness, TODO coverage, and next storyline target, call `copaper_storyline_structure_status`. Do not reimplement this as prompt-only section scans when the plugin tool is available. +- **Import Extraction**: For user-specified PDF and PPTX imports, call `copaper_pdf_extract` or `copaper_ppt_extract`. These tools are read-only and require an explicit user-provided absolute or relative path; do not run separate shell existence checks, scan directories, glob for candidates, or guess source files. +- **Checker Status Queries**: For read-only checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence, call `copaper_checker_status`. Do not read `.agents/state.json` or `.agents/precheck_report.md` directly just to infer checker status when the plugin tool is available. +- **Reviewer Boundary**: Route checker review, checker-result summarization, and issue explanation to `@copaper-reviewer` when available. The reviewer is read-only and must not edit `paper.md` or write checker records directly. +- **Phase Updates**: After explicit user confirmation, call `copaper_workflow_set_phase`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe this as a prompt-only action. +- **Workflow Log Queries**: For read-only inspection of `.agents/events.jsonl`, call `copaper_workflow_log` with optional `lastN`, `phase`, and `operator` filters. Do not read the event log file directly when the plugin tool is available. +- **Artifact Readiness Queries**: For read-only artifact readiness, evidence, confidence, and recommendation, call `copaper_artifact_status`. Do not manually infer readiness from files or `.agents/state.json` when the plugin tool is available. +- **Artifact Readiness Records**: After explicit user confirmation, route artifact readiness recording to `@copaper-recorder`; the recorder calls `copaper_artifact_record`, which writes the `artifacts` area in `.agents/state.json` and appends `.agents/events.jsonl`. Do not describe readiness recording as a prompt-only action. +- **Recorder Boundary**: `copaper_artifact_record` must be invoked through `@copaper-recorder`; other agents should route the recording action rather than calling it directly. - **Unsupported Tool Gaps**: If the OpenCode plugin does not yet expose a needed capability, state the gap explicitly instead of inventing a plugin tool or falling back silently. - **Scaffold Sync**: New or changed skills must be mirrored into the packaged scaffold. diff --git a/vibepaper/scaffold/skills/auto-init/SKILL.md b/copaper/scaffold/skills/auto-init/SKILL.md similarity index 82% rename from vibepaper/scaffold/skills/auto-init/SKILL.md rename to copaper/scaffold/skills/auto-init/SKILL.md index 6967354..2f849ff 100644 --- a/vibepaper/scaffold/skills/auto-init/SKILL.md +++ b/copaper/scaffold/skills/auto-init/SKILL.md @@ -1,11 +1,11 @@ --- name: auto-init -description: Detect when the user wants to start a new VibePaper paper project or initialize a workspace, run `vibe --root . init` when needed, then inspect the current workflow phase and immediately begin the appropriate next phase work. +description: Detect when the user wants to start a new CoPaper paper project or initialize a workspace, run `copaper --root . init` when needed, then inspect the current workflow phase and immediately begin the appropriate next phase work. --- # Auto Init -This skill initializes a VibePaper project when the user expresses intent to start a new paper or workspace. +This skill initializes a CoPaper project when the user expresses intent to start a new paper or workspace. ## Input Files @@ -18,7 +18,7 @@ This skill initializes a VibePaper project when the user expresses intent to sta ## Triggers -Use this skill when the user asks to start or initialize a VibePaper paper project, including phrases such as: +Use this skill when the user asks to start or initialize a CoPaper paper project, including phrases such as: - "start working" - "start writing paper" @@ -38,7 +38,7 @@ Use this skill when the user asks to start or initialize a VibePaper paper proje 5. Run: ```bash -vibe --root . init --name "<project_name>" --domain "<domain>" +copaper --root . init --name "<project_name>" --domain "<domain>" ``` 6. After initialization succeeds, tell the user where the scaffold was created. @@ -54,14 +54,14 @@ Only run `git init` when `command -v git` succeeds and `git rev-parse --is-insid 8. Continue immediately by checking status: ```bash -vibe --root . status --json +copaper --root . status --json ``` 9. Read `current_phase` from the JSON output and begin that phase's work without waiting for another user command. ## Phase Continuation -After `vibe --root . status --json`, use this routing: +After `copaper --root . status --json`, use this routing: | Current Phase | Begin This Work | |---------------|-----------------| @@ -80,5 +80,5 @@ If the phase requires information the user has not provided, ask only for the mi - Keep `--root` before the `init` subcommand. - Use the CLI for initialization instead of manually creating `.agents/state.json`. - Do not run `git init` when the current folder is already inside an existing Git work tree. -- Do not require Git; if it is unavailable, continue the VibePaper workflow. +- Do not require Git; if it is unavailable, continue the CoPaper workflow. - Do not stop after initialization when status can be read; continue into the current phase workflow. diff --git a/vibepaper/scaffold/skills/bogus-data-helper/SKILL.md b/copaper/scaffold/skills/bogus-data-helper/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/bogus-data-helper/SKILL.md rename to copaper/scaffold/skills/bogus-data-helper/SKILL.md index 4bbd05f..2e74286 100644 --- a/vibepaper/scaffold/skills/bogus-data-helper/SKILL.md +++ b/copaper/scaffold/skills/bogus-data-helper/SKILL.md @@ -28,7 +28,7 @@ You are an AI assistant helping create placeholder evaluation data. Your generat ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for inserting placeholder content: +The paper follows CoPaper structure. Key rules for inserting placeholder content: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). diff --git a/vibepaper/scaffold/skills/clarity-checker/SKILL.md b/copaper/scaffold/skills/clarity-checker/SKILL.md similarity index 98% rename from vibepaper/scaffold/skills/clarity-checker/SKILL.md rename to copaper/scaffold/skills/clarity-checker/SKILL.md index 0aed245..c61285c 100644 --- a/vibepaper/scaffold/skills/clarity-checker/SKILL.md +++ b/copaper/scaffold/skills/clarity-checker/SKILL.md @@ -5,7 +5,7 @@ description: Detects undefined terms, unclear descriptions, and clarity issues i # Clarity Checker Skill -This skill identifies clarity issues in academic paper drafts following the VibePaper structure, including undefined terms, vague descriptions, ambiguous references, and insufficient explanations that hinder reader comprehension. +This skill identifies clarity issues in academic paper drafts following the CoPaper structure, including undefined terms, vague descriptions, ambiguous references, and insufficient explanations that hinder reader comprehension. ## When to Use This Skill @@ -239,7 +239,7 @@ For each clarity issue found: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/clarity-checker/examples.md b/copaper/scaffold/skills/clarity-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/clarity-checker/examples.md rename to copaper/scaffold/skills/clarity-checker/examples.md diff --git a/vibepaper/scaffold/skills/vibepaper-manage/SKILL.md b/copaper/scaffold/skills/copaper-manage/SKILL.md similarity index 55% rename from vibepaper/scaffold/skills/vibepaper-manage/SKILL.md rename to copaper/scaffold/skills/copaper-manage/SKILL.md index 3b5eb77..8383c20 100644 --- a/vibepaper/scaffold/skills/vibepaper-manage/SKILL.md +++ b/copaper/scaffold/skills/copaper-manage/SKILL.md @@ -1,11 +1,11 @@ --- -name: vibepaper-manage -description: Teaches agents how to manage a VibePaper project through the OpenCode plugin tools, including dashboard, initialization, artifact readiness, workflow status, event log inspection, and phase updates. Use this skill whenever the task is about workflow/state management rather than direct paper writing. +name: copaper-manage +description: Teaches agents how to manage a CoPaper project through the OpenCode plugin tools, including dashboard, initialization, artifact readiness, workflow status, event log inspection, and phase updates. Use this skill whenever the task is about workflow/state management rather than direct paper writing. --- -# VibePaper-Manage Skill +# CoPaper-Manage Skill -This skill tells an agent how to manage a VibePaper project through the OpenCode plugin tools instead of shell commands, prompt-only instructions, or manual edits to workflow files. +This skill tells an agent how to manage a CoPaper project through the OpenCode plugin tools instead of shell commands, prompt-only instructions, or manual edits to workflow files. Use this skill when the task is about project lifecycle management, initialization, workflow status, phase control, artifact readiness, or event log inspection. @@ -13,7 +13,7 @@ Use this skill when the task is about project lifecycle management, initializati Use this skill when the user asks to: -- initialize a VibePaper project from OpenCode +- initialize a CoPaper project from OpenCode - check current workflow status - inspect recent workflow history - mark a phase as `not_started`, `in_progress`, `complete`, or `skipped` @@ -21,12 +21,12 @@ Use this skill when the user asks to: - record artifact readiness after confirmation - check checker status, severity counts, stale signals, and precheck evidence - record checker run summaries after confirmation -- understand what to do next in the VibePaper workflow +- understand what to do next in the CoPaper workflow Typical triggers: - `check workflow status` -- `show VibePaper dashboard` +- `show CoPaper dashboard` - `skip experiments for this project` - `record artifact readiness` - `manage this paper with OpenCode` @@ -36,13 +36,13 @@ Typical triggers: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `.agents/state.json` | Tool-managed | Status, phase, artifact-record, and initialization flows | Access only through plugin tools when possible; contains workflow phases and artifact records | -| `.agents/events.jsonl` | Tool-managed | Workflow history inspection | Access through `vibepaper_workflow_log`; do not read or append directly | -| `storyline.md` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `paper.md` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `relatedwork/` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| `.agents/cross_index.json` | Optional | Artifact readiness inspection | Checked by `vibepaper_artifact_status` as part of read-only evidence | -| Checker status | Optional | Checker inspection | Access through `vibepaper_checker_status`; do not inspect `.agents/state.json` directly just to infer checker status | -| Relatedwork status | Optional | Literature workflow inspection | Access through `vibepaper_relatedwork_status`; do not run CLI status or read `literature.json` directly just to summarize progress | +| `.agents/events.jsonl` | Tool-managed | Workflow history inspection | Access through `copaper_workflow_log`; do not read or append directly | +| `storyline.md` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `paper.md` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `relatedwork/` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| `.agents/cross_index.json` | Optional | Artifact readiness inspection | Checked by `copaper_artifact_status` as part of read-only evidence | +| Checker status | Optional | Checker inspection | Access through `copaper_checker_status`; do not inspect `.agents/state.json` directly just to infer checker status | +| Relatedwork status | Optional | Literature workflow inspection | Access through `copaper_relatedwork_status`; do not run CLI status or read `literature.json` directly just to summarize progress | ## OpenCode Plugin Tools @@ -50,16 +50,16 @@ Prefer these plugin tools whenever they are available: | User intent | Plugin tool | |---|---| -| Show project dashboard / init preview | `vibepaper_dashboard` | -| Initialize core VibePaper files after confirmation | `vibepaper_init_apply` | -| Read artifact readiness | `vibepaper_artifact_status` | -| Record artifact readiness after confirmation | `vibepaper_artifact_record` | -| Read workflow phase status and next step | `vibepaper_workflow_status` | -| Read recent workflow events | `vibepaper_workflow_log` | -| Update a workflow phase after confirmation | `vibepaper_workflow_set_phase` | -| Read checker run status and stale signals | `vibepaper_checker_status` | -| Record checker run summary after confirmation | `vibepaper_checker_record` | -| Read relatedwork catalog, PDF, summary, BibTeX, and cross-index status | `vibepaper_relatedwork_status` | +| Show project dashboard / init preview | `copaper_dashboard` | +| Initialize core CoPaper files after confirmation | `copaper_init_apply` | +| Read artifact readiness | `copaper_artifact_status` | +| Record artifact readiness after confirmation | `copaper_artifact_record` | +| Read workflow phase status and next step | `copaper_workflow_status` | +| Read recent workflow events | `copaper_workflow_log` | +| Update a workflow phase after confirmation | `copaper_workflow_set_phase` | +| Read checker run status and stale signals | `copaper_checker_status` | +| Record checker run summary after confirmation | `copaper_checker_record` | +| Read relatedwork catalog, PDF, summary, BibTeX, and cross-index status | `copaper_relatedwork_status` | Do not hand-edit: @@ -86,25 +86,25 @@ When a requested action needs one of those missing capabilities, state that no p ## Initialization Workflow -Use `vibepaper_dashboard` first to check whether initialization is needed. +Use `copaper_dashboard` first to check whether initialization is needed. If initialization is needed: 1. Ask for the project name and research domain. 2. Restate the initialization target, project name, and domain. 3. Wait for explicit confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`. +4. Call `copaper_init_apply` with `name` and `domain`. 5. Show the tool output to the user. -The tool call, not a prompt-only instruction, initializes the OpenCode-managed VibePaper core files and refuses conflicts. Do not manually create those core files when the plugin tool is available. +The tool call, not a prompt-only instruction, initializes the OpenCode-managed CoPaper core files and refuses conflicts. Do not manually create those core files when the plugin tool is available. The plugin initialization writes only the core files defined by the plugin, such as `paper.md`, `storyline.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, and `.agents/events.jsonl`. Do not claim it installs `.agents/skills/` unless the tool output says so. ## Status and Inspection -Use `vibepaper_workflow_status` for read-only inspection of workflow phase status, current phase, phase table, and next-step recommendation. Do not read `.agents/state.json` directly for phase state when this plugin tool is available. +Use `copaper_workflow_status` for read-only inspection of workflow phase status, current phase, phase table, and next-step recommendation. Do not read `.agents/state.json` directly for phase state when this plugin tool is available. -Use `vibepaper_workflow_log` for read-only inspection of `.agents/events.jsonl`. Do not read the event log file directly when this plugin tool is available. +Use `copaper_workflow_log` for read-only inspection of `.agents/events.jsonl`. Do not read the event log file directly when this plugin tool is available. Supported filters: @@ -112,19 +112,19 @@ Supported filters: - `phase` - `operator` -Use `vibepaper_artifact_status` for read-only inspection of artifact readiness, evidence, confidence, and recommendation. Do not manually infer readiness from files or `.agents/state.json` when this plugin tool is available. +Use `copaper_artifact_status` for read-only inspection of artifact readiness, evidence, confidence, and recommendation. Do not manually infer readiness from files or `.agents/state.json` when this plugin tool is available. It inspects artifacts such as `storyline.md`, `paper.md`, `relatedwork/`, `.agents/skills/`, `.agents/cross_index.json`, and checker results. -Use `vibepaper_checker_status` for read-only inspection of checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence. This tool does not run checkers, write checker results, mark issues resolved, update workflow phases, or record artifact readiness. +Use `copaper_checker_status` for read-only inspection of checker run status, Critical/Major/Minor counts, stale signals, and `.agents/precheck_report.md` evidence. This tool does not run checkers, write checker results, mark issues resolved, update workflow phases, or record artifact readiness. -Use `vibepaper_checker_record` only after a checker has actually run and the user explicitly confirms the summary to persist. This tool writes the `checkers` area in `.agents/state.json` and appends a `record_checker_result` event to `.agents/events.jsonl`. It does not run checker skills, mark individual issues resolved, update workflow phases, or record artifact readiness. +Use `copaper_checker_record` only after a checker has actually run and the user explicitly confirms the summary to persist. This tool writes the `checkers` area in `.agents/state.json` and appends a `record_checker_result` event to `.agents/events.jsonl`. It does not run checker skills, mark individual issues resolved, update workflow phases, or record artifact readiness. -Use `vibepaper_relatedwork_status` for read-only inspection of relatedwork catalog, BibTeX, PDF files, paper summaries, search cache, queries, aggregate summary, and `.agents/cross_index.json`. This tool does not run `relatedwork search`, `import`, `sync-bib`, `download`, `summarize`, `register-summary`, or `build-index`; it also does not write `.agents/state.json` or append events. +Use `copaper_relatedwork_status` for read-only inspection of relatedwork catalog, BibTeX, PDF files, paper summaries, search cache, queries, aggregate summary, and `.agents/cross_index.json`. This tool does not run `relatedwork search`, `import`, `sync-bib`, `download`, `summarize`, `register-summary`, or `build-index`; it also does not write `.agents/state.json` or append events. ## Phase Control -Use `vibepaper_workflow_set_phase` when a phase should be explicitly marked as: +Use `copaper_workflow_set_phase` when a phase should be explicitly marked as: - `not_started` - `in_progress` @@ -140,7 +140,7 @@ Before calling the tool: Then call: ```text -vibepaper_workflow_set_phase({ +copaper_workflow_set_phase({ phase: "<phase>", status: "<status>", reason: "<reason if skipped>" @@ -149,7 +149,7 @@ vibepaper_workflow_set_phase({ The tool call, not a prompt-only instruction, updates `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Valid phase names are project-defined and should come from `vibepaper_workflow_status`. Common defaults are: +Valid phase names are project-defined and should come from `copaper_workflow_status`. Common defaults are: - `storyline` - `literature` @@ -162,14 +162,14 @@ Do not use stage letters such as `A`, `B`, or `D`. ## Artifact Readiness -Use `vibepaper_artifact_status` for read-only readiness, evidence, confidence, and recommendation before deciding whether an artifact should be recorded. This tool does not modify files or workflow state. +Use `copaper_artifact_status` for read-only readiness, evidence, confidence, and recommendation before deciding whether an artifact should be recorded. This tool does not modify files or workflow state. When the user explicitly asks to record readiness: 1. Restate artifact, status, confidence, evidence, and reason. 2. Wait for explicit confirmation. -3. Route the confirmed record action to `@vibepaper-recorder`. -4. The recorder calls `vibepaper_artifact_record`. +3. Route the confirmed record action to `@copaper-recorder`. +4. The recorder calls `copaper_artifact_record`. The tool call, not a prompt-only instruction, writes the `artifacts` area in `.agents/state.json` and appends the readiness event to `.agents/events.jsonl`. It records artifact readiness only. It does not automatically advance phases. @@ -185,15 +185,15 @@ Use only plugin-supported record values: ## Checker Result Recording -Use `vibepaper_checker_status` first when you need to inspect existing checker freshness or counts. +Use `copaper_checker_status` first when you need to inspect existing checker freshness or counts. When the user explicitly asks to record a checker result: 1. Verify the result came from actual checker output, such as `markdown-review` or an individual checker skill. 2. Restate checker, status, Critical/Major/Minor counts, summary, evidence, issue list if provided, and reason. 3. Wait for explicit confirmation. -4. Route the confirmed record action to `@vibepaper-recorder`. -5. The recorder calls `vibepaper_checker_record`. +4. Route the confirmed record action to `@copaper-recorder`. +5. The recorder calls `copaper_checker_record`. Use only plugin-supported checker record values: @@ -209,15 +209,15 @@ Use only plugin-supported checker record values: ### Pattern 1: Dashboard -1. Call `vibepaper_dashboard`. -2. If ready, call `vibepaper_artifact_status` to inspect artifact readiness, evidence, confidence, and recommendation. -3. Then call `vibepaper_workflow_status`. -4. Optionally call `vibepaper_workflow_log`. +1. Call `copaper_dashboard`. +2. If ready, call `copaper_artifact_status` to inspect artifact readiness, evidence, confidence, and recommendation. +3. Then call `copaper_workflow_status`. +4. Optionally call `copaper_workflow_log`. ### Pattern 2: Safe Workflow Inspection -1. Call `vibepaper_workflow_status` to get the current phase, phase table, and next-step recommendation. -2. Call `vibepaper_workflow_log` with `lastN` or optional `phase`/`operator` filters to query `.agents/events.jsonl` read-only. +1. Call `copaper_workflow_status` to get the current phase, phase table, and next-step recommendation. +2. Call `copaper_workflow_log` with `lastN` or optional `phase`/`operator` filters to query `.agents/events.jsonl` read-only. 3. Decide the next action from the returned state. ### Pattern 3: Skip a Non-Applicable Phase @@ -225,18 +225,18 @@ Use only plugin-supported checker record values: 1. Confirm the phase is genuinely not needed. 2. Ask for or restate the skip reason. 3. Wait for confirmation. -4. Call `vibepaper_workflow_set_phase` with `status: "skipped"`. -5. Call `vibepaper_workflow_status` to verify the result. +4. Call `copaper_workflow_set_phase` with `status: "skipped"`. +5. Call `copaper_workflow_status` to verify the result. ## Must NOT Do - **NEVER** hand-edit `.agents/state.json` for actions covered by plugin tools. - **NEVER** append to `.agents/events.jsonl` for workflow phase changes covered by plugin tools. -- **NEVER** read `.agents/events.jsonl` directly for workflow history when `vibepaper_workflow_log` is available. +- **NEVER** read `.agents/events.jsonl` directly for workflow history when `copaper_workflow_log` is available. - **NEVER** update phases without explicit user confirmation. -- **NEVER** use shell `vibe` commands when an equivalent plugin tool exists. +- **NEVER** use shell `copaper` commands when an equivalent plugin tool exists. - **NEVER** claim unsupported plugin capabilities exist. -- **NEVER** read `.agents/state.json` directly just to infer checker status when `vibepaper_checker_status` is available. +- **NEVER** read `.agents/state.json` directly just to infer checker status when `copaper_checker_status` is available. ## End Condition diff --git a/vibepaper/scaffold/skills/data-checker/SKILL.md b/copaper/scaffold/skills/data-checker/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/data-checker/SKILL.md rename to copaper/scaffold/skills/data-checker/SKILL.md index 31494e0..5a591b1 100644 --- a/vibepaper/scaffold/skills/data-checker/SKILL.md +++ b/copaper/scaffold/skills/data-checker/SKILL.md @@ -289,7 +289,7 @@ Generate comprehensive data authenticity assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/data-checker/examples.md b/copaper/scaffold/skills/data-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/data-checker/examples.md rename to copaper/scaffold/skills/data-checker/examples.md diff --git a/vibepaper/scaffold/skills/evaluation-protocol-checker/SKILL.md b/copaper/scaffold/skills/evaluation-protocol-checker/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/evaluation-protocol-checker/SKILL.md rename to copaper/scaffold/skills/evaluation-protocol-checker/SKILL.md index cea6bc3..6da3ad2 100644 --- a/vibepaper/scaffold/skills/evaluation-protocol-checker/SKILL.md +++ b/copaper/scaffold/skills/evaluation-protocol-checker/SKILL.md @@ -318,7 +318,7 @@ Generate a comprehensive evaluation protocol assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/evaluation-protocol-checker/examples.md b/copaper/scaffold/skills/evaluation-protocol-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/evaluation-protocol-checker/examples.md rename to copaper/scaffold/skills/evaluation-protocol-checker/examples.md diff --git a/vibepaper/scaffold/skills/experiment-analyzer/SKILL.md b/copaper/scaffold/skills/experiment-analyzer/SKILL.md similarity index 92% rename from vibepaper/scaffold/skills/experiment-analyzer/SKILL.md rename to copaper/scaffold/skills/experiment-analyzer/SKILL.md index 601f637..883633a 100644 --- a/vibepaper/scaffold/skills/experiment-analyzer/SKILL.md +++ b/copaper/scaffold/skills/experiment-analyzer/SKILL.md @@ -104,7 +104,7 @@ This mode is for users who already have experimental data and want to skip the e 1. **Confirm intent**: Ask the user to confirm they want to skip the experiment phase. Warn them that skipping means no code understanding, result analysis, or protocol review will be performed. 2. **Collect data path**: Ask the user for the path to their existing data file(s). These will be referenced in `paper.md` but not analyzed by this skill. -3. **Update workflow phase**: Restate the skip reason and wait for explicit user confirmation. Then call `vibepaper_workflow_set_phase` with `phase: "experiments"`, `status: "skipped"`, and the confirmed `reason`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. +3. **Update workflow phase**: Restate the skip reason and wait for explicit user confirmation. Then call `copaper_workflow_set_phase` with `phase: "experiments"`, `status: "skipped"`, and the confirmed `reason`; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. 4. **Inform user**: Tell the user that the experiment phase has been marked as skipped. Suggest that they may still want to use Result Analysis mode later if they need help interpreting their data. ### Step 3: Update Workflow State @@ -113,7 +113,7 @@ After completing any mode (except Skip, which updates workflow state in Step 2d) 1. Restate the intended phase update to the user. 2. Wait for explicit confirmation. -3. Call `vibepaper_workflow_set_phase` with `phase: "experiments"` and `status: "complete"` after code/result/protocol analysis is complete; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. +3. Call `copaper_workflow_set_phase` with `phase: "experiments"` and `status: "complete"` after code/result/protocol analysis is complete; the tool writes `.agents/state.json` and appends `.agents/events.jsonl`. 4. Do not manually edit `.agents/state.json` when the plugin tool is available. 5. The current plugin does not expose a dedicated tool for storing experiment metadata such as `mode_used`, `last_updated`, or `data_files`; mention this limitation instead of writing those fields directly. @@ -123,7 +123,7 @@ After completing any mode (except Skip, which updates workflow state in Step 2d) |------|----------|-------------|---------| | `storyline.md` | **Required** | Step 2a/2b (mapping experiments to RQs) | Research narrative for mapping code/results to research questions | | `paper.md` | **Required** | Step 2a/2b (understanding evaluation needs) | Paper structure and evaluation section requirements | -| `.agents/state.json` | Tool-managed | Step 3 (end) and Step 2d (skip mode) | Update experiment phase via `vibepaper_workflow_set_phase`; do not edit directly | +| `.agents/state.json` | Tool-managed | Step 3 (end) and Step 2d (skip mode) | Update experiment phase via `copaper_workflow_set_phase`; do not edit directly | | User-provided experiment code path | Conditional | Step 2a (Code Understanding mode) | Directory of experiment code to analyze | | User-provided result file paths | Conditional | Step 2b (Result Analysis mode) | CSV/JSON/TXT/log files with experimental results | @@ -136,7 +136,7 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules - **NEVER** modify user code. Analysis is read-only; suggest changes but do not apply them. - **NEVER** fabricate or invent experimental results. Only report what exists in the data files. - **NEVER** skip the mode selection step. Always ask the user which mode they need first. -- **NEVER** bypass VibePaper structure constraints when suggesting content for `paper.md` (Level 6 title ≤50 chars, body ≤500 chars, do not modify Level 2-5 headers). +- **NEVER** bypass CoPaper structure constraints when suggesting content for `paper.md` (Level 6 title ≤50 chars, body ≤500 chars, do not modify Level 2-5 headers). - **NEVER** insert content into `paper.md` without the user explicitly reviewing and accepting it. - **NEVER** modify Level 1-5 headers in `paper.md`. Only suggest Level 6 content additions. @@ -145,6 +145,6 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules 1. **Read-only analysis**: This skill reads code and data but never modifies them. All suggestions are presented to the user for review. 2. **RQ alignment is critical**: Every analysis mode should cross-reference results or code with the stated research questions in `storyline.md` and `paper.md`. 3. **Protocol review delegates to evaluation-protocol-checker**: The Protocol Review mode does not duplicate the checker's logic. It invokes the checker and then discusses results with the user. -4. **State tracking**: Use `vibepaper_workflow_set_phase` after completing a mode to maintain workflow continuity. +4. **State tracking**: Use `copaper_workflow_set_phase` after completing a mode to maintain workflow continuity. 5. **Bilingual support**: Trigger words and user-facing prompts should accommodate both English and Chinese inputs. 6. **Data formats**: Result Analysis mode supports CSV, JSON, TXT, and common log file formats. If the user provides an unsupported format, ask them to convert it first. diff --git a/vibepaper/scaffold/skills/human-comment-helper/SKILL.md b/copaper/scaffold/skills/human-comment-helper/SKILL.md similarity index 100% rename from vibepaper/scaffold/skills/human-comment-helper/SKILL.md rename to copaper/scaffold/skills/human-comment-helper/SKILL.md diff --git a/vibepaper/scaffold/skills/humanizer/LICENSE b/copaper/scaffold/skills/humanizer/LICENSE similarity index 100% rename from vibepaper/scaffold/skills/humanizer/LICENSE rename to copaper/scaffold/skills/humanizer/LICENSE diff --git a/vibepaper/scaffold/skills/humanizer/README.md b/copaper/scaffold/skills/humanizer/README.md similarity index 100% rename from vibepaper/scaffold/skills/humanizer/README.md rename to copaper/scaffold/skills/humanizer/README.md diff --git a/vibepaper/scaffold/skills/humanizer/SKILL.md b/copaper/scaffold/skills/humanizer/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/humanizer/SKILL.md rename to copaper/scaffold/skills/humanizer/SKILL.md index 1dfd5e8..5d6b05b 100644 --- a/vibepaper/scaffold/skills/humanizer/SKILL.md +++ b/copaper/scaffold/skills/humanizer/SKILL.md @@ -475,7 +475,7 @@ Avoiding AI patterns is only half the job. Sterile, voiceless writing is just as ## Action Logging The current OpenCode plugin does not expose a generic `humanize_text` event logger or arbitrary tool-event writer. Do not append to `.agents/toolevents.jsonl` manually in plugin-based workflows. -If the user explicitly asks to record artifact readiness after humanization, restate the artifact, status, confidence, evidence, and reason, wait for confirmation, then route the record action to `@vibepaper-recorder` so it can call `vibepaper_artifact_record`. +If the user explicitly asks to record artifact readiness after humanization, restate the artifact, status, confidence, evidence, and reason, wait for confirmation, then route the record action to `@copaper-recorder` so it can call `copaper_artifact_record`. The recorder tool call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only readiness text. Otherwise, summarize the processed target and changes in the response. diff --git a/vibepaper/scaffold/skills/humanizer/WARP.md b/copaper/scaffold/skills/humanizer/WARP.md similarity index 100% rename from vibepaper/scaffold/skills/humanizer/WARP.md rename to copaper/scaffold/skills/humanizer/WARP.md diff --git a/copaper/scaffold/skills/latex-final-writer/SKILL.md b/copaper/scaffold/skills/latex-final-writer/SKILL.md new file mode 100644 index 0000000..57aac99 --- /dev/null +++ b/copaper/scaffold/skills/latex-final-writer/SKILL.md @@ -0,0 +1,309 @@ +--- +name: latex-final-writer +description: Guides the post-paper.md LaTeX final-draft workflow. Use when the user has a completed paper.md and wants to write the final LaTeX paper from a downloaded conference template, create writing_plan.md, initialize tex/ structure, draft sections, or revise the LaTeX final draft. +--- + +# LaTeX Final-Draft Writer Skill + +This skill manages the workflow from a completed `paper.md` to a conference-ready LaTeX final draft in a user-provided template directory, usually `tex/` at the project root. + +## When to Use This Skill + +- User says they have finished `paper.md` and want to write the LaTeX final paper. +- User says “写 LaTeX 终稿”, “生成终稿”, “根据模板写论文”, “create writing_plan.md”, or “初始化 tex 大纲”. +- User provides or downloads a conference/journal LaTeX template into the project root. +- User asks to continue section-by-section LaTeX writing according to a writing plan. +- User asks to review or revise the LaTeX final draft after the full draft is written. + +Do not use this skill for converting an existing LaTeX paper back into `paper.md`; use `latex2markdown` for that. Do not use it for generic Markdown-only writing; use `writing-orchestrator`, `markdown-helper`, or `mad-writer`. + +## Core Principle + +The LaTeX final draft must be a faithful, technically precise expansion of the already established research content. The agent may improve structure, wording, LaTeX formatting, and claim boundaries, but must not invent new experiments, numbers, citations, assumptions, or research claims. + +## Input Files + +| File/Directory | Required | Purpose | +|---|---:|---| +| `paper.md` | Required | Canonical paper content and claim source. | +| `storyline.md` | Strongly recommended | High-level problem, insight, design, and evaluation plan. | +| `writingrules.md` | Required | CoPaper structure and content constraints. | +| `relatedwork/literature.json` | Conditional | Canonical related-work metadata. | +| `relatedwork/papers/*.md` | Conditional | Paper summaries used to write Related Work accurately. | +| `.agents/cross_index.json` | Conditional | Concept-to-literature map, if available. | +| `tex/` or user template directory | Required before LaTeX writing | Target LaTeX template and output directory. | +| `fig/` and/or user figure assets | Conditional | Source figures to copy into `tex/fig/`. | +| `writing_plan.md` | Created or updated by this workflow | Section plan, page budget, figure/table plan, and claim constraints. | + +If the template directory or required source files are missing, stop and ask the user to provide them. Do not fabricate template files or figure assets. + +## Workflow Overview + +### Phase 1: Template Intake + +1. Confirm the user has downloaded the target LaTeX template into the project root, normally as `tex/`. +2. Inspect the template structure: + - main entry file, e.g. `tex/main.tex`; + - section files, e.g. `tex/tex/*.tex`; + - bibliography file, e.g. `tex/references.bib`; + - figure directory, e.g. `tex/fig/`; + - class/style files and page-limit notes. +3. Identify compilation command from the template where possible. Prefer `latexmk -pdf -interaction=nonstopmode -halt-on-error main.tex` from inside the template directory unless the template documents another command. +4. Report the detected template structure and any missing required folders/files before editing. + +### Phase 2: Writing Plan Creation + +Create or update `writing_plan.md` at the project root before drafting LaTeX prose. + +The plan should follow the style of the project’s existing `writing_plan.md` and include: + +1. **Writing target and current state** + - target venue or format; + - page limit and page budget; + - current completion status of each LaTeX section. +2. **Core storyline and contribution hierarchy** + - problem; + - key insight; + - main design components; + - evaluation claims; + - explicit claim boundaries. +3. **Section-by-section outline** + - abstract; + - introduction; + - background/motivation; + - method/design; + - analysis/theory, if any; + - evaluation; + - discussion/threats; + - related work; + - conclusion. +4. **Figure/table plan** + - each figure/table label; + - intended source file; + - target LaTeX path under `tex/fig/`; + - which section uses it; + - what claim it supports and what it does not support. +5. **Writing order** + - usually technical trunk first, then evaluation, discussion/related work, background/introduction, abstract/conclusion; + - adapt order to the paper’s risk profile. +6. **Hard writing constraints** + - no invented experiments or numbers; + - no claim beyond `paper.md`, `storyline.md`, related-work summaries, or actual experimental evidence; + - no unsupported novelty or safety claims; + - all claims must stay inside the evaluated scope. + +Ask the user to confirm the plan before large-scale drafting unless they explicitly request autonomous execution. + +### Phase 3: Template Outline Initialization + +Initialize the LaTeX template so that it has the intended paper skeleton before writing full prose. + +1. Update `main.tex` only as needed to include the target section files in the correct order. +2. Create or update section files under the template’s section directory, for example: + - `tex/tex/abstract.tex` + - `tex/tex/intro.tex` + - `tex/tex/background.tex` or `tex/tex/bg.tex` + - `tex/tex/method.tex` or `tex/tex/design.tex` + - `tex/tex/evaluation.tex` + - `tex/tex/discussion.tex` + - `tex/tex/relatedwork.tex` + - `tex/tex/conclusion.tex` +3. Insert only structural section/subsection headings and necessary figure/table skeletons at this stage. +4. Preserve the template’s class, package conventions, bibliography style, and author/title format unless the user asks to change them. +5. Guide the user to copy required figure files into the template figure directory, usually `tex/fig/`. +6. Do not invent placeholder experimental figures. If a figure is missing, insert a TODO comment or ask the user for the file. + +### Phase 4: Section-by-Section LaTeX Writing + +Write the final LaTeX draft according to `writing_plan.md`. Work one section at a time. + +Before writing each section, read and deeply understand the relevant sources: + +1. Always read the corresponding part of `paper.md`. +2. Read `storyline.md` when the section touches problem, insight, design, or evaluation narrative. +3. Read `writing_plan.md` to enforce page budget, section intent, and claim boundaries. +4. For Related Work, read: + - `relatedwork/literature.json`; + - relevant `relatedwork/papers/*.md` summaries; + - `.agents/cross_index.json`, if present. +5. For Evaluation, read actual result tables, figure data, experiment notes, and any scripts or data files that the user identifies as authoritative. +6. For LaTeX integration, read existing neighboring section files to maintain terminology and notation consistency. + +Writing requirements: + +- Produce conference-style LaTeX prose, not a mechanical paragraph-by-paragraph copy from `paper.md`. +- Preserve all math notation and define symbols before use. +- Use `\cite{...}` only for references that exist in the bibliography or that the user explicitly asks to add. +- Do not fabricate related-work summaries; only use downloaded/summarized papers or user-provided citation facts. +- Do not fabricate numerical results or experimental setup details. +- Keep Introduction and Conclusion natural; avoid unnecessary subsections unless the venue or template expects them. +- Keep captions concise but self-contained. +- Keep scope qualifiers close to strong claims, especially for safety, timing, theorem, empirical, or deployment claims. +- When a section relies on a claim boundary, write the boundary explicitly rather than burying it only in Discussion. + +After drafting a section: + +1. Check that the section satisfies its `writing_plan.md` purpose. +2. Check that all cited claims have support in `paper.md`, related-work summaries, or experiment evidence. +3. Check notation consistency with already written LaTeX sections. +4. Run a targeted read-through for unsupported claims, duplicated content, and page-budget risk. +5. If the user wants strict gating, run the relevant checker skill or ask for user confirmation before moving to the next section. + +### Phase 5: Full-Draft Review and Revision + +After all LaTeX sections are written, the user may ask for review or revision. Handle these requests as LaTeX final-draft tasks, not as free-form rewriting. + +Common review modes: + +- logic and claim-evidence consistency; +- data and experiment consistency; +- related-work citation accuracy; +- novelty and differentiation; +- technical depth; +- safety/scope boundary; +- AI-style writing artifacts; +- page-limit compression; +- LaTeX compile errors, undefined references, overfull boxes, and float placement. + +Review workflow: + +1. Read the relevant LaTeX files, not only `paper.md`. +2. Compare strong claims against `paper.md`, `storyline.md`, experiment evidence, and related-work summaries. +3. Report findings with exact file and line references. +4. For user-approved revisions, edit only the relevant LaTeX files. +5. Run targeted checks after edits. Compile only when useful or requested, or when changes could affect LaTeX validity. + +## Recommended Writing Order + +Default order for a new LaTeX final draft: + +1. Template and figure/table setup. +2. `writing_plan.md`. +3. Technical trunk: system model, method/design, analysis. +4. Evaluation. +5. Discussion/threats and related work. +6. Background/motivation. +7. Introduction. +8. Abstract and conclusion. +9. Full-paper consistency pass. +10. Compilation and submission-oriented checks. + +Rationale: write the technical and evidence-bearing sections first so that Introduction, Abstract, and Conclusion do not overclaim. + +## Writing Plan Template + +Use this structure when creating `writing_plan.md`: + +```markdown +# <Paper Title> 写作大纲与计划 + +## 1. 写作目标与当前状态 + +### 1.1 写作目标 +- 目标稿件:<venue/template/page limit>。 +- 主线:<one-sentence storyline>。 +- 核心贡献层级: + 1. <contribution 1> + 2. <contribution 2> + 3. <contribution 3> + +### 1.2 当前写作状态 +- 模板目录:`tex/`。 +- 编译命令:`<command>`。 +- 已完成:<files/sections>。 +- 待完成:<files/sections>。 + +## 2. 篇幅预算 + +| Part | 目标页数 | 当前状态 | +|---|---:|---| +| Abstract | | | +| Introduction | | | +| Background | | | +| Method / Design | | | +| Analysis | | | +| Evaluation | | | +| Discussion | | | +| Related Work | | | +| Conclusion | | | +| **Total** | | | + +## 3. 正文大纲 + +### Abstract +- <claims and evidence> + +### 1. Introduction +- <motivation, gap, insight, results, contributions> + +### 2. Background / Motivation +- <concepts and motivation evidence> + +### 3. Method / Design +- <technical structure> + +### 4. Analysis / Theory +- <assumptions, property, proof scope> + +### 5. Evaluation +- <RQs, setup, metrics, results, boundaries> + +### 6. Discussion / Threats +- <scope and limitations> + +### 7. Related Work +- <categories and differentiation> + +### 8. Conclusion +- <scoped takeaway> + +## 4. 图表计划 + +### Figures +1. **Fig.1** — <caption intent>. File: `tex/fig/<file>`. + +### Tables +1. **Table 1** — <caption intent>. Label: `<label>`. + +## 5. 写作顺序 +- Phase 0: Template and figures. +- Phase 1: Technical trunk. +- Phase 2: Evaluation. +- Phase 3: Discussion and related work. +- Phase 4: Background, introduction, abstract, conclusion. +- Phase 5: Full-paper checks. + +## 6. 写作约束 +- <do-not-invent constraints> +- <claim boundaries> +- <terminology rules> +- <page-limit strategy> +``` + +## Common Pitfalls + +- Do not treat `paper.md` as optional. It is the canonical source for final LaTeX content. +- Do not write from memory when writing a section; re-read relevant sources first. +- Do not fabricate related work or citations. +- Do not add numerical results without user-provided evidence. +- Do not overclaim in Abstract/Introduction before the body supports the claim. +- Do not bury important safety, timing, or deployment-scope limitations only in Discussion. +- Do not ignore the template’s bibliography, package, and figure conventions. +- Do not copy figures into the wrong folder; final LaTeX usually expects `tex/fig/` or the template’s configured figure path. +- Do not run broad rewrites after the final draft unless the user asks; use targeted review and revision. + +## Final Checks + +Before declaring the LaTeX final draft ready: + +1. Compile the template if appropriate: + ```powershell + latexmk -pdf -interaction=nonstopmode -halt-on-error main.tex + ``` + Run from the template directory, e.g. `tex/`. +2. Check undefined references and citations. +3. Check page count against the venue limit. +4. Check figure/table references and file existence. +5. Check all major claims against `paper.md`, `storyline.md`, and evidence. +6. Check that related work citations match actual summarized papers or verified bibliographic facts. +7. Check that Abstract, Introduction, Evaluation, Discussion, and Conclusion use the same scope and terminology. diff --git a/vibepaper/scaffold/skills/latex2markdown/SKILL.md b/copaper/scaffold/skills/latex2markdown/SKILL.md similarity index 95% rename from vibepaper/scaffold/skills/latex2markdown/SKILL.md rename to copaper/scaffold/skills/latex2markdown/SKILL.md index 3ec48b4..47e4f2e 100644 --- a/vibepaper/scaffold/skills/latex2markdown/SKILL.md +++ b/copaper/scaffold/skills/latex2markdown/SKILL.md @@ -1,21 +1,21 @@ --- name: latex2markdown -description: Extracts content from LaTeX files to fill in paper.md. Use this skill when the user wants to import content from existing LaTeX papers into the VibePaper structure. +description: Extracts content from LaTeX files to fill in paper.md. Use this skill when the user wants to import content from existing LaTeX papers into the CoPaper structure. --- # LaTeX to Markdown Conversion Skill -This skill extracts content from LaTeX academic papers and fills it into the VibePaper markdown structure. +This skill extracts content from LaTeX academic papers and fills it into the CoPaper markdown structure. ## When to Use This Skill - User requests to convert LaTeX to paper.md (e.g., "convert LaTeX to paper.md", "import my LaTeX paper") - User wants to extract content from existing LaTeX files to fill paper.md -- User needs to migrate LaTeX content to the VibePaper structure +- User needs to migrate LaTeX content to the CoPaper structure ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1-5** (`#` to `#####`): Structural headings only — do NOT modify these in `paper.md`. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. @@ -25,7 +25,7 @@ The paper follows VibePaper structure. Key rules for this skill: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `paper.md` | **Required** | Step 1 (start) | Target framework file whose existing structure guides the conversion | -| `writingrules.md` | **Required** | Step 1 (start) | Full structure and content constraints for mapping LaTeX content into VibePaper markdown | +| `writingrules.md` | **Required** | Step 1 (start) | Full structure and content constraints for mapping LaTeX content into CoPaper markdown | | User-provided LaTeX files | **Required** | Step 1 (start) | Source material to extract and map into `paper.md` | | `fig/` | Conditional | During special-element handling | Destination for user-provided figure assets referenced from the LaTeX source | diff --git a/vibepaper/scaffold/skills/logic-checker/SKILL.md b/copaper/scaffold/skills/logic-checker/SKILL.md similarity index 98% rename from vibepaper/scaffold/skills/logic-checker/SKILL.md rename to copaper/scaffold/skills/logic-checker/SKILL.md index 646fbe5..bb678b0 100644 --- a/vibepaper/scaffold/skills/logic-checker/SKILL.md +++ b/copaper/scaffold/skills/logic-checker/SKILL.md @@ -5,7 +5,7 @@ description: Detects logical discrepancies and inconsistencies in academic paper # Logic Checker Skill -This skill detects logical discrepancies, inconsistencies, and argumentation flaws in academic paper drafts following the VibePaper structure. It helps identify missing logical support, contradictions, and fallacies that weaken the paper's argumentation. +This skill detects logical discrepancies, inconsistencies, and argumentation flaws in academic paper drafts following the CoPaper structure. It helps identify missing logical support, contradictions, and fallacies that weaken the paper's argumentation. ## When to Use This Skill @@ -186,7 +186,7 @@ For each discrepancy found: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/logic-checker/examples.md b/copaper/scaffold/skills/logic-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/logic-checker/examples.md rename to copaper/scaffold/skills/logic-checker/examples.md diff --git a/vibepaper/scaffold/skills/mad-writer/SKILL.md b/copaper/scaffold/skills/mad-writer/SKILL.md similarity index 94% rename from vibepaper/scaffold/skills/mad-writer/SKILL.md rename to copaper/scaffold/skills/mad-writer/SKILL.md index ba8532f..21bcfad 100644 --- a/vibepaper/scaffold/skills/mad-writer/SKILL.md +++ b/copaper/scaffold/skills/mad-writer/SKILL.md @@ -38,7 +38,7 @@ This skill operates in a continuous loop: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -53,13 +53,13 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov | `paper.md` | **Required** | Phase 1 (initialization) and every rewrite iteration | Current paper content; scan for empty sections, assess state, write content | | `storyline.md` | Conditional | Phase 1 (if exists) | Research narrative for grounding content | | `relatedwork/summary.md` | Conditional | Phase 0-1 (if literature exists) | Context from related work for citations | -| Checker status | Conditional | Phase 3 (checker loop) | Use `vibepaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence | +| Checker status | Conditional | Phase 3 (checker loop) | Use `copaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence | | `.agents/state.json` | Tool gap / optional fallback | Phase 6 (progress tracking) | Read experiment context only when needed; the OpenCode plugin does not expose arbitrary progress metadata writes | When writing content, refer to the Paper Structure Reference above instead of reading `writingrules.md`. -For checker status summaries, call `vibepaper_checker_status`; do not read `.agents/state.json` directly just to infer checker run status when the plugin tool is available. -If the user wants durable checker summaries after an actual checker run, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason; wait for explicit confirmation; then route to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. -For phase-level workflow updates, use `vibepaper_workflow_set_phase` after restating the intended phase/status and waiting for explicit confirmation. The tool writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. Do not hand-edit `.agents/state.json` for checker results, progress counters, or experiment metadata in plugin-based workflows. +For checker status summaries, call `copaper_checker_status`; do not read `.agents/state.json` directly just to infer checker run status when the plugin tool is available. +If the user wants durable checker summaries after an actual checker run, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason; wait for explicit confirmation; then route to `@copaper-recorder` so it can call `copaper_checker_record`. +For phase-level workflow updates, use `copaper_workflow_set_phase` after restating the intended phase/status and waiting for explicit confirmation. The tool writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. Do not hand-edit `.agents/state.json` for checker results, progress counters, or experiment metadata in plugin-based workflows. ## Work Loop @@ -253,7 +253,7 @@ Aggregate feedback from all 7 checkers by severity: - **Minor issues**: Good to address - **Data issues**: Check if `⚠️ [BOGUS]` markers need replacement -After running the checker loop, call `vibepaper_checker_status` to inspect checker run status, severity counts, stale signals, and precheck evidence. Use the actual checker outputs for issue details; the status tool is a read-only summary and freshness check, not an issue-detail store. If the user confirms recording a run summary, use `vibepaper_checker_record` through `@vibepaper-recorder`; do not write checker state by hand. +After running the checker loop, call `copaper_checker_status` to inspect checker run status, severity counts, stale signals, and precheck evidence. Use the actual checker outputs for issue details; the status tool is a read-only summary and freshness check, not an issue-detail store. If the user confirms recording a run summary, use `copaper_checker_record` through `@copaper-recorder`; do not write checker state by hand. **Step 3.3: Filter Fixable Issues** @@ -520,7 +520,7 @@ To prevent infinite loops, the skill has these limits: ## Output Tracking -The skill maintains an in-session progress log in the response. The current OpenCode plugin can record confirmed checker run summaries through `vibepaper_checker_record`, but it has no generic progress-log tool. Do not write hidden progress data into `.agents/state.json` or `.agents/events.jsonl`. +The skill maintains an in-session progress log in the response. The current OpenCode plugin can record confirmed checker run summaries through `copaper_checker_record`, but it has no generic progress-log tool. Do not write hidden progress data into `.agents/state.json` or `.agents/events.jsonl`. ```markdown <!-- MAD-WRITER LOG (Hidden) diff --git a/vibepaper/scaffold/skills/markdown-helper/SKILL.md b/copaper/scaffold/skills/markdown-helper/SKILL.md similarity index 80% rename from vibepaper/scaffold/skills/markdown-helper/SKILL.md rename to copaper/scaffold/skills/markdown-helper/SKILL.md index f9f0e87..11358e0 100644 --- a/vibepaper/scaffold/skills/markdown-helper/SKILL.md +++ b/copaper/scaffold/skills/markdown-helper/SKILL.md @@ -1,11 +1,11 @@ --- name: markdown-helper -description: Helps users write and improve markdown academic paper content following VibePaper GUI structure. Use this skill when the user wants to write or improve paper.md content for academic quality. +description: Helps users write and improve markdown academic paper content following CoPaper GUI structure. Use this skill when the user wants to write or improve paper.md content for academic quality. --- # Markdown Helper Skill -This skill helps users write markdown content for computer science research papers following the VibePaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. +This skill helps users write markdown content for computer science research papers following the CoPaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. ## When to Use This Skill @@ -15,7 +15,7 @@ This skill helps users write markdown content for computer science research pape ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -27,11 +27,11 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `vibepaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | +| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `copaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | | `storyline.md` | **Required** | State 0 (outline) and State 2 (subagent prompt) | Core research narrative, insights, and method for grounding | | `.agents/cross_index.json` | Optional but preferred | State 1 (before reading relatedwork summaries) | Cross-reference index; consult FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current section | | `relatedwork/papers/*.md` | Optional | State 1 (only the summaries identified via cross-index) | Individual literature summaries; read ONLY the specific files identified through `.agents/cross_index.json` lookup | -| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `vibepaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | +| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `copaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | | `fig/` | Conditional | State 2 (when writing sections that reference visuals) | Available figures; list paths so the subagent can reference them | When the orchestrator needs literature context in State 1, it MUST: @@ -52,14 +52,14 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N 6. **STOP AND WAIT** for user confirmation. Once the user approves the outline, proceed to draft paragraphs one by one. ### Step 2: Scan & Propose Paragraph (WAIT FOR USER) -1. Call `vibepaper_paper_structure_status` instead of manually scanning `paper.md`. +1. Call `copaper_paper_structure_status` instead of manually scanning `paper.md`. 2. Use the tool's `nextTarget` as the next Level 5 section to draft. If `nextTarget` is `null`, report that no incomplete Level 5 writing target remains. 3. Use the tool's `violations` to warn the user about structural issues before drafting. 4. Read only the targeted region of `paper.md` if you need its `description` metadata or local context for the selected section. 5. **Announce and Ask**: Tell the user which section is next and its description. Ask: *"I found section **[Level 5 Title]** is next. Shall I launch a writing subagent to draft this paragraph based on our approved outline?"* 6. **STOP AND WAIT** for user confirmation. Do not proceed. -`vibepaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. +`copaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. ### Step 3: Delegate to Subagent 1. Once confirmed, use the `task` or `runSubagent` tool to launch an independent subagent for writing (`category="writing"`, `run_in_background=false`). @@ -70,7 +70,7 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N - "Read `storyline.md` for core narrative." - "Read `paper.md` to understand context and what has been written so far." - "Read `.agents/cross_index.json` FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current section's technical points. Then read ONLY those specific summaries — do NOT read all files under `relatedwork/papers/` indiscriminately." - - "Call `vibepaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If it is complete and experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool." + - "Call `copaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If it is complete and experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool." - "Check `fig/` directory with `Glob('fig/*')`. If relevant figures exist, reference them in your writing using markdown image syntax." - "Output ONLY the drafted Level 6 node (###### Title + Content). DO NOT edit `paper.md` yourself." - "**Writing Style Instructions**: @@ -92,10 +92,10 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N ## Action Logging -Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `vibepaper_workflow_set_phase` and `vibepaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. +Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `copaper_workflow_set_phase` and `copaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. Do not append to `.agents/events.jsonl` manually when using the plugin-based workflow. Report this limitation if the user asks for paragraph-level event logging. -If the user asks to inspect workflow event history, call `vibepaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. +If the user asks to inspect workflow event history, call `copaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. ## Crucial Anti-Patterns - **NEVER** write multiple paragraphs at once without user interactive review. diff --git a/vibepaper/scaffold/skills/markdown-review/SKILL.md b/copaper/scaffold/skills/markdown-review/SKILL.md similarity index 85% rename from vibepaper/scaffold/skills/markdown-review/SKILL.md rename to copaper/scaffold/skills/markdown-review/SKILL.md index 7048e87..19c2889 100644 --- a/vibepaper/scaffold/skills/markdown-review/SKILL.md +++ b/copaper/scaffold/skills/markdown-review/SKILL.md @@ -1,12 +1,12 @@ --- name: markdown-review -description: Reviews and improves markdown academic paper content following VibePaper GUI structure. Use this skill when the user wants to review or improve paper.md content for academic quality. +description: Reviews and improves markdown academic paper content following CoPaper GUI structure. Use this skill when the user wants to review or improve paper.md content for academic quality. --- # Markdown Review Skill -This skill provides comprehensive review of markdown content for computer science research papers by running all available checkers sequentially. It follows the VibePaper structure rules. -When the OpenCode plugin injects `@vibepaper-reviewer`, route checker execution summaries and issue explanations through that read-only reviewer subagent. The reviewer may call `vibepaper_checker_status` and prepare checker-record metadata, but it must not edit `paper.md` or write checker records directly. +This skill provides comprehensive review of markdown content for computer science research papers by running all available checkers sequentially. It follows the CoPaper structure rules. +When the OpenCode plugin injects `@copaper-reviewer`, route checker execution summaries and issue explanations through that read-only reviewer subagent. The reviewer may call `copaper_checker_status` and prepare checker-record metadata, but it must not edit `paper.md` or write checker records directly. ## When to Use This Skill @@ -19,10 +19,10 @@ When the OpenCode plugin injects `@vibepaper-reviewer`, route checker execution | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `paper.md` | **Required** | Step 1 (start) | Primary analysis target; read to understand paper content for all 7 checkers | -| Checker status | Optional | Step 1 and after checker execution | Use `vibepaper_checker_status` for read-only existing checker status, severity counts, stale signals, and precheck evidence | +| Checker status | Optional | Step 1 and after checker execution | Use `copaper_checker_status` for read-only existing checker status, severity counts, stale signals, and precheck evidence | -Additional files (such as `writingrules.md`, `relatedwork/papers/*.md`, `.agents/cross_index.json`) are read indirectly by the individual checker sub-skills, not by `markdown-review` itself. This orchestrator only reads `paper.md` directly. If existing checker status is needed, call `vibepaper_checker_status` instead of reading `.agents/state.json` or `.agents/precheck_report.md` directly. If the user wants durable checker summaries, restate the checker, status, Critical/Major/Minor counts, summary, evidence, and reason, wait for confirmation, then route the record action to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. -Use `@vibepaper-reviewer` for the read-only review explanation step when available; use `@vibepaper-recorder` only for confirmed persistence. +Additional files (such as `writingrules.md`, `relatedwork/papers/*.md`, `.agents/cross_index.json`) are read indirectly by the individual checker sub-skills, not by `markdown-review` itself. This orchestrator only reads `paper.md` directly. If existing checker status is needed, call `copaper_checker_status` instead of reading `.agents/state.json` or `.agents/precheck_report.md` directly. If the user wants durable checker summaries, restate the checker, status, Critical/Major/Minor counts, summary, evidence, and reason, wait for confirmation, then route the record action to `@copaper-recorder` so it can call `copaper_checker_record`. +Use `@copaper-reviewer` for the read-only review explanation step when available; use `@copaper-recorder` only for confirmed persistence. ## Review Workflow @@ -56,7 +56,7 @@ This skill runs **seven specialized checkers** in sequence, each focusing on a d First, read the essential files: 1. Read `paper.md` to understand the paper content -2. Call `vibepaper_checker_status` to see whether prior checker results or precheck evidence exist and whether they are stale. +2. Call `copaper_checker_status` to see whether prior checker results or precheck evidence exist and whether they are stale. 3. Do NOT read additional context files directly here. Related-work context, cross-index context, and structure rules are handled indirectly by the individual checker sub-skills. ### Step 2: Run Problem Checker @@ -147,7 +147,7 @@ First, read the essential files: After all checkers complete, generate a summary report aggregating all findings. -If the user asks to persist checker results, do not edit `.agents/state.json` manually. For each confirmed checker summary, route to `@vibepaper-recorder` and call `vibepaper_checker_record` with actual checker output. This records run-level summary only; it does not mark individual issues resolved. +If the user asks to persist checker results, do not edit `.agents/state.json` manually. For each confirmed checker summary, route to `@copaper-recorder` and call `copaper_checker_record` with actual checker output. This records run-level summary only; it does not mark individual issues resolved. ## Output Format @@ -375,7 +375,7 @@ Each checker will insert its own formatted HTML comments at relevant locations i ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -390,7 +390,7 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov 4. **AI-generated comments**: All comments are AI analysis, clearly marked to distinguish from human reviewer feedback 5. **Reproducible review**: Run this skill multiple times as you fix issues to track progress 6. **Author responsibility**: Authors should review all AI suggestions critically before implementing -7. **Plugin tool boundary**: Use `vibepaper_checker_status` for read-only checker status, severity counts, stale signals, and precheck evidence. Use `vibepaper_checker_record` only after explicit user confirmation to persist actual checker summaries. Use `vibepaper_init_apply` for confirmed core-file initialization requests. Report checker findings in the response even when a summary is recorded. +7. **Plugin tool boundary**: Use `copaper_checker_status` for read-only checker status, severity counts, stale signals, and precheck evidence. Use `copaper_checker_record` only after explicit user confirmation to persist actual checker summaries. Use `copaper_init_apply` for confirmed core-file initialization requests. Report checker findings in the response even when a summary is recorded. ## Usage Examples diff --git a/vibepaper/scaffold/skills/markdown2latex/SKILL.md b/copaper/scaffold/skills/markdown2latex/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/markdown2latex/SKILL.md rename to copaper/scaffold/skills/markdown2latex/SKILL.md index 7dd1167..a3d967e 100644 --- a/vibepaper/scaffold/skills/markdown2latex/SKILL.md +++ b/copaper/scaffold/skills/markdown2latex/SKILL.md @@ -15,7 +15,7 @@ This skill converts markdown academic paper content into high-quality LaTeX form ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title → maps to `\title{}`. - **Level 2-5** (`##` to `#####`): Structural headings → map to `\section{}`, `\subsection{}`, etc. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (becomes opening sentence). Body = supporting text. diff --git a/vibepaper/scaffold/skills/novelty-checker/SKILL.md b/copaper/scaffold/skills/novelty-checker/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/novelty-checker/SKILL.md rename to copaper/scaffold/skills/novelty-checker/SKILL.md index 30bc45e..246776f 100644 --- a/vibepaper/scaffold/skills/novelty-checker/SKILL.md +++ b/copaper/scaffold/skills/novelty-checker/SKILL.md @@ -270,7 +270,7 @@ Generate a comprehensive novelty assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/novelty-checker/examples.md b/copaper/scaffold/skills/novelty-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/novelty-checker/examples.md rename to copaper/scaffold/skills/novelty-checker/examples.md diff --git a/vibepaper/scaffold/skills/pdf2paper/SKILL.md b/copaper/scaffold/skills/pdf2paper/SKILL.md similarity index 82% rename from vibepaper/scaffold/skills/pdf2paper/SKILL.md rename to copaper/scaffold/skills/pdf2paper/SKILL.md index 7249f49..1699396 100644 --- a/vibepaper/scaffold/skills/pdf2paper/SKILL.md +++ b/copaper/scaffold/skills/pdf2paper/SKILL.md @@ -12,7 +12,7 @@ It is designed for cases where the PDF already contains most of the technical na - User asks to import an existing PDF draft into `paper.md` - User wants section-by-section conversion instead of one-shot rewrite -- User wants to preserve claims from PDF while adapting to VibePaper structure +- User wants to preserve claims from PDF while adapting to CoPaper structure Typical triggers: - `convert pdf to paper.md` @@ -24,7 +24,7 @@ Typical triggers: ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1-5** (`#` to `#####`): Structural headings only — do NOT modify these in `paper.md`. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. @@ -33,9 +33,9 @@ The paper follows VibePaper structure. Key rules for this skill: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | Conditional | Step 1 and Step 8 | Target framework; inspect through `vibepaper_paper_structure_status` if present | -| `*.pdf` | **Required** | Step 2 | Source draft content; extract and validate through `vibepaper_pdf_extract` | -| `.agents/state.json` | Optional | Step 9 | Updated only through `vibepaper_workflow_set_phase` | +| `paper.md` | Conditional | Step 1 and Step 8 | Target framework; inspect through `copaper_paper_structure_status` if present | +| `*.pdf` | **Required** | Step 2 | Source draft content; extract and validate through `copaper_pdf_extract` | +| `.agents/state.json` | Optional | Step 9 | Updated only through `copaper_workflow_set_phase` | | `fig/` | Optional | Step 5 | Keep references to figure files mentioned in PDF | Preferred source example: @@ -61,12 +61,12 @@ Path safety rule: ## Supported Formats -- Text-based `pdf`: supported through `vibepaper_pdf_extract` -- Scanned/image-only `pdf`: not OCRed by this skill; if `vibepaper_pdf_extract` reports low confidence or little/no text, stop and ask the user for a text-based PDF or extracted text +- Text-based `pdf`: supported through `copaper_pdf_extract` +- Scanned/image-only `pdf`: not OCRed by this skill; if `copaper_pdf_extract` reports low confidence or little/no text, stop and ask the user for a text-based PDF or extracted text ## Extraction Strategy -Call `vibepaper_pdf_extract` for source extraction when the OpenCode plugin tool is available. +Call `copaper_pdf_extract` for source extraction when the OpenCode plugin tool is available. This tool is read-only and requires an explicit `.pdf` path. It validates path safety, file existence, supported extension, file size, and readable text operators. It does not scan directories, guess source files, write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -77,7 +77,7 @@ Use the tool output to capture: - extraction confidence - source hash for traceability -If the tool reports low confidence or no text operators, disclose that limitation to the user and ask for a better source. Do not replace `vibepaper_pdf_extract` with prompt-only extraction instructions, shell existence checks, shell `pdftotext`, OCR, or directory scans when the plugin tool is available. +If the tool reports low confidence or no text operators, disclose that limitation to the user and ask for a better source. Do not replace `copaper_pdf_extract` with prompt-only extraction instructions, shell existence checks, shell `pdftotext`, OCR, or directory scans when the plugin tool is available. ## Mapping Rules (PDF -> paper.md) @@ -102,14 +102,14 @@ If one PDF paragraph supports multiple destinations, split conservatively and ke - `请提供要转换的 PDF 文件路径(例如:target/example_project/draft.pdf)。` 3. Do not scan the filesystem for PDF candidates when the path is missing. 4. Wait for user-provided absolute or relative path. -5. Do not run a separate shell/file existence check for the `.pdf`; `vibepaper_pdf_extract` performs this validation in Step 2. -6. Check whether `paper.md` exists through `vibepaper_paper_structure_status` in Step 3: +5. Do not run a separate shell/file existence check for the `.pdf`; `copaper_pdf_extract` performs this validation in Step 2. +6. Check whether `paper.md` exists through `copaper_paper_structure_status` in Step 3: - if yes, continue normal mapping and in-place update flow - if no, continue conversion in draft mode and initialize project at Step 8 before final write ### Step 2: Extract PDF content -1. Call `vibepaper_pdf_extract` with the explicit user-provided `.pdf` path. +1. Call `copaper_pdf_extract` with the explicit user-provided `.pdf` path. 2. If the tool returns an error, stop and report the error; do not retry by scanning directories, running `pdftotext`, or doing OCR. 3. Use the returned text, page count, confidence, warnings, and source hash. 4. Build an intermediate traceable note with available page information. @@ -120,7 +120,7 @@ If one PDF paragraph supports multiple destinations, split conservatively and ke ### Step 3: Scan target framework -1. Call `vibepaper_paper_structure_status` to inspect `paper.md` structure and Level 5 writing targets. +1. Call `copaper_paper_structure_status` to inspect `paper.md` structure and Level 5 writing targets. 2. If the tool reports missing `paper.md`, keep accepted conversion content in draft mode and initialize project at Step 8 before final write. 3. If the tool reports an unsafe path or unreadable file, stop and report the tool error. 4. Use the embedded Paper Structure Reference above for structure constraints. @@ -177,12 +177,12 @@ If `paper.md` is missing: - project `domain` 2. Restate the project directory, project `name`, and project `domain`. 3. Wait for explicit user confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed VibePaper core files and refuses conflicts. +4. Call `copaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed CoPaper core files and refuses conflicts. 5. Then apply the accepted converted content into initialized `paper.md`. -Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `vibepaper_init_apply` is available. +Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `copaper_init_apply` is available. -If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `vibepaper_init_apply` can repair missing skills. Continue only if `paper.md` exists and the current skill instructions are available in the active agent context. +If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `copaper_init_apply` can repair missing skills. Continue only if `paper.md` exists and the current skill instructions are available in the active agent context. ### Step 9: Update workflow status @@ -190,9 +190,9 @@ After accepted edits: - If at least one writing section is filled, set `writing` phase to `in_progress`. - If all intended conversion sections are materially filled, set `writing` phase to `complete`. -Use `vibepaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. +Use `copaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. +Do not run `copaper set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. ## Output Requirements @@ -208,7 +208,7 @@ Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when t Each inserted paragraph should be: - faithful to PDF content -- structurally compliant with VibePaper rules +- structurally compliant with CoPaper rules - concise and readable - traceable to source pages @@ -218,7 +218,7 @@ Each inserted paragraph should be: - **NEVER** invent experiment numbers, datasets, or baselines - **NEVER** modify Level 1-5 structure in `paper.md` - **NEVER** rewrite the full paper in one blind pass -- **NEVER** pretend OCR was performed by this skill; disclose low-confidence or missing text from `vibepaper_pdf_extract` +- **NEVER** pretend OCR was performed by this skill; disclose low-confidence or missing text from `copaper_pdf_extract` - **NEVER** treat this as autonomous writing without user confirmation ## Recommended Default Invocation diff --git a/vibepaper/scaffold/skills/phase-navigation/SKILL.md b/copaper/scaffold/skills/phase-navigation/SKILL.md similarity index 77% rename from vibepaper/scaffold/skills/phase-navigation/SKILL.md rename to copaper/scaffold/skills/phase-navigation/SKILL.md index 5286a11..f1a7db6 100644 --- a/vibepaper/scaffold/skills/phase-navigation/SKILL.md +++ b/copaper/scaffold/skills/phase-navigation/SKILL.md @@ -1,17 +1,17 @@ --- name: phase-navigation -description: Inspect the current VibePaper workflow phase, move forward, move backward, or jump to a named phase when the user asks to view, advance, return, roll back, or switch phases in OpenCode, then invoke the skill for the active phase. Uses `vibe status --json` and `vibe set-phase` instead of editing state files. +description: Inspect the current CoPaper workflow phase, move forward, move backward, or jump to a named phase when the user asks to view, advance, return, roll back, or switch phases in OpenCode, then invoke the skill for the active phase. Uses `copaper status --json` and `copaper set-phase` instead of editing state files. --- # Phase Navigation -This skill inspects and moves a VibePaper project between workflow phases through the `vibe` CLI. +This skill inspects and moves a CoPaper project between workflow phases through the `copaper` CLI. ## Input Files | File | Required | When Used | Purpose | |------|----------|-----------|---------| -| `.agents/state.json` | Required | Start | Read workflow state through `vibe status --json` | +| `.agents/state.json` | Required | Start | Read workflow state through `copaper status --json` | | `.agents/events.jsonl` | Optional | After phase change | CLI appends phase transition events | ## Triggers @@ -49,7 +49,7 @@ Accept clear aliases such as "latex", "review", "paper writing", or "related wor 1. Check current project status: ```bash -vibe --root . status --json +copaper --root . status --json ``` 2. If the user only asked to view or check the current phase, report `current_phase`, summarize the phase statuses briefly, and suggest the active phase's next work. Do not mutate state. @@ -57,7 +57,7 @@ vibe --root . status --json 3. If the user asked for the next phase, read `current_phase` and advance by marking the current phase complete: ```bash -vibe --root . set-phase <current_phase> --status complete +copaper --root . set-phase <current_phase> --status complete ``` The phase order is: @@ -73,9 +73,9 @@ storyline -> literature -> discussion -> experiments -> writing -> latex_review 6. To return to a previous phase, set the target phase to `in_progress`, then reset every later phase to `not_started`: ```bash -vibe --root . set-phase <target_phase> --status in_progress -vibe --root . set-phase <later_phase_1> --status not_started -vibe --root . set-phase <later_phase_2> --status not_started +copaper --root . set-phase <target_phase> --status in_progress +copaper --root . set-phase <later_phase_1> --status not_started +copaper --root . set-phase <later_phase_2> --status not_started ``` Run one `set-phase` command for each phase after the target. This preserves earlier completed work while making the returned phase the active workflow point. @@ -83,18 +83,18 @@ Run one `set-phase` command for each phase after the target. This preserves earl 7. If the user asked for a specific phase without rollback language, set that phase to `in_progress`: ```bash -vibe --root . set-phase <target_phase> --status in_progress +copaper --root . set-phase <target_phase> --status in_progress ``` 8. If the user asks to skip a phase, use: ```bash -vibe --root . skip <phase> --reason "<reason>" +copaper --root . skip <phase> --reason "<reason>" ``` If no reason is provided, ask for a short reason before skipping. -9. After any successful phase change, run `vibe --root . status --json` again and hand off to the active phase skill. Do not rely on OpenCode to auto-trigger another skill; explicitly open that skill's `SKILL.md` and continue its workflow. +9. After any successful phase change, run `copaper --root . status --json` again and hand off to the active phase skill. Do not rely on OpenCode to auto-trigger another skill; explicitly open that skill's `SKILL.md` and continue its workflow. ## Skill Invocation @@ -113,7 +113,7 @@ Important: skill chaining is manual. The agent must directly read the target `SK If the invoked skill needs missing inputs, ask only for the minimum information needed by that skill. For example, after entering `literature`, ask for topic constraints or seed papers only if they are not already available. -If the target skill file is missing, say which file is missing and fall back to `vibepaper-manage` only for workflow-state inspection. Do not stop silently. +If the target skill file is missing, say which file is missing and fall back to `copaper-manage` only for workflow-state inspection. Do not stop silently. ## Constraints @@ -125,5 +125,5 @@ If the target skill file is missing, say which file is missing and fall back to - Do not invent phase names outside the valid phase list. - If already at `latex_review` and the user asks for the next phase, explain that it is the final phase and show the current status. - If already at `storyline` and the user asks for the previous phase, explain that it is the first phase and show the current status. -- Do not use `vibe rollback` for phase navigation unless the user explicitly asks to restore a Git commit; this skill changes workflow phase state, not repository contents. -- If `vibe status --json` fails because the project is not initialized, use `auto-init` first. +- Do not use `copaper rollback` for phase navigation unless the user explicitly asks to restore a Git commit; this skill changes workflow phase state, not repository contents. +- If `copaper status --json` fails because the project is not initialized, use `auto-init` first. diff --git a/vibepaper/scaffold/skills/ppt2storyline/SKILL.md b/copaper/scaffold/skills/ppt2storyline/SKILL.md similarity index 82% rename from vibepaper/scaffold/skills/ppt2storyline/SKILL.md rename to copaper/scaffold/skills/ppt2storyline/SKILL.md index 032cf75..a084e38 100644 --- a/vibepaper/scaffold/skills/ppt2storyline/SKILL.md +++ b/copaper/scaffold/skills/ppt2storyline/SKILL.md @@ -28,9 +28,9 @@ Typical triggers: | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | Conditional | Step 1, Step 3, and Step 7 | Target template and section structure; inspect through `vibepaper_storyline_structure_status` | -| `*.pptx` | **Required** | Step 2 | Source research content; extract through `vibepaper_ppt_extract` | -| `.agents/state.json` | Optional | Step 8 | Updated only through `vibepaper_workflow_set_phase` | +| `storyline.md` | Conditional | Step 1, Step 3, and Step 7 | Target template and section structure; inspect through `copaper_storyline_structure_status` | +| `*.pptx` | **Required** | Step 2 | Source research content; extract through `copaper_ppt_extract` | +| `.agents/state.json` | Optional | Step 8 | Updated only through `copaper_workflow_set_phase` | | `relatedwork/` | Optional | Step 4 | Cross-check paper names/citations if needed | Preferred source example for this project: @@ -58,7 +58,7 @@ Path safety rule: ## Extraction Strategy -Call `vibepaper_ppt_extract` for source extraction when the OpenCode plugin tool is available. +Call `copaper_ppt_extract` for source extraction when the OpenCode plugin tool is available. This tool is read-only and requires an explicit `.pptx` path. It validates path safety, file existence, supported extension, file size, and readable slide content. It does not scan directories, guess source files, write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -69,9 +69,9 @@ Use the tool output to capture: - source hash for traceability - speaker notes only if explicitly requested through the tool argument -Do not replace `vibepaper_ppt_extract` with prompt-only extraction instructions, shell existence checks, shell unzip commands, `python-pptx`, or directory scans when the plugin tool is available. +Do not replace `copaper_ppt_extract` with prompt-only extraction instructions, shell existence checks, shell unzip commands, `python-pptx`, or directory scans when the plugin tool is available. -For target structure, call `vibepaper_storyline_structure_status`. This tool is read-only and reports whether `storyline.md` is present, safe, and structurally fillable. Do not manually infer storyline section readiness from prompt-only scans when the plugin tool is available. +For target structure, call `copaper_storyline_structure_status`. This tool is read-only and reports whether `storyline.md` is present, safe, and structurally fillable. Do not manually infer storyline section readiness from prompt-only scans when the plugin tool is available. ## Mapping Rules (Slide -> Storyline) @@ -98,15 +98,15 @@ If one slide supports multiple sections, split its points conservatively. - `请提供要转换的 PPTX 文件路径(例如:target/example_project/research_slides.pptx)。` 3. Do not scan the filesystem for PPT/PPTX candidates when the path is missing. 4. Wait for user-provided absolute or relative path. -5. Do not run a separate shell/file existence check for the `.pptx`; `vibepaper_ppt_extract` performs this validation in Step 2. -6. Call `vibepaper_storyline_structure_status` to check whether `storyline.md` exists and is structurally safe: +5. Do not run a separate shell/file existence check for the `.pptx`; `copaper_ppt_extract` performs this validation in Step 2. +6. Call `copaper_storyline_structure_status` to check whether `storyline.md` exists and is structurally safe: - if the tool succeeds, continue normal mapping and in-place update flow - if the tool reports missing `storyline.md`, continue conversion in draft mode and initialize project at Step 7 before final write - if the tool reports an unsafe path or unreadable file, stop and report the tool error ### Step 2: Extract slide text -1. Call `vibepaper_ppt_extract` with the explicit user-provided `.pptx` path. +1. Call `copaper_ppt_extract` with the explicit user-provided `.pptx` path. 2. If the tool returns an error, stop and report the error; do not retry by scanning directories or using shell/Python extraction. 3. Use the returned slides in order. 4. Build an intermediate note like: @@ -116,7 +116,7 @@ If one slide supports multiple sections, split its points conservatively. ### Step 3: Build section evidence map -1. Use the `vibepaper_storyline_structure_status` result from Step 1, or call it again if `storyline.md` was initialized or changed. +1. Use the `copaper_storyline_structure_status` result from Step 1, or call it again if `storyline.md` was initialized or changed. 2. Use the returned `sections`, `nextSection`, and `summary`; do not manually scan `storyline.md` to decide section readiness. 3. For each section, attach supporting slide snippets. 4. Mark section status: @@ -166,12 +166,12 @@ If `storyline.md` is missing: - project `domain` 2. Restate the project directory, project `name`, and project `domain`. 3. Wait for explicit user confirmation. -4. Call `vibepaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed VibePaper core files and refuses conflicts. +4. Call `copaper_init_apply` with `name` and `domain`; the tool initializes OpenCode-managed CoPaper core files and refuses conflicts. 5. Then apply the accepted converted content into the initialized `storyline.md`. -Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `vibepaper_init_apply` is available. +Do not manually create `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, or `.agents/events.jsonl` when `copaper_init_apply` is available. -If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `vibepaper_init_apply` can repair missing skills. Continue only if `storyline.md` exists and the current skill instructions are available in the active agent context. +If only `.agents/skills/` is missing or incomplete, report that the current OpenCode plugin initialization writes core project files only and does not install the skill library. Do not claim `copaper_init_apply` can repair missing skills. Continue only if `storyline.md` exists and the current skill instructions are available in the active agent context. ### Step 8: Update workflow status @@ -179,9 +179,9 @@ After accepted edits: - If at least one storyline section is filled, set storyline phase to `in_progress`. - If all storyline sections are materially filled, set storyline phase to `complete`. -Use `vibepaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. +Use `copaper_workflow_set_phase` for this update. Before calling it, restate the target phase and status and wait for explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -Do not run `vibe set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. +Do not run `copaper set-phase` and do not manually edit `.agents/state.json` when the OpenCode plugin tool is available. ## Output Requirements diff --git a/vibepaper/scaffold/skills/problem-checker/SKILL.md b/copaper/scaffold/skills/problem-checker/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/problem-checker/SKILL.md rename to copaper/scaffold/skills/problem-checker/SKILL.md index 016ac8e..577d5fd 100644 --- a/vibepaper/scaffold/skills/problem-checker/SKILL.md +++ b/copaper/scaffold/skills/problem-checker/SKILL.md @@ -361,7 +361,7 @@ Generate a comprehensive problem definition assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/problem-checker/examples.md b/copaper/scaffold/skills/problem-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/problem-checker/examples.md rename to copaper/scaffold/skills/problem-checker/examples.md diff --git a/vibepaper/scaffold/skills/relatedwork-finder/SKILL.md b/copaper/scaffold/skills/relatedwork-finder/SKILL.md similarity index 70% rename from vibepaper/scaffold/skills/relatedwork-finder/SKILL.md rename to copaper/scaffold/skills/relatedwork-finder/SKILL.md index 6734f99..49131a7 100644 --- a/vibepaper/scaffold/skills/relatedwork-finder/SKILL.md +++ b/copaper/scaffold/skills/relatedwork-finder/SKILL.md @@ -5,7 +5,7 @@ description: Find the related work papers in the relatedwork folder based on sto # Related Work Finder Skill -This skill automatically finds related-work papers. Every substantive step (keyword extraction, Semantic Scholar search, BibTeX sync, PDF download) is delegated to a `vibe` CLI subcommand, so the skill never calls MCP search tools or spawns subagents. The skill's job is to orchestrate the CLI calls and interact with the user. +This skill automatically finds related-work papers. Every substantive step (keyword extraction, Semantic Scholar search, BibTeX sync, PDF download) is delegated to a `copaper` CLI subcommand, so the skill never calls MCP search tools or spawns subagents. The skill's job is to orchestrate the CLI calls and interact with the user. ## When to Use This Skill @@ -15,20 +15,20 @@ This skill automatically finds related-work papers. Every substantive step (keyw | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | Required if present | Step 1 (input to CLI) | Primary source for keyword extraction by `vibe relatedwork keywords` | +| `storyline.md` | Required if present | Step 1 (input to CLI) | Primary source for keyword extraction by `copaper relatedwork keywords` | | `paper.md` | Fallback | Step 1 (auto-fallback) | Used by the CLI when `storyline.md` is missing | -| `relatedwork/queries.txt` | Read/write | Steps 1-2 | One query per line; written by `vibe relatedwork keywords`, consumed by `vibe relatedwork search --queries-file` | -| `relatedwork/search_cache.json` | Read/write | Steps 2-3 | Cache for search metadata (paper_id, title, authors, year, venue, bibtex, arxiv_id, pdf_url, source_queries) — written by `vibe relatedwork search` | +| `relatedwork/queries.txt` | Read/write | Steps 1-2 | One query per line; written by `copaper relatedwork keywords`, consumed by `copaper relatedwork search --queries-file` | +| `relatedwork/search_cache.json` | Read/write | Steps 2-3 | Cache for search metadata (paper_id, title, authors, year, venue, bibtex, arxiv_id, pdf_url, source_queries) — written by `copaper relatedwork search` | | `relatedwork/paper_list.bib` | Required | Step 3 | BibTeX entries for formalizing the reference list | -| Relatedwork status | Optional | Steps 3-4 | Call `vibepaper_relatedwork_status` for read-only catalog, BibTeX, PDF, summary, and cross-index counts | -| `relatedwork/literature.json` | Required after managed import | Steps 2-6 (after import) | Canonical metadata catalog; inspect progress through `vibepaper_relatedwork_status` when the plugin tool is available | +| Relatedwork status | Optional | Steps 3-4 | Call `copaper_relatedwork_status` for read-only catalog, BibTeX, PDF, summary, and cross-index counts | +| `relatedwork/literature.json` | Required after managed import | Steps 2-6 (after import) | Canonical metadata catalog; inspect progress through `copaper_relatedwork_status` when the plugin tool is available | | `.agents/skills/relatedwork-finder/template.md` | Required | Step 5 | Template for PDF summary generation; passed to subagent | Do NOT read `writingrules.md` — this skill does not need paper structure rules. ## Search & Caching Strategy -1. **Single Backend (Semantic Scholar)**: All searches go through the `vibe relatedwork search` CLI, which queries the Semantic Scholar Graph API. S2's index covers arXiv preprints, major CS/AI venues (CVPR, NeurIPS, ICML, ACL, etc.), and most journals. Do NOT call `serper_google_search_scholar`, `websearch_web_search_exa`, or any other external search tool from this skill — the CLI is the single source of truth. +1. **Single Backend (Semantic Scholar)**: All searches go through the `copaper relatedwork search` CLI, which queries the Semantic Scholar Graph API. S2's index covers arXiv preprints, major CS/AI venues (CVPR, NeurIPS, ICML, ACL, etc.), and most journals. Do NOT call `serper_google_search_scholar`, `websearch_web_search_exa`, or any other external search tool from this skill — the CLI is the single source of truth. 2. **Stateful Cache**: The CLI writes `relatedwork/search_cache.json` (envelope: `{"papers": [...]}`) with one entry per deduplicated paper, including: - `paper_id` (extracted from S2's BibTeX key, or generated as `<author><year><titletoken>`) - `title`, `authors`, `year`, `venue` @@ -38,7 +38,7 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules - `source_queries` (which CLI `--query` arguments returned this paper) - `tldr` (S2 model-generated one-sentence summary, when present — useful for filtering) 3. **API Key (optional but recommended)**: Set `SEMANTIC_SCHOLAR_API_KEY` in the environment before running this skill to lift the shared anonymous rate limit (~100 req / 5 min) up to 1 req/sec. The CLI auto-detects the env var; without it the CLI still works but may hit 429s on busy days (it retries with exponential backoff up to 4 attempts). -4. **Canonical Catalog**: After `relatedwork/search_cache.json` is reviewed and trimmed by the user, you MUST import it into `relatedwork/literature.json` via `vibe --root . relatedwork import --input relatedwork/search_cache.json`. `relatedwork/literature.json` is the canonical metadata store used by BibTeX sync, downloads, and summary tracking. +4. **Canonical Catalog**: After `relatedwork/search_cache.json` is reviewed and trimmed by the user, you MUST import it into `relatedwork/literature.json` via `copaper --root . relatedwork import --input relatedwork/search_cache.json`. `relatedwork/literature.json` is the canonical metadata store used by BibTeX sync, downloads, and summary tracking. ## PDF Download @@ -49,14 +49,14 @@ Do NOT read `writingrules.md` — this skill does not need paper structure rules ## Action Logging Use OpenCode plugin tools for workflow/artifact events when available. The current plugin does not expose a generic tool-call event logger or relatedwork event writer; do not append logs manually in plugin-based workflows. -If the user asks to inspect workflow event history, call `vibepaper_workflow_log` for read-only querying of `.agents/events.jsonl` instead of reading the file directly. +If the user asks to inspect workflow event history, call `copaper_workflow_log` for read-only querying of `.agents/events.jsonl` instead of reading the file directly. ## Instructions (STRICT INTERACTIVE WORKFLOW) You MUST follow this step-by-step interactive workflow. **STOP and wait for user confirmation after each step marked with [WAIT FOR CONFIRMATION].** ### Step 1: Extract Keywords [WAIT FOR CONFIRMATION] -- Run `vibe --root . relatedwork keywords --count 8` (adjust `--count` if the storyline is unusually broad/narrow). The CLI reads `storyline.md` (falling back to `paper.md`), calls the configured LLM via `VIBEPAPER_MODEL`, and writes the queries one-per-line to `relatedwork/queries.txt`. +- Run `copaper --root . relatedwork keywords --count 8` (adjust `--count` if the storyline is unusually broad/narrow). The CLI reads `storyline.md` (falling back to `paper.md`), calls the configured LLM via `COPAPER_MODEL`, and writes the queries one-per-line to `relatedwork/queries.txt`. - Do NOT extract keywords yourself in this context. Do NOT call any MCP search tool. The CLI is the single source of truth. - After the CLI finishes, `cat relatedwork/queries.txt` and present the list to the user. - **STOP**: Ask "These are the queries the CLI extracted. Do you want to edit `relatedwork/queries.txt` (add/remove/replace lines) before I run the search?" @@ -66,7 +66,7 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Run the search CLI consuming the queries file from Step 1: ```bash - vibe --root . relatedwork search \ + copaper --root . relatedwork search \ --queries-file relatedwork/queries.txt \ --limit 20 \ --year 2022-2026 @@ -83,15 +83,15 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user ### Step 3: Formalize BibTeX List [WAIT FOR CONFIRMATION] - If the user dropped any entries, rewrite `relatedwork/search_cache.json` keeping only the selected papers (preserve the `{"papers": [...]}` envelope). -- Run `vibe --root . relatedwork import --input relatedwork/search_cache.json` to merge the kept entries into `relatedwork/literature.json`. -- If `paper_list.bib` already contains papers missing from `relatedwork/literature.json`, you MAY rerun `vibe --root . relatedwork search --query "<title>"` to enrich them, then re-import. -- Run `vibe --root . relatedwork sync-bib` to write metadata-backed entries into `relatedwork/paper_list.bib` and to import any remaining bib-only entries into `relatedwork/literature.json`. -- Call `vibepaper_relatedwork_status` to inspect catalog and BibTeX counts. This tool is read-only; do not replace it with prompt-only status text or a manual `.agents/state.json` update. +- Run `copaper --root . relatedwork import --input relatedwork/search_cache.json` to merge the kept entries into `relatedwork/literature.json`. +- If `paper_list.bib` already contains papers missing from `relatedwork/literature.json`, you MAY rerun `copaper --root . relatedwork search --query "<title>"` to enrich them, then re-import. +- Run `copaper --root . relatedwork sync-bib` to write metadata-backed entries into `relatedwork/paper_list.bib` and to import any remaining bib-only entries into `relatedwork/literature.json`. +- Call `copaper_relatedwork_status` to inspect catalog and BibTeX counts. This tool is read-only; do not replace it with prompt-only status text or a manual `.agents/state.json` update. - **ACTION**: Show the final BibTeX entries and the relatedwork status summary to the user. - **STOP**: Ask "I have formalized the BibTeX entries in paper_list.bib. Should I proceed to download PDFs and write summaries?" ### Step 4: Download PDFs [WAIT FOR CONFIRMATION] - PDF download status must be recorded by a managed relatedwork operation. The current OpenCode plugin has no `relatedwork download` or retry tool; do not hand-write download results into JSON. Ask before using any CLI fallback. -- After the download command finishes, call `vibepaper_relatedwork_status` to inspect PDF download status, failures, and summary readiness. This tool is read-only and must not be used to fake download success. +- After the download command finishes, call `copaper_relatedwork_status` to inspect PDF download status, failures, and summary readiness. This tool is read-only and must not be used to fake download success. - **ACTION**: Present the status of downloaded PDFs to the user from the tool output. - **STOP AND TERMINATE**: This skill's responsibility strictly ENDS HERE. You MUST STOP execution. Ask the user: "I have finished finding the related work and downloading the PDFs. Would you like to continue and switch to the `relatedwork-summarizer` skill to generate summaries now?" diff --git a/vibepaper/scaffold/skills/relatedwork-finder/template.md b/copaper/scaffold/skills/relatedwork-finder/template.md similarity index 100% rename from vibepaper/scaffold/skills/relatedwork-finder/template.md rename to copaper/scaffold/skills/relatedwork-finder/template.md diff --git a/vibepaper/scaffold/skills/relatedwork-summarizer/SKILL.md b/copaper/scaffold/skills/relatedwork-summarizer/SKILL.md similarity index 78% rename from vibepaper/scaffold/skills/relatedwork-summarizer/SKILL.md rename to copaper/scaffold/skills/relatedwork-summarizer/SKILL.md index 5479acd..85ee001 100644 --- a/vibepaper/scaffold/skills/relatedwork-summarizer/SKILL.md +++ b/copaper/scaffold/skills/relatedwork-summarizer/SKILL.md @@ -5,7 +5,7 @@ description: Drive the relatedwork summarization CLI, build the literature cross # Related Work Summarizer Skill -This skill orchestrates per-paper summarization for downloaded PDFs by calling the `vibe relatedwork summarize` CLI, builds the literature cross-index via `vibe relatedwork build-index`, and produces a coverage report comparing summaries to `storyline.md`. The skill itself does not read PDFs, spawn subagents, or call MCP tools — all heavy lifting lives in the CLI. +This skill orchestrates per-paper summarization for downloaded PDFs by calling the `copaper relatedwork summarize` CLI, builds the literature cross-index via `copaper relatedwork build-index`, and produces a coverage report comparing summaries to `storyline.md`. The skill itself does not read PDFs, spawn subagents, or call MCP tools — all heavy lifting lives in the CLI. ## When to Use This Skill @@ -16,20 +16,20 @@ This skill orchestrates per-paper summarization for downloaded PDFs by calling t | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| Relatedwork status | Required | Steps 1, 2, 4 | Call `vibepaper_relatedwork_status` for read-only catalog, download, summary, BibTeX, and cross-index state | -| `relatedwork/literature.json` | Required | Steps 1, 4 | Canonical catalog used by the CLI; inspect queue state through `vibepaper_relatedwork_status` when available | +| Relatedwork status | Required | Steps 1, 2, 4 | Call `copaper_relatedwork_status` for read-only catalog, download, summary, BibTeX, and cross-index state | +| `relatedwork/literature.json` | Required | Steps 1, 4 | Canonical catalog used by the CLI; inspect queue state through `copaper_relatedwork_status` when available | | `storyline.md` | Required | Steps 2, 3 | Passed to the CLI as context for the "relation to our work" section, and used by the coverage report | | `.agents/skills/relatedwork-finder/template.md` | Required | Step 2 | Summary template; passed to the CLI | | `relatedwork/papers/<paper_id>.md` | Read/write | Steps 2-3 | Per-paper summary files written by the CLI | | `relatedwork/summary.md` | Read/write | Step 3 | Aggregated multi-paper summary (skill maintains this file) | -| `.agents/cross_index.json` | Read/write | Step 4 | Built by `vibe relatedwork build-index` | +| `.agents/cross_index.json` | Read/write | Step 4 | Built by `copaper relatedwork build-index` | ## Required Environment The summarization CLI uses an OpenAI-compatible LLM. Before running this skill, confirm the following are set (typically in `.env`): - `OPENAI_API_KEY` — required -- `VIBEPAPER_MODEL` — required (e.g. `gpt-4o-mini`) +- `COPAPER_MODEL` — required (e.g. `gpt-4o-mini`) - `OPENAI_BASE_URL` — optional, only if using a proxy endpoint If any of these are missing the CLI will fail loudly; do NOT try to summarize by reading the PDFs yourself. @@ -46,7 +46,7 @@ After invoking any tool, append a structured JSON log to `.agents/events.jsonl`. You MUST follow this step-by-step interactive workflow. **STOP and wait for user confirmation after each step marked with [WAIT FOR CONFIRMATION].** ### Step 1: Target Scope Parsing [WAIT FOR CONFIRMATION] -- Call `vibepaper_relatedwork_status` first. This tool is read-only and reports which papers are downloaded and which already have summaries; do not replace it with prompt-only status text or manual state inspection. +- Call `copaper_relatedwork_status` first. This tool is read-only and reports which papers are downloaded and which already have summaries; do not replace it with prompt-only status text or manual state inspection. - Check if the user requested a specific paper (by title or `paper_id`): - If yes: verify the paper exists in the tool output and its `downloadStatus` is `downloaded` with `pdfExists=true`. If not, REFUSE the request and explain why. The target queue contains ONLY this paper. - If no: the target queue contains every paper with `downloadStatus=downloaded`, `pdfExists=true`, and `summaryExists=false`. @@ -57,16 +57,16 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Run the summarize CLI. For the full queue: ```bash - vibe --root . relatedwork summarize + copaper --root . relatedwork summarize ``` For a single paper (when the user specified one in Step 1): ```bash - vibe --root . relatedwork summarize --paper-id <paper_id> + copaper --root . relatedwork summarize --paper-id <paper_id> ``` - Add `--force` if the user wants to re-summarize already-summarized papers. Other useful flags: `--qps 16` (default), `--concurrency 8` (default; worker threads), `--model <name>` (override `VIBEPAPER_MODEL`). + Add `--force` if the user wants to re-summarize already-summarized papers. Other useful flags: `--qps 16` (default), `--concurrency 8` (default; worker threads), `--model <name>` (override `COPAPER_MODEL`). - The CLI: 1. Extracts PDF text with `pypdf` 2. Sends `storyline.md` + the template + the PDF text to the configured LLM @@ -75,12 +75,12 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user - Do NOT spawn subagents. Do NOT use any `multimodal-looker` agent type. Do NOT read PDFs yourself. The CLI handles parallelism, rate limiting, and oversized-PDF failures internally. - After the CLI finishes, parse its stdout. For each `[ok]` line: open the new `relatedwork/papers/<paper_id>.md` and synthesize its key points (technical mechanism, methodology, empirical results, limitations) into `relatedwork/summary.md` under a `## <paper_id>: <Title>` heading. If a section for that `paper_id` already exists in `summary.md`, REPLACE it; otherwise APPEND it. - For each `[fail]` line, leave the paper alone. Surface the error to the user. -- Call `vibepaper_relatedwork_status` again to verify summary counts after the CLI updates `literature.json`. +- Call `copaper_relatedwork_status` again to verify summary counts after the CLI updates `literature.json`. - **ACTION**: Tell the user "Summarized X papers via the CLI (Y succeeded, Z failed). I have updated `relatedwork/summary.md` with the new sections." List any failures. - **STOP**: Ask "Should I proceed to build the cross-index and generate the coverage report?" ### Step 3: Build Cross-Index & Coverage Report [WAIT FOR CONFIRMATION] -- Run `vibe --root . relatedwork build-index`. The CLI scans `relatedwork/papers/*.md`, updates `.agents/cross_index.json`, and emits a coverage report (covered points, gaps, ratio) against `storyline.md`. +- Run `copaper --root . relatedwork build-index`. The CLI scans `relatedwork/papers/*.md`, updates `.agents/cross_index.json`, and emits a coverage report (covered points, gaps, ratio) against `storyline.md`. - Do NOT spawn task agents to "improve" the index in this skill — the CLI is authoritative. (If LLM-augmented technical-point extraction is added later it will be exposed as a `--use-llm` flag on the same CLI.) - **ACTION**: Present the coverage report verbatim: - Covered technical points (with paper references) @@ -91,6 +91,6 @@ You MUST follow this step-by-step interactive workflow. **STOP and wait for user ### Step 4: Finalize Summary Document - Read `relatedwork/summary.md` end-to-end and reorganize entries into thematic groups if the user requested it (e.g., by method family, by problem setting). Otherwise leave the order unchanged. - Keep `relatedwork/literature.json` as the canonical metadata artifact. Do NOT delete it. -- Call `vibepaper_relatedwork_status` before the final response if you need to report final literature, summary, BibTeX, or cross-index counts. +- Call `copaper_relatedwork_status` before the final response if you need to report final literature, summary, BibTeX, or cross-index counts. - If `relatedwork/search_cache.json` is no longer needed, ask the user before removing it. - Respond with "I have finalized `relatedwork/summary.md`." diff --git a/vibepaper/scaffold/skills/relatedwork-summarizer/template.md b/copaper/scaffold/skills/relatedwork-summarizer/template.md similarity index 100% rename from vibepaper/scaffold/skills/relatedwork-summarizer/template.md rename to copaper/scaffold/skills/relatedwork-summarizer/template.md diff --git a/vibepaper/scaffold/skills/review-revise/SKILL.md b/copaper/scaffold/skills/review-revise/SKILL.md similarity index 82% rename from vibepaper/scaffold/skills/review-revise/SKILL.md rename to copaper/scaffold/skills/review-revise/SKILL.md index de96a3b..168d3e8 100644 --- a/vibepaper/scaffold/skills/review-revise/SKILL.md +++ b/copaper/scaffold/skills/review-revise/SKILL.md @@ -3,8 +3,8 @@ name: review-revise description: Conducts multi-round Review-Revise cycles based on 7-checker output to systematically improve paper quality. Each issue requires user confirmation before modification. Use this skill when the user wants to review and revise their paper. --- # Review-Revise Skill -This skill runs a controlled Review-Revise loop over checker findings. In plugin-based workflows, read-only checker status is available through `vibepaper_checker_status`, and confirmed checker run summaries can be recorded through `vibepaper_checker_record`; full issue-resolution writes are still a tool gap. -Use `@vibepaper-reviewer` when available to explain checker findings, severity, and likely reviewer concerns before any writing revision is proposed. The reviewer is read-only and must not edit `paper.md`. +This skill runs a controlled Review-Revise loop over checker findings. In plugin-based workflows, read-only checker status is available through `copaper_checker_status`, and confirmed checker run summaries can be recorded through `copaper_checker_record`; full issue-resolution writes are still a tool gap. +Use `@copaper-reviewer` when available to explain checker findings, severity, and likely reviewer concerns before any writing revision is proposed. The reviewer is read-only and must not edit `paper.md`. It is the repair layer after diagnosis: the seven checkers identify issues, then this skill helps the user process them in a severity-first order, propose fixes one issue at a time, and apply changes only after explicit confirmation. Its purpose is not to auto-rewrite the paper. Its purpose is to convert checker output into careful, auditable, multi-round improvement while keeping the user in control of every modification. @@ -41,7 +41,7 @@ Never process Minor issues ahead of unresolved Critical or Major issues unless t | File | Required | When to Read | Purpose | |------|----------|-------------|---------| | `paper.md` | **Required** | Step 1 (start) | Primary analysis target; read to understand current paper content | -| Checker status | Optional | Step 1 (start) | Call `vibepaper_checker_status` to inspect existing checker runs, severity counts, stale signals, and precheck evidence | +| Checker status | Optional | Step 1 (start) | Call `copaper_checker_status` to inspect existing checker runs, severity counts, stale signals, and precheck evidence | | `storyline.md` | Optional | Step 5b (when revising narrative/claim alignment) | Research narrative for grounding revisions | | `.agents/cross_index.json` | Optional but preferred | Step 5b (before reading relatedwork summaries) | Cross-reference index; consult FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current issue | | `relatedwork/papers/*.md` | Optional | Step 5b (only the summaries identified through cross-index) | Individual literature summaries; read ONLY the specific files identified through `.agents/cross_index.json` or when the issue clearly depends on prior work | @@ -51,10 +51,10 @@ If some files do not exist yet, continue with the available context instead of b ## Workflow ### Step 1: Read Paper and Checker State 1. Read `paper.md`. -2. Call `vibepaper_checker_status` to determine whether previous checker results exist and whether they are stale. +2. Call `copaper_checker_status` to determine whether previous checker results exist and whether they are stale. 3. Use the current `markdown-review` output as the authoritative source for issue details. The status tool gives summary and freshness, not full issue text. 4. Extract checker name, issue ID, severity, description, suggestion, status, and any checker-generated HTML comment text from the fresh review output when available. -5. If `@vibepaper-reviewer` is available, ask it to summarize and explain the issue set without editing files. +5. If `@copaper-reviewer` is available, ask it to summarize and explain the issue set without editing files. 6. Build a working list of unresolved issues. Goal: understand what the paper says now and what the seven checkers still consider problematic. If checker results are not available, do not fabricate them and do not create state entries manually. @@ -64,8 +64,8 @@ If checker results do not exist yet, or the `checkers` field is missing or empty 1. Invoke the `markdown-review` skill first. 2. Run all seven checkers in the standard order. 3. Use the returned checker report as the working issue queue. -4. Call `vibepaper_checker_status` after the review to inspect status/freshness if checker summaries or precheck evidence were produced. -5. If the user wants durable checker summaries, restate the actual checker output summary and route the confirmed record action to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. +4. Call `copaper_checker_status` after the review to inspect status/freshness if checker summaries or precheck evidence were produced. +5. If the user wants durable checker summaries, restate the actual checker output summary and route the confirmed record action to `@copaper-recorder` so it can call `copaper_checker_record`. Do not invent checker findings. This skill must be driven by actual checker output from state or from the immediately returned review report. @@ -145,7 +145,7 @@ If and only if the user confirms: 1. Apply the approved modification to `paper.md`. 2. Keep the change tightly scoped to the current issue. 3. Avoid unrelated edits. -4. Preserve the existing VibePaper structure and heading hierarchy. +4. Preserve the existing CoPaper structure and heading hierarchy. If the user asks for a modified suggestion first, revise the suggestion and ask again. Do not silently merge user intent into the paper without another confirmation point. @@ -181,7 +181,7 @@ Recommended tracked fields, if a future dedicated review-revise history tool exi - current round number - stopped_by (`user_satisfied`, `max_rounds`, `no_critical_or_major`, `user_stopped`) - optional review-revise history summary -Do not update `.agents/state.json` directly in plugin-based workflows. The current OpenCode plugin exposes `vibepaper_workflow_set_phase` for phase status, `vibepaper_artifact_record` for artifact readiness, and `vibepaper_checker_record` for confirmed checker run summaries. It does not expose checker issue-resolution or review-revise history persistence. +Do not update `.agents/state.json` directly in plugin-based workflows. The current OpenCode plugin exposes `copaper_workflow_set_phase` for phase status, `copaper_artifact_record` for artifact readiness, and `copaper_checker_record` for confirmed checker run summaries. It does not expose checker issue-resolution or review-revise history persistence. ## Safety Valves This skill must enforce all of the following: @@ -210,16 +210,16 @@ Required interaction pattern: ## Checker Integration Notes This skill depends on actual checker output, either from a fresh `markdown-review` run or from already persisted checker data. Current OpenCode plugin tool coverage: -- Supported: `vibepaper_workflow_status`, `vibepaper_workflow_log`, `vibepaper_workflow_set_phase`, `vibepaper_artifact_status`, `vibepaper_artifact_record` -- Supported for read-only checker summaries: `vibepaper_checker_status` -- Supported for confirmed checker run summaries: `vibepaper_checker_record` +- Supported: `copaper_workflow_status`, `copaper_workflow_log`, `copaper_workflow_set_phase`, `copaper_artifact_status`, `copaper_artifact_record` +- Supported for read-only checker summaries: `copaper_checker_status` +- Supported for confirmed checker run summaries: `copaper_checker_record` - Not supported: full `get_unresolved_issues()` with issue text, `mark_issue_resolved()`, review-revise history persistence When an unsupported operation is needed, state the tool gap instead of editing `.agents/state.json` manually. -Use `vibepaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. -If the user asks to record a checker result, route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_checker_record`; do not directly edit checker state or use prompt-only persistence text. -Use `vibepaper_artifact_status` for read-only artifact readiness, evidence, confidence, and recommendation; do not infer readiness manually when the plugin tool is available. -Use `vibepaper_workflow_log` for read-only workflow event history queries; do not read `.agents/events.jsonl` directly when the plugin tool is available. -If the user asks to record artifact readiness, route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_artifact_record`; do not directly edit artifact state or use prompt-only readiness text. +Use `copaper_checker_status` for read-only checker run status, severity counts, stale signals, and precheck evidence; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. +If the user asks to record a checker result, route the confirmed action to `@copaper-recorder` so it can call `copaper_checker_record`; do not directly edit checker state or use prompt-only persistence text. +Use `copaper_artifact_status` for read-only artifact readiness, evidence, confidence, and recommendation; do not infer readiness manually when the plugin tool is available. +Use `copaper_workflow_log` for read-only workflow event history queries; do not read `.agents/events.jsonl` directly when the plugin tool is available. +If the user asks to record artifact readiness, route the confirmed action to `@copaper-recorder` so it can call `copaper_artifact_record`; do not directly edit artifact state or use prompt-only readiness text. ## Must NOT Do - **NEVER** auto-apply modifications diff --git a/vibepaper/scaffold/skills/socratic-discussion/SKILL.md b/copaper/scaffold/skills/socratic-discussion/SKILL.md similarity index 90% rename from vibepaper/scaffold/skills/socratic-discussion/SKILL.md rename to copaper/scaffold/skills/socratic-discussion/SKILL.md index 75445b7..99afd5e 100644 --- a/vibepaper/scaffold/skills/socratic-discussion/SKILL.md +++ b/copaper/scaffold/skills/socratic-discussion/SKILL.md @@ -3,7 +3,7 @@ name: socratic-discussion description: Conducts Socratic research discussions to help users critically examine their insights, methods, and claims. Integrates with 7 checker dimensions for targeted questioning. Use this skill when the user wants to discuss or analyze their research. --- # Socratic Discussion Skill -This is the core value skill in VibePaper. It helps researchers think more deeply about their own work through structured Socratic questioning instead of letting the system provide answers directly. It operates over the 57 discussion dimensions defined in `vibepaper/dimensions.py`, aligned with the 7 checker families used across the project. +This is the core value skill in CoPaper. It helps researchers think more deeply about their own work through structured Socratic questioning instead of letting the system provide answers directly. It operates over the 57 discussion dimensions defined in `copaper/dimensions.py`, aligned with the 7 checker families used across the project. Its purpose is not to draft faster. Its purpose is to improve judgment: clearer problem definition, better novelty boundaries, stronger technical depth, tighter logic, clearer expression, sounder evaluation design, and more trustworthy evidence. ## When to Use This Skill @@ -46,7 +46,7 @@ Do not reorder the sequence unless the user explicitly asks to jump. ## Core Discussion Principles - Ask one main question at a time. - Discuss exactly one dimension at a time. -- Prefer the predefined question bank in `vibepaper/dimensions.py`. +- Prefer the predefined question bank in `copaper/dimensions.py`. - If checker issues exist, use them to sharpen the first question. - If the user's answer is weak, ask a narrower follow-up instead of changing dimensions. - Never fabricate evidence, references, experiments, or prior work. @@ -58,11 +58,11 @@ Do not reorder the sequence unless the user explicitly asks to jump. |------|----------|-------------|---------| | `storyline.md` | **Required** | Step 1 (start) | Research narrative, insight, method outline | | `paper.md` | **Required** | Step 1 (start) | Current paper state and claim wording | -| Checker status | Optional | Step 2 (if checker-driven discussion) | Use `vibepaper_checker_status` for read-only checker family status, severity counts, stale signals, and precheck evidence | +| Checker status | Optional | Step 2 (if checker-driven discussion) | Use `copaper_checker_status` for read-only checker family status, severity counts, stale signals, and precheck evidence | | `relatedwork/papers/*.md` | Optional | Step 1 (as needed) | Prior-work summaries for contrast questions | | `.agents/cross_index.json` | Optional | Step 1 (as needed) | Paper-technique mappings for targeted questioning | | `.agents/discussion_log.json` | Optional | Step 3 (to find covered dimensions) | Prior discussion history | -| `vibepaper/dimensions.py` | **Required** | Step 1 (start) | 57 dimensions and question bank | +| `copaper/dimensions.py` | **Required** | Step 1 (start) | 57 dimensions and question bank | If some files do not exist yet, continue with the available context instead of blocking the workflow. @@ -72,12 +72,12 @@ If some files do not exist yet, continue with the available context instead of b 2. Read `paper.md`. 3. Read relevant summaries from `relatedwork/papers/`. 4. Read `.agents/cross_index.json` if available. -5. Read `vibepaper/dimensions.py`. +5. Read `copaper/dimensions.py`. Goal: understand the user's problem, insight, method, and evidence situation before asking questions. ### Step 2: Integrate Checker Results -1. Call `vibepaper_workflow_status` if workflow phase status, current phase, phase table, or next-step recommendation is needed. -2. Call `vibepaper_checker_status` to detect which of the 7 checker families have run, whether results are stale, and the Critical/Major/Minor counts. +1. Call `copaper_workflow_status` if workflow phase status, current phase, phase table, or next-step recommendation is needed. +2. Call `copaper_checker_status` to detect which of the 7 checker families have run, whether results are stale, and the Critical/Major/Minor counts. 3. Use the tool output to prioritize checker families with stale or non-clean statuses. 4. If detailed issue text is needed and is not present in the current conversation, ask the user to run or provide `markdown-review`; do not read `.agents/state.json` directly just to infer checker status. 5. Map available unresolved issues to dimensions using `checker_name` and issue meaning. @@ -92,7 +92,7 @@ If checker results exist, explicitly tell the user that checker-flagged dimensio 5. Sort uncovered dimensions in this order: - checker-flagged dimensions first - then by checker family - - then by registry order in `vibepaper/dimensions.py` + - then by registry order in `copaper/dimensions.py` ### Step 4: Present a Dimension Menu Present the uncovered dimensions grouped by checker family. @@ -117,7 +117,7 @@ For the selected dimension: 2. Reset the per-dimension round counter. 3. Load the five question types in order. 4. Start with Clarification. -5. Use the predefined question text from `vibepaper/dimensions.py` when available. +5. Use the predefined question text from `copaper/dimensions.py` when available. 6. If this dimension has checker issues, incorporate the issue wording into the first question. ### Step 6: Delegate Deep Question Preparation @@ -193,7 +193,7 @@ Write the result to `.agents/discussion_log.json`. If the file does not exist, create it. Preserve old records and append new session entries. ### Step 13: Workflow State -Use `vibepaper_workflow_set_phase` only for phase-level updates such as marking `discussion` as `in_progress` or `complete`, and only after explicit user confirmation. +Use `copaper_workflow_set_phase` only for phase-level updates such as marking `discussion` as `in_progress` or `complete`, and only after explicit user confirmation. The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`; do not substitute a prompt-only note or manual file edit. The current OpenCode plugin does not expose a dedicated tool for discussion metadata or checker issue resolution status. Do not manually edit `.agents/state.json` for those fields in plugin-based workflows; report the limitation instead. @@ -288,7 +288,7 @@ Required summary fields: `key_points`, `strengths`, `weaknesses`, `open_question - **NEVER** erase prior history from `.agents/discussion_log.json` ## Important Notes -1. This skill is the core value of VibePaper because it improves thinking, not just writing speed. +1. This skill is the core value of CoPaper because it improves thinking, not just writing speed. 2. The checkers provide the issue map; this skill provides the interactive reasoning layer. 3. Checker integration is optional, but much more powerful when checker results exist. 4. Every completed dimension should leave behind a reusable summary and concrete suggestions. diff --git a/vibepaper/scaffold/skills/state-machine-markdown-helper/SKILL.md b/copaper/scaffold/skills/state-machine-markdown-helper/SKILL.md similarity index 80% rename from vibepaper/scaffold/skills/state-machine-markdown-helper/SKILL.md rename to copaper/scaffold/skills/state-machine-markdown-helper/SKILL.md index 5cb8152..6f6f60c 100644 --- a/vibepaper/scaffold/skills/state-machine-markdown-helper/SKILL.md +++ b/copaper/scaffold/skills/state-machine-markdown-helper/SKILL.md @@ -5,7 +5,7 @@ description: Helps users write and improve markdown academic paper content using # State Machine Markdown Helper Skill -This skill helps users write markdown content for computer science research papers following the VibePaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. +This skill helps users write markdown content for computer science research papers following the CoPaper GUI structure. It uses a strictly controlled, subagent-based sequential writing workflow to maximize writing quality and user control. ## When to Use This Skill @@ -15,7 +15,7 @@ This skill helps users write markdown content for computer science research pape ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this skill: +The paper follows CoPaper structure. Key rules for this skill: - **Level 1** (`#`): Paper title only. - **Level 2-5** (`##` to `#####`): Structural headings only — do NOT modify these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). @@ -27,11 +27,11 @@ Do NOT read `writingrules.md` — the essential structure rules are inlined abov | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `vibepaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | +| `paper.md` | **Required** | State 0 (outline), State 1 (structure status), State 2 (subagent prompt) | Primary writing target; call `copaper_paper_structure_status` to identify empty Level 5 sections, then read targeted context as needed | | `storyline.md` | **Required** | State 0 (outline) and State 2 (subagent prompt) | Core research narrative, insights, and method for grounding | | `.agents/cross_index.json` | Optional but preferred | State 1 (before reading relatedwork summaries) | Cross-reference index; consult FIRST to identify which `relatedwork/papers/*.md` files are relevant to the current section | | `relatedwork/papers/*.md` | Optional | State 1 (only the summaries identified via cross-index) | Individual literature summaries; read ONLY the specific files identified through `.agents/cross_index.json` lookup | -| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `vibepaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | +| `.agents/state.json` | Conditional | State 1 (when writing experiment sections) | Use `copaper_workflow_status` for read-only phase status/current phase/next-step context; read state directly only for fields not exposed by plugin tools, such as `data_files` | | `fig/` | Conditional | State 2 (when writing sections that reference visuals) | Available figures; list paths so the subagent can reference them | When the orchestrator needs literature context in State 1, it MUST: @@ -53,17 +53,17 @@ You must explicitly announce your current state to the user in every message (e. 4. **STOP AND WAIT**. Once approved, continue to State 1. ### State 1: Context & Literature Gathering (READ) -1. Call `vibepaper_paper_structure_status` to locate the next incomplete Level 5 writing target. Use the tool's `nextTarget`, `level5Targets`, `summary`, and `violations` instead of manually scanning `paper.md`. +1. Call `copaper_paper_structure_status` to locate the next incomplete Level 5 writing target. Use the tool's `nextTarget`, `level5Targets`, `summary`, and `violations` instead of manually scanning `paper.md`. 2. **Retrieve RAG Data:** - Search `.agents/cross_index.json` first to identify papers relevant to this section's technical points. - Read snippets from `relatedwork/summary.md`. - If deeper details are needed, use `read_file` on the specific `.md` files in `relatedwork/papers/`. - - If writing experiments, call `vibepaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool. + - If writing experiments, call `copaper_workflow_status` to check workflow phase status, current phase, and next-step recommendation. Use its phase table to verify whether `experiments` is `complete`. If experiment data paths are still needed, read `.agents/state.json` only for `data_files` because the current plugin does not expose a dedicated data-file lookup tool. 3. **Output Fact Sheet:** Generate a strictly formatted "**Fact & Citation Sheet**" containing the core claims to be written and their exact citation tags (e.g., `[@author2024]`). 4. **Announce and Ask**: Show the target section and Fact Sheet to the user. Ask: *"Target section: **[Level 5 Title]**. Shall I launch the writing subagent using this Fact Sheet?"* 5. **STOP AND WAIT** for confirmation. Don't proceed. -`vibepaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. +`copaper_paper_structure_status` is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. Do not replace it with prompt-only heading scans, shell parsing, or manual completion inference when the plugin tool is available. ### State 2: Fresh Subagent Drafting (WRITE) 1. Once confirmed, launch an independent subagent (`runSubagent` or `task`). **CRITICAL: Ensure it operates in a fresh context.** Do not pass your entire chat history. @@ -94,10 +94,10 @@ You must explicitly announce your current state to the user in every message (e. ## Action Logging -Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `vibepaper_workflow_set_phase` and `vibepaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. +Use plugin tools for workflow events whenever possible. The current OpenCode plugin only appends events for supported tool actions such as `copaper_workflow_set_phase` and `copaper_artifact_record`; it does not expose a generic event-append tool for paragraph insertion logs. Do not append to `.agents/events.jsonl` manually when using the plugin-based workflow. Report this limitation if the user asks for paragraph-level event logging. -If the user asks to inspect workflow event history, call `vibepaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. +If the user asks to inspect workflow event history, call `copaper_workflow_log` for read-only querying instead of reading `.agents/events.jsonl` directly. ## Crucial Anti-Patterns - **NEVER** write multiple paragraphs at once without user interactive review. diff --git a/vibepaper/scaffold/skills/storyline-helper/SKILL.md b/copaper/scaffold/skills/storyline-helper/SKILL.md similarity index 87% rename from vibepaper/scaffold/skills/storyline-helper/SKILL.md rename to copaper/scaffold/skills/storyline-helper/SKILL.md index 2d61772..0f3aed5 100644 --- a/vibepaper/scaffold/skills/storyline-helper/SKILL.md +++ b/copaper/scaffold/skills/storyline-helper/SKILL.md @@ -18,9 +18,9 @@ This skill guides users through constructing their research storyline in `storyl | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `storyline.md` | **Required** | Step 1 (structure status) | Primary target file; inspect through `vibepaper_storyline_structure_status` for empty/partial/filled sections | +| `storyline.md` | **Required** | Step 1 (structure status) | Primary target file; inspect through `copaper_storyline_structure_status` for empty/partial/filled sections | | `paper.md` | Conditional | Reverse-extraction mode only | Source for reverse-extracting storyline content when `storyline.md` is sparse | -| `.agents/state.json` | Tool-managed | Step 5 (after applying edits) | Update storyline phase through `vibepaper_workflow_set_phase`; do not edit the file directly | +| `.agents/state.json` | Tool-managed | Step 5 (after applying edits) | Update storyline phase through `copaper_workflow_set_phase`; do not edit the file directly | Do NOT read `writingrules.md` — this skill works with the existing `storyline.md` structure directly. @@ -53,7 +53,7 @@ Do NOT read `writingrules.md` — this skill works with the existing `storyline. ## Section Detection Logic -Use `vibepaper_storyline_structure_status` for section readiness whenever the plugin tool is available. The tool is read-only and validates that `storyline.md` is present, safe, and structurally readable. It does not write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. +Use `copaper_storyline_structure_status` for section readiness whenever the plugin tool is available. The tool is read-only and validates that `storyline.md` is present, safe, and structurally readable. It does not write `storyline.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. The tool classifies sections using this logic: @@ -64,16 +64,16 @@ A section is considered **empty** if, after its `#####` header line, the content A section is considered **filled** if it contains substantive content beyond TODO placeholders and instructional text. -Do not replace `vibepaper_storyline_structure_status` with prompt-only section scans, shell existence checks, shell parsing, or manual completion inference when the plugin tool is available. +Do not replace `copaper_storyline_structure_status` with prompt-only section scans, shell existence checks, shell parsing, or manual completion inference when the plugin tool is available. ## State Management This skill updates workflow progress through the OpenCode plugin tool: -- When the first section is filled: call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"`. -- When all sections are filled: call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "complete"`. +- When the first section is filled: call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"`. +- When all sections are filled: call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "complete"`. - Before calling the tool, restate the phase/status update and wait for explicit user confirmation. - The tool call writes `.agents/state.json` and appends the workflow event to `.agents/events.jsonl`. -- Do not call `vibe set-phase`, use `StateManager.set_phase_status`, or manually edit `.agents/state.json` when the plugin tool is available. +- Do not call `copaper set-phase`, use `StateManager.set_phase_status`, or manually edit `.agents/state.json` when the plugin tool is available. ## Reverse Extraction Mode (`paper.md` → `storyline.md`) @@ -102,7 +102,7 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N ### Step 1: Scan & Present (WAIT FOR USER) -1. Call `vibepaper_storyline_structure_status`. +1. Call `copaper_storyline_structure_status`. 2. If the tool reports missing, unsafe, or unreadable `storyline.md`, stop and report the tool error instead of manually scanning files. 3. Use the returned `sections`, `nextSection`, and `summary` to identify empty, partial, and filled storyline sections. 4. Compile a list of empty or partial sections with their section numbers and titles. @@ -148,9 +148,9 @@ The Orchestrator MUST follow this interactive, sequential workflow strictly. **N ### Step 5: Apply or Iterate - If **Accept**: The Orchestrator uses the `Edit` tool to replace the section content in `storyline.md` under the correct `#####` header. Then: - 1. Call `vibepaper_storyline_structure_status` again to check whether all sections are now filled. + 1. Call `copaper_storyline_structure_status` again to check whether all sections are now filled. 2. Restate the intended workflow update and wait for user confirmation. - 3. Call `vibepaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"` if any section is filled, or `status: "complete"` if all sections are filled. + 3. Call `copaper_workflow_set_phase` with `phase: "storyline"` and `status: "in_progress"` if any section is filled, or `status: "complete"` if all sections are filled. 4. Treat the tool output as the audit record because it writes state and appends the workflow event. 5. Ask the user: *"Section **[Section Title]** has been filled. Would you like to continue with the next empty section?"* If yes, loop back to Step 2 with the next empty section. - If **Modify/Rewrite**: Launch the subagent again (use `session_id` to continue its context), passing the user's feedback. Repeat Step 4. diff --git a/vibepaper/scaffold/skills/submission-precheck/SKILL.md b/copaper/scaffold/skills/submission-precheck/SKILL.md similarity index 95% rename from vibepaper/scaffold/skills/submission-precheck/SKILL.md rename to copaper/scaffold/skills/submission-precheck/SKILL.md index 7125f79..0a266c6 100644 --- a/vibepaper/scaffold/skills/submission-precheck/SKILL.md +++ b/copaper/scaffold/skills/submission-precheck/SKILL.md @@ -23,7 +23,7 @@ This skill performs a comprehensive pre-submission check on `paper.md` before su | `writingrules.md` | **Required** | Step 1 (start) | Format constraints and structural rules; needed for Check 1 (Format) and Check 5 (Completeness) | | `relatedwork/paper_list.bib` | Conditional | Step 2 (Citation Check) | BibTeX references; needed for Check 2 (Citations) | | `fig/` | Conditional | Step 2 (Figure/Table Check) | Figure assets directory; needed for Check 3 (Figures/Tables) | -| Checker status | Conditional | Step 4 and Step 6 | Use `vibepaper_checker_status` for read-only checker summary, stale signals, and precheck evidence | +| Checker status | Conditional | Step 4 and Step 6 | Use `copaper_checker_status` for read-only checker summary, stale signals, and precheck evidence | | `.agents/state.json` | Conditional | Step 1 (start) | Project state for fields not exposed by plugin tools, such as `latex_template` config for Check 4 | | `.agents/cross_index.json` | Conditional | Step 1 (start) | Cross-reference index; used for completeness verification | @@ -33,7 +33,7 @@ If some files do not exist (e.g., `paper_list.bib`, `.agents/cross_index.json`), ### Check 1: Format Check (格式检查) -Verify that `paper.md` conforms to VibePaper structural rules defined in `writingrules.md`. +Verify that `paper.md` conforms to CoPaper structural rules defined in `writingrules.md`. **Sub-checks:** @@ -201,8 +201,8 @@ Invoke the `markdown-review` skill. Collect the comprehensive review report and - Number of Major issues - Number of Minor issues - Overall assessment -Then call `vibepaper_checker_status` to read any persisted checker summary, stale signal, and precheck evidence. Use this tool for status/freshness; do not read `.agents/state.json` directly just to infer checker status. -If the user asks to persist the precheck checker summaries, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason for each actual checker result; wait for explicit confirmation; then route to `@vibepaper-recorder` so it can call `vibepaper_checker_record`. +Then call `copaper_checker_status` to read any persisted checker summary, stale signal, and precheck evidence. Use this tool for status/freshness; do not read `.agents/state.json` directly just to infer checker status. +If the user asks to persist the precheck checker summaries, restate checker, status, Critical/Major/Minor counts, summary, evidence, and reason for each actual checker result; wait for explicit confirmation; then route to `@copaper-recorder` so it can call `copaper_checker_record`. ### Step 5: Generate Precheck Report @@ -211,7 +211,7 @@ Compile all findings into `.agents/precheck_report.md` following the output form ### Step 6: Present Summary to User Display a concise summary of the precheck results. Highlight any FAIL items that block submission. Provide actionable recommendations. -Call `vibepaper_checker_status` before presenting the final summary if you need to mention checker freshness or compare the precheck report against `paper.md`. +Call `copaper_checker_status` before presenting the final summary if you need to mention checker freshness or compare the precheck report against `paper.md`. ## Output Format @@ -374,7 +374,7 @@ Based on the 7 checks above: - **NEVER** modify `paper.md`, `writingrules.md`, `paper_list.bib`, or any other source file - **NEVER** skip any of the 7 checks — all checks must be performed regardless of earlier results - **NEVER** fabricate checker results — always invoke the actual `data-checker` and `markdown-review` skills for Checks 6 and 7 -- **NEVER** read `.agents/state.json` directly just to summarize checker run status when `vibepaper_checker_status` is available +- **NEVER** read `.agents/state.json` directly just to summarize checker run status when `copaper_checker_status` is available - **NEVER** delete or overwrite an existing `.agents/precheck_report.md` without preserving its content — append a timestamp or version if needed ## Important Notes diff --git a/vibepaper/scaffold/skills/technical-depth-checker/SKILL.md b/copaper/scaffold/skills/technical-depth-checker/SKILL.md similarity index 99% rename from vibepaper/scaffold/skills/technical-depth-checker/SKILL.md rename to copaper/scaffold/skills/technical-depth-checker/SKILL.md index dbee846..ae154fc 100644 --- a/vibepaper/scaffold/skills/technical-depth-checker/SKILL.md +++ b/copaper/scaffold/skills/technical-depth-checker/SKILL.md @@ -298,7 +298,7 @@ Generate a comprehensive technical depth assessment. ## Paper Structure Reference -The paper follows VibePaper structure. Key rules for this checker: +The paper follows CoPaper structure. Key rules for this checker: - **Level 1-5** (`#` to `#####`): Structural headings only — no body text allowed under these. - **Level 6** (`######`): Content paragraphs. Title = topic sentence (≤50 chars). Body = supporting text (≤500 chars). - **Metadata**: HTML comments `<!-- description: ... -->` guide what each section should contain. diff --git a/vibepaper/scaffold/skills/technical-depth-checker/examples.md b/copaper/scaffold/skills/technical-depth-checker/examples.md similarity index 100% rename from vibepaper/scaffold/skills/technical-depth-checker/examples.md rename to copaper/scaffold/skills/technical-depth-checker/examples.md diff --git a/vibepaper/scaffold/skills/template-latex-export/SKILL.md b/copaper/scaffold/skills/template-latex-export/SKILL.md similarity index 92% rename from vibepaper/scaffold/skills/template-latex-export/SKILL.md rename to copaper/scaffold/skills/template-latex-export/SKILL.md index 374797e..ba19a8b 100644 --- a/vibepaper/scaffold/skills/template-latex-export/SKILL.md +++ b/copaper/scaffold/skills/template-latex-export/SKILL.md @@ -1,6 +1,6 @@ --- name: template-latex-export -description: Convert `paper.md` into a final LaTeX paper project using a user-provided conference or journal template placed under `templates/latex/`. Use when the user asks to generate the final LaTeX paper from the VibePaper markdown draft with a local template. +description: Convert `paper.md` into a final LaTeX paper project using a user-provided conference or journal template placed under `templates/latex/`. Use when the user asks to generate the final LaTeX paper from the CoPaper markdown draft with a local template. --- # Template LaTeX Export @@ -11,8 +11,8 @@ This skill converts `paper.md` into a final LaTeX paper using a template that th | File | Required | When Used | Purpose | |------|----------|-----------|---------| -| `paper.md` | Required | Start | Source VibePaper draft to convert | -| `writingrules.md` | Required | Start | Interpret VibePaper heading and paragraph structure | +| `paper.md` | Required | Start | Source CoPaper draft to convert | +| `writingrules.md` | Required | Start | Interpret CoPaper heading and paragraph structure | | `templates/latex/` | Required | Start | User-provided LaTeX template directory | | `relatedwork/paper_list.bib` | Optional | Bibliography step | BibTeX entries to copy or reference | | `fig/` | Optional | Asset step | Figures referenced by the paper | diff --git a/vibepaper/scaffold/skills/writing-orchestrator/SKILL.md b/copaper/scaffold/skills/writing-orchestrator/SKILL.md similarity index 84% rename from vibepaper/scaffold/skills/writing-orchestrator/SKILL.md rename to copaper/scaffold/skills/writing-orchestrator/SKILL.md index ad1ee31..51faf02 100644 --- a/vibepaper/scaffold/skills/writing-orchestrator/SKILL.md +++ b/copaper/scaffold/skills/writing-orchestrator/SKILL.md @@ -5,7 +5,7 @@ description: Orchestrates structured paper framework writing by scanning paper.m # Writing-Orchestrator Skill -This skill is the human-led writing coordinator for VibePaper. +This skill is the human-led writing coordinator for CoPaper. It inspects `paper.md`, shows what is complete or still empty, recommends the next section based on logical dependency, and routes the user to `markdown-helper`, `state-machine-markdown-helper`, or `mad-writer` while treating `markdown-review` as the mandatory review gate. ## When to Use This Skill @@ -32,10 +32,10 @@ This skill is an orchestrator, not a direct replacement for drafting or revision | File | Required | When to Read | Purpose | |------|----------|-------------|---------| -| `paper.md` | **Required** | Step 1 (structure status) | Primary target; inspect through `vibepaper_paper_structure_status` for Level 2-5 completion and Level 5 writing targets | +| `paper.md` | **Required** | Step 1 (structure status) | Primary target; inspect through `copaper_paper_structure_status` for Level 2-5 completion and Level 5 writing targets | | `storyline.md` | Conditional | When recommending writing order | Research narrative for dependency-aware section ordering | -| Checker status | Conditional | Step 6 and Step 7 | Use `vibepaper_checker_status` for read-only checker run status, stale signals, and severity counts | -| `.agents/state.json` | Conditional | Step 8 (progress tracking) | Workflow phase status via `vibepaper_workflow_set_phase`; arbitrary writing metadata only if a dedicated tool exists | +| Checker status | Conditional | Step 6 and Step 7 | Use `copaper_checker_status` for read-only checker run status, stale signals, and severity counts | +| `.agents/state.json` | Conditional | Step 8 (progress tracking) | Workflow phase status via `copaper_workflow_set_phase`; arbitrary writing metadata only if a dedicated tool exists | | `.agents/cross_index.json` | Conditional | When routing to markdown-helper or mad-writer | Paper-technique mappings; pass to downstream skills for literature context | | `relatedwork/papers/*.md` | Conditional | When routing to markdown-helper or mad-writer | Individual literature summaries; pass to downstream skills, not read directly by orchestrator | | `fig/` | Conditional | When routing to markdown-helper or mad-writer | Available figures; pass to downstream skills for visual references | @@ -46,7 +46,7 @@ If some sources are missing, continue with available context and state what is m ## Completion Scan Rules -The orchestrator must call `vibepaper_paper_structure_status` to inspect `paper.md` completion instead of manually scanning headings when the plugin tool is available. +The orchestrator must call `copaper_paper_structure_status` to inspect `paper.md` completion instead of manually scanning headings when the plugin tool is available. This tool is read-only. It does not write `paper.md`, update `.agents/state.json`, append `.agents/events.jsonl`, or advance workflow phases. @@ -63,9 +63,9 @@ Reporting refinement: ## Workflow -### Step 1: Call `vibepaper_paper_structure_status` +### Step 1: Call `copaper_paper_structure_status` -1. Call `vibepaper_paper_structure_status`. +1. Call `copaper_paper_structure_status`. 2. Use the returned `headings`, `level5Targets`, `nextTarget`, `summary`, and `violations`. 3. If the tool reports missing or invalid `paper.md`, stop and tell the user the framework file is required first. 4. Do not reproduce this scan manually, shell out to parse markdown, or infer completion from ad hoc file reads when the plugin tool is available. @@ -158,7 +158,7 @@ Requirements: After the selected section is complete, automatically invoke `markdown-review`. This review is mandatory after every completed section. -When `@vibepaper-reviewer` is available, route checker-result summarization and issue explanation to that read-only subagent. It must not edit `paper.md`; writing fixes still go through the normal confirmed writing/revision path. +When `@copaper-reviewer` is available, route checker-result summarization and issue explanation to that read-only subagent. It must not edit `paper.md`; writing fixes still go through the normal confirmed writing/revision path. The required checker order is: 1. `problem-checker` @@ -174,23 +174,23 @@ Never skip this review stage. ### Step 6: Show seven-checker results and suggest revision path After review: -1. call `vibepaper_checker_status` to read the current checker status, severity counts, stale signals, and precheck evidence -2. use `@vibepaper-reviewer` when available to produce a compact seven-checker summary from the review output plus the tool status +1. call `copaper_checker_status` to read the current checker status, severity counts, stale signals, and precheck evidence +2. use `@copaper-reviewer` when available to produce a compact seven-checker summary from the review output plus the tool status 3. separate Critical, Major, and Minor issues 4. explain which issues matter most for the finished section -5. if the user wants durable checker summaries, restate the checker record details and route the confirmed action to `@vibepaper-recorder` so it can call `vibepaper_checker_record` +5. if the user wants durable checker summaries, restate the checker record details and route the confirmed action to `@copaper-recorder` so it can call `copaper_checker_record` 6. ask whether modifications are needed 7. if yes, suggest `review-revise` Do not fabricate checker results. -Use real review output or `vibepaper_checker_status`; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. +Use real review output or `copaper_checker_status`; do not read `.agents/state.json` directly just to infer checker status when the plugin tool is available. ### Step 7: Run a final full review after all sections are complete When the scan shows no incomplete writing targets remain: 1. announce that the framework is fully populated 2. run one final full `markdown-review` -3. call `vibepaper_checker_status` to verify status freshness and severity counts +3. call `copaper_checker_status` to verify status freshness and severity counts 4. present the final seven-checker summary 5. suggest `review-revise` if unresolved issues remain @@ -200,13 +200,13 @@ This final pass checks whole-paper consistency instead of only local section qua At the end of each cycle, update workflow phase status through the OpenCode plugin tool when appropriate. -Use `vibepaper_workflow_set_phase`: +Use `copaper_workflow_set_phase`: - after accepted writing edits, set `phase: "writing"` and `status: "in_progress"` - after all writing targets and the final full review are complete, set `phase: "writing"` and `status: "complete"` -Before calling the tool, restate the phase/status update and wait for explicit user confirmation. The `vibepaper_workflow_set_phase` call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. +Before calling the tool, restate the phase/status update and wait for explicit user confirmation. The `copaper_workflow_set_phase` call writes `.agents/state.json` and appends `.agents/events.jsonl`; do not replace it with prompt-only status text. -The current OpenCode plugin does not expose a dedicated tool for arbitrary writing metadata such as current mode, selected section path, completion snapshot, or review-revise history. It can record confirmed checker run summaries through `vibepaper_checker_record`. Do not manually edit `.agents/state.json` for unsupported fields when using the plugin-based workflow; report the limitation instead. +The current OpenCode plugin does not expose a dedicated tool for arbitrary writing metadata such as current mode, selected section path, completion snapshot, or review-revise history. It can record confirmed checker run summaries through `copaper_checker_record`. Do not manually edit `.agents/state.json` for unsupported fields when using the plugin-based workflow; report the limitation instead. ## Writing Order Recommendation @@ -241,7 +241,7 @@ Use this comparison when the user is choosing a mode. Mode guidance: Fine Mode is best for fluid paragraph-by-paragraph arguments; Strict Mode is essential for rigorous, RAG-heavy writing where hallucination must be zero; Fast Mode is better for large baseline sections where structural bulk drafting is acceptable. -The interaction loop must remain section-by-section: scan, summarize, recommend, let the user pick a section and mode, invoke the downstream skill, run `markdown-review`, report results, update workflow phase through `vibepaper_workflow_set_phase` when appropriate, and return to the overview. Do not silently expand into full-paper auto-writing. +The interaction loop must remain section-by-section: scan, summarize, recommend, let the user pick a section and mode, invoke the downstream skill, run `markdown-review`, report results, update workflow phase through `copaper_workflow_set_phase` when appropriate, and return to the overview. Do not silently expand into full-paper auto-writing. ## Must NOT Do @@ -251,7 +251,7 @@ The interaction loop must remain section-by-section: scan, summarize, recommend, - **NEVER** modify Level 2-5 framework headings during orchestration - **NEVER** fabricate completion state without reading `paper.md` - **NEVER** fabricate checker results instead of invoking or reading `markdown-review` -- **NEVER** manually edit `.agents/state.json` for workflow phase updates when `vibepaper_workflow_set_phase` is available +- **NEVER** manually edit `.agents/state.json` for workflow phase updates when `copaper_workflow_set_phase` is available ## End Condition diff --git a/vibepaper/scaffold/storyline.md b/copaper/scaffold/storyline.md similarity index 100% rename from vibepaper/scaffold/storyline.md rename to copaper/scaffold/storyline.md diff --git a/vibepaper/scaffold/templates/latex/README.md b/copaper/scaffold/templates/latex/README.md similarity index 100% rename from vibepaper/scaffold/templates/latex/README.md rename to copaper/scaffold/templates/latex/README.md diff --git a/vibepaper/scaffold/writingrules.md b/copaper/scaffold/writingrules.md similarity index 92% rename from vibepaper/scaffold/writingrules.md rename to copaper/scaffold/writingrules.md index 42a2748..69245ac 100644 --- a/vibepaper/scaffold/writingrules.md +++ b/copaper/scaffold/writingrules.md @@ -1,12 +1,12 @@ -# VibePaper GUI 写作规则指南 +# CoPaper GUI 写作规则指南 -本文档用于指导用户和 AI Agent 使用 VibePaper GUI 进行论文写作。 +本文档用于指导用户和 AI Agent 使用 CoPaper GUI 进行论文写作。 ## 项目概述 -VibePaper GUI 是一个基于树状结构的论文写作辅助工具,采用自顶向下的方式组织论文结构。论文以 Markdown 文件形式存储,通过标题层级组织结构,每个节点可包含描述、主题句、支撑句和图片等内容。 +CoPaper GUI 是一个基于树状结构的论文写作辅助工具,采用自顶向下的方式组织论文结构。论文以 Markdown 文件形式存储,通过标题层级组织结构,每个节点可包含描述、主题句、支撑句和图片等内容。 ## 项目文件夹概述 diff --git a/vibepaper/schema.py b/copaper/schema.py similarity index 96% rename from vibepaper/schema.py rename to copaper/schema.py index f91524a..d164d0d 100644 --- a/vibepaper/schema.py +++ b/copaper/schema.py @@ -1,4 +1,4 @@ -"""State schema definition for VibePaper projects. +"""State schema definition for CoPaper projects. The state.json file is the single source of truth for project progress. It lives at .agents/state.json and is shared between the CLI and OpenCode Skills. @@ -127,8 +127,8 @@ "auto_commit": False, "identity": { "role": "assistant", - "git_name": "VibePaper Bot", - "git_email": "bot@vibepaper.dev", + "git_name": "CoPaper Bot", + "git_email": "bot@copaper.dev", }, }, "checkers": {}, diff --git a/vibepaper/state.py b/copaper/state.py similarity index 96% rename from vibepaper/state.py rename to copaper/state.py index ba5b5dd..0cbc927 100644 --- a/vibepaper/state.py +++ b/copaper/state.py @@ -14,8 +14,8 @@ from pathlib import Path from typing import Any -from vibepaper.constants import PHASE_DEPENDENCIES, PHASE_ORDER, Phase, PhaseStatus -from vibepaper.schema import DEFAULT_STATE +from copaper.constants import PHASE_DEPENDENCIES, PHASE_ORDER, Phase, PhaseStatus +from copaper.schema import DEFAULT_STATE class StateFileError(Exception): @@ -23,7 +23,7 @@ class StateFileError(Exception): class StateManager: - """Manages the .agents/state.json file for a VibePaper project. + """Manages the .agents/state.json file for a CoPaper project. Provides atomic read/write operations and convenience methods for querying and updating phase status in the writing pipeline. @@ -62,7 +62,7 @@ def load(self) -> dict[str, Any]: if not self._state_file.exists(): raise StateFileError( f"State file not found: {self._state_file}. " - "Run 'vibe init' to create a new project." + "Run 'copaper init' to create a new project." ) try: diff --git a/docs/en.md b/docs/en.md new file mode 100644 index 0000000..ae85c0c --- /dev/null +++ b/docs/en.md @@ -0,0 +1,287 @@ +# Copaper - Your Paper Assistant + +## Before You Use CoPaper + +###### Tool Scope +CoPaper is an assistant for paper writing, project management, and research-material organization. It does not replace the author's academic judgment, experimental validation, or final responsibility. + +###### Academic Integrity +All experimental data, figures, metrics, case studies, and conclusions must come from real experiments or verifiable sources. Do not use CoPaper for plagiarism, data fabrication, invented citations, exaggerated contributions, or any other form of academic misconduct. + +###### Step-by-Step Generation +Because current model and project capabilities are still limited, generate and revise the paper section by section, subsection by subsection, or paragraph by paragraph. Avoid asking the system to generate the whole paper at once, since large one-shot generations are more likely to miss constraints, confuse context, or produce unstable quality. + +###### Human Verification +All content generated by CoPaper or by language models may contain hallucinations, inaccurate wording, or unverified inferences. Before submission, publication, or formal use, authors must manually verify facts, data, citations, experimental setup, conclusions, and textual originality. + +## CoPaper OpenCode Plugin Usage + +###### Install From Local Packages +From the repository root, enter the plugin package, install dependencies, and build it: + +```bash +cd packages/opencode-plugin +bun install +bun run build +``` + +Then install the local plugin into a target CoPaper project: + +```bash +bun run dev:install <target-project> +``` + +`<target-project>` is the project directory where the plugin should be enabled. After installation, restart OpenCode and run these commands inside the target project: + +```text +/copaper-doctor +/copaper +``` + +###### Install From npm +If you want to use the published package, run this from the target project root: + +```bash +bunx -p @copaper/opencode copaper-opencode init +``` + +Bun needs `-p` because the package name is `@copaper/opencode`, while the binary name is `copaper-opencode`. + +## Plugin Capability Overview + +###### OpenCode Tools +The plugin currently registers 23 `copaper_*` tools. They cover read-only inspection, initialization, import extraction, related-work operations, status recording, and workflow management. + +| Tool | Purpose | +|---|---| +| `copaper_dashboard` | Shows project readiness, core file status, and init preview; read-only. | +| `copaper_init_apply` | Initializes core project files after explicit user confirmation. | +| `copaper_artifact_status` | Checks readiness for `storyline.md`, `paper.md`, related work, checkers, and other artifacts; read-only. | +| `copaper_artifact_record` | Records artifact readiness into state and the event log after confirmation. | +| `copaper_paper_structure_status` | Scans `paper.md` structure completion, Level 5 writing targets, and structural issues; read-only. | +| `copaper_storyline_structure_status` | Scans `storyline.md` section completion, TODO coverage, and the next target; read-only. | +| `copaper_pdf_extract` | Extracts text from a user-specified in-project PDF; read-only. | +| `copaper_ppt_extract` | Extracts slide text and optional notes from a user-specified in-project PPTX; read-only. | +| `copaper_checker_status` | Summarizes checker status, severity counts, stale signals, and precheck evidence; read-only. | +| `copaper_checker_record` | Records a checker run summary after confirmation. | +| `copaper_relatedwork_status` | Checks related-work catalog, BibTeX, PDFs, summaries, and cross-index status; read-only. | +| `copaper_relatedwork_keywords` | Extracts search keywords from the storyline or a chosen source and writes `relatedwork/queries.txt`. | +| `copaper_relatedwork_search` | Searches related work through Semantic Scholar / arXiv and writes the search cache. | +| `copaper_relatedwork_import` | Imports the search cache into `relatedwork/literature.json`. | +| `copaper_relatedwork_sync_bib` | Synchronizes `relatedwork/paper_list.bib` from the literature catalog. | +| `copaper_relatedwork_download` | Downloads related-work PDFs into the relatedwork PDF directory. | +| `copaper_relatedwork_summarize` | Uses the CLI/LLM bridge to generate PDF summaries. | +| `copaper_relatedwork_register_summary` | Registers an existing summary file in the literature catalog. | +| `copaper_relatedwork_build_index` | Builds `.agents/cross_index.json` from related-work summaries. | +| `copaper_relatedwork_clean` | Cleans stale related-work entries, orphan PDFs, or orphan summaries. | +| `copaper_workflow_status` | Shows current phase, phase table, and next-step recommendation; read-only. | +| `copaper_workflow_log` | Queries recent workflow events, optionally filtered by phase or operator; read-only. | +| `copaper_workflow_set_phase` | Updates workflow phase status after confirmation and appends an event record. | + +###### CoPaper Subagents +The plugin injects 6 built-in subagents into OpenCode. Their permission boundaries separate coordination, writing, reviewing, recording, and literature work. + +| Subagent | Purpose | +|---|---| +| `@copaper-coordinator` | Read-only coordinator; checks project status, clarifies scope, and recommends the next role or next step. | +| `@copaper-storyline` | Maintains the research storyline in `storyline.md`; edits storyline only after confirmation. | +| `@copaper-writer` | Drafts or revises `paper.md` under CoPaper structure rules; does not edit storyline or state files. | +| `@copaper-reviewer` | Read-only reviewer; explains checker results, severity, and likely review risks without editing the paper. | +| `@copaper-recorder` | Records artifact readiness or checker summaries as state facts; does not edit paper content. | +| `@copaper-literature` | Drives the related-work workflow through search, import, download, summary, and cross-index tools. | + +###### Project Skills +The project currently includes 28 skills under `.agents/skills/`. These are workflow instructions for agents: when to read which files, how to edit safely, and when explicit confirmation is required. + +| Skill | Purpose | +|---|---| +| `storyline-helper` | Interactively builds and improves `storyline.md`; polishes user-provided research content without inventing the storyline. | +| `socratic-discussion` | Uses Socratic questioning to examine insights, claims, methods, and evidence across the 7 checker dimensions. | +| `writing-orchestrator` | Scans `paper.md` completion, recommends writing order, and routes to fine, strict, or fast writing modes. | +| `markdown-helper` | Helps write and improve `paper.md` content under the CoPaper structure. | +| `state-machine-markdown-helper` | Writes paragraph by paragraph with a strict state machine and context isolation to reduce hallucination. | +| `mad-writer` | Runs an automatic write-check-fix loop, optionally using related work and placeholder data. | +| `markdown-review` | Reviews markdown paper content and produces structured improvement guidance. | +| `review-revise` | Conducts multi-round checker-driven revision, confirming each issue before edits. | +| `problem-checker` | Checks whether the problem is clear and whether importance/practicality are well supported. | +| `novelty-checker` | Checks whether the core insight is novel and differentiated from prior work. | +| `technical-depth-checker` | Checks whether the design has enough technical depth, non-trivial challenges, and concrete solutions. | +| `logic-checker` | Checks claim-evidence alignment, contradictions, and argument gaps. | +| `clarity-checker` | Checks term definitions, description clarity, references, and readability. | +| `evaluation-protocol-checker` | Checks RQs, experiment design, design-decision validation, and threats to validity. | +| `data-checker` | Checks for placeholder/bogus data and verifies reproducibility scripts for tables and figures. | +| `submission-precheck` | Runs pre-submission checks for format, citations, figures, word count, completeness, data authenticity, and quality. | +| `experiment-analyzer` | Analyzes experiment code, results, or protocols and maps them to research questions. | +| `bogus-data-helper` | Creates clearly marked synthetic placeholder tables, figures, and metrics that must be replaced with real results. | +| `relatedwork-finder` | Finds, imports, and downloads related work based on `storyline.md` or `paper.md`. | +| `relatedwork-summarizer` | Runs the relatedwork CLI to summarize PDFs, build the cross-index, and produce a coverage report. | +| `pdf2paper` | Maps an existing PDF draft into the `paper.md` framework without inventing new content. | +| `ppt2storyline` | Extracts slide content from PPT/PPTX files and maps it into `storyline.md`. | +| `latex2markdown` | Migrates LaTeX paper content into the CoPaper `paper.md` structure. | +| `markdown2latex` | Converts `paper.md` into high-quality LaTeX, with optional conference template adaptation. | +| `latex-final-writer` | After `paper.md` is complete, creates `writing_plan.md`, initializes the `tex/` structure, and writes the final LaTeX draft from a conference or journal template. | +| `humanizer` | Removes AI-writing traces and makes prose sound more natural while preserving meaning and tone. | +| `human-comment-helper` | Helps advisors or instructors turn human feedback into structured comments while distinguishing AI examples from real feedback. | +| `copaper-manage` | Guides agents in using OpenCode plugin tools for initialization, workflow, event log, readiness, and phase management. | + +###### Phase Management Entry Point +In OpenCode, the direct entry point for phase management is the `copaper-manage` skill. It first reads the current phase through `copaper_workflow_status`, then calls `copaper_workflow_set_phase` after explicit user confirmation. That tool writes `.agents/state.json` and appends `.agents/events.jsonl`. Other skills also use the same tool at the end of their own workflows, such as `storyline-helper` for `storyline`, `experiment-analyzer` for `experiments`, and `writing-orchestrator` for `writing`. + +## End-to-End Usage Guide + +###### Choose an Operating Mode +CoPaper can be operated in two ways. The CLI is best for scripts, batch operations, relatedwork pipelines, and Git-backed phase management. The OpenCode plugin is best for IDE-based daily writing through `/copaper`, subagents, and confirmation-based tools. The recommended mode is mixed: use the CLI for initialization, relatedwork batch work, and Git; use the plugin for status inspection, storyline work, paper writing, review, and readiness recording. + +###### Step 0: Prepare the Environment +The target project needs Python, Git, Bun, and OpenCode. The Python side provides the `copaper` CLI. The Bun side installs `@copaper/opencode`. OpenCode provides slash commands, tools, and subagents. Related-work search, keyword extraction, and summarization also require `.env` configuration in the target project. Do not commit secrets. + +```bash +# Install the Python CLI from the CoPaper repository +pip install -e .[dev] + +# Install the OpenCode plugin in the target project +bunx -p @copaper/opencode copaper-opencode init +``` + +For local development, use `bun run dev:install <target-project>` as described above. After installation, restart OpenCode and run `/copaper-doctor` and `/copaper` inside the target project. + +###### Git-Assisted Management +Git is not a standalone writing step. It is an optional management layer across the workflow. Inside a Git repository, use `copaper commit` for phase-scoped commits, `diff` to compare phase commits, and `rollback` to soft-reset to the last commit for a phase while resetting that phase status. `report` can run outside a Git repository. `commit`, `rollback`, and `diff` must run inside one. + +```bash +copaper --root <target-project> commit --phase storyline -m "Complete storyline draft" +copaper --root <target-project> diff storyline literature +copaper --root <target-project> rollback storyline +``` + +Rollback changes the worktree state, so make sure important edits are saved first. + +###### Readiness and Phase Management +Readiness and phase updates are not standalone writing steps either. They are state-management actions used throughout the workflow. Update CoPaper state through the CLI or plugin tools. Do not hand-edit `.agents/state.json`. When an artifact becomes usable, inspect evidence first, then explicitly confirm readiness recording. When a phase is complete, skipped, or rolled back, confirm the phase update. + +```text +/copaper +Please check artifact readiness. +Confirm recording paper.md as partial with medium confidence because the Introduction is done but Evaluation is not written yet. +Confirm marking the writing phase as in_progress. +``` + +CLI equivalents: + +```bash +copaper --root <target-project> set-phase writing --status in_progress +copaper --root <target-project> log --last 10 +copaper --root <target-project> report --output report.md +``` + +In OpenCode, trigger `copaper-manage` or simply say that a phase should be marked as a certain status. The agent should restate phase, status, and reason, then wait for confirmation before calling `copaper_workflow_set_phase`. This is safer than editing the state file directly. + +###### Step 1: Initialize the Paper Project +Start by creating the CoPaper core artifacts. The CLI copies `storyline.md`, `paper.md`, `writingrules.md`, `AGENTS.md`, and `.agents/skills/`. The plugin initialization flow first shows a preview and writes core files only after explicit confirmation. + +```bash +copaper --root <target-project> init --name "<project-name>" --domain "<research-domain>" +copaper --root <target-project> status +``` + +In OpenCode, open `/copaper` to view the dashboard. If the dashboard says the project is not ready, follow the prompt and confirm initialization. If files already exist, decide whether to keep, migrate, or use a different directory before writing anything. + +You can also initialize a project from existing materials instead of starting from blank templates. `ppt2storyline` can convert a meeting PPT/PPTX into `storyline.md`. `pdf2paper` can map an existing PDF draft into `paper.md`. `latex2markdown` can migrate an existing LaTeX paper into the markdown framework. Import should remain faithful to the source material: map and lightly polish, but do not invent new claims. + +```text +Extract this PPTX into storyline.md, but do not add claims that are not present in the slides. +Import this PDF draft into paper.md while preserving the original claim boundaries. +Migrate this LaTeX paper into the CoPaper paper.md structure. +``` + +If the import produces `storyline.md`, you can skip blank storyline drafting in Step 2, inspect and confirm the storyline, then continue with Step 3 for related work. If the import produces a complete or nearly complete `paper.md`, you can fill any necessary storyline or related-work evidence, then jump to Step 7 for review, revision, and checker recording. + +###### Step 2: Fill the Research Storyline +Complete `storyline.md` first. It is the primary constraint for later literature search, discussion, experiments, and writing. Use `@copaper-storyline` or trigger `storyline-helper`, then provide your problem, importance, insight, design idea, and evaluation plan section by section. The agent may polish and organize your content, but it should not invent research substance. + +```text +@copaper-storyline Help me fill the problem statement section in storyline.md. +``` + +Afterward, check the structure status and record progress only after confirmation: + +```text +/copaper +Please check storyline structure completion. +Confirm marking the storyline phase as complete because the first storyline draft is done. +``` + +###### Step 3: Search and Organize Related Work +The literature phase converts `storyline.md` or `paper.md` into search keywords, searches papers, imports metadata, syncs BibTeX, downloads PDFs, generates per-paper summaries, and builds `.agents/cross_index.json`. In the plugin, hand this to `@copaper-literature`. In the CLI, run the 7-step pipeline: + +```bash +copaper --root <target-project> relatedwork keywords --count 6 +copaper --root <target-project> relatedwork search --queries-file relatedwork/queries.txt --limit 5 +copaper --root <target-project> relatedwork import --input relatedwork/search_cache.json +copaper --root <target-project> relatedwork sync-bib +copaper --root <target-project> relatedwork download +copaper --root <target-project> relatedwork summarize --concurrency 4 +copaper --root <target-project> relatedwork build-index +copaper --root <target-project> relatedwork status +``` + +Keyword extraction and summarization require an OpenAI-compatible LLM. Search uses Semantic Scholar / arXiv. Start with a small `limit` for a smoke test, confirm `.env`, network access, and the `copaper` bridge, then scale up. + +###### Step 4: Discuss and Tighten the Argument +The discussion phase uses `socratic-discussion` to stress-test the problem, novelty, technical depth, logic chain, clarity, evaluation protocol, and data evidence. This phase is not paper drafting; it is a way to expose likely reviewer concerns early and revise the storyline or experiment plan. + +```text +Run a Socratic discussion focused on novelty and technical depth. +``` + +If the discussion exposes storyline gaps, return to `storyline-helper`. If it exposes missing experiments or evidence, move to experiment analysis. If it only exposes wording issues, leave them for writing and review. + +###### Step 5: Prepare Experiments or Record a Skip +The experiments phase can use `experiment-analyzer` to understand experiment code, analyze results, or review the protocol. For theoretical or design-only papers, you can explicitly skip the phase and record the reason. Do not treat placeholder data as real results. If placeholder content is needed, use `bogus-data-helper` and mark it as synthetic. + +```text +Analyze the results in experiments/ and map them to the paper's RQs. +``` + +When skipping experiments, use the full phase name: + +```bash +copaper --root <target-project> skip experiments --reason "<reason>" +``` + +###### Step 6: Write paper.md +The writing phase centers on `paper.md`. Start with `writing-orchestrator` to scan completion and recommend order. Then choose a writing mode: `markdown-helper` for careful section-by-section drafting, `state-machine-markdown-helper` for strict paragraph-by-paragraph writing, or `mad-writer` for faster generation and iteration. In the plugin, use `@copaper-writer`; it should edit only `paper.md`. + +```text +@copaper-writer Based on storyline.md and the cross-index, write the first Level 5 section of the Introduction. +``` + +Follow the CoPaper structure. Levels 1-5 are structural headings only. Body text must appear under Level 6 headings. Level 6 titles must be at most 50 characters, and paragraph bodies must be at most 500 characters. When citing literature, inspect `.agents/cross_index.json` first, then read only the targeted `relatedwork/papers/*.md` summaries. + +###### Step 7: Review, Revise, and Record Checkers +After writing a section, run review. `@copaper-reviewer` and the checker skills identify issues. `review-revise` processes them in Critical, Major, then Minor order, with confirmation before each edit. If checker results should be persisted, route the record action to `@copaper-recorder` after restating checker, status, counts, summary, evidence, and reason. + +```text +@copaper-reviewer Check the current paper.md for problem, novelty, and logic risks. +``` + +Before submission, run `submission-precheck`. It checks format, citations, figures, word count, completeness, data authenticity, and overall quality, then generates a precheck report. + +###### Step 8: Generate the Final LaTeX Draft +The import entry point for existing materials is in Step 1 during initialization. After the paper is complete and has passed the necessary review, the final step is to use `latex-final-writer` to generate the LaTeX final draft. This skill uses the completed `paper.md`, `storyline.md`, related-work summaries, experiment materials, and the user-provided conference or journal template to create or update `writing_plan.md`, initialize the `tex/` structure, and write the submission-ready LaTeX draft section by section. + +```text +I have completed paper.md. Use latex-final-writer with the tex/ template to generate the final LaTeX draft. +``` + +The final draft must not invent experiments, numbers, citations, or claims. After generation, compile the LaTeX and manually verify citations, figures, formulas, page limits, anonymity requirements, overfull boxes, and undefined references. + +###### Recommended End-to-End Path +The safest complete path is: install plugin and CLI, initialize the project or import existing materials, complete or confirm `storyline.md`, run relatedwork, run Socratic discussion, prepare experiments or record a skip reason, write or import `paper.md`, review and revise section by section, run submission precheck, then use `latex-final-writer` to generate the final LaTeX draft. After importing slides into the storyline, continue from Step 3. After importing an existing paper into `paper.md`, continue from Step 7. Every phase can be re-entered. If a later step exposes an earlier gap, return to the corresponding skill and fix it. + +```text +Initialize -> Storyline -> Literature -> Discussion -> Experiments/Skip -> Writing -> Review/Revise -> Precheck -> Final LaTeX Draft +``` + +###### Common Notes +`--root` is a global CLI option and must appear before the subcommand. Phase names must be `storyline`, `literature`, `discussion`, `experiments`, `writing`, or `latex_review`. Read-only plugin tools do not write files. Write-capable tools usually require the agent to restate parameters and wait for explicit confirmation. Store secrets in `.env` and do not commit them. Do not directly edit `.agents/state.json` or `.agents/events.jsonl` unless you are debugging the implementation. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..2b91c5f --- /dev/null +++ b/docs/index.md @@ -0,0 +1,287 @@ +# Copaper-你的论文助手 + +## 使用前须知 + +###### 工具定位 +CoPaper 只能用于辅助完成论文写作、项目管理和资料整理,不能替代作者的学术判断、实验验证或最终责任。 + +###### 学术诚信 +所有实验数据、图表、指标、案例和结论都必须来自真实实验或可核查来源。不得使用 CoPaper 抄袭、伪造数据、编造引用、夸大贡献,或进行任何其他学术不端行为。 + +###### 分步生成 +由于目前模型和项目能力仍有局限,建议按章节、按小节、按段落逐步生成和修改论文,不要一次性要求生成整篇论文。一次处理过多内容时,模型更容易遗漏约束、混淆上下文或产生质量不稳定的结果。 + +###### 人工核查 +所有由 CoPaper 或模型生成的内容都可能包含幻觉、不准确表述或未经验证的推断。提交、传播或用于正式论文前,作者必须逐条人工核查事实、数据、引用、实验设置、结论和文字原创性。 + +## CoPaper OpenCode 插件安装 + +###### 从本地 packages 安装 +在仓库根目录进入插件包并安装依赖、构建: + +```bash +cd packages/opencode-plugin +bun install +bun run build +``` + +然后把本地插件安装到目标 CoPaper 项目: + +```bash +bun run dev:install <target-project> +``` + +其中 `<target-project>` 是需要启用插件的项目目录。安装完成后重启 OpenCode,并在目标项目中运行: + +```text +/copaper-doctor +/copaper +``` + +###### 从 npm 安装 +如果使用已发布版本,可在目标项目根目录运行: + +```bash +bunx -p @copaper/opencode copaper-opencode init +``` + +Bun 需要 `-p`,因为包名是 `@copaper/opencode`,命令名是 `copaper-opencode`。 + +## 插件能力总览 + +###### OpenCode Tools +插件目前注册了 23 个 `copaper_*` 工具,主要分为只读检查、初始化、导入提取、relatedwork、状态记录和 workflow 管理。 + +| 工具 | 作用 | +|---|---| +| `copaper_dashboard` | 显示项目 readiness、核心文件状态和初始化预览;只读。 | +| `copaper_init_apply` | 在用户明确确认后初始化项目核心文件。 | +| `copaper_artifact_status` | 检查 `storyline.md`、`paper.md`、relatedwork、checker 等工件就绪度;只读。 | +| `copaper_artifact_record` | 在确认后记录工件 readiness 到状态文件和事件日志。 | +| `copaper_paper_structure_status` | 扫描 `paper.md` 结构完成度、Level 5 写作目标和结构问题;只读。 | +| `copaper_storyline_structure_status` | 扫描 `storyline.md` 章节完成度、TODO 和下一步目标;只读。 | +| `copaper_pdf_extract` | 从用户指定的项目内 PDF 提取文本;只读。 | +| `copaper_ppt_extract` | 从用户指定的项目内 PPTX 提取 slide 文本和可选 notes;只读。 | +| `copaper_checker_status` | 汇总 checker 状态、严重程度计数、stale 信号和预检证据;只读。 | +| `copaper_checker_record` | 在确认后记录一次 checker 结果摘要。 | +| `copaper_relatedwork_status` | 检查 relatedwork catalog、BibTeX、PDF、summary 和 cross-index 状态;只读。 | +| `copaper_relatedwork_keywords` | 基于 storyline 或指定文档提取检索关键词,写入 `relatedwork/queries.txt`。 | +| `copaper_relatedwork_search` | 调用 Semantic Scholar / arXiv 搜索相关工作,写入搜索缓存。 | +| `copaper_relatedwork_import` | 将搜索缓存导入 `relatedwork/literature.json`。 | +| `copaper_relatedwork_sync_bib` | 根据 literature catalog 同步 `relatedwork/paper_list.bib`。 | +| `copaper_relatedwork_download` | 下载相关工作 PDF 到 relatedwork PDF 目录。 | +| `copaper_relatedwork_summarize` | 调用 CLI/LLM 为 PDF 生成论文摘要。 | +| `copaper_relatedwork_register_summary` | 把已有摘要文件登记到 literature catalog。 | +| `copaper_relatedwork_build_index` | 从相关工作摘要构建 `.agents/cross_index.json`。 | +| `copaper_relatedwork_clean` | 清理 relatedwork 中的陈旧条目、孤立 PDF 或摘要。 | +| `copaper_workflow_status` | 显示当前 phase、各 phase 状态和下一步建议;只读。 | +| `copaper_workflow_log` | 查询近期 workflow event log,可按 phase/operator 过滤;只读。 | +| `copaper_workflow_set_phase` | 在确认后修改 workflow phase 状态并写入事件日志。 | + +###### CoPaper Subagents +插件会向 OpenCode 注入 6 个内置 subagents,用权限边界把协调、写作、审稿、记录和文献流程分开。 + +| Subagent | 作用 | +|---|---| +| `@copaper-coordinator` | 只读协调者;查看项目状态、澄清任务范围、推荐下一步或应交给哪个角色。 | +| `@copaper-storyline` | 负责 `storyline.md` 的研究主线整理和结构维护,只在确认后修改 storyline。 | +| `@copaper-writer` | 负责按 CoPaper 结构撰写或修改 `paper.md`,不改 storyline 或状态文件。 | +| `@copaper-reviewer` | 只读审稿角色;解释 checker 结果、严重程度和潜在审稿风险,不直接改论文。 | +| `@copaper-recorder` | 负责记录 artifact readiness 或 checker summary 等状态事实,不改论文内容。 | +| `@copaper-literature` | 负责 relatedwork 流程,调用检索、导入、下载、摘要和 cross-index 工具。 | + +###### Project Skills +项目当前包含 28 个 skills,位于 `.agents/skills/`。它们是给 agent 的工作流说明,用来约束什么时候读哪些文件、如何修改、何时必须等待确认。 + +| Skill | 作用 | +|---|---| +| `storyline-helper` | 交互式构建和改进 `storyline.md`,只润色用户提供的研究内容,不凭空生成主线。 | +| `socratic-discussion` | 通过苏格拉底式提问审视 insight、claim、方法和证据,覆盖 7 类 checker 维度。 | +| `writing-orchestrator` | 扫描 `paper.md` 完成度,推荐写作顺序,并路由到细粒度、严格或快速写作模式。 | +| `markdown-helper` | 按 CoPaper 结构帮助撰写和改进 `paper.md` 内容。 | +| `state-machine-markdown-helper` | 用严格状态机和上下文隔离逐段写作,减少幻觉和跨段污染。 | +| `mad-writer` | 自动执行 write-check-fix 循环,可结合 relatedwork 和 placeholder data 迭代改稿。 | +| `markdown-review` | 对 markdown 论文内容进行结构化审阅和改进建议。 | +| `review-revise` | 基于 7-checker 输出进行多轮确认式修改,每个问题单独确认后再改。 | +| `problem-checker` | 检查问题定义是否清楚、重要性和实践性证据是否充分。 | +| `novelty-checker` | 检查核心 insight 的新颖性,以及与已有工作的差异是否讲清楚。 | +| `technical-depth-checker` | 检查设计是否有足够技术深度、非平凡挑战和具体解决方案。 | +| `logic-checker` | 检查 claim 与 evidence 是否匹配,是否有矛盾或论证断裂。 | +| `clarity-checker` | 检查术语定义、描述清晰度、指代和可读性问题。 | +| `evaluation-protocol-checker` | 检查 RQ、实验设计、设计决策验证和 validity threats 是否充分。 | +| `data-checker` | 检查 placeholder/bogus data,并验证表格和图是否有可复现实验脚本。 | +| `submission-precheck` | 投稿前综合检查格式、引用、图表、字数、完整性、数据真实性和质量。 | +| `experiment-analyzer` | 分析实验代码、实验结果或实验协议,并帮助映射到研究问题。 | +| `bogus-data-helper` | 生成明确标记为 synthetic 的占位实验表格、图和指标,提醒必须替换为真实结果。 | +| `relatedwork-finder` | 根据 `storyline.md` 或 `paper.md` 查找、导入和下载相关工作。 | +| `relatedwork-summarizer` | 调用 relatedwork CLI 总结 PDF、构建 cross-index,并生成覆盖报告。 | +| `pdf2paper` | 从已有 PDF 草稿提取内容并映射到 `paper.md` 框架,不发明新内容。 | +| `ppt2storyline` | 从 PPT/PPTX 提取 slide 信息并映射到 `storyline.md`。 | +| `latex2markdown` | 将 LaTeX 论文内容迁移进 CoPaper 的 `paper.md` 结构。 | +| `markdown2latex` | 将 `paper.md` 转为高质量 LaTeX,可适配会议模板。 | +| `latex-final-writer` | 在 `paper.md` 完成后,基于会议/期刊 LaTeX 模板创建 `writing_plan.md`、初始化 `tex/` 结构,并逐节写作终稿。 | +| `humanizer` | 去除 AI 写作痕迹,让文本更自然,同时保留原意和语气。 | +| `human-comment-helper` | 帮教师或导师把人工反馈整理成结构化 comments,并区分 AI 示例与真人意见。 | +| `copaper-manage` | 指导 agent 使用 OpenCode 插件工具管理初始化、workflow、event log 和 readiness 状态。 | + +###### Phase 管理入口 +OpenCode 里直接管理 phase 的入口是 `copaper-manage` skill。它会先用 `copaper_workflow_status` 读取当前阶段,再在用户明确确认后调用 `copaper_workflow_set_phase` 写入 `.agents/state.json` 并追加 `.agents/events.jsonl`。其它 skill 也会在自身流程结束时使用同一个 tool,例如 `storyline-helper` 更新 `storyline`,`experiment-analyzer` 更新或跳过 `experiments`,`writing-orchestrator` 更新 `writing`。 + +## 整体使用流程说明书 + +###### 使用方式选择 +CoPaper 可以用两种方式操作:CLI 适合脚本化、批处理和 Git 阶段管理;OpenCode 插件适合在 IDE 中通过 `/copaper`、subagents 和确认式工具完成日常写作。推荐混合使用:项目初始化、relatedwork 批处理和 Git 操作用 CLI;状态查看、主线写作、论文写作、审阅和 readiness 记录用插件。 + +###### Step 0:准备环境 +目标项目至少需要 Python、Git、Bun 和 OpenCode。Python 端提供 `copaper` CLI;Bun 端安装 `@copaper/opencode` 插件;OpenCode 端负责 slash commands、tools 和 subagents。relatedwork 的搜索、关键词和摘要功能还需要在目标项目配置 `.env`,但不要把密钥提交进 Git。 + +```bash +# 在 CoPaper 仓库中安装 Python CLI +pip install -e .[dev] + +# 在目标项目中安装 OpenCode 插件 +bunx -p @copaper/opencode copaper-opencode init +``` + +本地开发版本可使用前文的 `bun run dev:install <target-project>`。安装后重启 OpenCode,并在目标项目运行 `/copaper-doctor` 和 `/copaper`。 + +###### Git 辅助管理 +Git 不是单独写作阶段,而是贯穿流程的辅助管理手段。在 Git 仓库中可用 `copaper commit` 做阶段化提交,`diff` 比较阶段提交差异,`rollback` soft reset 到某阶段最后一次提交并重置阶段状态。`report` 不要求 Git 存在;但 `commit`、`rollback`、`diff` 必须在 Git 仓库中运行。 + +```bash +copaper --root <target-project> commit --phase storyline -m "完成研究主线初稿" +copaper --root <target-project> diff storyline literature +copaper --root <target-project> rollback storyline +``` + +回滚会影响工作区状态,使用前先确认当前改动是否需要保存。 + +###### Readiness 与 Phase 管理 +Readiness 和 phase 更新也不是单独写作阶段,而是贯穿流程的状态管理动作。CoPaper 的状态更新应通过 CLI 或插件工具完成,不手改 `.agents/state.json`。当某个工件达到可用状态时,先查看证据,再显式确认记录 readiness;当一个阶段完成、跳过或回退时,再确认修改 phase。 + +```text +/copaper +请检查 artifact readiness +确认记录 paper.md 为 partial,confidence 为 medium,原因是 Introduction 已完成但 Evaluation 未写 +确认把 writing 阶段标记为 in_progress +``` + +CLI 等价操作: + +```bash +copaper --root <target-project> set-phase writing --status in_progress +copaper --root <target-project> log --last 10 +copaper --root <target-project> report --output report.md +``` + +在 OpenCode 中,推荐触发 `copaper-manage` 或直接说明“把某个 phase 标记为某状态”。agent 应先复述 phase、status 和 reason,并等待确认后调用 `copaper_workflow_set_phase`;这比让 agent 手改状态文件更安全。 + +###### Step 1:初始化论文项目 +新项目先创建 CoPaper 核心工件。CLI 会复制 `storyline.md`、`paper.md`、`writingrules.md`、`AGENTS.md` 和 `.agents/skills/`;插件初始化流程会先展示预览,并在用户明确确认后写入核心文件。 + +```bash +copaper --root <target-project> init --name "<project-name>" --domain "<research-domain>" +copaper --root <target-project> status +``` + +在 OpenCode 中可以打开 `/copaper` 查看 Dashboard。如果 Dashboard 显示项目未 ready,按提示确认初始化;如果已有文件冲突,先人工决定保留、迁移或换目录,避免覆盖已有研究材料。 + +初始化时也可以从已有材料导入项目,而不是从空模板开始。`ppt2storyline` 可以把组会 PPT/PPTX 转成 `storyline.md`;`pdf2paper` 可以把已有 PDF 初稿映射到 `paper.md`;`latex2markdown` 可以把已有 LaTeX 论文迁移到 markdown 框架。导入时仍要遵守“不发明新 claim”的原则,只做忠实映射和轻量润色。 + +```text +将这个 PPTX 提取为 storyline.md,但不要新增 slides 中没有的 claim +将这个 PDF 初稿导入到 paper.md,并保留原有论点边界 +将这份 LaTeX 论文迁移到 CoPaper 的 paper.md 结构 +``` + +如果导入生成的是 `storyline.md`,可以跳过 Step 2 的空白主线填写,检查并确认主线后直接进入 Step 3 相关工作流程。如果导入生成的是完整或接近完整的 `paper.md`,可以先补齐必要的 storyline/relatedwork 证据,然后直接进入 Step 7 审阅、修订和 checker 记录流程。 + +###### Step 2:填写研究主线 +优先完成 `storyline.md`,它是后续文献检索、讨论、实验和写作的最高约束。推荐调用 `@copaper-storyline` 或触发 `storyline-helper`,按章节提供你的问题、重要性、insight、设计思路和评测计划。这个阶段的原则是:agent 可以润色和组织,但不替你发明研究内容。 + +```text +@copaper-storyline 帮我填写 storyline.md 的问题描述部分 +``` + +完成后检查结构状态,并在确认后记录阶段进度: + +```text +/copaper +请检查 storyline 结构完成度 +确认把 storyline 阶段标记为 complete,原因是主线初稿已完成 +``` + +###### Step 3:检索和整理相关工作 +literature 阶段把 `storyline.md` 或 `paper.md` 转成检索关键词,搜索论文,导入元数据,同步 BibTeX,下载 PDF,生成单篇摘要,并构建 `.agents/cross_index.json`。插件中可交给 `@copaper-literature`;CLI 中可按 7 步流水线执行。 + +```bash +copaper --root <target-project> relatedwork keywords --count 6 +copaper --root <target-project> relatedwork search --queries-file relatedwork/queries.txt --limit 5 +copaper --root <target-project> relatedwork import --input relatedwork/search_cache.json +copaper --root <target-project> relatedwork sync-bib +copaper --root <target-project> relatedwork download +copaper --root <target-project> relatedwork summarize --concurrency 4 +copaper --root <target-project> relatedwork build-index +copaper --root <target-project> relatedwork status +``` + +关键词和摘要依赖 OpenAI 兼容 LLM;搜索依赖 Semantic Scholar / arXiv。建议先用小 `limit` smoke test,确认 `.env`、网络和 `copaper` bridge 都正常,再扩大检索规模。 + +###### Step 4:讨论并收敛论证 +discussion 阶段用 `socratic-discussion` 压测研究问题、novelty、技术深度、逻辑链、清晰度、评估协议和数据证据。这个阶段不是写论文,而是把可能被审稿人质疑的点提前暴露出来,并反向修正 `storyline.md` 或实验计划。 + +```text +帮我做一次 socratic discussion,重点检查 novelty 和 technical depth +``` + +如果讨论发现主线缺口,回到 `storyline-helper` 修改;如果发现缺实验或证据,进入实验分析;如果只是表达问题,留到 writing/review 阶段处理。 + +###### Step 5:准备实验或说明跳过 +experiments 阶段可以用 `experiment-analyzer` 理解实验代码、分析结果、审查实验协议,或在理论/系统设计类论文中明确跳过并记录原因。不要把 placeholder data 当真实结果;如需占位,必须使用 `bogus-data-helper` 并明确标记为 synthetic。 + +```text +帮我分析 experiments/ 中的结果,并映射到 paper.md 的 RQ +``` + +跳过实验时用完整 phase 名: + +```bash +copaper --root <target-project> skip experiments --reason "<reason>" +``` + +###### Step 6:撰写 paper.md +writing 阶段围绕 `paper.md` 展开。推荐先用 `writing-orchestrator` 扫描完成度和推荐顺序,再选择写作模式:`markdown-helper` 适合稳妥逐节写,`state-machine-markdown-helper` 适合高保真逐段写,`mad-writer` 适合快速生成和迭代。插件里可使用 `@copaper-writer`,它只应修改 `paper.md`。 + +```text +@copaper-writer 请根据 storyline.md 和 cross_index,先写 Introduction 的第一个 Level 5 section +``` + +写作时必须遵守 CoPaper 结构:Level 1-5 只做结构标题,正文只能写在 Level 6 下;Level 6 标题不超过 50 字符,正文段落不超过 500 字符。涉及文献时优先读 `.agents/cross_index.json`,再定向读取 `relatedwork/papers/*.md`。 + +###### Step 7:审阅、修订和记录 checker +写完一个章节后运行审阅流程。`@copaper-reviewer` 和各类 checker 负责发现问题,`review-revise` 负责按 Critical、Major、Minor 顺序逐项确认和修复。需要持久记录 checker 结果时,让 `@copaper-recorder` 在复述 checker、status、计数、summary、evidence 和 reason 后调用记录工具。 + +```text +@copaper-reviewer 请检查当前 paper.md 的 problem、novelty 和 logic 风险 +``` + +最终投稿前运行 `submission-precheck`,它会检查格式、引用、图表、字数、完整性、数据真实性和整体质量,并生成预检报告。 + +###### Step 8:生成 LaTeX 终稿 +已有材料的导入入口放在 Step 1 初始化阶段。论文成形并通过必要审阅后,最后一步使用 `latex-final-writer` 生成 LaTeX 终稿。该 skill 会基于已完成的 `paper.md`、`storyline.md`、相关工作摘要、实验材料和用户提供的会议/期刊模板,创建或更新 `writing_plan.md`,初始化 `tex/` 结构,并逐节写作可投稿的 LaTeX 草稿。 + +```text +我已经完成 paper.md,请基于 tex/ 模板使用 latex-final-writer 生成 LaTeX 终稿 +``` + +生成终稿时不要凭空新增实验、数字、引用或 claim。完成后应编译 LaTeX,并人工核对引用、图表、公式、页数、匿名要求、overfull boxes 和未定义引用。 + +###### 推荐完整路径 +最稳妥的完整路径是:安装插件和 CLI → 初始化项目或导入已有材料 → 完成/确认 `storyline.md` → 跑 relatedwork → 做 Socratic discussion → 准备实验或记录跳过原因 → 写/导入 `paper.md` → 逐节 checker/review-revise → submission precheck → 使用 `latex-final-writer` 生成 LaTeX 终稿。PPT 导入主线后可从 Step 3 继续;已有论文导入 `paper.md` 后可从 Step 7 继续。每个阶段都可以重入;如果后面发现前面有缺口,回到对应 skill 修正即可。 + +```text +初始化 → 主线 → 文献 → 讨论 → 实验/跳过 → 写作 → 审阅修订 → 预检 → LaTeX 终稿 +``` + +###### 常见注意事项 +`--root` 是 CLI 全局选项,必须放在子命令前。phase 名称必须使用 `storyline`、`literature`、`discussion`、`experiments`、`writing`、`latex_review`。插件中只读工具不会写文件;写盘工具通常要求先复述参数并等待明确确认。`.env` 存放密钥,不要提交。不要直接修改 `.agents/state.json` 或 `.agents/events.jsonl`,除非你是在调试底层实现。 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..4df33c5 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +mkdocs-material>=9.5 diff --git a/docs/superpowers/specs/2026-05-01-opencode-dashboard-guided-init-design.md b/docs/superpowers/specs/2026-05-01-opencode-dashboard-guided-init-design.md index 351572a..7896b70 100644 --- a/docs/superpowers/specs/2026-05-01-opencode-dashboard-guided-init-design.md +++ b/docs/superpowers/specs/2026-05-01-opencode-dashboard-guided-init-design.md @@ -5,7 +5,7 @@ <!-- description: 本阶段目标 --> ###### 中文优先的项目入口 -下一阶段将 `/vibe` 从安装状态面板升级为中文优先的项目入口。它回答三个问题:当前工作区是否 VibePaper-ready、缺少什么、下一步可以安全做什么。 +下一阶段将 `/copaper` 从安装状态面板升级为中文优先的项目入口。它回答三个问题:当前工作区是否 CoPaper-ready、缺少什么、下一步可以安全做什么。 ###### 只读优先的初始化预览 本阶段只展示初始化计划,不实际创建 `paper.md`、`storyline.md`、`.agents/state.json` 等文件。所有写入动作留给后续独立确认流程。 @@ -14,10 +14,10 @@ <!-- description: 必须实现的能力 --> ###### 默认中文输出 -`/vibe`、`/vibe-doctor`、CLI 文本输出、doctor 文本和 README 默认使用 `zh-CN`。命令名、工具名、JSON 字段名保持英文,避免破坏 OpenCode 调用和自动化解析。 +`/copaper`、`/copaper-doctor`、CLI 文本输出、doctor 文本和 README 默认使用 `zh-CN`。命令名、工具名、JSON 字段名保持英文,避免破坏 OpenCode 调用和自动化解析。 ###### 多语言接口 -CLI 支持 `--locale zh-CN|en-US`,并读取 `VIBEPAPER_LANG=zh-CN|en-US`。默认语言为 `zh-CN`。未来可从 OpenCode config 中读取 locale。 +CLI 支持 `--locale zh-CN|en-US`,并读取 `COPAPER_LANG=zh-CN|en-US`。默认语言为 `zh-CN`。未来可从 OpenCode config 中读取 locale。 ###### 项目就绪度模型 Dashboard 展示 OpenCode 集成状态、核心文件状态、状态文件状态、命令文件状态和可选 `relatedwork/` 状态。状态枚举保持稳定英文值。 @@ -32,7 +32,7 @@ Dashboard 在项目未初始化时展示 init preview。预览列出路径、动 本阶段不实际创建或修改 `paper.md`、`storyline.md`、`writingrules.md`、`.agents/state.json`、`.agents/events.jsonl`、`AGENTS.md` 或 `relatedwork/`。 ###### 不做阶段编排 -本阶段不推进 VibePaper 阶段,不写工作流状态,不调用子代理,不执行文献下载或索引构建。 +本阶段不推进 CoPaper 阶段,不写工作流状态,不调用子代理,不执行文献下载或索引构建。 ###### 不做复杂 UI OpenCode 插件仍返回结构化 Markdown。浏览器 mockup 只用于讨论信息层级,不进入产品实现。 @@ -40,11 +40,11 @@ OpenCode 插件仍返回结构化 Markdown。浏览器 mockup 只用于讨论信 ## Product Behavior <!-- description: 用户可见行为 --> -###### `/vibe` 主入口 -`/vibe` 调用 `vibepaper_dashboard` 工具并显示中文 Dashboard。它优先展示一个推荐动作,而不是给出多个同级选择。 +###### `/copaper` 主入口 +`/copaper` 调用 `copaper_dashboard` 工具并显示中文 Dashboard。它优先展示一个推荐动作,而不是给出多个同级选择。 -###### `/vibe-doctor` 诊断入口 -`/vibe-doctor` 保持安装诊断职责,但默认输出中文。它仍用于确认 OpenCode config、插件入口和 slash command 是否正常。 +###### `/copaper-doctor` 诊断入口 +`/copaper-doctor` 保持安装诊断职责,但默认输出中文。它仍用于确认 OpenCode config、插件入口和 slash command 是否正常。 ###### Dashboard 五段结构 Dashboard 输出固定为 Header、Readiness Summary、Checklist、Recommended Next Step、Init Preview。末尾保留 JSON block,供 agent 稳定解析。 @@ -56,10 +56,10 @@ Dashboard 输出固定为 Header、Readiness Summary、Checklist、Recommended N <!-- description: 模块拆分 --> ###### `doctor.ts` -继续只负责 OpenCode 集成健康检查,包括 config、插件入口、命令文件和受管标记。它不读取 VibePaper 项目文件。 +继续只负责 OpenCode 集成健康检查,包括 config、插件入口、命令文件和受管标记。它不读取 CoPaper 项目文件。 ###### `readiness.ts` -新增只读模块,检查 VibePaper 项目文件状态。它返回核心文件、状态文件、可选目录和冲突信息,不写入磁盘。 +新增只读模块,检查 CoPaper 项目文件状态。它返回核心文件、状态文件、可选目录和冲突信息,不写入磁盘。 ###### `init-preview.ts` 新增只读模块,生成初始化计划。计划动作包括 `create`、`exists-managed`、`exists-user`、`conflict`、`optional`。 @@ -74,7 +74,7 @@ Dashboard 输出固定为 Header、Readiness Summary、Checklist、Recommended N <!-- description: Dashboard 构建流程 --> ###### 工具调用路径 -`vibepaper_dashboard` 接收 OpenCode 的 `directory` 和 `worktree`,调用 root detection,然后执行 doctor、readiness、init preview,最后渲染 Dashboard。 +`copaper_dashboard` 接收 OpenCode 的 `directory` 和 `worktree`,调用 root detection,然后执行 doctor、readiness、init preview,最后渲染 Dashboard。 ###### 模型分层 Dashboard model 包含 `integration`、`readiness`、`initPreview`、`recommendation`、`locale`、`schemaVersion`。各层可独立测试。 @@ -92,7 +92,7 @@ JSON 字段名和枚举值保持英文,例如 `ready`、`missing`、`conflict` 检查 `.agents/state.json` 是否存在且可解析为 JSON object。检查 `.agents/events.jsonl` 是否存在且为普通文件。缺失标记为 `missing`。 ###### 指导文件 -检查 `AGENTS.md` 是否存在。若存在但没有明显 VibePaper 指引,标记为 `exists-user` 或 `needs-review`,不自动覆盖。 +检查 `AGENTS.md` 是否存在。若存在但没有明显 CoPaper 指引,标记为 `exists-user` 或 `needs-review`,不自动覆盖。 ###### 文献目录 `relatedwork/` 第一版作为 optional readiness。缺失不阻塞 ready 的核心判断,但 Dashboard 可以提示后续可初始化。 @@ -104,7 +104,7 @@ JSON 字段名和枚举值保持英文,例如 `ready`、`missing`、`conflict` 第一版预览 `paper.md`、`storyline.md`、`writingrules.md`、`.agents/state.json`、`.agents/events.jsonl` 和 `AGENTS.md`。`relatedwork/` 只作为 optional。 ###### 冲突策略 -如果目标路径存在且不是 VibePaper 管理的安全目标,预览标记为 `exists-user` 或 `conflict`。本阶段不覆盖用户文件。 +如果目标路径存在且不是 CoPaper 管理的安全目标,预览标记为 `exists-user` 或 `conflict`。本阶段不覆盖用户文件。 ###### 输出表格 预览表格包含 `Path`、`Action`、`Reason`。中文渲染中列名和 reason 本地化,JSON 中保留英文枚举。 @@ -116,10 +116,10 @@ JSON 字段名和枚举值保持英文,例如 `ready`、`missing`、`conflict` 默认 locale 为 `zh-CN`。缺省 CLI、doctor、Dashboard、slash command 模板、README 都使用中文。 ###### 英文兼容 -`--locale en-US` 和 `VIBEPAPER_LANG=en-US` 输出英文文本。测试应覆盖至少一个英文 doctor 或 Dashboard 快照。 +`--locale en-US` 和 `COPAPER_LANG=en-US` 输出英文文本。测试应覆盖至少一个英文 doctor 或 Dashboard 快照。 ###### Slash command 更新 -受管 `.opencode/commands/vibe.md` 与 `vibe-doctor.md` 默认生成中文提示。切换 locale 后需要重新运行 `init` 刷新受管命令。 +受管 `.opencode/commands/copaper.md` 与 `copaper-doctor.md` 默认生成中文提示。切换 locale 后需要重新运行 `init` 刷新受管命令。 ## Error Handling <!-- description: 失败和异常规则 --> @@ -143,19 +143,19 @@ readiness 或 preview 遇到不可读路径、目录占位、JSON 解析错误 新增 Dashboard 渲染测试,覆盖未初始化项目、已初始化项目、OpenCode 集成损坏项目,以及 `zh-CN` 与 `en-US` 输出。 ###### CLI 回归 -现有 CLI 测试扩展 `--locale` 和 `VIBEPAPER_LANG`。JSON 输出测试确认字段名和枚举不随语言改变。 +现有 CLI 测试扩展 `--locale` 和 `COPAPER_LANG`。JSON 输出测试确认字段名和枚举不随语言改变。 ###### Smoke 文档 -更新中文使用测试文档,说明 `/vibe` 的 readiness 和 init preview 预期行为。 +更新中文使用测试文档,说明 `/copaper` 的 readiness 和 init preview 预期行为。 ## Acceptance Criteria <!-- description: 完成判定 --> ###### 中文用户可理解 -新用户运行 `/vibe` 后,可以用中文看懂当前项目是否 ready、缺少哪些文件、下一步应预览初始化。 +新用户运行 `/copaper` 后,可以用中文看懂当前项目是否 ready、缺少哪些文件、下一步应预览初始化。 ###### Dashboard 保持只读 -运行 `/vibe` 不创建、不修改、不删除任何文件。测试通过目录 hash 或文件快照证明只读。 +运行 `/copaper` 不创建、不修改、不删除任何文件。测试通过目录 hash 或文件快照证明只读。 ###### Preview 可复用 init preview 生成的计划模型可被未来 apply 命令复用,不把渲染文案和写入计划耦合在一起。 diff --git a/docs/superpowers/specs/2026-05-01-opencode-init-apply-design.md b/docs/superpowers/specs/2026-05-01-opencode-init-apply-design.md index 71d1e07..4e33b0b 100644 --- a/docs/superpowers/specs/2026-05-01-opencode-init-apply-design.md +++ b/docs/superpowers/specs/2026-05-01-opencode-init-apply-design.md @@ -5,7 +5,7 @@ <!-- description: 本阶段目标 --> ###### 从预览到显式写入 -本阶段将 `/vibe` 的初始化预览扩展为显式确认后的项目初始化写入。用户先看到 readiness 和 init preview,再通过对话确认并提供 `name`、`domain`,最后由 OpenCode 插件内置 apply 工具创建核心 VibePaper 文件。 +本阶段将 `/copaper` 的初始化预览扩展为显式确认后的项目初始化写入。用户先看到 readiness 和 init preview,再通过对话确认并提供 `name`、`domain`,最后由 OpenCode 插件内置 apply 工具创建核心 CoPaper 文件。 ###### 保持安全闭环 第一版只写 Dashboard preview 已列出的核心文件,不创建 `.agents/skills/` 或 `relatedwork/`。遇到任何用户文件冲突时整体中止,避免半初始化和误覆盖。 @@ -14,16 +14,16 @@ <!-- description: 必须实现的能力 --> ###### 对话式确认初始化 -用户在 `/vibe` 后说“确认初始化”才进入写入流程。若缺少项目 `name` 或 `domain`,OpenCode 先用中文追问,参数齐全后才调用 apply 工具。 +用户在 `/copaper` 后说“确认初始化”才进入写入流程。若缺少项目 `name` 或 `domain`,OpenCode 先用中文追问,参数齐全后才调用 apply 工具。 ###### 插件内置写入 -`@vibepaper/opencode` 内置精简初始化模板和完整 `DEFAULT_STATE` 等价结构。第一版不依赖 Python CLI,也不要求目标机器已安装 Python 版 `vibe` 命令。 +`@copaper/opencode` 内置精简初始化模板和完整 `DEFAULT_STATE` 等价结构。第一版不依赖 Python CLI,也不要求目标机器已安装 Python 版 `copaper` 命令。 ###### 非破坏性文件创建 apply 只创建缺失的核心文件。任何目标路径存在且不是安全缺失状态时,apply 整体中止,不覆盖、不备份、不部分继续。 ###### 成功后 ready -初始化成功后,重新运行 `/vibe` 应显示项目 ready。Dashboard 后续只提示 workflow 入口,不在本阶段推进 phase 或调用子代理。 +初始化成功后,重新运行 `/copaper` 应显示项目 ready。Dashboard 后续只提示 workflow 入口,不在本阶段推进 phase 或调用子代理。 ## Non-Goals <!-- description: 本阶段明确不做的内容 --> @@ -43,14 +43,14 @@ apply 只创建缺失的核心文件。任何目标路径存在且不是安全 ## Product Behavior <!-- description: 用户可见行为 --> -###### `/vibe` 主入口延续 -`/vibe` 继续先显示中文 Dashboard。若状态为 `needs-init`,模板提示用户可以说“确认初始化”,并说明需要项目名称和研究领域。 +###### `/copaper` 主入口延续 +`/copaper` 继续先显示中文 Dashboard。若状态为 `needs-init`,模板提示用户可以说“确认初始化”,并说明需要项目名称和研究领域。 ###### 参数收集 -用户确认初始化但未提供 `name` 或 `domain` 时,agent 先追问缺失参数。工具参数齐全前不得调用 `vibepaper_init_apply`。 +用户确认初始化但未提供 `name` 或 `domain` 时,agent 先追问缺失参数。工具参数齐全前不得调用 `copaper_init_apply`。 ###### Apply 成功输出 -apply 成功后返回中文摘要、写入文件列表、跳过文件列表、稳定 JSON block 和下一步建议。下一步建议为重新运行 `/vibe` 查看 ready 状态。 +apply 成功后返回中文摘要、写入文件列表、跳过文件列表、稳定 JSON block 和下一步建议。下一步建议为重新运行 `/copaper` 查看 ready 状态。 ###### Apply 失败输出 apply 失败时返回中文错误摘要、冲突路径或文件系统错误、稳定 JSON block 和恢复建议。冲突失败不得写入任何目标文件。 @@ -68,10 +68,10 @@ apply 失败时返回中文错误摘要、冲突路径或文件系统错误、 扩展为 preview 与 apply 共享的目标集合来源。preview 继续只读;apply 使用同一文件集合决定可创建目标,避免预览和实际写入不一致。 ###### `index.ts` -新增 OpenCode 工具 `vibepaper_init_apply`。工具参数为 `name` 和 `domain`,使用 OpenCode 提供的 `directory`、`worktree` 做 root detection 后执行 apply。 +新增 OpenCode 工具 `copaper_init_apply`。工具参数为 `name` 和 `domain`,使用 OpenCode 提供的 `directory`、`worktree` 做 root detection 后执行 apply。 ###### `templates.ts` -更新 `/vibe` slash command 模板。模板必须说明确认门槛、参数追问、只在明确确认后调用 apply 工具,以及不要编造初始化结果。 +更新 `/copaper` slash command 模板。模板必须说明确认门槛、参数追问、只在明确确认后调用 apply 工具,以及不要编造初始化结果。 ## Data Model <!-- description: 结构化返回模型 --> @@ -92,10 +92,10 @@ apply 工具的 JSON 字段名和枚举值保持英文。中文摘要只出现 <!-- description: 第一版写入文件集合 --> ###### 核心文档 -第一版创建 `paper.md`、`storyline.md` 和 `writingrules.md`。内容为插件内置精简模板,满足后续 VibePaper workflow 识别和人工继续编辑。 +第一版创建 `paper.md`、`storyline.md` 和 `writingrules.md`。内容为插件内置精简模板,满足后续 CoPaper workflow 识别和人工继续编辑。 ###### 指导文件 -第一版创建 `AGENTS.md`,内容说明当前项目是 VibePaper 项目、建议使用 `/vibe` 查看状态、使用 VibePaper CLI 或后续 OpenCode 入口推进流程。 +第一版创建 `AGENTS.md`,内容说明当前项目是 CoPaper 项目、建议使用 `/copaper` 查看状态、使用 CoPaper CLI 或后续 OpenCode 入口推进流程。 ###### 状态文件 第一版创建 `.agents/state.json`,结构与 Python `DEFAULT_STATE` 等价。它填入 `project.name`、`project.domain`、`project.created_at`,并保留 `current_phase: "storyline"`。 @@ -125,7 +125,7 @@ apply 前必须重新运行 readiness,不信任旧 Dashboard preview。用户 工具收到缺失或空白 `name`、`domain` 时返回结构化错误,不写文件。slash command 模板要求 agent 在调用工具前追问缺失参数。 ###### 集成损坏 -OpenCode 集成损坏不阻止项目初始化写入。apply 结果可以提示用户运行 `/vibe-doctor` 修复插件安装,但项目文件写入只依赖 root 和磁盘安全检查。 +OpenCode 集成损坏不阻止项目初始化写入。apply 结果可以提示用户运行 `/copaper-doctor` 修复插件安装,但项目文件写入只依赖 root 和磁盘安全检查。 ###### 模板错误 模板生成失败应作为内部错误返回。错误摘要不得建议用户手动编辑 `.agents/state.json`,只建议重新运行或提交 issue。 @@ -146,22 +146,22 @@ OpenCode 集成损坏不阻止项目初始化写入。apply 结果可以提示 测试 apply 成功后 readiness 从 `needs-init` 变为 `ready`。测试 `relatedwork/` 仍为 optional,`.agents/skills/` 不参与 ready 判定。 ###### 工具测试 -测试 `vibepaper_init_apply` 的参数 schema、成功 Markdown、冲突 Markdown、稳定 JSON block 和不会在未确认路径中被 `/vibe` 自动调用。 +测试 `copaper_init_apply` 的参数 schema、成功 Markdown、冲突 Markdown、稳定 JSON block 和不会在未确认路径中被 `/copaper` 自动调用。 ###### 文档测试 -更新中文使用测试文档,新增确认初始化、参数追问、冲突中止和成功后 `/vibe` ready 的手动 smoke 步骤。 +更新中文使用测试文档,新增确认初始化、参数追问、冲突中止和成功后 `/copaper` ready 的手动 smoke 步骤。 ## Acceptance Criteria <!-- description: 完成判定 --> ###### OpenCode 内闭环 -用户能从 `/vibe` 看到初始化预览,通过对话确认并提供 `name`、`domain`,再由插件内 apply 创建核心 VibePaper 项目文件。 +用户能从 `/copaper` 看到初始化预览,通过对话确认并提供 `name`、`domain`,再由插件内 apply 创建核心 CoPaper 项目文件。 ###### 非破坏性保证 已有用户文件冲突时 apply 整体中止,并且目录 hash 或文件快照证明没有写入任何目标文件。 ###### Ready 状态达成 -成功 apply 后,重新运行 `/vibe` 显示 `ready` 语义,核心文件和状态文件检查通过,JSON block 保持英文稳定字段。 +成功 apply 后,重新运行 `/copaper` 显示 `ready` 语义,核心文件和状态文件检查通过,JSON block 保持英文稳定字段。 ###### 范围保持克制 成功 apply 不创建 `.agents/skills/` 或 `relatedwork/`,不推进 phase,不写 event log 事件,不调用子代理。 diff --git a/docs/superpowers/specs/2026-05-01-opencode-workflow-tools-design.md b/docs/superpowers/specs/2026-05-01-opencode-workflow-tools-design.md index 5cf3720..7fd5d62 100644 --- a/docs/superpowers/specs/2026-05-01-opencode-workflow-tools-design.md +++ b/docs/superpowers/specs/2026-05-01-opencode-workflow-tools-design.md @@ -5,7 +5,7 @@ <!-- description: 本阶段目标 --> ###### 从初始化到工作流 cockpit -本阶段将 `/vibe` 从初始化入口扩展为 post-init 工作流 cockpit。项目 ready 后,用户可以查看当前 workflow 状态、最近事件,并在明确确认后修改 phase status。 +本阶段将 `/copaper` 从初始化入口扩展为 post-init 工作流 cockpit。项目 ready 后,用户可以查看当前 workflow 状态、最近事件,并在明确确认后修改 phase status。 ###### 保持 workflow schema 可演进 当前 `.agents/state.json` 仍使用现有 6-phase preset,但 OpenCode workflow tools 不写死 phase 数量、名称、顺序或依赖关系。工具从 state 动态读取 phase,并为未来可变 phase graph 预留读取能力。 @@ -14,16 +14,16 @@ <!-- description: 必须实现的能力 --> ###### 动态 workflow 状态 -`vibepaper_workflow_status` 读取 `.agents/state.json`,展示 `current_phase`、所有 `state.phases` 条目、状态摘要、可选 workflow metadata 和下一步建议。phase 列表来自实际 state,而不是 TypeScript 固定枚举。 +`copaper_workflow_status` 读取 `.agents/state.json`,展示 `current_phase`、所有 `state.phases` 条目、状态摘要、可选 workflow metadata 和下一步建议。phase 列表来自实际 state,而不是 TypeScript 固定枚举。 ###### 事件日志查询 -`vibepaper_workflow_log` 读取 `.agents/events.jsonl`,支持最近事件、phase 过滤和 operator 过滤。日志查询不要求 phase 属于固定集合,只按事件中的 `phase` 字段匹配。 +`copaper_workflow_log` 读取 `.agents/events.jsonl`,支持最近事件、phase 过滤和 operator 过滤。日志查询不要求 phase 属于固定集合,只按事件中的 `phase` 字段匹配。 ###### 显式确认阶段控制 -`vibepaper_workflow_set_phase` 在用户明确确认后修改指定 phase 的 status,重新计算 `current_phase`,并追加一条 Python `EventLogger` 兼容 JSONL 事件。 +`copaper_workflow_set_phase` 在用户明确确认后修改指定 phase 的 status,重新计算 `current_phase`,并追加一条 Python `EventLogger` 兼容 JSONL 事件。 ###### Dashboard ready 后增强 -项目 ready 后,`/vibe` 显示 workflow status、phase table、最近事件和推荐下一步。项目未 ready 时,Dashboard 继续优先展示初始化预览,不暴露复杂 workflow 操作。 +项目 ready 后,`/copaper` 显示 workflow status、phase table、最近事件和推荐下一步。项目未 ready 时,Dashboard 继续优先展示初始化预览,不暴露复杂 workflow 操作。 ## Non-Goals <!-- description: 本阶段明确不做的内容 --> @@ -44,22 +44,22 @@ <!-- description: 用户可见行为 --> ###### Ready Dashboard -当 readiness 为 `ready` 时,`/vibe` 增加 workflow 区块:当前 phase、phase 状态表、最近事件和建议动作。建议动作使用实际 `current_phase`,不写死 `storyline`、`literature` 等 phase 名。 +当 readiness 为 `ready` 时,`/copaper` 增加 workflow 区块:当前 phase、phase 状态表、最近事件和建议动作。建议动作使用实际 `current_phase`,不写死 `storyline`、`literature` 等 phase 名。 ###### 状态查看 -用户询问“当前进度”“现在是什么阶段”时,agent 调用 `vibepaper_workflow_status`。输出默认中文摘要,并附稳定 JSON block 供自动化解析。 +用户询问“当前进度”“现在是什么阶段”时,agent 调用 `copaper_workflow_status`。输出默认中文摘要,并附稳定 JSON block 供自动化解析。 ###### 日志查看 -用户询问“最近发生了什么”或“某个 phase 的记录”时,agent 调用 `vibepaper_workflow_log`。默认返回最近 5 条事件,用户可要求更多或指定 phase/operator。 +用户询问“最近发生了什么”或“某个 phase 的记录”时,agent 调用 `copaper_workflow_log`。默认返回最近 5 条事件,用户可要求更多或指定 phase/operator。 ###### 阶段修改 -用户明确要求修改 phase 后,agent 必须确认目标 `phase` 和 `status`。若 status 为 `skipped`,还必须获得 `reason`。参数齐全且用户确认后,才调用 `vibepaper_workflow_set_phase`。 +用户明确要求修改 phase 后,agent 必须确认目标 `phase` 和 `status`。若 status 为 `skipped`,还必须获得 `reason`。参数齐全且用户确认后,才调用 `copaper_workflow_set_phase`。 ## Workflow State Compatibility <!-- description: 当前 preset 与未来 schema 的关系 --> ###### 当前 preset 保留 -`vibepaper_init_apply` 继续创建当前 Python `DEFAULT_STATE` 等价结构,包括 `storyline`、`literature`、`discussion`、`experiments`、`writing` 和 `latex_review`。这是默认数据,不是 OpenCode workflow tools 的逻辑边界。 +`copaper_init_apply` 继续创建当前 Python `DEFAULT_STATE` 等价结构,包括 `storyline`、`literature`、`discussion`、`experiments`、`writing` 和 `latex_review`。这是默认数据,不是 OpenCode workflow tools 的逻辑边界。 ###### Phase 动态读取 Workflow tools 使用 `Object.keys(state.phases)` 作为 phase ID 集合。每个 phase 的对象只要求可读取 `status` 和 `completed_at`;其他字段按原样保留并在写入时不删除。 @@ -76,13 +76,13 @@ Workflow tools 使用 `Object.keys(state.phases)` 作为 phase ID 集合。每 ## Tool Design <!-- description: OpenCode 工具边界 --> -###### `vibepaper_workflow_status` +###### `copaper_workflow_status` 该工具只读 state。参数为空。返回 `schemaVersion`、`ok`、`root`、`currentPhase`、`phases`、`summary`、`workflowMetadata`、`warnings`、`recommendation` 和 `locale`。 -###### `vibepaper_workflow_log` +###### `copaper_workflow_log` 该工具只读 event log。参数为 `lastN`、`phase` 和 `operator`,均可选。`lastN` 默认 5,最大 50。operator 只接受 `user`、`ai` 或 `system`;phase 作为普通字符串过滤。 -###### `vibepaper_workflow_set_phase` +###### `copaper_workflow_set_phase` 该工具写 state 和 event log。参数为必需 `phase`、必需 `status`、可选 `reason`。status 支持 `not_started`、`in_progress`、`complete` 和 `skipped`。 ###### ToolContext root @@ -122,7 +122,7 @@ Workflow tools 使用 `Object.keys(state.phases)` 作为 phase ID 集合。每 写工具先校验 state 和 event log 目标路径可用,再原子写 state,最后 append event。若 event append 失败,工具返回结构化错误并说明 state 是否已写入。第一版不自动回滚 state。 ## Dashboard Integration -<!-- description: `/vibe` 展示变化 --> +<!-- description: `/copaper` 展示变化 --> ###### 未 ready 优先初始化 readiness 为 `needs-init` 或 `blocked` 时,Dashboard 行为保持现状:展示 readiness、init preview、冲突说明和初始化建议,不显示 phase 控制建议。 @@ -131,13 +131,13 @@ readiness 为 `needs-init` 或 `blocked` 时,Dashboard 行为保持现状: readiness 为 `ready` 时,Dashboard 增加 `Workflow` 区块。该区块展示当前 phase、phase 表、最近事件和下一步建议,例如“确认后可将当前 phase 设为 `in_progress`”。 ###### 模板确认门槛 -`/vibe` slash command 模板必须说明:修改 phase 是写操作,必须先复述目标 phase/status/reason 并等待用户确认。未确认前不得调用 `vibepaper_workflow_set_phase`。 +`/copaper` slash command 模板必须说明:修改 phase 是写操作,必须先复述目标 phase/status/reason 并等待用户确认。未确认前不得调用 `copaper_workflow_set_phase`。 ## Error Handling <!-- description: 失败和异常规则 --> ###### Missing state -如果 `.agents/state.json` 不存在,workflow tools 返回 `needs-init` 风格错误,建议先运行 `/vibe` 完成初始化写入。 +如果 `.agents/state.json` 不存在,workflow tools 返回 `needs-init` 风格错误,建议先运行 `/copaper` 完成初始化写入。 ###### Invalid state 如果 state 不是 JSON object、缺少 `phases` object 或 phase 对象不可解释,status/log 可返回 blocked 摘要,set phase 必须拒绝写入。 @@ -188,7 +188,7 @@ log 查询在 `.agents/events.jsonl` 不存在时返回空事件列表和 warnin <!-- description: 完成判定 --> ###### Post-init 闭环 -用户完成 init apply 后,可以在 `/vibe` 中看到 workflow 状态、当前 phase、最近事件和可确认执行的下一步 phase 操作。 +用户完成 init apply 后,可以在 `/copaper` 中看到 workflow 状态、当前 phase、最近事件和可确认执行的下一步 phase 操作。 ###### Schema 不锁死 测试证明工具能处理非默认 phase 名称、额外 phase 数量、未来 workflow metadata 和循环 dependencies。实现中不应出现固定 phase 名称驱动的 workflow 逻辑。 diff --git a/docs/superpowers/specs/2026-05-02-opencode-artifact-cockpit-design.md b/docs/superpowers/specs/2026-05-02-opencode-artifact-cockpit-design.md index 5ad075a..6107420 100644 --- a/docs/superpowers/specs/2026-05-02-opencode-artifact-cockpit-design.md +++ b/docs/superpowers/specs/2026-05-02-opencode-artifact-cockpit-design.md @@ -5,7 +5,7 @@ <!-- description: 本阶段目标 --> ###### 从 phase cockpit 到 artifact cockpit -本阶段将 `/vibe` 从 phase 状态视图扩展为 artifact cockpit。项目 ready 后,用户可以看到 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/` 和 checker 结果是否真正可用。 +本阶段将 `/copaper` 从 phase 状态视图扩展为 artifact cockpit。项目 ready 后,用户可以看到 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/` 和 checker 结果是否真正可用。 ###### 判断材料而不是自动推进 Artifact cockpit 只暴露证据、风险和建议,不自动推进 phase,不运行 relatedwork,不安装 skills,也不运行 checker。它为后续纵向能力提供判断基础。 @@ -14,13 +14,13 @@ Artifact cockpit 只暴露证据、风险和建议,不自动推进 phase,不 <!-- description: 必须实现的能力 --> ###### 统一 artifact 状态 -`vibepaper_artifact_status` 读取项目中的关键工件,并为每个工件返回 `missing`、`template`、`partial`、`ready`、`stale` 或 `unknown`。 +`copaper_artifact_status` 读取项目中的关键工件,并为每个工件返回 `missing`、`template`、`partial`、`ready`、`stale` 或 `unknown`。 ###### 证据驱动判断 每个 artifact 状态必须附带 evidence 和 confidence。Dashboard 不应只因为文件存在就宣称材料 ready,尤其不能把初始化模板误判为实质内容。 ###### Dashboard ready 后增强 -项目 ready 后,`/vibe` 显示 Artifacts 区块,让用户先理解哪些材料可用,再理解 workflow phase 如何推进。 +项目 ready 后,`/copaper` 显示 Artifacts 区块,让用户先理解哪些材料可用,再理解 workflow phase 如何推进。 ###### 为后续能力铺路 Artifact status 结果要能被后续 relatedwork、skills 安装、checker/report 联动复用,但本阶段不实现这些纵向流程。 @@ -29,7 +29,7 @@ Artifact status 结果要能被后续 relatedwork、skills 安装、checker/repo <!-- description: 本阶段明确不做的内容 --> ###### 不写入 readiness state -第一版不新增写入型 `vibepaper_artifact_set_readiness`,也不主动写入 `state.artifacts`。若未来 state 中已有 artifact 记录,工具可以读取为辅助证据。 +第一版不新增写入型 `copaper_artifact_set_readiness`,也不主动写入 `state.artifacts`。若未来 state 中已有 artifact 记录,工具可以读取为辅助证据。 ###### 不运行外部流程 本阶段不下载论文、不同步 BibTeX、不构建 cross-index、不安装 `.agents/skills/`、不运行 checker、不生成 report,也不执行 Git 操作。 @@ -47,7 +47,7 @@ Artifact 状态不自动改变 workflow phase。`paper=ready` 不代表自动把 当 readiness 为 `ready` 时,Dashboard 展示顺序为 `Readiness`、`Artifacts`、`Workflow`、`Recommendation`。Artifact evidence 用来校准 phase 建议。 ###### Artifact 状态查看 -用户询问“哪些材料准备好了”“storyline 是否可用”“paper 还是模板吗”时,agent 调用 `vibepaper_artifact_status`。 +用户询问“哪些材料准备好了”“storyline 是否可用”“paper 还是模板吗”时,agent 调用 `copaper_artifact_status`。 ###### 保守推荐下一步 推荐逻辑以 artifact evidence 为主。若 `storyline` 是模板,建议完善研究主线;若 `relatedwork` 缺失,建议后续进入 relatedwork 流程;若 `skills` 缺失,建议显式安装完整 skills。 @@ -58,17 +58,17 @@ Artifact 状态不自动改变 workflow phase。`paper=ready` 不代表自动把 ## Tool Design <!-- description: OpenCode 工具边界 --> -###### `vibepaper_artifact_status` +###### `copaper_artifact_status` 该工具只读项目文件。参数为空或仅包含未来兼容的可选显示参数。它使用 OpenCode runtime `ToolContext.directory` 和 `ToolContext.worktree` 做 root detection。 ###### 结构化返回 返回字段包括 `schemaVersion`、`ok`、`root`、`artifacts`、`summary`、`recommendation`、`warnings` 和 `locale`。失败时仍尽量返回已能读取的 artifact 诊断。 ###### Dashboard 集成 -`vibepaper_dashboard` 在项目 ready 时调用 artifact status 逻辑,并在 JSON block 中加入 `artifactStatus`。artifact status 失败时,Dashboard 隐藏 Markdown 区块但保留 JSON 诊断。 +`copaper_dashboard` 在项目 ready 时调用 artifact status 逻辑,并在 JSON block 中加入 `artifactStatus`。artifact status 失败时,Dashboard 隐藏 Markdown 区块但保留 JSON 诊断。 ###### 命令模板 -`/vibe` slash command 应说明 artifact status 是只读工具。agent 可用它回答材料状态问题,但不得基于 artifact 结果直接写 state 或推进 phase。 +`/copaper` slash command 应说明 artifact status 是只读工具。agent 可用它回答材料状态问题,但不得基于 artifact 结果直接写 state 或推进 phase。 ## Data Model <!-- description: 稳定结果模型 --> @@ -122,7 +122,7 @@ Artifact 状态不自动改变 workflow phase。`paper=ready` 不代表自动把 `metadata.provenance` 可记录 `file`、`state`、`event_log` 或 `heuristic`。第一版只展示简短来源,不建立完整 lineage graph。 ## Dashboard Integration -<!-- description: `/vibe` 展示变化 --> +<!-- description: `/copaper` 展示变化 --> ###### Artifacts 区块 Ready Dashboard 增加 `Artifacts` 区块。每行展示 artifact ID、status、confidence、关键 evidence 和下一步建议。 @@ -158,7 +158,7 @@ Workflow 区块继续显示 phase 状态。若 artifact evidence 与 phase 直 验证 ready 项目显示 Artifacts 区块,未 ready 项目仍优先显示初始化预览。验证 artifact status 异常时隐藏 Markdown 区块但保留 JSON 诊断。 ###### Tool registration tests -验证插件注册 `vibepaper_artifact_status`,并验证它使用 runtime `ToolContext` root,而不是插件初始化时捕获的 root。 +验证插件注册 `copaper_artifact_status`,并验证它使用 runtime `ToolContext` root,而不是插件初始化时捕获的 root。 ###### Localization tests 验证中文默认输出、英文输出和稳定英文 JSON 字段。状态值、confidence 值和 artifact ID 不随 locale 变化。 @@ -170,7 +170,7 @@ Workflow 区块继续显示 phase 状态。若 artifact evidence 与 phase 直 <!-- description: 完成判定 --> ###### 用户可理解材料状态 -用户运行 `/vibe` 后,可以清楚看到哪些材料缺失、哪些只是模板、哪些已有实质内容、哪些结果可能过期。 +用户运行 `/copaper` 后,可以清楚看到哪些材料缺失、哪些只是模板、哪些已有实质内容、哪些结果可能过期。 ###### Dashboard 不误导 默认初始化后的 `storyline.md` 和 `paper.md` 不应被误判为 ready。Dashboard 推荐必须基于 evidence,而不是只看文件存在。 diff --git a/docs/superpowers/specs/2026-05-02-opencode-artifact-readiness-state-design.md b/docs/superpowers/specs/2026-05-02-opencode-artifact-readiness-state-design.md index acc98f4..db5a266 100644 --- a/docs/superpowers/specs/2026-05-02-opencode-artifact-readiness-state-design.md +++ b/docs/superpowers/specs/2026-05-02-opencode-artifact-readiness-state-design.md @@ -11,16 +11,16 @@ 新能力只写 `.agents/state.json` 的 `artifacts` 区域,并追加 `.agents/events.jsonl`。它不推进 phase,不运行 checker,不触发 relatedwork,不安装 skills,也不执行 Git 操作。 ###### 不再规划 Python CLI parity -后续新控制能力以 `@vibepaper/opencode` 为主入口。Python CLI 不新增对应 artifact record 命令,仅作为旧项目状态格式的兼容背景。 +后续新控制能力以 `@copaper/opencode` 为主入口。Python CLI 不新增对应 artifact record 命令,仅作为旧项目状态格式的兼容背景。 ## Goals <!-- description: 必须实现的能力 --> ###### 记录 artifact readiness -新增 `vibepaper_artifact_record` 工具,用于记录 `storyline`、`paper`、`relatedwork`、`cross_index` 和 `checker_results` 的显式 readiness 状态。 +新增 `copaper_artifact_record` 工具,用于记录 `storyline`、`paper`、`relatedwork`、`cross_index` 和 `checker_results` 的显式 readiness 状态。 ###### 保留扫描事实 -现有 `vibepaper_artifact_status` 继续读取文件系统并报告观察结果。持久 readiness 是额外证据,不取代扫描事实,也不允许掩盖文件缺失或过期。 +现有 `copaper_artifact_status` 继续读取文件系统并报告观察结果。持久 readiness 是额外证据,不取代扫描事实,也不允许掩盖文件缺失或过期。 ###### 审计每次写入 每次成功写入必须追加 event log,记录 artifact、status、confidence、reason、previous status 和 stale 信息。失败时返回结构化错误。 @@ -32,7 +32,7 @@ <!-- description: 本阶段明确不做的内容 --> ###### 不做 Python CLI 命令 -本阶段不新增 `vibe artifact record` 或其他 Python CLI 入口。新写入能力只存在于 OpenCode plugin 工具层。 +本阶段不新增 `copaper artifact record` 或其他 Python CLI 入口。新写入能力只存在于 OpenCode plugin 工具层。 ###### 不做 workflow 调度器 本阶段不实现 `resume`、`progress` 或下一步自动调度。artifact readiness 不自动改变 `current_phase`,也不自动设置任何 phase status。 @@ -47,7 +47,7 @@ <!-- description: 用户可见行为 --> ###### 确认后写入 -agent 调用 `vibepaper_artifact_record` 前,必须复述 artifact、status、confidence 和 reason,并等待用户确认。未确认不得调用写入工具。 +agent 调用 `copaper_artifact_record` 前,必须复述 artifact、status、confidence 和 reason,并等待用户确认。未确认不得调用写入工具。 ###### Dashboard 合并展示 项目 ready 后,Dashboard 展示扫描状态和 recorded readiness。若二者冲突,Dashboard 显示冲突或 stale 提示,而不是静默相信其中一方。 @@ -79,7 +79,7 @@ Markdown 说明默认中文。工具名、artifact ID、JSON 字段、status、c ## Tool Design <!-- description: OpenCode 写入工具 --> -###### `vibepaper_artifact_record` +###### `copaper_artifact_record` 该工具使用 OpenCode runtime `ToolContext.directory` 和 `ToolContext.worktree` 做 root detection。不得使用插件初始化时捕获的 root。 ###### 参数 @@ -98,7 +98,7 @@ Markdown 说明默认中文。工具名、artifact ID、JSON 字段、status、c <!-- description: 扫描结果与记录状态合并 --> ###### 扫描事实优先 -`vibepaper_artifact_status` 继续以文件系统扫描判断事实状态。recorded readiness 只能作为辅助 evidence 和人工确认信号。 +`copaper_artifact_status` 继续以文件系统扫描判断事实状态。recorded readiness 只能作为辅助 evidence 和人工确认信号。 ###### Hash stale 若 recorded `content_hash` 与当前 artifact hash 不一致,Dashboard 标记 recorded readiness stale。工具不得继续把旧记录当成当前 ready 事实。 @@ -125,7 +125,7 @@ Markdown 说明默认中文。工具名、artifact ID、JSON 字段、status、c 日志行使用 UTF-8 compact JSON。现有 workflow log 读取 malformed line 时应继续跳过,不能因为 artifact event 破坏日志展示。 ## Dashboard Integration -<!-- description: `/vibe` 展示变化 --> +<!-- description: `/copaper` 展示变化 --> ###### Recorded readiness 列 Artifacts 区块增加 recorded readiness 信息,展示 recorded status、confidence、updated time 和 stale 标记。扫描 evidence 仍保留。 @@ -137,7 +137,7 @@ Artifacts 区块增加 recorded readiness 信息,展示 recorded status、conf Dashboard JSON 中的 `artifactStatus` 包含每个 artifact 的 scan row 和 recorded record 摘要。字段名保持 English。 ###### Slash command 指引 -`/vibe` 模板必须说明 `vibepaper_artifact_record` 是写操作,调用前需要用户明确确认,且不会自动推进 phase 或运行重型流程。 +`/copaper` 模板必须说明 `copaper_artifact_record` 是写操作,调用前需要用户明确确认,且不会自动推进 phase 或运行重型流程。 ## Error Handling <!-- description: 失败和异常规则 --> @@ -173,10 +173,10 @@ state 不是 JSON object 或无法解析时,record 工具拒绝写入。artifa 记录 content hash 后修改对应文件,验证 artifact status 和 Dashboard 将 recorded readiness 标记为 stale 或冲突。 ###### Integration tests -验证 `vibepaper_artifact_status` 仍然只读,但能读取 recorded readiness;验证 Dashboard 合并展示扫描事实和 recorded record。 +验证 `copaper_artifact_status` 仍然只读,但能读取 recorded readiness;验证 Dashboard 合并展示扫描事实和 recorded record。 ###### Template tests -验证 `/vibe` 文案包含写入确认门槛、无自动 phase 推进、无 checker、无 relatedwork、无 skills 安装和无 Git 操作。 +验证 `/copaper` 文案包含写入确认门槛、无自动 phase 推进、无 checker、无 relatedwork、无 skills 安装和无 Git 操作。 ## Acceptance Criteria <!-- description: 完成判定 --> diff --git a/docs/superpowers/specs/2026-05-03-opencode-agent-permission-profile-design.md b/docs/superpowers/specs/2026-05-03-opencode-agent-permission-profile-design.md index 31efea0..27e5a1d 100644 --- a/docs/superpowers/specs/2026-05-03-opencode-agent-permission-profile-design.md +++ b/docs/superpowers/specs/2026-05-03-opencode-agent-permission-profile-design.md @@ -1,11 +1,11 @@ # OpenCode Agent Permission Profile Design -<!-- description: VibePaper 专用 agent 与权限配置设计 --> +<!-- description: CoPaper 专用 agent 与权限配置设计 --> ## Summary <!-- description: 本阶段目标 --> ###### 建立专用 agent 底座 -本阶段为 `@vibepaper/opencode` 增加 VibePaper 专用 subagent profile。插件启动时注入论文工作流角色、默认 prompt、模型 hint 和权限模板,为后续 writing、skills、review、literature 等流程提供基础设施。 +本阶段为 `@copaper/opencode` 增加 CoPaper 专用 subagent profile。插件启动时注入论文工作流角色、默认 prompt、模型 hint 和权限模板,为后续 writing、skills、review、literature 等流程提供基础设施。 ###### 保持声明式启动 插件启动时只读取配置并注入 OpenCode agent config。启动不得写文件、不得扫描论文状态、不得执行 workflow、不得自动调用 subagent,也不得安装 skills。 @@ -17,13 +17,13 @@ <!-- description: 必须实现的能力 --> ###### 注入四个 v1 agents -默认注入 `vibepaper-coordinator`、`vibepaper-storyline`、`vibepaper-writer` 和 `vibepaper-recorder`。它们都是 OpenCode `subagent`,由用户或 `/vibe` 建议显式调用。 +默认注入 `copaper-coordinator`、`copaper-storyline`、`copaper-writer` 和 `copaper-recorder`。它们都是 OpenCode `subagent`,由用户或 `/copaper` 建议显式调用。 ###### 支持项目级覆盖 -读取项目本地 `.opencode/vibepaper.json`。配置可禁用 agent、替换模型 hint、调整 temperature、追加 prompt 偏好,并在允许范围内收紧权限。 +读取项目本地 `.opencode/copaper.json`。配置可禁用 agent、替换模型 hint、调整 temperature、追加 prompt 偏好,并在允许范围内收紧权限。 ###### 输出安全诊断 -配置解析失败、未知 agent、权限升级被拒、同名 OpenCode agent 冲突等情况必须进入 diagnostics。`/vibe-doctor` 应能展示 agent 注入状态和修复建议。 +配置解析失败、未知 agent、权限升级被拒、同名 OpenCode agent 冲突等情况必须进入 diagnostics。`/copaper-doctor` 应能展示 agent 注入状态和修复建议。 ###### 复用后续工具治理 Agent profile 应为后续 `skills install/apply`、reviewer、literature、reporter 和 git operator 提供权限分层基础,而不是只服务当前四个角色。 @@ -35,7 +35,7 @@ Agent profile 应为后续 `skills install/apply`、reviewer、literature、repo 本阶段不实现多 agent scheduler,不自动 handoff,不自动串联 storyline、writing、record、review 或 literature。Agent 只能建议用户切换角色。 ###### 不管理 provider secret -VibePaper 不配置 API key、provider base URL 或全局模型提供商。模型字段只是 OpenCode agent 的 model hint,provider 管理交给 OpenCode。 +CoPaper 不配置 API key、provider base URL 或全局模型提供商。模型字段只是 OpenCode agent 的 model hint,provider 管理交给 OpenCode。 ###### 不开放危险工具 v1 不给任何 agent 默认开放 unrestricted bash、git、checker、relatedwork download、web search、external directory 或 report generation。 @@ -46,38 +46,38 @@ v1 不给任何 agent 默认开放 unrestricted bash、git、checker、relatedwo ## Role Taxonomy <!-- description: v1 内置角色 --> -###### `vibepaper-coordinator` +###### `copaper-coordinator` 只读调度员。它读取 Dashboard、artifact readiness 和项目状态,解释当前项目位置,推荐下一步角色。它不写文件、不更新 state、不运行 shell、不联网,也不直接执行论文流程。 -###### `vibepaper-storyline` +###### `copaper-storyline` 研究叙事架构师。它围绕 `storyline.md` 帮用户收敛 problem、central claim、contribution、evidence plan 和 reader journey。写入 `storyline.md` 前必须确认,不直接修改 `paper.md` 或 state。 -###### `vibepaper-writer` +###### `copaper-writer` 正文写作者。它围绕 `paper.md` 起草或改写 Level 6 段落,参考 `storyline.md`、`.agents/cross_index.json` 和相关 `relatedwork/papers/*.md`。它不得修改 Level 1-5 结构,不直接写 state。 -###### `vibepaper-recorder` -状态记录员。它只在用户确认后调用 VibePaper confirmed state-write 工具,记录 artifact readiness 或后续 phase decision。它不编辑 `paper.md`、`storyline.md` 或 relatedwork。 +###### `copaper-recorder` +状态记录员。它只在用户确认后调用 CoPaper confirmed state-write 工具,记录 artifact readiness 或后续 phase decision。它不编辑 `paper.md`、`storyline.md` 或 relatedwork。 ## Deferred Roles <!-- description: v2 或更晚角色 --> -###### `vibepaper-literature` +###### `copaper-literature` 文献角色需要联网、下载、BibTeX 同步、PDF 摘要和 cross-index 写入,权限复杂。它应等 v1 profile 稳定后作为 `researchNetwork` 类能力加入。 -###### `vibepaper-reviewer` +###### `copaper-reviewer` 评审角色可先读 `paper.md` 和 checker 结果,但一旦运行 checker 或 precheck 就进入 process 类权限。v1 不开放自动 checker 执行。 -###### `vibepaper-experiment` +###### `copaper-experiment` 实验角色需要读取代码、数据和结果文件,项目差异大。它应在 artifact permissions 和 external directory 策略更成熟后设计。 -###### `vibepaper-git` +###### `copaper-git` Git 角色涉及 commit、diff、rollback 和工作区安全,是最高风险类别。它必须最后引入,并只响应显式用户请求。 ## Configuration File <!-- description: 项目级配置 --> ###### 配置路径 -项目级覆盖文件为 `.opencode/vibepaper.json`。该文件属于 OpenCode 插件运行配置,不写入 `.agents/state.json`,也不承载 API key 或 provider secret。 +项目级覆盖文件为 `.opencode/copaper.json`。该文件属于 OpenCode 插件运行配置,不写入 `.agents/state.json`,也不承载 API key 或 provider secret。 ###### Schema version 配置使用 `schemaVersion: 1`。缺少文件时使用默认 profile。不支持的版本不会中断插件,而是降级到安全默认配置并产生 warning diagnostic。 @@ -94,7 +94,7 @@ Git 角色涉及 commit、diff、rollback 和工作区安全,是最高风险 "temperature": 0.2 }, "agents": { - "vibepaper-writer": { + "copaper-writer": { "model": "anthropic/claude-sonnet-4-5", "temperature": 0.4, "promptAppend": "Use concise conference-paper style.", @@ -111,7 +111,7 @@ v1 不支持 `promptOverride`、`rawOpenCodeAgent`、原始 `permission`、原 <!-- description: 权限模板 --> ###### `readOnly` -允许 `read`、`glob`、`grep` 和 `question`。禁止 `edit`、`bash`、`webfetch`、`websearch`、`external_directory`、process 类能力和危险 VibePaper 写工具。 +允许 `read`、`glob`、`grep` 和 `question`。禁止 `edit`、`bash`、`webfetch`、`websearch`、`external_directory`、process 类能力和危险 CoPaper 写工具。 ###### `storylineWrite` 继承只读能力,并允许确认式编辑 `storyline.md`。它禁止编辑 `paper.md`、`.agents/state.json`、`.agents/events.jsonl`、relatedwork、shell、网络和外部目录。 @@ -120,22 +120,22 @@ v1 不支持 `promptOverride`、`rawOpenCodeAgent`、原始 `permission`、原 继承只读能力,并允许确认式编辑 `paper.md`。它禁止编辑 `storyline.md`、state、events、relatedwork、shell、网络和外部目录。 ###### `stateRecord` -允许读取和调用 VibePaper confirmed state-write 工具,但不给 OpenCode 通用 `edit` 权限。State 写入必须经工具内部路径、schema、event log 和确认校验。 +允许读取和调用 CoPaper confirmed state-write 工具,但不给 OpenCode 通用 `edit` 权限。State 写入必须经工具内部路径、schema、event log 和确认校验。 ## Maximum Permission Matrix <!-- description: 安全天花板 --> ###### Coordinator 上限 -`vibepaper-coordinator` 最大权限是 `readOnly`。项目配置不能把它升级为任何写权限。 +`copaper-coordinator` 最大权限是 `readOnly`。项目配置不能把它升级为任何写权限。 ###### Storyline 上限 -`vibepaper-storyline` 最大权限是 `storylineWrite`,可降级为 `readOnly`。它不能获得 paper、state、shell 或网络权限。 +`copaper-storyline` 最大权限是 `storylineWrite`,可降级为 `readOnly`。它不能获得 paper、state、shell 或网络权限。 ###### Writer 上限 -`vibepaper-writer` 最大权限是 `paperWrite`,可降级为 `readOnly`。它不能获得 storyline、state、shell 或网络权限。 +`copaper-writer` 最大权限是 `paperWrite`,可降级为 `readOnly`。它不能获得 storyline、state、shell 或网络权限。 ###### Recorder 上限 -`vibepaper-recorder` 最大权限是 `stateRecord`,可降级为 `readOnly`。它不能获得通用 edit,也不能修改论文正文。 +`copaper-recorder` 最大权限是 `stateRecord`,可降级为 `readOnly`。它不能获得通用 edit,也不能修改论文正文。 ## Merge Semantics <!-- description: 默认与覆盖合并 --> @@ -156,28 +156,28 @@ v1 不支持 `promptOverride`、`rawOpenCodeAgent`、原始 `permission`、原 <!-- description: config hook 行为 --> ###### 纯配置转换 -`config` hook 读取 `.opencode/vibepaper.json`,合并 agent profile,生成 OpenCode `agent` config,并注入缺失的 `vibepaper-*` agents。它不得产生文件写入副作用。 +`config` hook 读取 `.opencode/copaper.json`,合并 agent profile,生成 OpenCode `agent` config,并注入缺失的 `copaper-*` agents。它不得产生文件写入副作用。 ###### Subagent mode -所有 v1 agents 都使用 `mode: "subagent"`。它们不替代主 assistant,而是由用户通过 `@vibepaper-*` 或 `/vibe` 建议显式调用。 +所有 v1 agents 都使用 `mode: "subagent"`。它们不替代主 assistant,而是由用户通过 `@copaper-*` 或 `/copaper` 建议显式调用。 ###### 命名空间 -插件只管理内置 `vibepaper-*` 名称。v1 不支持用户新增任意 VibePaper agent,因为新增 agent 需要单独权限审计。 +插件只管理内置 `copaper-*` 名称。v1 不支持用户新增任意 CoPaper agent,因为新增 agent 需要单独权限审计。 ###### 同名冲突 -如果 OpenCode 现有 config 已定义同名 agent,插件不覆盖用户定义,跳过注入并记录 warning。用户应删除同名 OpenCode agent,改用 `.opencode/vibepaper.json` 覆盖。 +如果 OpenCode 现有 config 已定义同名 agent,插件不覆盖用户定义,跳过注入并记录 warning。用户应删除同名 OpenCode agent,改用 `.opencode/copaper.json` 覆盖。 ## Tool Governance -<!-- description: VibePaper 工具层权限 --> +<!-- description: CoPaper 工具层权限 --> ###### 双层权限 -OpenCode permission 控制通用工具,VibePaper 工具内部仍要检查 `context.agent` 和 capability。高层工具不能只靠 prompt 防止越权。 +OpenCode permission 控制通用工具,CoPaper 工具内部仍要检查 `context.agent` 和 capability。高层工具不能只靠 prompt 防止越权。 ###### Inspect tools Dashboard、artifact status、readiness preview 等只读工具默认允许 v1 agents 使用。它们不得写 state、events 或 artifacts。 ###### Record tools -`vibepaper_artifact_record` 等 confirmed state-write 工具只允许 `vibepaper-recorder` 使用,或要求未知 agent 经过额外明确确认。 +`copaper_artifact_record` 等 confirmed state-write 工具只允许 `copaper-recorder` 使用,或要求未知 agent 经过额外明确确认。 ###### Process tools skills install、relatedwork、checker、report、git 和 export 属 process 类能力。v1 默认不开放,未来必须逐项设计 agent capability 和确认策略。 @@ -204,19 +204,19 @@ Agent 可建议切换角色,但 v1 不自动 handoff。Coordinator 负责推 Diagnostics 至少包含 severity、code、path 和 message。Code 覆盖 `config-missing`、`config-parse-failed`、`unknown-agent`、`unsupported-field`、`permission-escalation-denied` 和 `agent-name-conflict`。 ###### 进程内保存 -`config` hook 产生的 diagnostics 保存在插件实例闭包中。v1 不写磁盘,不追加 event log。`/vibe-doctor` 读取当前进程内的最新 diagnostics。 +`config` hook 产生的 diagnostics 保存在插件实例闭包中。v1 不写磁盘,不追加 event log。`/copaper-doctor` 读取当前进程内的最新 diagnostics。 ###### Doctor 展示 -`/vibe-doctor` 展示每个 agent 的 injected、disabled、skipped 或 conflicted 状态,并列出权限 profile、模型 hint 和诊断修复建议。 +`/copaper-doctor` 展示每个 agent 的 injected、disabled、skipped 或 conflicted 状态,并列出权限 profile、模型 hint 和诊断修复建议。 -###### `/vibe` 提示 -普通 `/vibe` 输出只提示存在 agent profile warnings,并建议运行 `/vibe-doctor`。它不展开全部 diagnostics,避免污染 Dashboard。 +###### `/copaper` 提示 +普通 `/copaper` 输出只提示存在 agent profile warnings,并建议运行 `/copaper-doctor`。它不展开全部 diagnostics,避免污染 Dashboard。 ## Error Handling <!-- description: 失败行为 --> ###### Missing config -找不到 `.opencode/vibepaper.json` 时使用内置默认 agents,并产生 info diagnostic。缺配置不是错误。 +找不到 `.opencode/copaper.json` 时使用内置默认 agents,并产生 info diagnostic。缺配置不是错误。 ###### Parse failure JSON 解析失败时使用内置默认 agents,并产生 warning。插件不得因配置文件损坏而停止加载。 @@ -231,7 +231,7 @@ JSON 解析失败时使用内置默认 agents,并产生 warning。插件不得 <!-- description: 推荐工程结构 --> ###### 新增模块 -新增 `agent-profiles.ts`、`permission-profiles.ts`、`vibepaper-config.ts`、`agent-config.ts` 和 `agent-diagnostics.ts`。`index.ts` 只负责连接 plugin hook 和工具注册。 +新增 `agent-profiles.ts`、`permission-profiles.ts`、`copaper-config.ts`、`agent-config.ts` 和 `agent-diagnostics.ts`。`index.ts` 只负责连接 plugin hook 和工具注册。 ###### Prompt 存放 v1 prompt 可先以内联 TypeScript 字符串存放。这样编译后自动进入 `dist`,避免 npm package 资源路径、文件扫描和 dev/prod 差异。 @@ -255,13 +255,13 @@ v1 prompt 可先以内联 TypeScript 字符串存放。这样编译后自动进 覆盖默认注入、同名 OpenCode agent 冲突、权限升级拒绝、agent 禁用和 diagnostics 保存。确认 config hook 不写文件。 ###### Template tests -更新 `/vibe` 和 `/vibe-doctor` 模板测试,确认用户能看到可用 agents、warnings 提示和 doctor 诊断入口。 +更新 `/copaper` 和 `/copaper-doctor` 模板测试,确认用户能看到可用 agents、warnings 提示和 doctor 诊断入口。 ## Acceptance Criteria <!-- description: 完成判定 --> ###### 默认可用 -没有 `.opencode/vibepaper.json` 时,插件启动可注入四个安全默认 subagents,并记录缺配置 info diagnostic。 +没有 `.opencode/copaper.json` 时,插件启动可注入四个安全默认 subagents,并记录缺配置 info diagnostic。 ###### 可安全覆盖 项目配置可禁用 agent、替换模型、调整 temperature、追加 prompt,并把 writer/storyline/recorder 降级为只读。 @@ -285,10 +285,10 @@ v1 prompt 可先以内联 TypeScript 字符串存放。这样编译后自动进 下一步可把 skills 安装作为 process 类 confirmed tool 接入 profile 治理,由 coordinator 推荐,用户确认后执行。 ###### Reviewer role -之后可加入 `vibepaper-reviewer`,先做 read-only checker result review,再设计 confirmed checker/precheck execution。 +之后可加入 `copaper-reviewer`,先做 read-only checker result review,再设计 confirmed checker/precheck execution。 ###### Literature role -`vibepaper-literature` 应单独设计 network、download、PDF 和 cross-index 写入权限,不应混入 v1。 +`copaper-literature` 应单独设计 network、download、PDF 和 cross-index 写入权限,不应混入 v1。 ###### Git role -`vibepaper-git` 必须最后引入,并有比普通写入更强的显式确认、状态检查和失败说明。 +`copaper-git` 必须最后引入,并有比普通写入更强的显式确认、状态检查和失败说明。 diff --git a/docs/superpowers/specs/2026-05-19-opencode-relatedwork-release-fix-design.md b/docs/superpowers/specs/2026-05-19-opencode-relatedwork-release-fix-design.md index ec5632c..adf0bcf 100644 --- a/docs/superpowers/specs/2026-05-19-opencode-relatedwork-release-fix-design.md +++ b/docs/superpowers/specs/2026-05-19-opencode-relatedwork-release-fix-design.md @@ -5,22 +5,22 @@ <!-- description: 本次设计目标 --> ###### 修复发布阻塞路径 -本阶段只修复 `@vibepaper/opencode` 调用 Python `vibe relatedwork ...` 的最小发布风险。目标是让 OpenCode relatedwork 工具生成的 argv 与 Python Click CLI 接受的参数保持一致,避免用户在插件中触发文献流程时遇到非零退出或交互式阻塞。 +本阶段只修复 `@copaper/opencode` 调用 Python `copaper relatedwork ...` 的最小发布风险。目标是让 OpenCode relatedwork 工具生成的 argv 与 Python Click CLI 接受的参数保持一致,避免用户在插件中触发文献流程时遇到非零退出或交互式阻塞。 ###### 锁定跨运行时合同 -VibePaper 当前是 Python CLI 与 TypeScript OpenCode 插件的双运行时架构。相关文献能力由 Python 侧实现,插件侧只负责参数构造、bridge 调用、状态刷新和事件补丁。本设计用合同测试防止两侧再次漂移。 +CoPaper 当前是 Python CLI 与 TypeScript OpenCode 插件的双运行时架构。相关文献能力由 Python 侧实现,插件侧只负责参数构造、bridge 调用、状态刷新和事件补丁。本设计用合同测试防止两侧再次漂移。 ## Goals <!-- description: 必须实现的能力 --> ###### 修正 download 参数 -`vibepaper_relatedwork_download` 必须向 CLI 传递 `--paper-id <id>`,而不是 `--id <id>`。没有 `paperId` 时不传额外选择参数,因为 Python CLI 默认处理待下载论文。插件已有的 `all` 选项视为兼容字段,不应生成 Python 不支持的 `--all`。 +`copaper_relatedwork_download` 必须向 CLI 传递 `--paper-id <id>`,而不是 `--id <id>`。没有 `paperId` 时不传额外选择参数,因为 Python CLI 默认处理待下载论文。插件已有的 `all` 选项视为兼容字段,不应生成 Python 不支持的 `--all`。 ###### 修正 register 参数 -`vibepaper_relatedwork_register_summary` 必须向 CLI 传递 `--summary-path <path>`,而不是 `--path <path>`。`paperId` 和 summary path 仍需在插件侧先做非空校验,缺失时返回 `invalid-args`,不调用 bridge。 +`copaper_relatedwork_register_summary` 必须向 CLI 传递 `--summary-path <path>`,而不是 `--path <path>`。`paperId` 和 summary path 仍需在插件侧先做非空校验,缺失时返回 `invalid-args`,不调用 bridge。 ###### 避免 clean 阻塞 -`vibepaper_relatedwork_clean` 是插件侧确认后的写操作。非 dry-run 调用必须传递 `--yes`,避免 Python CLI 的 `click.confirm("Proceed?")` 在 OpenCode bridge 中等待输入直到超时。dry-run 继续只传 `--dry-run`。 +`copaper_relatedwork_clean` 是插件侧确认后的写操作。非 dry-run 调用必须传递 `--yes`,避免 Python CLI 的 `click.confirm("Proceed?")` 在 OpenCode bridge 中等待输入直到超时。dry-run 继续只传 `--dry-run`。 ###### 补齐合同测试 `relatedwork-tools.test.ts` 应断言每个 relatedwork 工具最终传给 bridge 的 argv,至少覆盖 `download`、`register-summary`、`clean`、`summarize`、`search`、`keywords`、`import`、`sync-bib` 和 `build-index` 的关键参数。 @@ -44,7 +44,7 @@ Semantic Scholar 搜索、BibTeX 同步、PDF 下载、LLM 摘要、cross-index <!-- description: 当前已确认的合同漂移 --> ###### Download flag mismatch -插件当前在 `packages/opencode-plugin/src/relatedwork-tools.ts` 使用 `--id` 和 `--all`。Python CLI 在 `vibepaper/cli.py` 的 `relatedwork download` 只接受 `--paper-id` 和 `--retry-failed`,因此 `--id` 或 `--all` 会导致 Click 参数错误。 +插件当前在 `packages/opencode-plugin/src/relatedwork-tools.ts` 使用 `--id` 和 `--all`。Python CLI 在 `copaper/cli.py` 的 `relatedwork download` 只接受 `--paper-id` 和 `--retry-failed`,因此 `--id` 或 `--all` 会导致 Click 参数错误。 ###### Register flag mismatch 插件当前使用 `--path` 传 summary 文件。Python CLI 的 `relatedwork register-summary` 要求 `--summary-path`,因此插件调用会失败,即使 `paperId` 和路径都有效。 @@ -59,7 +59,7 @@ Python CLI 的 `relatedwork clean` 在没有 `--yes` 且非 `--dry-run` 时会 主要修改 `packages/opencode-plugin/src/relatedwork-tools.ts` 的 argv 构造。每个工具函数继续只负责把 typed options 转成 CLI 参数,然后交给统一 `invoke` 流程处理 bridge、status refresh、phase patch 和渲染。 ###### 以 Python CLI 为真源 -参数合同以 `vibepaper/cli.py` 的 Click option 为准。若插件 option 与 CLI 不完全一致,优先映射到 CLI 已支持语义;无法映射的字段不生成未知参数,并由测试记录该兼容行为。 +参数合同以 `copaper/cli.py` 的 Click option 为准。若插件 option 与 CLI 不完全一致,优先映射到 CLI 已支持语义;无法映射的字段不生成未知参数,并由测试记录该兼容行为。 ###### 合同测试优先 测试不只检查 `result.ok`,还要检查记录到的 `calls[0].command`。这样即使 mock bridge 返回成功,也能发现插件生成了 Python CLI 不支持的参数。 @@ -68,13 +68,13 @@ Python CLI 的 `relatedwork clean` 在没有 `--yes` 且非 `--dry-run` 时会 <!-- description: 调用路径 --> ###### OpenCode 工具入口 -OpenCode 调用 `vibepaper_relatedwork_*` 工具,`index.ts` 把参数传给 `relatedwork-tools.ts` 中对应的 `runRelatedwork*` 函数。 +OpenCode 调用 `copaper_relatedwork_*` 工具,`index.ts` 把参数传给 `relatedwork-tools.ts` 中对应的 `runRelatedwork*` 函数。 ###### 参数构造 `runRelatedwork*` 根据 options 构造 `args: ["relatedwork", "<subcommand>", ...flags]`。本阶段只调整 flag 名称和非交互确认参数,不改变 root、locale、timeout 或 env 的处理。 ###### Bridge 调用 -`invoke` 调用 `python-bridge.ts`,解析 `.venv/bin/vibe` 或 `uv run --project <root> vibe`,再执行 `vibe --root <root> relatedwork ...`。命令结果和 stderr/stdout 仍按现有 `RelatedworkToolResult` 返回。 +`invoke` 调用 `python-bridge.ts`,解析 `.venv/bin/copaper` 或 `uv run --project <root> copaper`,再执行 `copaper --root <root> relatedwork ...`。命令结果和 stderr/stdout 仍按现有 `RelatedworkToolResult` 返回。 ###### 状态刷新 写工具完成后继续刷新 relatedwork status,并对 literature phase counters 做 idempotent patch。失败时仍尽量返回 bridge 错误、stderr 和 statusAfter,方便用户诊断。 @@ -98,7 +98,7 @@ OpenCode 调用 `vibepaper_relatedwork_*` 工具,`index.ts` 把参数传给 `r 更新 `packages/opencode-plugin/tests/relatedwork-tools.test.ts`。新增或强化 argv assertions,确保 download、register-summary 和 clean 的关键参数与 Python CLI 一致。 ###### Existing behavior coverage -保留现有 phase patch、event append、read-only no-event、nonzero bridge error、vibe unavailable、render output 等测试。参数修复不得破坏这些行为。 +保留现有 phase patch、event append、read-only no-event、nonzero bridge error、copaper unavailable、render output 等测试。参数修复不得破坏这些行为。 ###### Optional Python sanity 如果实现中需要确认 CLI 参数,可运行相关 pytest 或 Click runner 测试。但本阶段主要风险在 TypeScript argv 生成,因此最小验证以 Bun relatedwork tool 测试为主。 @@ -110,7 +110,7 @@ OpenCode 调用 `vibepaper_relatedwork_*` 工具,`index.ts` 把参数传给 `r 若 README 或中文测试说明列出了 relatedwork 工具行为,应更新为 Python CLI 真实参数语义:download 可按 `paperId` 限定,否则处理待下载论文;register-summary 使用 summary path;clean 的真实删除由确认后的工具调用执行。 ###### Manual smoke path -文档应建议最小发布验证:运行 plugin relatedwork tests、typecheck,并在需要时用本地 OpenCode 项目执行 `/vibe-relatedwork` 的 dry-run 或状态检查。不要在本阶段承诺完整 npm 发布流程。 +文档应建议最小发布验证:运行 plugin relatedwork tests、typecheck,并在需要时用本地 OpenCode 项目执行 `/copaper-relatedwork` 的 dry-run 或状态检查。不要在本阶段承诺完整 npm 发布流程。 ## Acceptance Criteria <!-- description: 完成判定 --> diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..833567b --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,32 @@ +site_name: Copaper +site_description: Copaper - 你的论文助手 +site_url: "" + +theme: + name: material + language: zh + features: + - navigation.tabs + - navigation.sections + - navigation.top + - search.highlight + - search.suggest + +nav: + - 中文: index.md + - English: en.md + +markdown_extensions: + - admonition + - tables + - toc: + permalink: true + +extra: + alternate: + - name: 中文 + link: / + lang: zh + - name: English + link: /en/ + lang: en diff --git a/packages/codemap.md b/packages/codemap.md index 8021674..8e90caa 100644 --- a/packages/codemap.md +++ b/packages/codemap.md @@ -3,7 +3,7 @@ ## Responsibility ###### Integration package workspace -`packages/` contains distributable integration packages that extend VibePaper beyond the Python CLI. The current package is `opencode-plugin/`, the OpenCode integration published as `@vibepaper/opencode`. +`packages/` contains distributable integration packages that extend CoPaper beyond the Python CLI. The current package is `opencode-plugin/`, the OpenCode integration published as `@copaper/opencode`. ###### Package-level navigation This aggregate map points maintainers to package boundaries and cross-package responsibilities. For OpenCode-specific entry points, tools, tests, and release risks, see [packages/opencode-plugin/codemap.md](opencode-plugin/codemap.md). @@ -11,26 +11,26 @@ This aggregate map points maintainers to package boundaries and cross-package re ## Directory Map ###### `opencode-plugin/` -OpenCode integration package with a Bun/TypeScript plugin export, `vibepaper-opencode` installer CLI, command templates, agent profiles, dashboard/status tools, Python CLI bridge helpers, scripts, tests, and package metadata. +OpenCode integration package with a Bun/TypeScript plugin export, `copaper-opencode` installer CLI, command templates, agent profiles, dashboard/status tools, Python CLI bridge helpers, scripts, tests, and package metadata. ## Data & Control Flow ###### Package build path -Source package code builds from `opencode-plugin/src/` into `opencode-plugin/dist/`. `package.json` exposes `./dist/index.js` as the plugin export and `./dist/cli.js` as the `vibepaper-opencode` binary. +Source package code builds from `opencode-plugin/src/` into `opencode-plugin/dist/`. `package.json` exposes `./dist/index.js` as the plugin export and `./dist/cli.js` as the `copaper-opencode` binary. ###### Runtime interaction path -Installed OpenCode commands and plugin tools operate inside a target VibePaper project, reading workflow artifacts and using confirmed state-write bridges where mutation is required. +Installed OpenCode commands and plugin tools operate inside a target CoPaper project, reading workflow artifacts and using confirmed state-write bridges where mutation is required. ## Integration Points ###### OpenCode host `opencode-plugin/` depends on `@opencode-ai/plugin` and updates OpenCode configuration plus managed `.opencode/commands/` entries during install workflows. -###### VibePaper project assets +###### CoPaper project assets The package connects to `paper.md`, `storyline.md`, `writingrules.md`, `.agents/` state and events, checker reports, cross-index data, and `relatedwork/` metadata in target projects. ###### Python CLI bridge -Related-work and doctor workflows can resolve the Python `vibe` CLI through a target virtual environment or `uv run --project`, reporting bridge failures as structured diagnostics. +Related-work and doctor workflows can resolve the Python `copaper` CLI through a target virtual environment or `uv run --project`, reporting bridge failures as structured diagnostics. ## Maintenance Notes diff --git a/packages/opencode-plugin/MANUAL_SMOKE.md b/packages/opencode-plugin/MANUAL_SMOKE.md index 7394e21..2ea2122 100644 --- a/packages/opencode-plugin/MANUAL_SMOKE.md +++ b/packages/opencode-plugin/MANUAL_SMOKE.md @@ -3,14 +3,14 @@ 1. Build package: `bun run build`. 2. Create a local tarball: `npm pack`. 3. Create a temporary project: `tmp_project="$(mktemp -d)"`. -4. If reusing a temporary project, remove stale local installs first: `bun remove --cwd "$tmp_project" @vibepaper/opencode || true; rm -rf "$tmp_project/node_modules/@vibepaper" "$tmp_project/bun.lock" "$tmp_project/package-lock.json"`. -5. Test the local tarball by installing it first: `bun add --cwd "$tmp_project" "$(pwd)/vibepaper-opencode-0.1.0.tgz"`. -6. Run the installed binary: `"$tmp_project/node_modules/.bin/vibepaper-opencode" init --root "$tmp_project"`. +4. If reusing a temporary project, remove stale local installs first: `bun remove --cwd "$tmp_project" @copaper/opencode || true; rm -rf "$tmp_project/node_modules/@copaper" "$tmp_project/bun.lock" "$tmp_project/package-lock.json"`. +5. Test the local tarball by installing it first: `bun add --cwd "$tmp_project" "$(pwd)/copaper-opencode-0.1.0.tgz"`. +6. Run the installed binary: `"$tmp_project/node_modules/.bin/copaper-opencode" init --root "$tmp_project"`. 7. If local tarball installation is not needed, run the deterministic local fallback: `bun <repo>/packages/opencode-plugin/dist/cli.js init --root <tmp-project>`. -8. Confirm `opencode.json` contains a VibePaper plugin entry. Local tarball installs should use a `file://.../node_modules/@vibepaper/opencode/dist/index.js` entry; published installs should use `"@vibepaper/opencode"`. -9. Confirm `.opencode/commands/vibe.md` exists. -10. Confirm `.opencode/commands/vibe-doctor.md` exists. +8. Confirm `opencode.json` contains a CoPaper plugin entry. Local tarball installs should use a `file://.../node_modules/@copaper/opencode/dist/index.js` entry; published installs should use `"@copaper/opencode"`. +9. Confirm `.opencode/commands/copaper.md` exists. +10. Confirm `.opencode/commands/copaper-doctor.md` exists. 11. Restart OpenCode in the temporary project. -12. Run `/vibe-doctor` and confirm it displays doctor markdown. -13. Run `/vibe` and confirm the agent calls or attempts to call `vibepaper_dashboard`. -14. If `/vibe` cannot call the tool, run terminal doctor and record the failure. +12. Run `/copaper-doctor` and confirm it displays doctor markdown. +13. Run `/copaper` and confirm the agent calls or attempts to call `copaper_dashboard`. +14. If `/copaper` cannot call the tool, run terminal doctor and record the failure. diff --git a/packages/opencode-plugin/README.md b/packages/opencode-plugin/README.md index a6e5040..d24f87c 100644 --- a/packages/opencode-plugin/README.md +++ b/packages/opencode-plugin/README.md @@ -1,8 +1,8 @@ -# @vibepaper/opencode +# @copaper/opencode -###### VibePaper 的 OpenCode 集成插件 +###### CoPaper 的 OpenCode 集成插件 <!-- description: Package purpose and language defaults --> -`@vibepaper/opencode` 为 VibePaper 提供 OpenCode 集成,默认输出中文。命令名、工具名和 JSON 字段名保持 English,便于脚本和自动化稳定解析。 +`@copaper/opencode` 为 CoPaper 提供 OpenCode 集成,默认输出中文。命令名、工具名和 JSON 字段名保持 English,便于脚本和自动化稳定解析。 ## 安装 @@ -11,35 +11,35 @@ 在目标项目根目录运行: ```bash -bunx -p @vibepaper/opencode vibepaper-opencode init +bunx -p @copaper/opencode copaper-opencode init ``` -Bun 需要 `-p`,因为包名 `@vibepaper/opencode` 和二进制名 `vibepaper-opencode` 不同。 +Bun 需要 `-p`,因为包名 `@copaper/opencode` 和二进制名 `copaper-opencode` 不同。 ###### 重启并检查 <!-- description: OpenCode restart and commands --> 安装后重启 OpenCode,然后依次运行: ```text -/vibe-doctor -/vibe +/copaper-doctor +/copaper ``` 如果已经安装过旧版本地构建,重新运行 `init` 以刷新受管 slash commands。 -## VibePaper Agents +## CoPaper Agents ###### Injected Agents -<!-- description: Managed VibePaper agent profiles --> -- `@vibepaper-coordinator`: read-only workflow routing and next-step recommendations; it does not write project files. -- `@vibepaper-storyline`: confirmed edits to `storyline.md` only; it cannot edit other project files. -- `@vibepaper-writer`: confirmed edits to `paper.md` only, following VibePaper writing rules. -- `@vibepaper-reviewer`: read-only checker review, issue explanation, and checker-summary preparation; it does not edit `paper.md` or write state. -- `@vibepaper-recorder`: confirmed readiness records through VibePaper state-write tools; it does not edit paper content. +<!-- description: Managed CoPaper agent profiles --> +- `@copaper-coordinator`: read-only workflow routing and next-step recommendations; it does not write project files. +- `@copaper-storyline`: confirmed edits to `storyline.md` only; it cannot edit other project files. +- `@copaper-writer`: confirmed edits to `paper.md` only, following CoPaper writing rules. +- `@copaper-reviewer`: read-only checker review, issue explanation, and checker-summary preparation; it does not edit `paper.md` or write state. +- `@copaper-recorder`: confirmed readiness records through CoPaper state-write tools; it does not edit paper content. ###### Project Overrides <!-- description: Project-level agent override example --> -可在项目根目录创建 `.opencode/vibepaper.json` 覆盖默认 agent profile。例如: +可在项目根目录创建 `.opencode/copaper.json` 覆盖默认 agent profile。例如: ```json { @@ -49,7 +49,7 @@ Bun 需要 `-p`,因为包名 `@vibepaper/opencode` 和二进制名 `vibepaper- "temperature": 0.2 }, "agents": { - "vibepaper-writer": { + "copaper-writer": { "model": "openai/gpt-5.1", "promptAppend": "Prefer concise transitions and preserve Markdown headings.", "permissionProfile": "paperWrite" @@ -60,65 +60,65 @@ Bun 需要 `-p`,因为包名 `@vibepaper/opencode` 和二进制名 `vibepaper- ###### Override Boundaries <!-- description: Agent override security boundaries --> -覆盖配置可以禁用 agents、设置 model hints、设置 temperature、追加 preferences,或把 permissions downgrade 到更严格的 profile。覆盖配置不能授予 shell、Git、unrestricted editing、network 或 external directory access。VibePaper does not expose or manage raw provider secrets/API keys; model calls still use the provider credentials configured in OpenCode. +覆盖配置可以禁用 agents、设置 model hints、设置 temperature、追加 preferences,或把 permissions downgrade 到更严格的 profile。覆盖配置不能授予 shell、Git、unrestricted editing、network 或 external directory access。CoPaper does not expose or manage raw provider secrets/API keys; model calls still use the provider credentials configured in OpenCode. ## Dashboard ###### 只读仪表盘 <!-- description: Read-only Dashboard behavior --> -`/vibe` 会打开只读 Dashboard,检查 OpenCode 集成、VibePaper 核心文件、状态文件、项目指导文件、可选 `relatedwork/`,并显示初始化预览。 +`/copaper` 会打开只读 Dashboard,检查 OpenCode 集成、CoPaper 核心文件、状态文件、项目指导文件、可选 `relatedwork/`,并显示初始化预览。 ###### Dashboard 只读边界 <!-- description: Read-only Dashboard boundary --> -Dashboard 工具本身只读取项目并展示初始化预览,不写入项目文件。确认初始化后的实际写入由下一节的 `vibepaper_init_apply` 流程完成。 +Dashboard 工具本身只读取项目并展示初始化预览,不写入项目文件。确认初始化后的实际写入由下一节的 `copaper_init_apply` 流程完成。 ## 工件状态 ###### Ready 后的材料视图 <!-- description: Artifact status shown after ready --> -项目 ready 后,`/vibe` 会展示 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/`、`.agents/cross_index.json` 和 checker results 的工件状态。状态值保持 English:`missing`、`template`、`partial`、`ready`、`stale`、`unknown`。 +项目 ready 后,`/copaper` 会展示 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/`、`.agents/cross_index.json` 和 checker results 的工件状态。状态值保持 English:`missing`、`template`、`partial`、`ready`、`stale`、`unknown`。 ###### 只读证据 <!-- description: Read-only artifact evidence behavior --> -`vibepaper_artifact_status` 只读取文件并展示 evidence、confidence 和 recommendation;它不写 `.agents/state.json`,不推进 phase,不安装 skills,也不运行 relatedwork、checker、report 或 git。 +`copaper_artifact_status` 只读取文件并展示 evidence、confidence 和 recommendation;它不写 `.agents/state.json`,不推进 phase,不安装 skills,也不运行 relatedwork、checker、report 或 git。 ###### 显式记录就绪度 <!-- description: Artifact readiness write behavior --> -当用户明确要求记录工件就绪度时,agent 必须先复述 artifact、status、confidence 和 reason,并等待确认后才调用 `vibepaper_artifact_record`。该工具只写 `.agents/state.json` 的 `artifacts` 区域并追加 `.agents/events.jsonl`,不推进 phase,不运行 checker、relatedwork、report、skills 或 git。 +当用户明确要求记录工件就绪度时,agent 必须先复述 artifact、status、confidence 和 reason,并等待确认后才调用 `copaper_artifact_record`。该工具只写 `.agents/state.json` 的 `artifacts` 区域并追加 `.agents/events.jsonl`,不推进 phase,不运行 checker、relatedwork、report、skills 或 git。 ## 论文结构 ###### paper.md 只读结构扫描 <!-- description: Read-only paper structure status tool --> -`vibepaper_paper_structure_status` 只读取 `paper.md`,解析 Level 2-5 结构标题、Level 5 写作目标、Level 6 子段落覆盖情况、推荐的下一个未完成 Level 5 section,以及结构问题。该工具不写文件、不推进 phase、不记录 artifact readiness。 +`copaper_paper_structure_status` 只读取 `paper.md`,解析 Level 2-5 结构标题、Level 5 写作目标、Level 6 子段落覆盖情况、推荐的下一个未完成 Level 5 section,以及结构问题。该工具不写文件、不推进 phase、不记录 artifact readiness。 ###### storyline.md 只读结构扫描 <!-- description: Read-only storyline structure status tool --> -`vibepaper_storyline_structure_status` 只读取 `storyline.md`,解析 `#####` 故事线章节、filled/partial/empty 状态、TODO 覆盖和下一个待补章节。该工具不写文件、不推进 phase、不记录 artifact readiness。 +`copaper_storyline_structure_status` 只读取 `storyline.md`,解析 `#####` 故事线章节、filled/partial/empty 状态、TODO 覆盖和下一个待补章节。该工具不写文件、不推进 phase、不记录 artifact readiness。 ## 导入提取 ###### 显式路径提取 <!-- description: Read-only import extraction tools --> -`vibepaper_pdf_extract` 和 `vibepaper_ppt_extract` 只读取用户明确提供的项目内路径,不会自动扫描目录或猜测候选文件。PDF 工具提取文本、页数、source hash 和置信度;PPTX 工具提取 slide text、标题、可选 notes、source hash。二者都不写文件、不推进 phase、不记录 artifact readiness。 +`copaper_pdf_extract` 和 `copaper_ppt_extract` 只读取用户明确提供的项目内路径,不会自动扫描目录或猜测候选文件。PDF 工具提取文本、页数、source hash 和置信度;PPTX 工具提取 slide text、标题、可选 notes、source hash。二者都不写文件、不推进 phase、不记录 artifact readiness。 ###### checker 只读状态 <!-- description: Read-only checker status tool --> -`vibepaper_checker_status` 只读取 `.agents/state.json` 的 `checkers` 区域、`.agents/precheck_report.md` 和 `paper.md` 更新时间,汇总 7 个 checker 的运行状态、Critical/Major/Minor 计数、stale 信号和预检报告证据。该工具不运行 checker、不写状态、不推进 phase、不记录 artifact readiness。 +`copaper_checker_status` 只读取 `.agents/state.json` 的 `checkers` 区域、`.agents/precheck_report.md` 和 `paper.md` 更新时间,汇总 7 个 checker 的运行状态、Critical/Major/Minor 计数、stale 信号和预检报告证据。该工具不运行 checker、不写状态、不推进 phase、不记录 artifact readiness。 ###### relatedwork 只读状态 <!-- description: Read-only relatedwork status tool --> -`vibepaper_relatedwork_status` 只读取 `relatedwork/literature.json`、`relatedwork/paper_list.bib`、`relatedwork/pdfs/`、`relatedwork/papers/`、`relatedwork/search_cache.json`、`relatedwork/queries.txt`、`relatedwork/summary.md` 和 `.agents/cross_index.json`,汇总论文数量、PDF 下载、摘要、BibTeX、cross-index 和每篇论文状态。该工具不运行 search/import/download/summarize/build-index,不写 `.agents/state.json`,不追加事件日志。 +`copaper_relatedwork_status` 只读取 `relatedwork/literature.json`、`relatedwork/paper_list.bib`、`relatedwork/pdfs/`、`relatedwork/papers/`、`relatedwork/search_cache.json`、`relatedwork/queries.txt`、`relatedwork/summary.md` 和 `.agents/cross_index.json`,汇总论文数量、PDF 下载、摘要、BibTeX、cross-index 和每篇论文状态。该工具不运行 search/import/download/summarize/build-index,不写 `.agents/state.json`,不追加事件日志。 ###### checker 结果记录 <!-- description: Checker result recording tool --> -当用户明确要求记录 checker 结果时,agent 必须先复述 checker、status、Critical/Major/Minor 计数、summary、evidence 和 reason,并等待确认后才由 `@vibepaper-recorder` 调用 `vibepaper_checker_record`。该工具写入 `.agents/state.json` 的 `checkers` 区域并追加 `.agents/events.jsonl`,不运行 checker、不标记单个 issue resolved、不推进 phase、不记录 artifact readiness。 +当用户明确要求记录 checker 结果时,agent 必须先复述 checker、status、Critical/Major/Minor 计数、summary、evidence 和 reason,并等待确认后才由 `@copaper-recorder` 调用 `copaper_checker_record`。该工具写入 `.agents/state.json` 的 `checkers` 区域并追加 `.agents/events.jsonl`,不运行 checker、不标记单个 issue resolved、不推进 phase、不记录 artifact readiness。 ## 初始化项目 ###### 显式确认写入 <!-- description: Init apply confirmation flow --> -`/vibe` 会先显示初始化预览。只有当用户明确说“确认初始化”,并提供项目名称与研究领域后,agent 才会调用 `vibepaper_init_apply` 工具。 +`/copaper` 会先显示初始化预览。只有当用户明确说“确认初始化”,并提供项目名称与研究领域后,agent 才会调用 `copaper_init_apply` 工具。 ###### 第一版写入范围 <!-- description: Files written by init apply --> @@ -132,11 +132,11 @@ Dashboard 工具本身只读取项目并展示初始化预览,不写入项目 ###### Ready 后的工作流视图 <!-- description: Workflow tools after init apply --> -项目 ready 后,`/vibe` 会显示当前 phase、phase 状态表和最近事件。phase 列表来自 `.agents/state.json`,不会写死当前 6 个默认阶段。 +项目 ready 后,`/copaper` 会显示当前 phase、phase 状态表和最近事件。phase 列表来自 `.agents/state.json`,不会写死当前 6 个默认阶段。 ###### 显式确认修改阶段 <!-- description: Phase status confirmation rule --> -修改阶段状态时,agent 必须先复述目标 phase、status 和 reason(当 status 为 `skipped` 时),并等待用户确认后才调用 `vibepaper_workflow_set_phase`。 +修改阶段状态时,agent 必须先复述目标 phase、status 和 reason(当 status 为 `skipped` 时),并等待用户确认后才调用 `copaper_workflow_set_phase`。 ## 诊断 @@ -145,18 +145,18 @@ Dashboard 工具本身只读取项目并展示初始化预览,不写入项目 终端中可运行: ```bash -bunx -p @vibepaper/opencode vibepaper-opencode doctor -bunx -p @vibepaper/opencode vibepaper-opencode doctor --format markdown -bunx -p @vibepaper/opencode vibepaper-opencode doctor --format json +bunx -p @copaper/opencode copaper-opencode doctor +bunx -p @copaper/opencode copaper-opencode doctor --format markdown +bunx -p @copaper/opencode copaper-opencode doctor --format json ``` ###### 英文输出示例 <!-- description: Locale command examples --> -需要英文输出时可使用 `--locale` 或 `VIBEPAPER_LANG`: +需要英文输出时可使用 `--locale` 或 `COPAPER_LANG`: ```bash -bunx -p @vibepaper/opencode vibepaper-opencode doctor --locale en-US -VIBEPAPER_LANG=en-US bunx -p @vibepaper/opencode vibepaper-opencode doctor +bunx -p @copaper/opencode copaper-opencode doctor --locale en-US +COPAPER_LANG=en-US bunx -p @copaper/opencode copaper-opencode doctor ``` 未知 locale 会回退到 `zh-CN`。JSON 字段名、状态值和 action 枚举保持 English,例如 `ok`、`checks`、`status`、`pass`、`fail`、`create`。 @@ -171,7 +171,7 @@ VIBEPAPER_LANG=en-US bunx -p @vibepaper/opencode vibepaper-opencode doctor ###### 发布前本地测试 <!-- description: Local tarball install note --> -测试本地 tarball 时,先把 tarball 安装到目标项目,再运行 `node_modules/.bin/vibepaper-opencode init`;这会在发布前写入稳定的项目内 `file://` 插件入口。具体命令和验收点见 `USAGE_TEST.zh-CN.md`。 +测试本地 tarball 时,先把 tarball 安装到目标项目,再运行 `node_modules/.bin/copaper-opencode init`;这会在发布前写入稳定的项目内 `file://` 插件入口。具体命令和验收点见 `USAGE_TEST.zh-CN.md`。 ## 本地开发 @@ -191,11 +191,11 @@ bun run dev:install /path/to/target-project --skip-init # 不刷新 .open 1. `bun run build`(除非 `--skip-build`) 2. 在插件目录 `bun link` -3. 在目标项目 `bun link @vibepaper/opencode`(自动补一个最小 `package.json` 以满足 bun link 要求) -4. 运行 `vibepaper-opencode init --force --root <target>`,刷新 `.opencode/commands/vibe.md`、`vibe-doctor.md`、`vibe-relatedwork.md` -5. `--with-python` 时若目标项目缺 `.venv` 就先 `uv venv`,然后 `uv pip install -e <repo-root>`,让 `<target>/.venv/bin/vibe` 可用 +3. 在目标项目 `bun link @copaper/opencode`(自动补一个最小 `package.json` 以满足 bun link 要求) +4. 运行 `copaper-opencode init --force --root <target>`,刷新 `.opencode/commands/copaper.md`、`copaper-doctor.md`、`copaper-relatedwork.md` +5. `--with-python` 时若目标项目缺 `.venv` 就先 `uv venv`,然后 `uv pip install -e <repo-root>`,让 `<target>/.venv/bin/copaper` 可用 -完成后**重启 OpenCode**,在目标项目里运行 `/vibe-doctor` 验证 `commands.vibe-relatedwork.present` 与 `vibe-cli.available` 这两条 check 都通过。 +完成后**重启 OpenCode**,在目标项目里运行 `/copaper-doctor` 验证 `commands.copaper-relatedwork.present` 与 `copaper-cli.available` 这两条 check 都通过。 ###### 日常迭代 <!-- description: dev:watch workflow for source edits --> @@ -215,7 +215,7 @@ bun run dev:watch bun run dev:reset /path/to/target-project ``` -会从目标项目卸掉 `@vibepaper/opencode`、删除 `node_modules/@vibepaper/opencode` 符号链接,并解除全局 link。`.opencode/commands/` 下的文件和 `opencode.json` 的 plugin 条目保留,需要手动清理。 +会从目标项目卸掉 `@copaper/opencode`、删除 `node_modules/@copaper/opencode` 符号链接,并解除全局 link。`.opencode/commands/` 下的文件和 `opencode.json` 的 plugin 条目保留,需要手动清理。 ###### 升级到新版本 <!-- description: dev:install is idempotent; rerun to upgrade --> @@ -226,7 +226,7 @@ cd packages/opencode-plugin bun run dev:install /path/to/target-project ``` -`init --force` 会安全覆盖带有 `<!-- VibePaper managed: ... -->` 标记的 `vibe.md` 与 `vibe-doctor.md`,新增 `vibe-relatedwork.md`;`opencode.json` 已包含 `@vibepaper/opencode` 条目时不重复添加;`bun link` 让该 specifier 解析到本地最新源码,覆盖之前的 npm 安装。重启 OpenCode 即可生效。 +`init --force` 会安全覆盖带有 `<!-- CoPaper managed: ... -->` 标记的 `copaper.md` 与 `copaper-doctor.md`,新增 `copaper-relatedwork.md`;`opencode.json` 已包含 `@copaper/opencode` 条目时不重复添加;`bun link` 让该 specifier 解析到本地最新源码,覆盖之前的 npm 安装。重启 OpenCode 即可生效。 ###### 完整卸载 <!-- description: full uninstall steps for a target project --> @@ -234,26 +234,26 @@ bun run dev:install /path/to/target-project ```bash # 1. 解除 link 并删除 node_modules 符号链接 -cd /Users/zrzz/Coding/VibePaper-OpenCode/packages/opencode-plugin +cd /Users/zrzz/Coding/CoPaper-OpenCode/packages/opencode-plugin bun run dev:reset /path/to/target-project # 2. 删除 slash 命令和 OpenCode 配置中的 plugin 条目 cd /path/to/target-project -trash .opencode/commands/vibe.md .opencode/commands/vibe-doctor.md .opencode/commands/vibe-relatedwork.md -trash opencode.json # 或手动编辑去掉 plugin 数组里的 "@vibepaper/opencode" +trash .opencode/commands/copaper.md .opencode/commands/copaper-doctor.md .opencode/commands/copaper-relatedwork.md +trash opencode.json # 或手动编辑去掉 plugin 数组里的 "@copaper/opencode" # 3. 重启 OpenCode 让其重新读取配置 ``` -`trash` 取代 `rm` 以便文件可恢复;若不可用可用 `rm`。Python 端的 `<target>/.venv/bin/vibe` 不属于 OpenCode 集成,保留即可。 +`trash` 取代 `rm` 以便文件可恢复;若不可用可用 `rm`。Python 端的 `<target>/.venv/bin/copaper` 不属于 OpenCode 集成,保留即可。 ###### Python 端前置条件 <!-- description: Python prerequisites for relatedwork tools --> -`vibe-relatedwork` 的所有写盘工具底层都调用 `vibe relatedwork ...` Python CLI。bridge 的解析顺序: +`copaper-relatedwork` 的所有写盘工具底层都调用 `copaper relatedwork ...` Python CLI。bridge 的解析顺序: -1. `<target>/.venv/bin/vibe`(首选;最快、零依赖) -2. `PATH` 中的 `uv` → `uv run --project <target> vibe ...` -3. 都没有 → 工具返回 `vibe-cli-unavailable`,`/vibe-doctor` 的 `vibe-cli.available` 检查会标红 +1. `<target>/.venv/bin/copaper`(首选;最快、零依赖) +2. `PATH` 中的 `uv` → `uv run --project <target> copaper ...` +3. 都没有 → 工具返回 `copaper-cli-unavailable`,`/copaper-doctor` 的 `copaper-cli.available` 检查会标红 ###### Relatedwork 参数合同 <!-- description: Python CLI argument contract for relatedwork bridge --> @@ -271,7 +271,7 @@ bun run dev:install /path/to/target-project --with-python # 方式 B:手动管理目标项目的 venv cd /path/to/target-project uv venv # 若没有 .venv -uv pip install -e /path/to/VibePaper-OpenCode # 把 vibepaper 装到当前 .venv +uv pip install -e /path/to/CoPaper-OpenCode # 把 copaper 装到当前 .venv ``` ###### Relatedwork 最小发布验证 @@ -283,6 +283,6 @@ bun test tests/relatedwork-tools.test.ts bun run typecheck ``` -这两个命令验证 TypeScript 工具生成的 `vibe relatedwork ...` 参数与当前 Python CLI 合同一致,并保证类型检查通过。 +这两个命令验证 TypeScript 工具生成的 `copaper relatedwork ...` 参数与当前 Python CLI 合同一致,并保证类型检查通过。 要求 `uv >= 0.4`(用于 `uv venv` 和 `uv pip install`)。bridge 不会主动激活 `.venv`,所以**不依赖** shell 的 `source .venv/bin/activate`。 diff --git a/packages/opencode-plugin/USAGE_TEST.zh-CN.md b/packages/opencode-plugin/USAGE_TEST.zh-CN.md index 7486553..954ae60 100644 --- a/packages/opencode-plugin/USAGE_TEST.zh-CN.md +++ b/packages/opencode-plugin/USAGE_TEST.zh-CN.md @@ -1,29 +1,29 @@ -# @vibepaper/opencode 测试手册 +# @copaper/opencode 测试手册 <!-- description: OpenCode 插件 Dashboard、工件状态、初始化写入与 workflow 工具测试流程 --> ## 文档状态 <!-- description: 测试手册适用范围和当前基线 --> ###### 适用阶段 -本文档覆盖 `feature/opencode-plugin-mvp` 分支的 Dashboard、初始化写入、artifact status、artifact readiness record、workflow 工具和 VibePaper agent profile 阶段。测试范围包括安装、诊断、locale、Dashboard、工件状态、显式就绪度记录、专用 subagent 注入、权限 profile、显式确认初始化、workflow 状态/日志/阶段控制、冲突保护、本地 tarball、打包内容和回归验证。 +本文档覆盖 `feature/opencode-plugin-mvp` 分支的 Dashboard、初始化写入、artifact status、artifact readiness record、workflow 工具和 CoPaper agent profile 阶段。测试范围包括安装、诊断、locale、Dashboard、工件状态、显式就绪度记录、专用 subagent 注入、权限 profile、显式确认初始化、workflow 状态/日志/阶段控制、冲突保护、本地 tarball、打包内容和回归验证。 ###### 当前边界 初始化 smoke 只在用户明确确认并提供项目名称、研究领域后写入第一版初始化文件。它不会创建 `.agents/skills/` 或 `relatedwork/`,也不会自动推进阶段、记忆、文献流程或子代理编排;显式 workflow 阶段控制见后文手测步骤。 -Artifact status 默认用于只读材料诊断。只有用户明确要求并确认后,`vibepaper-recorder` 才能通过 `vibepaper_artifact_record` 写入 `.agents/state.json.artifacts` 并追加 `.agents/events.jsonl`;非 recorder agent 调用该工具应返回 `agent-not-authorized` 且不写文件。该记录不会推进 phase、安装 skills、运行 relatedwork、运行 checker/report/git,或触发 Python CLI parity。 +Artifact status 默认用于只读材料诊断。只有用户明确要求并确认后,`copaper-recorder` 才能通过 `copaper_artifact_record` 写入 `.agents/state.json.artifacts` 并追加 `.agents/events.jsonl`;非 recorder agent 调用该工具应返回 `agent-not-authorized` 且不写文件。该记录不会推进 phase、安装 skills、运行 relatedwork、运行 checker/report/git,或触发 Python CLI parity。 -Agent profile 层默认注入 `@vibepaper-coordinator`、`@vibepaper-storyline`、`@vibepaper-writer` 和 `@vibepaper-recorder`。项目覆盖只能禁用 agent、设置 model hint/temperature、追加 prompt preference 或降级 permission profile;不能扩大到 shell、Git、network、external directory、unrestricted edit 或 provider secret/API key 访问。 +Agent profile 层默认注入 `@copaper-coordinator`、`@copaper-storyline`、`@copaper-writer` 和 `@copaper-recorder`。项目覆盖只能禁用 agent、设置 model hint/temperature、追加 prompt preference 或降级 permission profile;不能扩大到 shell、Git、network、external directory、unrestricted edit 或 provider secret/API key 访问。 ###### 最近验证基线 - `python -m pytest tests/ -q`:`305 passed in 45.82s` -- `bun test tests/permission-profiles.test.ts tests/agent-profiles.test.ts tests/vibepaper-config.test.ts tests/agent-config.test.ts`:`31 pass`,`0 fail` +- `bun test tests/permission-profiles.test.ts tests/agent-profiles.test.ts tests/copaper-config.test.ts tests/agent-config.test.ts`:`31 pass`,`0 fail` - `bun test tests/plugin.test.ts tests/doctor.test.ts tests/command-templates.test.ts`:`34 pass`,`0 fail` - `bun test`:`202 pass`,`0 fail` - `bun run typecheck`:通过 - `bun run build`:通过 - `bun run test:cli`:`16 pass`,`0 fail` - `bun run test:package`:`5 pass`,`0 fail` -- `npm pack --dry-run`:`48` 个 package 文件,tarball 文件名为 `vibepaper-opencode-0.1.0.tgz` +- `npm pack --dry-run`:`48` 个 package 文件,tarball 文件名为 `copaper-opencode-0.1.0.tgz` ###### 更新规则 每次修改插件行为后,先更新自动化验证结果,再更新手测记录。命令名、工具名、JSON 字段和枚举保持 English;说明文字默认使用中文。 @@ -76,10 +76,10 @@ bun test tests/artifact-record.test.ts tests/artifacts.test.ts tests/dashboard.t 在 `packages/opencode-plugin` 运行: ```bash -bun test tests/permission-profiles.test.ts tests/agent-profiles.test.ts tests/vibepaper-config.test.ts tests/agent-config.test.ts tests/plugin.test.ts tests/doctor.test.ts tests/command-templates.test.ts +bun test tests/permission-profiles.test.ts tests/agent-profiles.test.ts tests/copaper-config.test.ts tests/agent-config.test.ts tests/plugin.test.ts tests/doctor.test.ts tests/command-templates.test.ts ``` -期望 permission profile、内置 agent prompt、`.opencode/vibepaper.json` 解析、OpenCode agent 注入、同名冲突、权限升级拒绝、recorder 工具门控和 doctor/template 诊断全部通过。 +期望 permission profile、内置 agent prompt、`.opencode/copaper.json` 解析、OpenCode agent 注入、同名冲突、权限升级拒绝、recorder 工具门控和 doctor/template 诊断全部通过。 ###### Relatedwork bridge 聚焦回归 在 `packages/opencode-plugin` 运行: @@ -102,25 +102,25 @@ bun run typecheck - `project-init.test.ts`:验证 apply 成功、缺参、冲突、父路径阻塞、dangling symlink 和本地化输出。 - `workflow.test.ts`:验证动态 phase status/log、JSONL 容错、set phase、事件追加、路径安全和无固定阶段假设。 - `artifacts.test.ts`:验证 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/`、`.agents/cross_index.json`、checker result 状态值、recorded readiness 合并、stale hash、summary、recommendation、evidence、locale、路径安全和只读行为。 -- `artifact-record.test.ts`:验证 `vibepaper_artifact_record` 核心逻辑,包括参数校验、state artifacts 写入、事件追加、previous record、hash fallback、事件路径边界、symlink 安全和失败不写入。 +- `artifact-record.test.ts`:验证 `copaper_artifact_record` 核心逻辑,包括参数校验、state artifacts 写入、事件追加、previous record、hash fallback、事件路径边界、symlink 安全和失败不写入。 - `dashboard.test.ts`:验证中文/英文 Dashboard、坏集成优先修复、ready 项目、apply 后 ready、Artifacts→Workflow 展示顺序、artifact recommendation 列、recorded readiness/stale 展示和 JSON block。 -- `permission-profiles.test.ts`:验证 `readOnly`、`storylineWrite`、`paperWrite`、`stateRecord` 权限模板、secret read deny、VibePaper 工具 allow/deny、降级矩阵和 clone safety。 +- `permission-profiles.test.ts`:验证 `readOnly`、`storylineWrite`、`paperWrite`、`stateRecord` 权限模板、secret read deny、CoPaper 工具 allow/deny、降级矩阵和 clone safety。 - `agent-profiles.test.ts`:验证四个内置 subagent、permission ceiling、prompt 边界、反编造规则、writer reference boundary 和 handoff policy。 -- `vibepaper-config.test.ts`:验证 `.opencode/vibepaper.json` 缺失、JSONC 解析、schema fallback、未知字段/agent、无效 locale/temperature/permission profile 和 no-write 行为。 +- `copaper-config.test.ts`:验证 `.opencode/copaper.json` 缺失、JSONC 解析、schema fallback、未知字段/agent、无效 locale/temperature/permission profile 和 no-write 行为。 - `agent-config.test.ts`:验证默认注入、model/temperature/promptAppend 合并、禁用 agent、同名冲突、权限升级拒绝、安全降级和 diagnostic path/field。 - `plugin.test.ts`:验证工具注册、`config` hook 注入和幂等、root-aware diagnostics、`ToolContext` 根目录、Dashboard 只读路径、artifact status 运行时 root、recorder-only artifact record、init apply 写入路径和 workflow 工具运行时 root。 -- `command-templates.test.ts`:验证 `/vibe` 初始化确认、artifact status 只读指引、artifact record 显式确认指引、workflow read 工具指引、set phase 写入确认规则和 agent profile 指引。 +- `command-templates.test.ts`:验证 `/copaper` 初始化确认、artifact status 只读指引、artifact record 显式确认指引、workflow read 工具指引、set phase 写入确认规则和 agent profile 指引。 - `relatedwork-tools.test.ts`:验证 OpenCode relatedwork 工具生成的 Python CLI argv、bridge 错误展示、status refresh、literature phase patch、事件追加、keywords 写入由 Python CLI 处理且插件不额外追加 phase-patch 事件和输出渲染。 - `cli.test.ts`、`doctor.test.ts`、`package-smoke.test.ts`:验证 CLI、doctor、agent profile diagnostics、打包 smoke 和 locale。 ###### 回归重点 -`/vibe` 必须先返回只读 Dashboard,不应直接写项目文件。`vibepaper_init_apply` 必须要求 `name` 和 `domain`,并在任何目标冲突、父路径阻塞或 dangling symlink 时整体中止。`vibepaper_workflow_status` 与 `vibepaper_workflow_log` 必须只读;`vibepaper_workflow_set_phase` 只能在确认后写入 `.agents/state.json` 和 `.agents/events.jsonl`,且 phase 列表必须来自实际 `state.phases`。 +`/copaper` 必须先返回只读 Dashboard,不应直接写项目文件。`copaper_init_apply` 必须要求 `name` 和 `domain`,并在任何目标冲突、父路径阻塞或 dangling symlink 时整体中止。`copaper_workflow_status` 与 `copaper_workflow_log` 必须只读;`copaper_workflow_set_phase` 只能在确认后写入 `.agents/state.json` 和 `.agents/events.jsonl`,且 phase 列表必须来自实际 `state.phases`。 -`vibepaper_artifact_status` 必须保持只读;默认初始化模板不得被误判为 `ready`;所有 artifact status 都必须包含 `evidence` 和 `confidence`。 +`copaper_artifact_status` 必须保持只读;默认初始化模板不得被误判为 `ready`;所有 artifact status 都必须包含 `evidence` 和 `confidence`。 -`vibepaper_artifact_record` 只能由 `vibepaper-recorder` 在用户确认后写 `.agents/state.json.artifacts` 和 `.agents/events.jsonl`;非 recorder agent 必须返回 `agent-not-authorized` 且不写文件。该工具还必须拒绝 `skills`、无效 status/confidence、空 evidence/reason、缺失/损坏 state,以及非 `.agents/events.jsonl` 的事件路径。 +`copaper_artifact_record` 只能由 `copaper-recorder` 在用户确认后写 `.agents/state.json.artifacts` 和 `.agents/events.jsonl`;非 recorder agent 必须返回 `agent-not-authorized` 且不写文件。该工具还必须拒绝 `skills`、无效 status/confidence、空 evidence/reason、缺失/损坏 state,以及非 `.agents/events.jsonl` 的事件路径。 -Agent profile config hook 启动时只能读取 `.opencode/vibepaper.json` 并注入缺失的 `vibepaper-*` agents;不得写 `.agents/state.json`、`.agents/events.jsonl`、`.opencode/agents` 或任何项目 artifact。同名 OpenCode agent 必须由用户定义优先,VibePaper 只记录 conflict diagnostic。`read` 权限必须保留 `.env` 和 `.env.*` deny,并允许 `.env.example`。 +Agent profile config hook 启动时只能读取 `.opencode/copaper.json` 并注入缺失的 `copaper-*` agents;不得写 `.agents/state.json`、`.agents/events.jsonl`、`.opencode/agents` 或任何项目 artifact。同名 OpenCode agent 必须由用户定义优先,CoPaper 只记录 conflict diagnostic。`read` 权限必须保留 `.env` 和 `.env.*` deny,并允许 `.env.example`。 ## 本地包安装测试 <!-- description: 不依赖 npm 发布的本地安装流程 --> @@ -133,7 +133,7 @@ bun run build npm pack ``` -期望生成 `vibepaper-opencode-0.1.0.tgz`。如果只需要检查打包内容,使用 `npm pack --dry-run`,避免留下 tarball 工件。 +期望生成 `copaper-opencode-0.1.0.tgz`。如果只需要检查打包内容,使用 `npm pack --dry-run`,避免留下 tarball 工件。 ###### 创建临时项目 创建空目录作为目标项目: @@ -148,11 +148,11 @@ tmp_project="$(mktemp -d)" Bun 1.3.13 的 `bunx` 不能直接执行本地 tarball。测试 tarball 时,应先安装到临时项目,再运行安装后的 bin: ```bash -tarball="$(pwd)/vibepaper-opencode-0.1.0.tgz" -bun remove --cwd "$tmp_project" @vibepaper/opencode || true -rm -rf "$tmp_project/node_modules/@vibepaper" "$tmp_project/bun.lock" "$tmp_project/package-lock.json" +tarball="$(pwd)/copaper-opencode-0.1.0.tgz" +bun remove --cwd "$tmp_project" @copaper/opencode || true +rm -rf "$tmp_project/node_modules/@copaper" "$tmp_project/bun.lock" "$tmp_project/package-lock.json" bun add --cwd "$tmp_project" "$tarball" -"$tmp_project/node_modules/.bin/vibepaper-opencode" init --root "$tmp_project" +"$tmp_project/node_modules/.bin/copaper-opencode" init --root "$tmp_project" ``` 如果不验证 tarball 安装路径,可使用本地构建 fallback: @@ -165,8 +165,8 @@ bun dist/cli.js init --root "$tmp_project" `init` 只应写入 OpenCode 集成文件: - `$tmp_project/opencode.json` -- `$tmp_project/.opencode/commands/vibe.md` -- `$tmp_project/.opencode/commands/vibe-doctor.md` +- `$tmp_project/.opencode/commands/copaper.md` +- `$tmp_project/.opencode/commands/copaper-doctor.md` `init` 不应写入 `paper.md`、`storyline.md`、`writingrules.md`、`AGENTS.md`、`.agents/state.json`、`.agents/events.jsonl`、`.agents/skills/` 或 `relatedwork/`。 @@ -175,11 +175,11 @@ bun dist/cli.js init --root "$tmp_project" ```json { - "plugin": ["file:///tmp/project/node_modules/@vibepaper/opencode/dist/index.js"] + "plugin": ["file:///tmp/project/node_modules/@copaper/opencode/dist/index.js"] } ``` -发布后的 npm 安装应写入包名:`"@vibepaper/opencode"`。如果项目已有 OpenCode 配置,安装器应合并插件项,而不是覆盖无关配置。 +发布后的 npm 安装应写入包名:`"@copaper/opencode"`。如果项目已有 OpenCode 配置,安装器应合并插件项,而不是覆盖无关配置。 ## Doctor 测试 <!-- description: 终端诊断命令验证流程 --> @@ -193,13 +193,13 @@ bun dist/cli.js doctor --root "$tmp_project" --format markdown bun dist/cli.js doctor --root "$tmp_project" --format json ``` -期望 doctor 识别 OpenCode 配置、插件注册、`/vibe` 和 `/vibe-doctor`。默认文本和 Markdown 输出为中文;JSON 字段名和状态枚举保持 English。 +期望 doctor 识别 OpenCode 配置、插件注册、`/copaper` 和 `/copaper-doctor`。默认文本和 Markdown 输出为中文;JSON 字段名和状态枚举保持 English。 ###### Locale 诊断 验证英文输出: ```bash -VIBEPAPER_LANG=en-US bun dist/cli.js doctor --root "$tmp_project" +COPAPER_LANG=en-US bun dist/cli.js doctor --root "$tmp_project" bun dist/cli.js doctor --root "$tmp_project" --locale en-US ``` @@ -209,10 +209,10 @@ bun dist/cli.js doctor --root "$tmp_project" --locale en-US 测试已发布 npm 包时,应使用 Bun 的 `-p` 语法: ```bash -bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" +bunx -p @copaper/opencode copaper-opencode doctor --root "$tmp_project" ``` -不要写成 `bunx @vibepaper/opencode doctor`,因为包名和 bin 名不同。 +不要写成 `bunx @copaper/opencode doctor`,因为包名和 bin 名不同。 ###### 歧义配置 如果同一项目同时存在 `opencode.json` 和 `opencode.jsonc`,且未显式传入 `--config`,doctor 应失败关闭并提示选择配置文件。传入 `--config opencode.jsonc` 后应读取指定配置。 @@ -227,7 +227,7 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" 在 OpenCode 会话中执行: ```text -/vibe-doctor +/copaper-doctor ``` 期望看到 doctor markdown 输出,且能指出当前插件集成状态。若工具或命令无法加载,用终端 doctor 复核配置。 @@ -236,16 +236,16 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" 在 OpenCode 会话中执行: ```text -/vibe +/copaper ``` -期望 agent 调用或尝试调用 `vibepaper_dashboard`,并在最终回复中包含工具返回的人类可读 markdown 正文和表格,而不是只总结工具结果。默认省略 fenced JSON block;只有用户明确要求 JSON、debug、原始输出或完整工具输出时,才包含 JSON。输出应包含 Header、项目就绪度、检查清单、推荐下一步和初始化预览等人类可读区块。此步骤只读,`/vibe` 前后的目录 hash 应保持一致。 +期望 agent 调用或尝试调用 `copaper_dashboard`,并在最终回复中包含工具返回的人类可读 markdown 正文和表格,而不是只总结工具结果。默认省略 fenced JSON block;只有用户明确要求 JSON、debug、原始输出或完整工具输出时,才包含 JSON。输出应包含 Header、项目就绪度、检查清单、推荐下一步和初始化预览等人类可读区块。此步骤只读,`/copaper` 前后的目录 hash 应保持一致。 ###### Dashboard 状态 未初始化但 OpenCode 集成健康的项目应显示 `needs-init`,并列出核心文件的 `create` 预览动作。已具备核心文件和 `.agents/state.json` 的项目应显示 `ready`。OpenCode 集成损坏时,应优先推荐修复安装,并隐藏项目初始化预览。 ###### 确认初始化 -在 `/vibe` 显示 `needs-init` 后,期望 agent 使用 `question tool` 询问是否初始化,并收集或确认项目名称和研究领域。如果缺少项目名称或研究领域,期望 agent 继续使用 `question tool` 追问缺失字段。提供 `name` 和 `domain` 且明确确认后,agent 才应调用 `vibepaper_init_apply`。 +在 `/copaper` 显示 `needs-init` 后,期望 agent 使用 `question tool` 询问是否初始化,并收集或确认项目名称和研究领域。如果缺少项目名称或研究领域,期望 agent 继续使用 `question tool` 追问缺失字段。提供 `name` 和 `domain` 且明确确认后,agent 才应调用 `copaper_init_apply`。 ###### 成功写入 成功 apply 后应出现以下文件: @@ -257,30 +257,30 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" - `.agents/state.json` - `.agents/events.jsonl` -不应出现 `.agents/skills/` 或 `relatedwork/`。再次运行 `/vibe` 应显示 ready 语义,`.agents/state.json` 中的 `project.name`、`project.domain` 和 `project.created_at` 应被写入。 +不应出现 `.agents/skills/` 或 `relatedwork/`。再次运行 `/copaper` 应显示 ready 语义,`.agents/state.json` 中的 `project.name`、`project.domain` 和 `project.created_at` 应被写入。 ###### Workflow 状态检查 -成功初始化后,再次运行 `/vibe`。期望 Dashboard 包含工作流区块,展示当前 phase、动态 phase 状态表和最近事件。若 `.agents/state.json` 中出现非默认 phase 名称,Dashboard 应展示实际 phase 名称,不应假设固定 6 个阶段。 +成功初始化后,再次运行 `/copaper`。期望 Dashboard 包含工作流区块,展示当前 phase、动态 phase 状态表和最近事件。若 `.agents/state.json` 中出现非默认 phase 名称,Dashboard 应展示实际 phase 名称,不应假设固定 6 个阶段。 ###### Artifact 状态检查 <!-- description: Manual artifact status after init apply --> -成功初始化后运行 `/vibe`。期望 Dashboard 先显示 artifact status,再显示 workflow。artifact 覆盖 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/`、`.agents/cross_index.json` 和 checker results;行包含 ID、status、confidence、recorded status、recorded freshness、evidence 和推荐下一步;默认模板中的 `storyline` 和 `paper` 应为 `template`,不是 `ready`。 +成功初始化后运行 `/copaper`。期望 Dashboard 先显示 artifact status,再显示 workflow。artifact 覆盖 `storyline.md`、`paper.md`、`relatedwork/`、`.agents/skills/`、`.agents/cross_index.json` 和 checker results;行包含 ID、status、confidence、recorded status、recorded freshness、evidence 和推荐下一步;默认模板中的 `storyline` 和 `paper` 应为 `template`,不是 `ready`。 ###### Artifact 就绪度记录 <!-- description: Manual artifact readiness recording behavior --> -用户明确要求记录工件就绪度时,agent 必须先复述 artifact、status、confidence 和 reason,并等待确认。确认后才可调用 `vibepaper_artifact_record`,成功时只更新 `.agents/state.json.artifacts` 并追加 `.agents/events.jsonl` 的 `record_artifact_readiness` 事件。 +用户明确要求记录工件就绪度时,agent 必须先复述 artifact、status、confidence 和 reason,并等待确认。确认后才可调用 `copaper_artifact_record`,成功时只更新 `.agents/state.json.artifacts` 并追加 `.agents/events.jsonl` 的 `record_artifact_readiness` 事件。 ###### Artifact 记录边界 手测时可把 `.agents/state.json` 的 `event_log_path` 临时改成 `paper.md`,再尝试记录 `paper`。期望工具返回 `event-log-failed`,`paper.md` 和 `.agents/state.json` 都保持不变。 ###### Artifact 记录 agent 门控 -在非 `@vibepaper-recorder` 角色中尝试调用 `vibepaper_artifact_record`。期望工具返回 `agent-not-authorized`,`.agents/state.json` 和 `.agents/events.jsonl` 都保持不变。切换到 `@vibepaper-recorder` 并明确确认后,才允许记录 readiness。 +在非 `@copaper-recorder` 角色中尝试调用 `copaper_artifact_record`。期望工具返回 `agent-not-authorized`,`.agents/state.json` 和 `.agents/events.jsonl` 都保持不变。切换到 `@copaper-recorder` 并明确确认后,才允许记录 readiness。 ###### Workflow 日志查询 -询问“最近发生了什么”时,期望 agent 调用 `vibepaper_workflow_log`。输出应包含最近事件表和稳定 JSON block。损坏的 JSONL 行应被跳过并通过 warning 反映。 +询问“最近发生了什么”时,期望 agent 调用 `copaper_workflow_log`。输出应包含最近事件表和稳定 JSON block。损坏的 JSONL 行应被跳过并通过 warning 反映。 ###### Workflow 阶段修改 -要求修改阶段状态时,期望 agent 先复述目标 phase、status,并在 status 为 `skipped` 时复述 reason,然后等待确认。确认后调用 `vibepaper_workflow_set_phase`,更新 `.agents/state.json` 并向 `.agents/events.jsonl` 追加 `set_phase_status` 事件。 +要求修改阶段状态时,期望 agent 先复述目标 phase、status,并在 status 为 `skipped` 时复述 reason,然后等待确认。确认后调用 `copaper_workflow_set_phase`,更新 `.agents/state.json` 并向 `.agents/events.jsonl` 追加 `set_phase_status` 事件。 ###### 动态 phase 回归 将 `.agents/state.json` 的 `phases` 临时改为自定义 phase,例如 `discussion_problem_framing` 和 `discussion_evidence_mapping`,并加入循环 `workflow.dependencies`。期望 status、Dashboard 和 set phase 都能工作,不要求 DAG,也不阻止写入。 @@ -295,19 +295,19 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" <!-- description: OpenCode agent profile diagnostics manual checks --> ###### Agent 基线检查 -在 OpenCode 会话中运行 `/vibe`。期望 Dashboard 或 agent selector 可见四个注入 agent:`@vibepaper-coordinator`、`@vibepaper-storyline`、`@vibepaper-writer` 和 `@vibepaper-recorder`。 +在 OpenCode 会话中运行 `/copaper`。期望 Dashboard 或 agent selector 可见四个注入 agent:`@copaper-coordinator`、`@copaper-storyline`、`@copaper-writer` 和 `@copaper-recorder`。 ###### Agent 诊断检查 -运行 `/vibe-doctor`。期望 agent profile diagnostics 列出四个注入 agent,并显示每个 agent 的 permission profile;有效覆盖配置不应产生 config warning。 +运行 `/copaper-doctor`。期望 agent profile diagnostics 列出四个注入 agent,并显示每个 agent 的 permission profile;有效覆盖配置不应产生 config warning。 ###### Writer 偏好覆盖 -在项目根创建 `.opencode/vibepaper.json`,只覆盖 `vibepaper-writer.promptAppend`: +在项目根创建 `.opencode/copaper.json`,只覆盖 `copaper-writer.promptAppend`: ```json { "schemaVersion": 1, "agents": { - "vibepaper-writer": { + "copaper-writer": { "promptAppend": "Prefer concise transitions during manual smoke tests." } } @@ -315,13 +315,13 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" ``` ###### Doctor 覆盖诊断 -重启 OpenCode 后运行 `/vibe-doctor`。期望 agent profile diagnostics 通过,`vibepaper-writer` 仍处于可用状态,且有效 `.opencode/vibepaper.json` 覆盖不会产生 config warning。 +重启 OpenCode 后运行 `/copaper-doctor`。期望 agent profile diagnostics 通过,`copaper-writer` 仍处于可用状态,且有效 `.opencode/copaper.json` 覆盖不会产生 config warning。 ###### Coordinator 权限降级 -把 `.opencode/vibepaper.json` 改为给 `vibepaper-coordinator` 设置 `permissionProfile: "paperWrite"`,重启 OpenCode 并运行 `/vibe-doctor`。期望出现 `permission-escalation-denied`,且 coordinator 最终仍保持 `readOnly`。 +把 `.opencode/copaper.json` 改为给 `copaper-coordinator` 设置 `permissionProfile: "paperWrite"`,重启 OpenCode 并运行 `/copaper-doctor`。期望出现 `permission-escalation-denied`,且 coordinator 最终仍保持 `readOnly`。 ###### 配置清理 -完成权限降级检查后,删除 `.opencode/vibepaper.json`,或还原为只包含 `vibepaper-writer.promptAppend` 的覆盖配置。再次运行 `/vibe-doctor`,确认不再出现 `permission-escalation-denied`,避免污染后续手测。 +完成权限降级检查后,删除 `.opencode/copaper.json`,或还原为只包含 `copaper-writer.promptAppend` 的覆盖配置。再次运行 `/copaper-doctor`,确认不再出现 `permission-escalation-denied`,避免污染后续手测。 ## 场景矩阵 <!-- description: 手动和自动化场景对照 --> @@ -329,26 +329,26 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" ###### 必测路径 | 场景 | 触发方式 | 期望结果 | | --- | --- | --- | -| 空项目 Dashboard | `/vibe` | `needs-init`,只读预览,目录 hash 不变 | +| 空项目 Dashboard | `/copaper` | `needs-init`,只读预览,目录 hash 不变 | | 缺少参数 | “确认初始化”但缺 name/domain | agent 使用 `question tool` 追问,不调用 apply | | 成功 apply | 确认并提供 name/domain | 写入 6 个核心文件,ready | | 用户文件冲突 | 预先创建 `paper.md` | 整体中止,`changedFiles` 为空 | | 父路径阻塞 | 预先创建 `.agents` 文件 | 整体中止,无部分写入 | | 损坏集成 | 删除插件配置或命令 | Dashboard 推荐修复安装 | -| Workflow 状态 | ready 后运行 `/vibe` | 展示当前 phase、动态 phase 表和最近事件 | -| Artifact 模板识别 | init apply 后运行 `/vibe` | `storyline` 和 `paper` 显示 `template`,含 evidence | -| Artifact 只读 | `/vibe` 或直接 artifact tool | 目录 hash 不变,不写 state、不推进 phase | -| Artifact 记录 | 确认 artifact/status/confidence/reason 后 | 调用 `vibepaper_artifact_record`,写 `state.artifacts` 并追加 `record_artifact_readiness` 事件 | +| Workflow 状态 | ready 后运行 `/copaper` | 展示当前 phase、动态 phase 表和最近事件 | +| Artifact 模板识别 | init apply 后运行 `/copaper` | `storyline` 和 `paper` 显示 `template`,含 evidence | +| Artifact 只读 | `/copaper` 或直接 artifact tool | 目录 hash 不变,不写 state、不推进 phase | +| Artifact 记录 | 确认 artifact/status/confidence/reason 后 | 调用 `copaper_artifact_record`,写 `state.artifacts` 并追加 `record_artifact_readiness` 事件 | | Artifact 记录边界 | `event_log_path` 指向 `paper.md` | 返回 `event-log-failed`,不写 state,不污染 `paper.md` | | Artifact recorder 门控 | 非 recorder agent 调用 record tool | 返回 `agent-not-authorized`,不写 state/events | | Artifact 空目录 | 创建空 `relatedwork/` 后运行 artifact tool | `relatedwork` 为 `partial`,含 `directory-present` evidence | | Artifact stale | `paper.md` 晚于 precheck report | `checker_results` 显示 `stale` 和 warning | -| Workflow 日志 | 询问最近记录 | 调用 `vibepaper_workflow_log`,坏 JSONL 行只产生 warning | -| Workflow 修改 | 确认 phase/status 后 | 调用 `vibepaper_workflow_set_phase`,写 state 并追加事件 | +| Workflow 日志 | 询问最近记录 | 调用 `copaper_workflow_log`,坏 JSONL 行只产生 warning | +| Workflow 修改 | 确认 phase/status 后 | 调用 `copaper_workflow_set_phase`,写 state 并追加事件 | | 动态 phase | 自定义 `state.phases` 和循环 dependencies | 不要求 DAG,不阻止 status/log/set phase | -| Agent 默认注入 | OpenCode 重启后运行 `/vibe-doctor` | 四个 `vibepaper-*` agent injected,显示 permission profile | +| Agent 默认注入 | OpenCode 重启后运行 `/copaper-doctor` | 四个 `copaper-*` agent injected,显示 permission profile | | Agent 权限升级拒绝 | coordinator 请求 `paperWrite` | `permission-escalation-denied`,coordinator 保持 `readOnly` | -| Agent 同名冲突 | OpenCode config 已有 `vibepaper-writer` | 用户 agent 保留,doctor 显示 conflict diagnostic | +| Agent 同名冲突 | OpenCode config 已有 `copaper-writer` | 用户 agent 保留,doctor 显示 conflict diagnostic | | 英文输出 | `--locale en-US` 或 env | 文案英文,JSON 字段仍 English | ## 根目录识别测试 @@ -358,10 +358,10 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" 传入 `--root <dir>` 时,CLI 应以该目录为项目根,而不是继续向上搜索 Git 或 OpenCode 配置。 ###### 最近配置优先 -从子目录运行时,应优先选择最近目录中的 `opencode.json`、`opencode.jsonc` 或受管 `.opencode/commands/vibe.md` 标记。同一目录内优先级为 `opencode.json`、`opencode.jsonc`、marker。 +从子目录运行时,应优先选择最近目录中的 `opencode.json`、`opencode.jsonc` 或受管 `.opencode/commands/copaper.md` 标记。同一目录内优先级为 `opencode.json`、`opencode.jsonc`、marker。 ###### 损坏 marker -如果较近的 `.opencode/commands/vibe.md` 是目录或不可读文件,root 检测不应崩溃。应忽略该 marker 并继续向父目录查找有效配置。 +如果较近的 `.opencode/commands/copaper.md` 是目录或不可读文件,root 检测不应崩溃。应忽略该 marker 并继续向父目录查找有效配置。 ## 验收标准 <!-- description: Dashboard + 初始化写入阶段通过条件 --> @@ -380,14 +380,14 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" ###### 手动验收 - `init` 能写入 OpenCode 插件配置和两个 slash command。 -- `/vibe-doctor` 能默认展示中文诊断信息。 -- `/vibe` 能展示工具返回的人类可读 markdown/table、readiness、检查清单、推荐下一步和初始化预览;默认省略 fenced JSON block,显式要求 JSON/debug/原始/完整输出时才包含 JSON。 -- `/vibe` 在收集参数后能确认执行初始化写入。 -- ready 项目的 `/vibe` 能展示 artifact 区块,且 artifact status 只读、不触发写 state 或自动流程。 +- `/copaper-doctor` 能默认展示中文诊断信息。 +- `/copaper` 能展示工具返回的人类可读 markdown/table、readiness、检查清单、推荐下一步和初始化预览;默认省略 fenced JSON block,显式要求 JSON/debug/原始/完整输出时才包含 JSON。 +- `/copaper` 在收集参数后能确认执行初始化写入。 +- ready 项目的 `/copaper` 能展示 artifact 区块,且 artifact status 只读、不触发写 state 或自动流程。 - artifact readiness 记录必须先等待用户确认;成功后只写 `state.artifacts` 和 event log,不自动推进 phase。 -- artifact readiness 记录必须由 `@vibepaper-recorder` 执行;非 recorder agent 被拒绝且不写 state/events。 -- `/vibe-doctor` 能展示 agent profile diagnostics,包括 injected、disabled/conflicted、permission profile 和 permission escalation warning。 -- ready 项目的 `/vibe` 能展示 workflow 区块,并在 workflow 状态无效时隐藏区块但保留 JSON 诊断。 +- artifact readiness 记录必须由 `@copaper-recorder` 执行;非 recorder agent 被拒绝且不写 state/events。 +- `/copaper-doctor` 能展示 agent profile diagnostics,包括 injected、disabled/conflicted、permission profile 和 permission escalation warning。 +- ready 项目的 `/copaper` 能展示 workflow 区块,并在 workflow 状态无效时隐藏区块但保留 JSON 诊断。 - workflow 状态修改必须先等待用户确认;`skipped` 必须说明 reason,并追加 `set_phase_status` 事件。 - 冲突场景有明确错误输出,且不会部分写入。 @@ -400,14 +400,14 @@ bunx -p @vibepaper/opencode vibepaper-opencode doctor --root "$tmp_project" - 执行的命令、完整输出和当前工作目录。 - `opencode.json` 或 `opencode.jsonc` 的相关片段。 - `.opencode/commands/` 下实际生成的文件列表。 -- `/vibe` 或 `/vibe-doctor` 的完整 markdown 输出。 +- `/copaper` 或 `/copaper-doctor` 的完整 markdown 输出。 - 是否能通过终端 `doctor --format json` 复现。 ## 后续扩展 <!-- description: 当前阶段之后可补充的测试方向 --> ###### 发布后测试 -包发布到 npm 后,应补充真实 `bunx -p @vibepaper/opencode vibepaper-opencode init` 安装测试,并确认 OpenCode 能从已发布包加载插件。 +包发布到 npm 后,应补充真实 `bunx -p @copaper/opencode copaper-opencode init` 安装测试,并确认 OpenCode 能从已发布包加载插件。 ###### Workflow 深化 后续可补充 skills 安装、relatedwork 实际流程、报告联动、状态迁移和更深 workflow 行为测试。当前 artifact cockpit 只扫描材料状态并支持显式就绪度记录,不负责启动这些后续流程。 diff --git a/packages/opencode-plugin/codemap.md b/packages/opencode-plugin/codemap.md index 0010d04..5b21833 100644 --- a/packages/opencode-plugin/codemap.md +++ b/packages/opencode-plugin/codemap.md @@ -3,7 +3,7 @@ ## Responsibility ###### OpenCode package boundary -This package publishes `@vibepaper/opencode`, the OpenCode integration for VibePaper. It provides the installer CLI, plugin export, managed slash commands, agent profiles, dashboard tools, read-only status tools, and confirmed state-write bridges used inside target projects. +This package publishes `@copaper/opencode`, the OpenCode integration for CoPaper. It provides the installer CLI, plugin export, managed slash commands, agent profiles, dashboard tools, read-only status tools, and confirmed state-write bridges used inside target projects. ###### Implementation detail map Source-level architecture lives in `src/codemap.md`. This file stays package-level: entry points, directories, scripts, tests, generated outputs, integrations, and release risks. @@ -11,13 +11,13 @@ Source-level architecture lives in `src/codemap.md`. This file stays package-lev ## Package Entry Points ###### CLI binary -`package.json` exposes `vibepaper-opencode` as `./dist/cli.js`. Source lives in `src/cli.ts`; the README documents `init`, `doctor`, locale options, local tarball usage, and dev install workflows. +`package.json` exposes `copaper-opencode` as `./dist/cli.js`. Source lives in `src/cli.ts`; the README documents `init`, `doctor`, locale options, local tarball usage, and dev install workflows. ###### Plugin export -The package export `.` resolves to `./dist/index.js`, built from `src/index.ts`. It registers the OpenCode plugin hook, injected VibePaper agents, and all `vibepaper_*` tool handlers. +The package export `.` resolves to `./dist/index.js`, built from `src/index.ts`. It registers the OpenCode plugin hook, injected CoPaper agents, and all `copaper_*` tool handlers. ###### Published files -The npm package includes `dist/`, `package.json`, and `README.md`. Generated `dist/` files and local `vibepaper-opencode-0.1.0.tgz` tarballs are build/release artifacts, not source of truth. +The npm package includes `dist/`, `package.json`, and `README.md`. Generated `dist/` files and local `copaper-opencode-0.1.0.tgz` tarballs are build/release artifacts, not source of truth. ## Directory Map @@ -39,18 +39,18 @@ Developer automation lives in `scripts/dev-install.ts` and `scripts/dev-reset.ts `bun run test` runs the full Bun test suite. Focused scripts include `bun run test:cli` for `tests/cli.test.ts` and `bun run test:package` for `tests/package-smoke.test.ts`. ###### Release artifacts -Release packaging depends on a fresh `dist/` matching `src/`, plus any checked local `.tgz` generated for smoke testing. The tarball should install the stable `vibepaper-opencode` binary and plugin export documented in README. +Release packaging depends on a fresh `dist/` matching `src/`, plus any checked local `.tgz` generated for smoke testing. The tarball should install the stable `copaper-opencode` binary and plugin export documented in README. ## Integration Points ###### OpenCode runtime The plugin depends on `@opencode-ai/plugin` and reads OpenCode directory/worktree/client context. It installs `.opencode/commands/` wrappers and updates `opencode.json` or `opencode.jsonc` plugin entries using managed markers. -###### VibePaper project files -Tools inspect or write VibePaper project artifacts such as `paper.md`, `storyline.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, `.agents/events.jsonl`, checker reports, cross-index data, and `relatedwork/` metadata. +###### CoPaper project files +Tools inspect or write CoPaper project artifacts such as `paper.md`, `storyline.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, `.agents/events.jsonl`, checker reports, cross-index data, and `relatedwork/` metadata. ###### Python CLI bridge -Related-work write tools and doctor checks resolve the Python `vibe` CLI through a target `.venv` or `uv run --project`. Failures are reported as structured plugin diagnostics instead of hidden shell errors. +Related-work write tools and doctor checks resolve the Python `copaper` CLI through a target `.venv` or `uv run --project`. Failures are reported as structured plugin diagnostics instead of hidden shell errors. ## Key Risks @@ -61,4 +61,4 @@ Related-work write tools and doctor checks resolve the Python `vibe` CLI through Most tools are intentionally read-only, while state writers require explicit confirmation and validated paths. New integrations must preserve non-destructive installs, managed-marker checks, and atomic state/event writes. ###### Runtime dependency gaps -OpenCode context, Bun, `@opencode-ai/plugin`, and optional Python `vibe` or `uv` availability shape behavior. Doctor and package smoke tests should catch missing command files, plugin entries, binary wiring, and bridge failures. +OpenCode context, Bun, `@opencode-ai/plugin`, and optional Python `copaper` or `uv` availability shape behavior. Doctor and package smoke tests should catch missing command files, plugin entries, binary wiring, and bridge failures. diff --git a/packages/opencode-plugin/package.json b/packages/opencode-plugin/package.json index 6d90146..22bb428 100644 --- a/packages/opencode-plugin/package.json +++ b/packages/opencode-plugin/package.json @@ -1,10 +1,10 @@ { - "name": "@vibepaper/opencode", + "name": "@copaper/opencode", "version": "0.1.0", - "description": "OpenCode integration plugin for VibePaper", + "description": "OpenCode integration plugin for CoPaper", "type": "module", "bin": { - "vibepaper-opencode": "./dist/cli.js" + "copaper-opencode": "./dist/cli.js" }, "exports": { ".": "./dist/index.js", diff --git a/packages/opencode-plugin/scripts/dev-install.ts b/packages/opencode-plugin/scripts/dev-install.ts index 6be19ca..01260af 100644 --- a/packages/opencode-plugin/scripts/dev-install.ts +++ b/packages/opencode-plugin/scripts/dev-install.ts @@ -40,10 +40,10 @@ async function main(): Promise<void> { if (!skipBuild) await run(["bun", "run", "build"], PLUGIN_DIR, "build") await run(["bun", "link"], PLUGIN_DIR, "link-plugin") - await run(["bun", "link", "@vibepaper/opencode"], target, "link-target") + await run(["bun", "link", "@copaper/opencode"], target, "link-target") if (!skipInit) { - const cliPath = join(target, "node_modules", ".bin", "vibepaper-opencode") + const cliPath = join(target, "node_modules", ".bin", "copaper-opencode") if (!existsSync(cliPath)) { throw new Error(`Linked CLI not found at ${cliPath}. bun link may have failed; rerun and inspect the link-target step output.`) } @@ -63,8 +63,8 @@ async function main(): Promise<void> { console.log("") console.log("Done. Next steps:") console.log(` 1. Restart OpenCode inside ${target}.`) - console.log(" 2. Run /vibe-doctor to verify the install (look for vibe-cli.available and commands.vibe-relatedwork.present).") - console.log(" 3. Run /vibe-relatedwork to drive the relatedwork workflow.") + console.log(" 2. Run /copaper-doctor to verify the install (look for copaper-cli.available and commands.copaper-relatedwork.present).") + console.log(" 3. Run /copaper-relatedwork to drive the relatedwork workflow.") } function parseArgs(argv: string[]): Args | { error: string } { @@ -107,7 +107,7 @@ function ensureTargetPackageJson(target: string): void { } function pickStubName(target: string): string { - const base = target.split("/").filter((part) => part.length > 0).pop() ?? "vibepaper-target" + const base = target.split("/").filter((part) => part.length > 0).pop() ?? "copaper-target" return base.toLowerCase().replace(/[^a-z0-9._-]/g, "-") } diff --git a/packages/opencode-plugin/scripts/dev-reset.ts b/packages/opencode-plugin/scripts/dev-reset.ts index f8b7d76..81a99a3 100644 --- a/packages/opencode-plugin/scripts/dev-reset.ts +++ b/packages/opencode-plugin/scripts/dev-reset.ts @@ -23,9 +23,9 @@ async function main(): Promise<void> { process.exit(2) } - await runBestEffort(["bun", "remove", "@vibepaper/opencode"], target, "unlink-target") + await runBestEffort(["bun", "remove", "@copaper/opencode"], target, "unlink-target") - const linkPath = join(target, "node_modules", "@vibepaper", "opencode") + const linkPath = join(target, "node_modules", "@copaper", "opencode") if (existsSync(linkPath) || isOrphanSymlink(linkPath)) { try { unlinkSync(linkPath) diff --git a/packages/opencode-plugin/src/agent-config.ts b/packages/opencode-plugin/src/agent-config.ts index a07a4a5..d69400b 100644 --- a/packages/opencode-plugin/src/agent-config.ts +++ b/packages/opencode-plugin/src/agent-config.ts @@ -1,8 +1,8 @@ import { - VIBEPAPER_AGENT_NAMES, + COPAPER_AGENT_NAMES, buildDefaultAgentProfiles, - type VibePaperAgentName, - type VibePaperAgentProfile, + type CoPaperAgentName, + type CoPaperAgentProfile, } from "./agent-profiles" import { canUsePermissionProfile, @@ -11,13 +11,13 @@ import { type PermissionProfileName, } from "./permission-profiles" import { - loadVibePaperConfig, + loadCoPaperConfig, type AgentDiagnostic, type AgentDiagnosticCode, type AgentDiagnosticSeverity, -} from "./vibepaper-config" +} from "./copaper-config" -const CONFIG_RELATIVE_PATH = ".opencode/vibepaper.json" +const CONFIG_RELATIVE_PATH = ".opencode/copaper.json" export type AgentRuntimeStatus = "injected" | "disabled" | "conflicted" @@ -30,8 +30,8 @@ export interface OpenCodeAgentConfig { permission: OpenCodePermissionConfig } -export interface VibePaperAgentRuntimeRow { - name: VibePaperAgentName +export interface CoPaperAgentRuntimeRow { + name: CoPaperAgentName status: AgentRuntimeStatus description: string permissionProfile: PermissionProfileName @@ -39,24 +39,24 @@ export interface VibePaperAgentRuntimeRow { temperature?: number } -export interface VibePaperAgentRuntimeState { - agents: VibePaperAgentRuntimeRow[] +export interface CoPaperAgentRuntimeState { + agents: CoPaperAgentRuntimeRow[] diagnostics: AgentDiagnostic[] } -export interface VibePaperAgentConfigResult { - injectedAgents: Partial<Record<VibePaperAgentName, OpenCodeAgentConfig>> - runtime: VibePaperAgentRuntimeState +export interface CoPaperAgentConfigResult { + injectedAgents: Partial<Record<CoPaperAgentName, OpenCodeAgentConfig>> + runtime: CoPaperAgentRuntimeState diagnostics: AgentDiagnostic[] } -interface BuildVibePaperAgentConfigInput { +interface BuildCoPaperAgentConfigInput { root: string existingAgents: Record<string, OpenCodeAgentConfig> } interface EffectiveAgentProfile { - name: VibePaperAgentName + name: CoPaperAgentName enabled: boolean description: string mode: "subagent" @@ -66,17 +66,17 @@ interface EffectiveAgentProfile { permissionProfile: PermissionProfileName } -export function buildVibePaperAgentConfig({ +export function buildCoPaperAgentConfig({ root, existingAgents, -}: BuildVibePaperAgentConfigInput): VibePaperAgentConfigResult { - const loaded = loadVibePaperConfig(root) +}: BuildCoPaperAgentConfigInput): CoPaperAgentConfigResult { + const loaded = loadCoPaperConfig(root) const profiles = buildDefaultAgentProfiles(loaded.config.locale) const mergeDiagnostics: AgentDiagnostic[] = [] - const injectedAgents: Partial<Record<VibePaperAgentName, OpenCodeAgentConfig>> = {} - const runtimeAgents: VibePaperAgentRuntimeRow[] = [] + const injectedAgents: Partial<Record<CoPaperAgentName, OpenCodeAgentConfig>> = {} + const runtimeAgents: CoPaperAgentRuntimeRow[] = [] - for (const agentName of VIBEPAPER_AGENT_NAMES) { + for (const agentName of COPAPER_AGENT_NAMES) { const profile = profiles[agentName] const override = loaded.config.agents[agentName] const effectiveProfile = buildEffectiveProfile(profile, { @@ -99,7 +99,7 @@ export function buildVibePaperAgentConfig({ mergeDiagnostics.push(agentConfigDiagnostic( "warning", "agent-name-conflict", - `OpenCode agent "${agentName}" already exists; VibePaper injection is skipped.`, + `OpenCode agent "${agentName}" already exists; CoPaper injection is skipped.`, `agents.${agentName}`, )) runtimeAgents.push(toRuntimeRow(effectiveProfile, "conflicted")) @@ -122,7 +122,7 @@ export function buildVibePaperAgentConfig({ } function buildEffectiveProfile( - profile: VibePaperAgentProfile, + profile: CoPaperAgentProfile, options: { model?: string temperature?: number @@ -176,7 +176,7 @@ function toOpenCodeAgentConfig(profile: EffectiveAgentProfile): OpenCodeAgentCon function toRuntimeRow( profile: EffectiveAgentProfile, status: AgentRuntimeStatus, -): VibePaperAgentRuntimeRow { +): CoPaperAgentRuntimeRow { return { name: profile.name, status, @@ -198,7 +198,7 @@ function appendProjectPreferences(prompt: string, promptAppend: string | undefin ].join("\n") } -function temperatureFromHint(hint: VibePaperAgentProfile["temperatureHint"]): number { +function temperatureFromHint(hint: CoPaperAgentProfile["temperatureHint"]): number { switch (hint) { case "low": return 0.2 diff --git a/packages/opencode-plugin/src/agent-diagnostics.ts b/packages/opencode-plugin/src/agent-diagnostics.ts index b314801..0289224 100644 --- a/packages/opencode-plugin/src/agent-diagnostics.ts +++ b/packages/opencode-plugin/src/agent-diagnostics.ts @@ -1,22 +1,22 @@ -import type { VibePaperAgentRuntimeState } from "./agent-config" -import type { AgentDiagnostic } from "./vibepaper-config" +import type { CoPaperAgentRuntimeState } from "./agent-config" +import type { AgentDiagnostic } from "./copaper-config" import type { DoctorCheck } from "./types" -const defaultRuntimeState: VibePaperAgentRuntimeState = { agents: [], diagnostics: [] } -const runtimeStateByRoot = new Map<string, VibePaperAgentRuntimeState>() -let latestRuntimeState: VibePaperAgentRuntimeState = defaultRuntimeState +const defaultRuntimeState: CoPaperAgentRuntimeState = { agents: [], diagnostics: [] } +const runtimeStateByRoot = new Map<string, CoPaperAgentRuntimeState>() +let latestRuntimeState: CoPaperAgentRuntimeState = defaultRuntimeState -export function setLatestVibePaperAgentRuntimeState(state: VibePaperAgentRuntimeState, root?: string): void { +export function setLatestCoPaperAgentRuntimeState(state: CoPaperAgentRuntimeState, root?: string): void { latestRuntimeState = state if (root !== undefined) runtimeStateByRoot.set(root, state) } -export function getLatestVibePaperAgentRuntimeState(root?: string): VibePaperAgentRuntimeState { +export function getLatestCoPaperAgentRuntimeState(root?: string): CoPaperAgentRuntimeState { if (root !== undefined) return runtimeStateByRoot.get(root) ?? defaultRuntimeState return latestRuntimeState } -export function agentRuntimeToDoctorChecks(state: VibePaperAgentRuntimeState): DoctorCheck[] { +export function agentRuntimeToDoctorChecks(state: CoPaperAgentRuntimeState): DoctorCheck[] { return [ ...state.agents.map((agent): DoctorCheck => { if (agent.status === "injected") { @@ -24,7 +24,7 @@ export function agentRuntimeToDoctorChecks(state: VibePaperAgentRuntimeState): D id: `agents.${agent.name}`, status: "pass", severity: "info", - message: `VibePaper agent "${agent.name}" is injected`, + message: `CoPaper agent "${agent.name}" is injected`, remediation: null, } } @@ -34,8 +34,8 @@ export function agentRuntimeToDoctorChecks(state: VibePaperAgentRuntimeState): D id: `agents.${agent.name}`, status: "warn", severity: "warning", - message: `VibePaper agent "${agent.name}" is disabled`, - remediation: `Set agents.${agent.name}.enabled to true in .opencode/vibepaper.json`, + message: `CoPaper agent "${agent.name}" is disabled`, + remediation: `Set agents.${agent.name}.enabled to true in .opencode/copaper.json`, } } @@ -43,8 +43,8 @@ export function agentRuntimeToDoctorChecks(state: VibePaperAgentRuntimeState): D id: `agents.${agent.name}`, status: "fail", severity: "warning", - message: `VibePaper agent "${agent.name}" conflicts with an existing OpenCode agent`, - remediation: `Rename the existing agent or disable agents.${agent.name} in .opencode/vibepaper.json`, + message: `CoPaper agent "${agent.name}" conflicts with an existing OpenCode agent`, + remediation: `Rename the existing agent or disable agents.${agent.name} in .opencode/copaper.json`, } }), ...state.diagnostics.flatMap(diagnosticToDoctorCheck), @@ -59,6 +59,6 @@ function diagnosticToDoctorCheck(diagnostic: AgentDiagnostic): DoctorCheck[] { status: diagnostic.severity === "error" ? "fail" : "warn", severity: diagnostic.severity === "error" ? "error" : "warning", message: diagnostic.message, - remediation: "Fix .opencode/vibepaper.json, then restart OpenCode", + remediation: "Fix .opencode/copaper.json, then restart OpenCode", }] } diff --git a/packages/opencode-plugin/src/agent-profiles.ts b/packages/opencode-plugin/src/agent-profiles.ts index 684dec1..110de6a 100644 --- a/packages/opencode-plugin/src/agent-profiles.ts +++ b/packages/opencode-plugin/src/agent-profiles.ts @@ -1,19 +1,19 @@ import type { PermissionProfileName } from "./permission-profiles" import { DEFAULT_LOCALE, type Locale } from "./types" -export const VIBEPAPER_AGENT_NAMES = [ - "vibepaper-coordinator", - "vibepaper-storyline", - "vibepaper-writer", - "vibepaper-reviewer", - "vibepaper-recorder", - "vibepaper-literature", +export const COPAPER_AGENT_NAMES = [ + "copaper-coordinator", + "copaper-storyline", + "copaper-writer", + "copaper-reviewer", + "copaper-recorder", + "copaper-literature", ] as const -export type VibePaperAgentName = (typeof VIBEPAPER_AGENT_NAMES)[number] +export type CoPaperAgentName = (typeof COPAPER_AGENT_NAMES)[number] -export interface VibePaperAgentProfile { - name: VibePaperAgentName +export interface CoPaperAgentProfile { + name: CoPaperAgentName enabled: true mode: "subagent" description: string @@ -23,116 +23,116 @@ export interface VibePaperAgentProfile { maxPermissionProfile: PermissionProfileName } -type VibePaperAgentProfiles = Record<VibePaperAgentName, VibePaperAgentProfile> -type VibePaperAgentProfileInput = Omit<VibePaperAgentProfile, "enabled" | "mode"> +type CoPaperAgentProfiles = Record<CoPaperAgentName, CoPaperAgentProfile> +type CoPaperAgentProfileInput = Omit<CoPaperAgentProfile, "enabled" | "mode"> -export function isVibePaperAgentName(value: unknown): value is VibePaperAgentName { - return typeof value === "string" && VIBEPAPER_AGENT_NAMES.includes(value as VibePaperAgentName) +export function isCoPaperAgentName(value: unknown): value is CoPaperAgentName { + return typeof value === "string" && COPAPER_AGENT_NAMES.includes(value as CoPaperAgentName) } -export function buildDefaultAgentProfiles(locale: Locale = DEFAULT_LOCALE): VibePaperAgentProfiles { +export function buildDefaultAgentProfiles(locale: Locale = DEFAULT_LOCALE): CoPaperAgentProfiles { return { - "vibepaper-coordinator": buildProfile({ - name: "vibepaper-coordinator", - description: "Coordinates VibePaper work with read-only project awareness.", + "copaper-coordinator": buildProfile({ + name: "copaper-coordinator", + description: "Coordinates CoPaper work with read-only project awareness.", temperatureHint: "low", permissionProfile: "readOnly", maxPermissionProfile: "readOnly", prompt: buildPrompt( locale, - "Coordinate VibePaper work by reading project artifacts, clarifying scope, and keeping subagent roles separate.", + "Coordinate CoPaper work by reading project artifacts, clarifying scope, and keeping subagent roles separate.", "Read storyline.md, paper.md, writingrules.md, and readiness state only when needed. Do not edit project artifacts.", "Keep work phase-aware, preserve user intent, and ask for explicit direction before requesting artifact changes.", "Use only read-oriented tools granted by this profile. Do not change files or invoke unrelated operations.", "Summarize the needed next role and pass only the relevant artifact context to the user or selected subagent.", ), }), - "vibepaper-storyline": buildProfile({ - name: "vibepaper-storyline", - description: "Maintains VibePaper storyline structure and research narrative boundaries.", + "copaper-storyline": buildProfile({ + name: "copaper-storyline", + description: "Maintains CoPaper storyline structure and research narrative boundaries.", temperatureHint: "medium-low", permissionProfile: "storylineWrite", maxPermissionProfile: "storylineWrite", prompt: buildPrompt( locale, - "Shape the VibePaper research storyline while staying focused on the narrative plan and structural clarity.", + "Shape the CoPaper research storyline while staying focused on the narrative plan and structural clarity.", "Edit storyline.md only when explicitly asked. Treat paper.md and readiness state as reference artifacts.", "Preserve existing intent, keep changes scoped to storyline structure, and avoid drafting paper prose. Do not fabricate experiments, data, citations, literature conclusions, or contributions; when facts are missing, ask the user or mark assumptions explicitly.", "Use only tools granted by this profile. Ask before changing storyline.md and do not alter unrelated files.", "Return concise storyline notes, unresolved questions, and suggested next focus without triggering another role.", ), }), - "vibepaper-writer": buildProfile({ - name: "vibepaper-writer", - description: "Edits VibePaper paper.md within strict structural writing boundaries.", + "copaper-writer": buildProfile({ + name: "copaper-writer", + description: "Edits CoPaper paper.md within strict structural writing boundaries.", temperatureHint: "medium-low", permissionProfile: "paperWrite", maxPermissionProfile: "paperWrite", prompt: buildPrompt( locale, - "Draft and revise VibePaper paper content while respecting the documented writing structure.", + "Draft and revise CoPaper paper content while respecting the documented writing structure.", "Read storyline.md before drafting. Edit paper.md only when explicitly asked. Do not edit .agents/state.json, storyline.md, or unrelated artifacts. If literature is needed, inspect .agents/cross_index.json first, then only targeted relatedwork/papers/*.md summaries.", "Keep Level 1-5 headings structural only. Put paragraph content under Level 6 headings. Keep Level 6 titles within 50 characters and supporting content within 500 characters. Do not fabricate experiments, data, citations, literature conclusions, or contributions; when facts are missing, ask the user or mark assumptions explicitly.", "Use only tools granted by this profile. Ask before changing paper.md and do not alter unrelated files.", "Return concise paper.md change notes, open questions, and any storyline dependency for the user to route.", ), }), - "vibepaper-reviewer": buildProfile({ - name: "vibepaper-reviewer", - description: "Reviews VibePaper drafts by running and summarizing checkers without editing paper content.", + "copaper-reviewer": buildProfile({ + name: "copaper-reviewer", + description: "Reviews CoPaper drafts by running and summarizing checkers without editing paper content.", temperatureHint: "low", permissionProfile: "readOnly", maxPermissionProfile: "readOnly", prompt: buildPrompt( locale, - "Run, summarize, and explain VibePaper checker findings while keeping review separate from writing or recording.", + "Run, summarize, and explain CoPaper checker findings while keeping review separate from writing or recording.", "Read paper.md, storyline.md, checker status, relatedwork status, and checker outputs only as needed. Do not edit paper.md, storyline.md, .agents/state.json, or .agents/events.jsonl.", - "Use actual checker output and read-only tool evidence. Explain severity, affected claims, and likely reviewer concerns without inventing findings. If durable checker recording is requested, prepare the checker/status/counts/summary/evidence/reason for @vibepaper-recorder rather than recording it yourself.", - "Use only read-oriented tools granted by this profile, especially vibepaper_checker_status and vibepaper_relatedwork_status when relevant. Do not call state-writing tools or modify files.", + "Use actual checker output and read-only tool evidence. Explain severity, affected claims, and likely reviewer concerns without inventing findings. If durable checker recording is requested, prepare the checker/status/counts/summary/evidence/reason for @copaper-recorder rather than recording it yourself.", + "Use only read-oriented tools granted by this profile, especially copaper_checker_status and copaper_relatedwork_status when relevant. Do not call state-writing tools or modify files.", "Return a concise review summary, prioritized issues, and optional record-ready metadata for the recorder; do not trigger paper edits directly.", ), }), - "vibepaper-recorder": buildProfile({ - name: "vibepaper-recorder", - description: "Records VibePaper artifact readiness using the dedicated artifact record flow.", + "copaper-recorder": buildProfile({ + name: "copaper-recorder", + description: "Records CoPaper artifact readiness using the dedicated artifact record flow.", temperatureHint: "low", permissionProfile: "stateRecord", maxPermissionProfile: "stateRecord", prompt: buildPrompt( locale, - "Record VibePaper artifact readiness after the user provides evidence and reasoned status context.", - "Use vibepaper_artifact_record for readiness updates. Do not edit paper.md. Do not edit storyline.md.", + "Record CoPaper artifact readiness after the user provides evidence and reasoned status context.", + "Use copaper_artifact_record for readiness updates. Do not edit paper.md. Do not edit storyline.md.", "Record only explicit readiness facts, preserve artifact boundaries, and avoid rewriting project content.", "Use only tools granted by this profile. Do not alter narrative or paper artifacts.", "Return the recorded artifact, status, confidence, and any warnings for the user to decide the next step.", ), }), - "vibepaper-literature": buildProfile({ - name: "vibepaper-literature", - description: "Drives the VibePaper literature workflow via the dedicated relatedwork tools.", + "copaper-literature": buildProfile({ + name: "copaper-literature", + description: "Drives the CoPaper literature workflow via the dedicated relatedwork tools.", temperatureHint: "low", permissionProfile: "literatureWrite", maxPermissionProfile: "literatureWrite", prompt: buildPrompt( locale, - "Drive the VibePaper relatedwork / literature phase using the vibepaper_relatedwork_* tools granted by this profile.", + "Drive the CoPaper relatedwork / literature phase using the copaper_relatedwork_* tools granted by this profile.", "Read storyline.md, paper.md, relatedwork/literature.json, relatedwork/paper_list.bib, relatedwork/papers/*.md, and .agents/cross_index.json only as needed. Do not edit storyline.md or paper.md.", - "Always call vibepaper_relatedwork_status before and after every write tool. Restate full arguments and wait for explicit user confirmation before calling search, import, sync_bib, download, summarize, register_summary, build_index, or clean. Never auto-advance the literature phase; only call vibepaper_workflow_set_phase after explicit user confirmation.", - "Use only the vibepaper_relatedwork_* tools and read-oriented status tools granted by this profile. Do not invoke unrelated VibePaper tools or arbitrary subprocesses.", - "Return the refreshed relatedwork status, phase patch diff, and any vibe-cli-unavailable / vibe-nonzero-exit / bridge-timeout errors verbatim; on vibe-cli-unavailable instruct the user to install the VibePaper Python package and rerun /vibe-doctor.", + "Always call copaper_relatedwork_status before and after every write tool. Restate full arguments and wait for explicit user confirmation before calling search, import, sync_bib, download, summarize, register_summary, build_index, or clean. Never auto-advance the literature phase; only call copaper_workflow_set_phase after explicit user confirmation.", + "Use only the copaper_relatedwork_* tools and read-oriented status tools granted by this profile. Do not invoke unrelated CoPaper tools or arbitrary subprocesses.", + "Return the refreshed relatedwork status, phase patch diff, and any copaper-cli-unavailable / copaper-nonzero-exit / bridge-timeout errors verbatim; on copaper-cli-unavailable instruct the user to install the CoPaper Python package and rerun /copaper-doctor.", ), }), } } export function getDefaultAgentProfile( - name: VibePaperAgentName, + name: CoPaperAgentName, locale: Locale = DEFAULT_LOCALE, -): VibePaperAgentProfile { +): CoPaperAgentProfile { return buildDefaultAgentProfiles(locale)[name] } -function buildProfile(profile: VibePaperAgentProfileInput): VibePaperAgentProfile { +function buildProfile(profile: CoPaperAgentProfileInput): CoPaperAgentProfile { return { ...profile, enabled: true, @@ -151,7 +151,7 @@ function buildPrompt( const localeGuidance = locale === "zh-CN" ? "Use concise Chinese when the user writes Chinese; preserve quoted artifact text as-is." : "Use concise English unless the user asks otherwise." return [ - "You are a built-in VibePaper subagent.", + "You are a built-in CoPaper subagent.", `Locale Guidance: ${localeGuidance}`, "", "## Role Boundary", diff --git a/packages/opencode-plugin/src/artifact-record.ts b/packages/opencode-plugin/src/artifact-record.ts index f66f0b3..bf06218 100644 --- a/packages/opencode-plugin/src/artifact-record.ts +++ b/packages/opencode-plugin/src/artifact-record.ts @@ -25,7 +25,7 @@ export async function recordArtifactReadiness(options: ArtifactRecordOptions): P return makeResult({ locale: resolved.locale, localeFallback: resolved.fallback, ok: false, root: null, artifact: options.artifact, errors: [{ code: "root-detection-failed", message: `Failed to detect project root: ${errorMessage(error)}` }] }) } - if (options.agent !== undefined && options.agent !== "vibepaper-recorder") { + if (options.agent !== undefined && options.agent !== "copaper-recorder") { return makeResult({ locale: resolved.locale, localeFallback: resolved.fallback, ok: false, root, artifact: options.artifact, errors: [{ code: "agent-not-authorized", message: `Agent "${options.agent}" is not authorized to record artifact readiness.` }] }) } diff --git a/packages/opencode-plugin/src/checker-record.ts b/packages/opencode-plugin/src/checker-record.ts index c9b0aa0..b03b685 100644 --- a/packages/opencode-plugin/src/checker-record.ts +++ b/packages/opencode-plugin/src/checker-record.ts @@ -28,7 +28,7 @@ export async function recordCheckerResult(options: CheckerRecordOptions): Promis return makeResult({ locale: resolved.locale, localeFallback: resolved.fallback, ok: false, root: null, checker: options.checker, errors: [{ code: "root-detection-failed", message: `Failed to detect project root: ${errorMessage(error)}` }] }) } - if (options.agent !== undefined && options.agent !== "vibepaper-recorder") { + if (options.agent !== undefined && options.agent !== "copaper-recorder") { return makeResult({ locale: resolved.locale, localeFallback: resolved.fallback, ok: false, root, checker: options.checker, errors: [{ code: "agent-not-authorized", message: `Agent "${options.agent}" is not authorized to record checker results.` }] }) } diff --git a/packages/opencode-plugin/src/cli.ts b/packages/opencode-plugin/src/cli.ts index c39bb0f..3f3eef9 100644 --- a/packages/opencode-plugin/src/cli.ts +++ b/packages/opencode-plugin/src/cli.ts @@ -126,8 +126,8 @@ function unsupportedOption(command: Command, arg: string): { ok: false; error: s function help(code: number) { console.log(`Usage: - vibepaper-opencode init [--root <dir>] [--config <path>] [--locale zh-CN|en-US] [--dry-run] [--force] - vibepaper-opencode doctor [--root <dir>] [--config <path>] [--locale zh-CN|en-US] [--format text|markdown|json] + copaper-opencode init [--root <dir>] [--config <path>] [--locale zh-CN|en-US] [--dry-run] [--force] + copaper-opencode doctor [--root <dir>] [--config <path>] [--locale zh-CN|en-US] [--format text|markdown|json] `) return code } diff --git a/packages/opencode-plugin/src/codemap.md b/packages/opencode-plugin/src/codemap.md index 527c84d..29ed5b5 100644 --- a/packages/opencode-plugin/src/codemap.md +++ b/packages/opencode-plugin/src/codemap.md @@ -3,10 +3,10 @@ ## Responsibility ###### OpenCode integration layer -This folder implements the VibePaper OpenCode plugin, local installer CLI, slash-command templates, managed subagent injection, and tool handlers that expose VibePaper project status and controlled state updates inside OpenCode. +This folder implements the CoPaper OpenCode plugin, local installer CLI, slash-command templates, managed subagent injection, and tool handlers that expose CoPaper project status and controlled state updates inside OpenCode. -###### VibePaper project operations -It bridges OpenCode to VibePaper artifacts: project initialization, readiness dashboards, workflow phase state, checker records, artifact readiness records, related-work workflows, structure status, and read-only PDF/PPTX extraction. +###### CoPaper project operations +It bridges OpenCode to CoPaper artifacts: project initialization, readiness dashboards, workflow phase state, checker records, artifact readiness records, related-work workflows, structure status, and read-only PDF/PPTX extraction. ###### Safety boundary Most tools are read-only. State-writing tools validate agent identity, paths, inputs, event-log targets, and user-confirmed arguments before touching `.agents/state.json`, `.agents/events.jsonl`, or generated project files. @@ -14,7 +14,7 @@ Most tools are read-only. State-writing tools validate agent identity, paths, in ## Design Patterns ###### Thin tool registry -`index.ts` registers every `vibepaper_*` tool with OpenCode schemas, then delegates to focused modules that return typed result objects and render human-readable Markdown plus JSON payloads. +`index.ts` registers every `copaper_*` tool with OpenCode schemas, then delegates to focused modules that return typed result objects and render human-readable Markdown plus JSON payloads. ###### Build and render split Status modules follow `build*Result` plus `render*Output` pairs. Builders detect roots, inspect files, normalize errors, and produce schema-versioned results; renderers handle localized tables and summaries. @@ -23,27 +23,27 @@ Status modules follow `build*Result` plus `render*Output` pairs. Builders detect Write paths use readiness checks, conflict detection, canonical event-log validation, symlink/non-file rejection, inside-root assertions, and atomic writes before changing project or OpenCode config files. ###### Managed overlay -Agent and command injection are treated as an overlay: existing unmanaged user config is retained, VibePaper-managed fingerprints/markers identify safe replacements, and conflicts become diagnostics instead of overwrites. +Agent and command injection are treated as an overlay: existing unmanaged user config is retained, CoPaper-managed fingerprints/markers identify safe replacements, and conflicts become diagnostics instead of overwrites. ###### Python command facade -Related-work write tools are TypeScript facades over the Python `vibe` CLI. The bridge resolves `.venv/bin/vibe` first, falls back to `uv run --project <root> vibe`, captures bounded output, and reports structured errors. +Related-work write tools are TypeScript facades over the Python `copaper` CLI. The bridge resolves `.venv/bin/copaper` first, falls back to `uv run --project <root> copaper`, captures bounded output, and reports structured errors. ## Data & Control Flow ###### Plugin startup -`VibePaperPlugin` logs initialization, filters previously injected agents from user config, calls `buildVibePaperAgentConfig`, records runtime diagnostics, injects current agents, and registers all OpenCode tools. +`CoPaperPlugin` logs initialization, filters previously injected agents from user config, calls `buildCoPaperAgentConfig`, records runtime diagnostics, injects current agents, and registers all OpenCode tools. ###### Dashboard path -`vibepaper_dashboard` runs `doctor`, derives installation health, inspects readiness, builds an init preview, and, only for ready roots, includes artifact status, workflow status, and recent workflow log entries. +`copaper_dashboard` runs `doctor`, derives installation health, inspects readiness, builds an init preview, and, only for ready roots, includes artifact status, workflow status, and recent workflow log entries. ###### Initialization path -The installer CLI updates OpenCode config and slash-command files. The plugin init tool separately creates VibePaper project files from templates after checking `readiness` and `init-preview` conflicts. +The installer CLI updates OpenCode config and slash-command files. The plugin init tool separately creates CoPaper project files from templates after checking `readiness` and `init-preview` conflicts. ###### State update path Workflow, checker, and artifact record tools read `.agents/state.json`, validate requested changes, write updated state atomically, then append canonical JSONL events to `.agents/events.jsonl` when preflight succeeds. ###### Related-work path -Related-work tools detect the root, assemble `vibe relatedwork ...` args, run the Python bridge with per-command timeouts, refresh related-work status, and patch literature phase counters plus events for write subcommands. +Related-work tools detect the root, assemble `copaper relatedwork ...` args, run the Python bridge with per-command timeouts, refresh related-work status, and patch literature phase counters plus events for write subcommands. ###### Import extraction path PDF/PPTX extractors require explicit in-project paths, enforce extension and size limits, reject symlinks/non-files, hash sources, extract best-effort text locally, and never scan or mutate project state. @@ -54,26 +54,26 @@ PDF/PPTX extractors require explicit in-project paths, enforce extension and siz `index.ts` uses `@opencode-ai/plugin` to provide the config hook and tool map. OpenCode supplies `directory`, `worktree`, `client`, `context.directory`, `context.worktree`, and `context.agent`. ###### OpenCode project files -`installer.ts`, `config.ts`, and `templates.ts` manage `opencode.json`/`opencode.jsonc` plugin entries and `.opencode/commands/{vibe,vibe-doctor,vibe-relatedwork}.md` command wrappers with VibePaper markers. +`installer.ts`, `config.ts`, and `templates.ts` manage `opencode.json`/`opencode.jsonc` plugin entries and `.opencode/commands/{copaper,copaper-doctor,copaper-relatedwork}.md` command wrappers with CoPaper markers. -###### VibePaper artifacts +###### CoPaper artifacts Readiness and status modules inspect `paper.md`, `storyline.md`, `writingrules.md`, `AGENTS.md`, `.agents/state.json`, `.agents/events.jsonl`, `.agents/precheck_report.md`, `.agents/cross_index.json`, and `relatedwork/` files. ###### Python CLI bridge -`python-bridge.ts` is used by `relatedwork-tools.ts` and `doctor.ts` to locate and run `vibe`, surface `vibe-cli-unavailable`, `bridge-timeout`, spawn failures, and nonzero exits without hiding stdout/stderr. +`python-bridge.ts` is used by `relatedwork-tools.ts` and `doctor.ts` to locate and run `copaper`, surface `copaper-cli-unavailable`, `bridge-timeout`, spawn failures, and nonzero exits without hiding stdout/stderr. ###### Config and i18n -`vibepaper-config.ts` reads `.opencode/vibepaper.json` for locale, default model/temperature, and per-agent overrides. `i18n.ts` resolves `zh-CN`/`en-US` text via explicit locale or `VIBEPAPER_LANG`. +`copaper-config.ts` reads `.opencode/copaper.json` for locale, default model/temperature, and per-agent overrides. `i18n.ts` resolves `zh-CN`/`en-US` text via explicit locale or `COPAPER_LANG`. ## Key Files ###### Entry and registration -- `index.ts`: OpenCode plugin entry, agent injection hook, and complete `vibepaper_*` tool registration. -- `cli.ts`: `vibepaper-opencode init|doctor` Bun CLI wrapper for installation and diagnostics. +- `index.ts`: OpenCode plugin entry, agent injection hook, and complete `copaper_*` tool registration. +- `cli.ts`: `copaper-opencode init|doctor` Bun CLI wrapper for installation and diagnostics. ###### Agent injection -- `agent-config.ts`: merges default agent profiles with `.opencode/vibepaper.json`, detects name conflicts, and builds OpenCode agent configs. -- `agent-profiles.ts`: defines VibePaper subagent roles, prompts, boundaries, and default permission profiles. +- `agent-config.ts`: merges default agent profiles with `.opencode/copaper.json`, detects name conflicts, and builds OpenCode agent configs. +- `agent-profiles.ts`: defines CoPaper subagent roles, prompts, boundaries, and default permission profiles. - `permission-profiles.ts`: read/write permission matrices for read-only, storyline, paper, recorder, and literature agents. - `agent-diagnostics.ts`: stores latest runtime agent state and converts diagnostics into doctor checks. @@ -84,9 +84,9 @@ Readiness and status modules inspect `paper.md`, `storyline.md`, `writingrules.m ###### Dashboard and readiness - `dashboard.ts`: composes doctor, readiness, init preview, artifact, workflow, and recent event summaries. -- `readiness.ts`: classifies required and optional VibePaper files as ready, missing, blocked, invalid, user-owned, or managed. +- `readiness.ts`: classifies required and optional CoPaper files as ready, missing, blocked, invalid, user-owned, or managed. - `init-preview.ts`: converts readiness into safe init actions for project scaffolding. -- `project-init.ts` and `project-templates.ts`: write initial VibePaper project files and state after conflict preflight. +- `project-init.ts` and `project-templates.ts`: write initial CoPaper project files and state after conflict preflight. ###### Workflow and records - `workflow.ts`: reads workflow status/logs, sets phase statuses, recomputes current phase, patches phase metadata, and appends events. @@ -101,7 +101,7 @@ Readiness and status modules inspect `paper.md`, `storyline.md`, `writingrules.m ###### Related work bridge - `relatedwork-tools.ts`: builds relatedwork CLI invocations, refreshes status, and patches literature phase counters/events. -- `python-bridge.ts`: resolves and executes the Python `vibe` CLI with timeout, env cleanup, command display, and bounded stream capture. +- `python-bridge.ts`: resolves and executes the Python `copaper` CLI with timeout, env cleanup, command display, and bounded stream capture. ###### Import extraction - `pdf-extract.ts`: extracts text from explicit in-root PDFs using PDF text operators and Flate streams. diff --git a/packages/opencode-plugin/src/config.ts b/packages/opencode-plugin/src/config.ts index b9778a3..ba04304 100644 --- a/packages/opencode-plugin/src/config.ts +++ b/packages/opencode-plugin/src/config.ts @@ -1,5 +1,5 @@ import { applyEdits, findNodeAtLocation, getNodeValue, modify, parse, parseTree, type ParseError } from "jsonc-parser" -import { isVibePaperPluginSpecifier, PACKAGE_NAME } from "./types" +import { isCoPaperPluginSpecifier, PACKAGE_NAME } from "./types" export type MergeResult = | { ok: true; changed: boolean; output: string } @@ -28,7 +28,7 @@ export function mergePluginConfig(input: string, pluginSpecifier: string = PACKA return { ok: false, changed: false, error: "OpenCode config field plugin must be an array" } } - const currentPluginIndex = current.findIndex(isVibePaperPluginSpecifier) + const currentPluginIndex = current.findIndex(isCoPaperPluginSpecifier) if (currentPluginIndex >= 0) { if (current[currentPluginIndex] === pluginSpecifier) return { ok: true, changed: false, output: input } const edits = modify(input, ["plugin", currentPluginIndex], pluginSpecifier, { formattingOptions: { insertSpaces: true, tabSize: 2 } }) diff --git a/packages/opencode-plugin/src/vibepaper-config.ts b/packages/opencode-plugin/src/copaper-config.ts similarity index 90% rename from packages/opencode-plugin/src/vibepaper-config.ts rename to packages/opencode-plugin/src/copaper-config.ts index e32cd4a..55abf0e 100644 --- a/packages/opencode-plugin/src/vibepaper-config.ts +++ b/packages/opencode-plugin/src/copaper-config.ts @@ -1,12 +1,12 @@ import { readFileSync, statSync } from "node:fs" import { resolve } from "node:path" import { parse, type ParseError } from "jsonc-parser" -import { isVibePaperAgentName, type VibePaperAgentName } from "./agent-profiles" +import { isCoPaperAgentName, type CoPaperAgentName } from "./agent-profiles" import { assertInsideRoot } from "./fs-utils" import { isPermissionProfileName, type PermissionProfileName } from "./permission-profiles" import { DEFAULT_LOCALE, SCHEMA_VERSION, SUPPORTED_LOCALES, type Locale } from "./types" -const CONFIG_RELATIVE_PATH = ".opencode/vibepaper.json" +const CONFIG_RELATIVE_PATH = ".opencode/copaper.json" const SUPPORTED_TOP_LEVEL_FIELDS = new Set(["$schema", "schemaVersion", "locale", "defaults", "agents"]) const SUPPORTED_DEFAULT_FIELDS = new Set(["model", "temperature"]) const SUPPORTED_AGENT_OVERRIDE_FIELDS = new Set(["enabled", "model", "temperature", "promptAppend", "permissionProfile"]) @@ -33,12 +33,12 @@ export interface AgentDiagnostic { field?: string } -export interface VibePaperConfigDefaults { +export interface CoPaperConfigDefaults { model?: string temperature?: number } -export interface VibePaperAgentOverride { +export interface CoPaperAgentOverride { enabled?: boolean model?: string temperature?: number @@ -46,20 +46,20 @@ export interface VibePaperAgentOverride { permissionProfile?: PermissionProfileName } -export interface VibePaperProjectConfig { +export interface CoPaperProjectConfig { schemaVersion: typeof SCHEMA_VERSION locale: Locale - defaults: VibePaperConfigDefaults - agents: Partial<Record<VibePaperAgentName, VibePaperAgentOverride>> + defaults: CoPaperConfigDefaults + agents: Partial<Record<CoPaperAgentName, CoPaperAgentOverride>> } -export interface VibePaperConfigLoadResult { +export interface CoPaperConfigLoadResult { path: string - config: VibePaperProjectConfig + config: CoPaperProjectConfig diagnostics: AgentDiagnostic[] } -export function loadVibePaperConfig(root: string): VibePaperConfigLoadResult { +export function loadCoPaperConfig(root: string): CoPaperConfigLoadResult { const absoluteRoot = resolve(root) const configPath = resolve(absoluteRoot, CONFIG_RELATIVE_PATH) assertInsideRoot(absoluteRoot, configPath) @@ -119,7 +119,7 @@ export function loadVibePaperConfig(root: string): VibePaperConfigLoadResult { } } -function safeConfig(): VibePaperProjectConfig { +function safeConfig(): CoPaperProjectConfig { return { schemaVersion: SCHEMA_VERSION, locale: DEFAULT_LOCALE, @@ -128,7 +128,7 @@ function safeConfig(): VibePaperProjectConfig { } } -function withSafeConfig(path: string, diagnostics: AgentDiagnostic[]): VibePaperConfigLoadResult { +function withSafeConfig(path: string, diagnostics: AgentDiagnostic[]): CoPaperConfigLoadResult { return { path, config: safeConfig(), @@ -144,7 +144,7 @@ function parseLocale(value: unknown, diagnostics: AgentDiagnostic[]): Locale { return DEFAULT_LOCALE } -function parseDefaults(value: unknown, diagnostics: AgentDiagnostic[]): VibePaperConfigDefaults { +function parseDefaults(value: unknown, diagnostics: AgentDiagnostic[]): CoPaperConfigDefaults { if (value === undefined) return {} if (!isPlainObject(value)) { diagnostics.push(diagnostic("warning", "invalid-field", "Defaults must be a JSON object and are ignored.", "defaults")) @@ -153,7 +153,7 @@ function parseDefaults(value: unknown, diagnostics: AgentDiagnostic[]): VibePape addUnsupportedFieldDiagnostics(value, SUPPORTED_DEFAULT_FIELDS, diagnostics, "defaults") - const defaults: VibePaperConfigDefaults = {} + const defaults: CoPaperConfigDefaults = {} if (hasOwn(value, "model")) { const model = parseNonEmptyString(value.model, "defaults.model", diagnostics) if (model !== undefined) defaults.model = model @@ -168,16 +168,16 @@ function parseDefaults(value: unknown, diagnostics: AgentDiagnostic[]): VibePape function parseAgents( value: unknown, diagnostics: AgentDiagnostic[], -): Partial<Record<VibePaperAgentName, VibePaperAgentOverride>> { +): Partial<Record<CoPaperAgentName, CoPaperAgentOverride>> { if (value === undefined) return {} if (!isPlainObject(value)) { diagnostics.push(diagnostic("warning", "invalid-field", "Agents must be a JSON object and are ignored.", "agents")) return {} } - const agents: Partial<Record<VibePaperAgentName, VibePaperAgentOverride>> = {} + const agents: Partial<Record<CoPaperAgentName, CoPaperAgentOverride>> = {} for (const [agentName, rawOverride] of Object.entries(value)) { - if (!isVibePaperAgentName(agentName)) { + if (!isCoPaperAgentName(agentName)) { diagnostics.push(diagnostic("warning", "unknown-agent", `Unknown agent "${agentName}" is ignored.`, `agents.${agentName}`)) continue } @@ -193,13 +193,13 @@ function parseAgents( } function parseAgentOverride( - agentName: VibePaperAgentName, + agentName: CoPaperAgentName, value: Record<string, unknown>, diagnostics: AgentDiagnostic[], -): VibePaperAgentOverride { +): CoPaperAgentOverride { addUnsupportedFieldDiagnostics(value, SUPPORTED_AGENT_OVERRIDE_FIELDS, diagnostics, `agents.${agentName}`) - const override: VibePaperAgentOverride = {} + const override: CoPaperAgentOverride = {} if (hasOwn(value, "enabled")) { if (typeof value.enabled === "boolean") { override.enabled = value.enabled diff --git a/packages/opencode-plugin/src/dashboard.ts b/packages/opencode-plugin/src/dashboard.ts index edfa77c..bac8743 100644 --- a/packages/opencode-plugin/src/dashboard.ts +++ b/packages/opencode-plugin/src/dashboard.ts @@ -102,10 +102,10 @@ function integrationFromDoctor(checks: { id: string; status: string }[]): Dashbo configPresent: check("config.present"), configParseable: check("config.parse"), pluginConfigured: check("plugin.configured"), - vibeCommandPresent: check("commands.vibe.present"), - vibeDoctorCommandPresent: check("commands.vibe-doctor.present"), - vibeCommandManaged: check("commands.vibe.managed"), - vibeDoctorCommandManaged: check("commands.vibe-doctor.managed"), + copaperCommandPresent: check("commands.copaper.present"), + copaperDoctorCommandPresent: check("commands.copaper-doctor.present"), + copaperCommandManaged: check("commands.copaper.managed"), + copaperDoctorCommandManaged: check("commands.copaper-doctor.managed"), } } diff --git a/packages/opencode-plugin/src/doctor.ts b/packages/opencode-plugin/src/doctor.ts index 90271df..0f7d48b 100644 --- a/packages/opencode-plugin/src/doctor.ts +++ b/packages/opencode-plugin/src/doctor.ts @@ -1,14 +1,14 @@ import { existsSync, readFileSync, statSync } from "node:fs" import { join, resolve } from "node:path" import { parse, type ParseError } from "jsonc-parser" -import { buildVibePaperAgentConfig, type OpenCodeAgentConfig } from "./agent-config" +import { buildCoPaperAgentConfig, type OpenCodeAgentConfig } from "./agent-config" import { agentRuntimeToDoctorChecks } from "./agent-diagnostics" import { assertInsideRoot } from "./fs-utils" import { detectRoot } from "./root" import { resolveBridge, type BridgeDeps } from "./python-bridge" import { hasManagedMarker, MANAGED_COMMAND_NAMES, type CommandName } from "./templates" import { t } from "./i18n" -import { BUNX_CLI_COMMAND, DEFAULT_LOCALE, isVibePaperPluginSpecifier, PACKAGE_NAME, SCHEMA_VERSION, VIBE_COMMAND, type DoctorCheck, type DoctorResult, type Locale } from "./types" +import { BUNX_CLI_COMMAND, DEFAULT_LOCALE, isCoPaperPluginSpecifier, PACKAGE_NAME, SCHEMA_VERSION, COPAPER_COMMAND, type DoctorCheck, type DoctorResult, type Locale } from "./types" import { LOCAL_PLUGIN_IMPORT, LOCAL_PLUGIN_MARKER, LOCAL_PLUGIN_RELATIVE_PATH } from "./installer" const INIT_REMEDIATION = `Run: ${BUNX_CLI_COMMAND} init` @@ -51,7 +51,7 @@ export async function runDoctor(options: DoctorOptions): Promise<DoctorResult> { } else { checks.push({ id: "config.parse", status: "pass", severity: "error", message: "OpenCode config parsed successfully", remediation: null }) const plugins = parsedConfig.plugin - const configuredByPackage = Array.isArray(plugins) && plugins.some(isVibePaperPluginSpecifier) + const configuredByPackage = Array.isArray(plugins) && plugins.some(isCoPaperPluginSpecifier) const localPlugin = readManagedLocalPlugin(root) const configured = configuredByPackage || localPlugin.ok checks.push({ @@ -73,10 +73,10 @@ export async function runDoctor(options: DoctorOptions): Promise<DoctorResult> { for (const command of MANAGED_COMMAND_NAMES) { addCommandChecks(root, checks, command) } - await addVibeCliCheck(root, checks, options.bridgeDeps) + await addCoPaperCliCheck(root, checks, options.bridgeDeps) checks.push(...buildAgentChecks(root, existingAgents)) const ok = checks.every((check) => !(check.severity === "error" && check.status === "fail")) - return { schemaVersion: SCHEMA_VERSION, ok, root, rootReason: detection.reason, packageVersion: options.packageVersion, checks, nextSteps: ok ? ["Restart OpenCode if you just installed, then run /vibe"] : [INIT_REMEDIATION, "Restart OpenCode, then run /vibe-doctor"] } + return { schemaVersion: SCHEMA_VERSION, ok, root, rootReason: detection.reason, packageVersion: options.packageVersion, checks, nextSteps: ok ? ["Restart OpenCode if you just installed, then run /copaper"] : [INIT_REMEDIATION, "Restart OpenCode, then run /copaper-doctor"] } } export function renderDoctorJson(result: DoctorResult): string { @@ -163,7 +163,7 @@ function addCommandChecks(root: string, checks: DoctorCheck[], command: CommandN const path = join(root, ".opencode", "commands", `${command}.md`) const presentId = `commands.${command}.present` const managedId = `commands.${command}.managed` - const severity = command === VIBE_COMMAND ? "error" : "warning" + const severity = command === COPAPER_COMMAND ? "error" : "warning" if (!existsSync(path)) { checks.push({ id: presentId, status: "fail", severity, message: `${path} not found`, remediation: INIT_REMEDIATION }) checks.push({ id: managedId, status: "warn", severity: "warning", message: `${command} command marker missing because command file is missing`, remediation: INIT_REMEDIATION }) @@ -178,34 +178,34 @@ function addCommandChecks(root: string, checks: DoctorCheck[], command: CommandN const content = commandRead.content checks.push({ id: presentId, status: "pass", severity, message: `${path} exists`, remediation: null }) const managed = hasManagedMarker(content, command) - checks.push({ id: managedId, status: managed ? "pass" : "warn", severity: "warning", message: managed ? `${command} command is VibePaper-managed` : `${command} command exists but is not VibePaper-managed`, remediation: managed ? null : "Review the command file or rerun init with --force" }) + checks.push({ id: managedId, status: managed ? "pass" : "warn", severity: "warning", message: managed ? `${command} command is CoPaper-managed` : `${command} command exists but is not CoPaper-managed`, remediation: managed ? null : "Review the command file or rerun init with --force" }) } -const VIBE_CLI_REMEDIATION = "Install the VibePaper Python CLI via `uv pip install -e .` in the project root." +const COPAPER_CLI_REMEDIATION = "Install the CoPaper Python CLI via `uv pip install -e .` in the project root." -async function addVibeCliCheck(root: string, checks: DoctorCheck[], bridgeDeps?: BridgeDeps): Promise<void> { +async function addCoPaperCliCheck(root: string, checks: DoctorCheck[], bridgeDeps?: BridgeDeps): Promise<void> { const resolved = await resolveBridge(root, bridgeDeps ?? {}) if (!resolved.ok) { checks.push({ - id: "vibe-cli.available", + id: "copaper-cli.available", status: "fail", severity: "warning", message: resolved.error.message, - remediation: VIBE_CLI_REMEDIATION, + remediation: COPAPER_CLI_REMEDIATION, }) return } checks.push({ - id: "vibe-cli.available", + id: "copaper-cli.available", status: "pass", severity: "warning", - message: `vibe CLI resolved via ${resolved.resolution.kind} (${resolved.resolution.path})`, + message: `copaper CLI resolved via ${resolved.resolution.kind} (${resolved.resolution.path})`, remediation: null, }) } function buildAgentChecks(root: string, existingAgents: Record<string, OpenCodeAgentConfig>): DoctorCheck[] { - const result = buildVibePaperAgentConfig({ root, existingAgents }) + const result = buildCoPaperAgentConfig({ root, existingAgents }) const permissionProfiles = new Map(result.runtime.agents.map((agent) => [`agents.${agent.name}`, agent.permissionProfile])) return agentRuntimeToDoctorChecks(result.runtime).map((check) => { const permissionProfile = permissionProfiles.get(check.id) diff --git a/packages/opencode-plugin/src/fs-utils.ts b/packages/opencode-plugin/src/fs-utils.ts index ba743d4..3e9b6c8 100644 --- a/packages/opencode-plugin/src/fs-utils.ts +++ b/packages/opencode-plugin/src/fs-utils.ts @@ -18,7 +18,7 @@ export function backupPathFor(root: string, relativePath: string, now = new Date throw new Error(`Refusing to create backup outside backup directory: ${relativePath}`) } const stamp = now.toISOString().replace(/[:.]/g, "-") - const backupBase = resolve(root, ".opencode", "vibepaper", "backups", stamp) + const backupBase = resolve(root, ".opencode", "copaper", "backups", stamp) const backupPath = resolve(backupBase, relativePath) if (!isInsideOrSame(backupBase, backupPath)) { throw new Error(`Refusing to create backup outside backup directory: ${relativePath}`) diff --git a/packages/opencode-plugin/src/i18n.ts b/packages/opencode-plugin/src/i18n.ts index 2d50afc..aa208b5 100644 --- a/packages/opencode-plugin/src/i18n.ts +++ b/packages/opencode-plugin/src/i18n.ts @@ -8,15 +8,15 @@ export interface ResolvedLocale { const zhCN = { "cli.dryRun": "演练模式", - "cli.installed": "已安装 VibePaper OpenCode 集成。", + "cli.installed": "已安装 CoPaper OpenCode 集成。", "cli.noFilesChanged": "没有修改任何文件。", - "cli.restart": "重启 OpenCode,然后运行 /vibe-doctor。", - "doctor.title": "VibePaper OpenCode 诊断 v{version}", + "cli.restart": "重启 OpenCode,然后运行 /copaper-doctor。", + "doctor.title": "CoPaper OpenCode 诊断 v{version}", "doctor.root": "根目录:{root}({reason})", "doctor.allPassed": "所有必需检查均已通过。", "doctor.failed": "一个或多个必需检查失败。", "doctor.next": "下一步:{step}", - "apply.title": "VibePaper 初始化写入", + "apply.title": "CoPaper 初始化写入", "apply.success": "初始化写入完成。", "apply.failed": "初始化写入未完成。", "apply.changedFiles": "已写入", @@ -24,9 +24,9 @@ const zhCN = { "apply.conflicts": "冲突", "apply.errors": "错误", "apply.none": "无", - "apply.next": "下一步:重新运行 `/vibe` 查看 ready 状态。", + "apply.next": "下一步:重新运行 `/copaper` 查看 ready 状态。", "apply.fixConflicts": "请先处理冲突文件,然后重新确认初始化。", - "dashboard.title": "VibePaper 项目仪表盘", + "dashboard.title": "CoPaper 项目仪表盘", "dashboard.statusLabel": "状态:", "dashboard.statusReady": "ready", "dashboard.statusNeedsInit": "needs-init", @@ -46,9 +46,9 @@ const zhCN = { "summary.conflict": "冲突", "summary.invalid": "无效", "summary.optional": "可选", - "recommendation.repairInstallation": "先修复 OpenCode 插件安装,再运行 /vibe。", + "recommendation.repairInstallation": "先修复 OpenCode 插件安装,再运行 /copaper。", "recommendation.previewInit": "检查初始化预览;本阶段不会写入文件。", - "recommendation.ready": "项目已具备核心 VibePaper 文件,可以进入后续写作流程。", + "recommendation.ready": "项目已具备核心 CoPaper 文件,可以进入后续写作流程。", "table.check": "检查项", "table.status": "状态", "table.message": "说明", @@ -77,9 +77,9 @@ const zhCN = { "reason.user-owned": "检测到用户已有内容,本阶段不会覆盖", "reason.unsafe-target": "目标不是安全的普通文件或内容无效", "reason.future-optional": "可在后续文献工作流中创建", - "workflow.statusTitle": "VibePaper 工作流状态", - "workflow.logTitle": "VibePaper 工作流日志", - "workflow.setPhaseTitle": "VibePaper 阶段状态更新", + "workflow.statusTitle": "CoPaper 工作流状态", + "workflow.logTitle": "CoPaper 工作流日志", + "workflow.setPhaseTitle": "CoPaper 阶段状态更新", "workflow.setPhaseSuccess": "阶段状态已更新。", "workflow.setPhaseFailed": "阶段状态更新失败。", "workflow.statusReady": "已读取工作流状态。", @@ -101,10 +101,10 @@ const zhCN = { "workflow.result": "结果", "workflow.recommendationContinue": "继续当前阶段。", "workflow.recommendationUnavailable": "先完成初始化或修复状态文件。", - "artifact.statusTitle": "VibePaper 工件状态", + "artifact.statusTitle": "CoPaper 工件状态", "artifact.statusReady": "已读取工件状态。", "artifact.statusUnavailable": "工件状态不可用。", - "artifact.recordTitle": "VibePaper 工件就绪度记录", + "artifact.recordTitle": "CoPaper 工件就绪度记录", "artifact.recordSuccess": "工件就绪度已记录。", "artifact.recordFailed": "工件就绪度记录失败。", "artifact.artifact": "工件", @@ -135,7 +135,7 @@ const zhCN = { "artifact.recommendationCheckers": "重新运行检查器,刷新检查结果。", "artifact.recommendationContinue": "核心工件已可用,可以继续当前写作流程。", "artifact.recommendationUnavailable": "先完成初始化或修复不可读取的工件。", - "paperStructure.title": "VibePaper 论文结构状态", + "paperStructure.title": "CoPaper 论文结构状态", "paperStructure.ready": "已读取 paper.md 结构。", "paperStructure.unavailable": "paper.md 结构不可用。", "paperStructure.path": "路径", @@ -153,7 +153,7 @@ const zhCN = { "paperStructure.severity": "严重度", "paperStructure.message": "说明", "paperStructure.none": "无", - "storylineStructure.title": "VibePaper 故事线结构状态", + "storylineStructure.title": "CoPaper 故事线结构状态", "storylineStructure.ready": "已读取 storyline.md 结构。", "storylineStructure.unavailable": "storyline.md 结构不可用。", "storylineStructure.path": "路径", @@ -166,11 +166,11 @@ const zhCN = { "storylineStructure.substantiveLines": "实质行数", "storylineStructure.todoLines": "TODO 行数", "storylineStructure.none": "无", - "pdfExtract.title": "VibePaper PDF 提取", + "pdfExtract.title": "CoPaper PDF 提取", "pdfExtract.ready": "已提取 PDF 文本。", "pdfExtract.unavailable": "PDF 提取不可用。", "pdfExtract.pages": "页数", - "pptExtract.title": "VibePaper PPTX 提取", + "pptExtract.title": "CoPaper PPTX 提取", "pptExtract.ready": "已提取 PPTX 文本。", "pptExtract.unavailable": "PPTX 提取不可用。", "pptExtract.slides": "幻灯片数", @@ -184,7 +184,7 @@ const zhCN = { "importExtract.warnings": "警告", "importExtract.textPreview": "文本预览", "importExtract.none": "无", - "checkerStatus.title": "VibePaper 检查器状态", + "checkerStatus.title": "CoPaper 检查器状态", "checkerStatus.ready": "已读取检查器状态。", "checkerStatus.unavailable": "检查器状态不可用。", "checkerStatus.statePath": "状态文件", @@ -200,7 +200,7 @@ const zhCN = { "checkerStatus.minor": "Minor", "checkerStatus.warnings": "警告", "checkerStatus.none": "无", - "checkerRecord.title": "VibePaper 检查器结果记录", + "checkerRecord.title": "CoPaper 检查器结果记录", "checkerRecord.success": "检查器结果已记录。", "checkerRecord.failed": "检查器结果记录失败。", "checkerRecord.checker": "检查器", @@ -208,7 +208,7 @@ const zhCN = { "checkerRecord.counts": "问题计数", "checkerRecord.warnings": "警告", "checkerRecord.none": "无", - "relatedworkStatus.title": "VibePaper 相关工作状态", + "relatedworkStatus.title": "CoPaper 相关工作状态", "relatedworkStatus.ready": "已读取相关工作状态。", "relatedworkStatus.unavailable": "相关工作状态不可用。", "relatedworkStatus.summary": "摘要", @@ -249,15 +249,15 @@ const zhCN = { const enUS: Record<keyof typeof zhCN, string> = { "cli.dryRun": "DRY RUN", - "cli.installed": "Installed VibePaper OpenCode integration.", + "cli.installed": "Installed CoPaper OpenCode integration.", "cli.noFilesChanged": "No files were changed.", - "cli.restart": "Restart OpenCode, then run /vibe-doctor.", - "doctor.title": "VibePaper OpenCode Doctor v{version}", + "cli.restart": "Restart OpenCode, then run /copaper-doctor.", + "doctor.title": "CoPaper OpenCode Doctor v{version}", "doctor.root": "Root: {root} ({reason})", "doctor.allPassed": "All required checks passed.", "doctor.failed": "One or more required checks failed.", "doctor.next": "Next: {step}", - "apply.title": "VibePaper Init Apply", + "apply.title": "CoPaper Init Apply", "apply.success": "Initialization files were written.", "apply.failed": "Initialization did not complete.", "apply.changedFiles": "Changed files", @@ -265,9 +265,9 @@ const enUS: Record<keyof typeof zhCN, string> = { "apply.conflicts": "Conflicts", "apply.errors": "Errors", "apply.none": "none", - "apply.next": "Next: rerun `/vibe` to view ready status.", + "apply.next": "Next: rerun `/copaper` to view ready status.", "apply.fixConflicts": "Resolve the conflicting files, then confirm initialization again.", - "dashboard.title": "VibePaper Project Dashboard", + "dashboard.title": "CoPaper Project Dashboard", "dashboard.statusLabel": "Status:", "dashboard.statusReady": "ready", "dashboard.statusNeedsInit": "needs-init", @@ -287,9 +287,9 @@ const enUS: Record<keyof typeof zhCN, string> = { "summary.conflict": "conflict", "summary.invalid": "invalid", "summary.optional": "optional", - "recommendation.repairInstallation": "Repair the OpenCode plugin installation, then run /vibe again.", + "recommendation.repairInstallation": "Repair the OpenCode plugin installation, then run /copaper again.", "recommendation.previewInit": "Review the init preview; this phase does not write files.", - "recommendation.ready": "Core VibePaper files are ready, so you can continue with the writing workflow.", + "recommendation.ready": "Core CoPaper files are ready, so you can continue with the writing workflow.", "table.check": "Check", "table.status": "Status", "table.message": "Message", @@ -496,7 +496,7 @@ const messages: Record<Locale, Record<keyof typeof zhCN, string>> = { export type MessageKey = keyof typeof zhCN export function resolveLocale(input?: string | null, env: Record<string, string | undefined> = process.env): ResolvedLocale { - const requested = input ?? env.VIBEPAPER_LANG ?? null + const requested = input ?? env.COPAPER_LANG ?? null if (isSupportedLocale(requested)) return { locale: requested, requested, fallback: false } if (requested === null || requested === "") return { locale: DEFAULT_LOCALE, requested, fallback: false } return { locale: DEFAULT_LOCALE, requested, fallback: true } diff --git a/packages/opencode-plugin/src/index.ts b/packages/opencode-plugin/src/index.ts index a03a47d..1861426 100644 --- a/packages/opencode-plugin/src/index.ts +++ b/packages/opencode-plugin/src/index.ts @@ -1,6 +1,6 @@ import { tool, type Plugin } from "@opencode-ai/plugin" -import { buildVibePaperAgentConfig, type OpenCodeAgentConfig } from "./agent-config" -import { setLatestVibePaperAgentRuntimeState } from "./agent-diagnostics" +import { buildCoPaperAgentConfig, type OpenCodeAgentConfig } from "./agent-config" +import { setLatestCoPaperAgentRuntimeState } from "./agent-diagnostics" import { recordArtifactReadiness, renderArtifactRecordOutput } from "./artifact-record" import { buildArtifactStatus, renderArtifactStatusOutput } from "./artifacts" import { recordCheckerResult, renderCheckerRecordOutput } from "./checker-record" @@ -20,9 +20,9 @@ const packageVersion = "0.1.0" type PluginConfigInput = Parameters<NonNullable<Awaited<ReturnType<Plugin>>["config"]>>[0] -export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) => { +export const CoPaperPlugin: Plugin = async ({ directory, worktree, client }) => { await client?.app?.log?.({ - body: { service: "vibepaper", level: "info", message: "VibePaper OpenCode plugin initialized" }, + body: { service: "copaper", level: "info", message: "CoPaper OpenCode plugin initialized" }, }).catch(() => undefined) let managedAgentFingerprints = new Map<string, string>() @@ -37,22 +37,22 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = retainedAgents[agentName] = agentConfig as OpenCodeAgentConfig } - const result = buildVibePaperAgentConfig({ root: directory, existingAgents: retainedAgents }) - setLatestVibePaperAgentRuntimeState(result.runtime, directory) + const result = buildCoPaperAgentConfig({ root: directory, existingAgents: retainedAgents }) + setLatestCoPaperAgentRuntimeState(result.runtime, directory) managedAgentFingerprints = new Map(Object.entries(result.injectedAgents).map(([agentName, agentConfig]) => [agentName, agentConfigFingerprint(agentConfig)])) input.agent = { ...retainedAgents, ...result.injectedAgents } as PluginConfigInput["agent"] }, tool: { - vibepaper_dashboard: tool({ - description: "Show VibePaper project readiness and init preview. Read-only, does not modify files.", + copaper_dashboard: tool({ + description: "Show CoPaper project readiness and init preview. Read-only, does not modify files.", args: {}, async execute(_args, context) { const result = await buildDashboardResult({ cwd: context.directory, worktree: context.worktree, packageVersion }) return renderDashboardOutput(result) }, }), - vibepaper_init_apply: tool({ - description: "Apply VibePaper project initialization after explicit user confirmation. Writes core files only and refuses conflicts.", + copaper_init_apply: tool({ + description: "Apply CoPaper project initialization after explicit user confirmation. Writes core files only and refuses conflicts.", args: { name: tool.schema.string().describe("Project name"), domain: tool.schema.string().describe("Research domain"), @@ -62,15 +62,15 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderProjectInitApplyOutput(result) }, }), - vibepaper_artifact_status: tool({ - description: "Show read-only VibePaper artifact readiness, evidence, and recommendation. Does not modify files or workflow state.", + copaper_artifact_status: tool({ + description: "Show read-only CoPaper artifact readiness, evidence, and recommendation. Does not modify files or workflow state.", args: {}, async execute(_args, context) { const result = await buildArtifactStatus({ cwd: context.directory, worktree: context.worktree }) return renderArtifactStatusOutput(result) }, }), - vibepaper_paper_structure_status: tool({ + copaper_paper_structure_status: tool({ description: "Show read-only paper.md structure completion, Level 5 writing targets, next target, and structural issues. Does not modify files.", args: {}, async execute(_args, context) { @@ -78,7 +78,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderPaperStructureStatusOutput(result) }, }), - vibepaper_storyline_structure_status: tool({ + copaper_storyline_structure_status: tool({ description: "Show read-only storyline.md section readiness, next storyline target, and TODO coverage. Does not modify files.", args: {}, async execute(_args, context) { @@ -86,7 +86,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderStorylineStructureStatusOutput(result) }, }), - vibepaper_pdf_extract: tool({ + copaper_pdf_extract: tool({ description: "Extract text from a user-specified PDF inside the project. Read-only; does not scan for files or modify project state.", args: { path: tool.schema.string().describe("Explicit relative or in-project absolute path to the PDF file"), @@ -97,7 +97,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderPdfExtractOutput(result) }, }), - vibepaper_ppt_extract: tool({ + copaper_ppt_extract: tool({ description: "Extract slide text from a user-specified PPTX inside the project. Read-only; does not scan for files or modify project state.", args: { path: tool.schema.string().describe("Explicit relative or in-project absolute path to the PPTX file"), @@ -109,7 +109,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderPptExtractOutput(result) }, }), - vibepaper_checker_status: tool({ + copaper_checker_status: tool({ description: "Show read-only checker result status, severity counts, stale signals, and precheck report evidence. Does not run checkers or modify files.", args: {}, async execute(_args, context) { @@ -117,7 +117,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderCheckerStatusOutput(result) }, }), - vibepaper_relatedwork_status: tool({ + copaper_relatedwork_status: tool({ description: "Show read-only related-work catalog, BibTeX, PDF, summary, and cross-index status. Does not run search, import, download, summarize, build-index, or modify files.", args: {}, async execute(_args, context) { @@ -125,7 +125,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkStatusOutput(result) }, }), - vibepaper_relatedwork_keywords: tool({ + copaper_relatedwork_keywords: tool({ description: "Extract relatedwork keywords via the Python CLI. Writes relatedwork/queries.txt; does not patch literature phase counters.", args: { source: tool.schema.string().optional().describe("Optional source markdown path (defaults to storyline.md)"), @@ -136,7 +136,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_search: tool({ + copaper_relatedwork_search: tool({ description: "Search related work via Semantic Scholar / arXiv. Writes relatedwork/search_cache.json. Requires explicit user confirmation before invoking.", args: { queries: tool.schema.array(tool.schema.string()).min(1).describe("List of search query strings"), @@ -148,7 +148,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_import: tool({ + copaper_relatedwork_import: tool({ description: "Import relatedwork/search_cache.json into relatedwork/literature.json. Writes the literature catalog. Requires explicit user confirmation.", args: { input: tool.schema.string().optional().describe("Optional input cache path (defaults to relatedwork/search_cache.json)"), @@ -158,7 +158,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_sync_bib: tool({ + copaper_relatedwork_sync_bib: tool({ description: "Synchronize relatedwork/paper_list.bib with the literature catalog. Writes the bibliography. Requires explicit user confirmation.", args: {}, async execute(_args, context) { @@ -166,7 +166,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_download: tool({ + copaper_relatedwork_download: tool({ description: "Download related-work PDFs into relatedwork/pdfs/. Writes files. Requires explicit user confirmation.", args: { paperId: tool.schema.string().optional().describe("Optional paper id to download (defaults to all queued papers)"), @@ -177,7 +177,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_summarize: tool({ + copaper_relatedwork_summarize: tool({ description: "Generate LLM-backed PDF summaries into relatedwork/papers/. Writes markdown summary files. Requires explicit user confirmation.", args: { paperId: tool.schema.string().optional().describe("Optional paper id to summarize (defaults to all eligible papers)"), @@ -189,7 +189,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_register_summary: tool({ + copaper_relatedwork_register_summary: tool({ description: "Register an existing PDF summary in relatedwork/literature.json. Writes the literature catalog. Requires explicit user confirmation.", args: { paperId: tool.schema.string().describe("Paper id whose summary path should be registered"), @@ -200,7 +200,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_build_index: tool({ + copaper_relatedwork_build_index: tool({ description: "Build the cross-paper index at .agents/cross_index.json from relatedwork/papers/. Writes the index. Requires explicit user confirmation.", args: {}, async execute(_args, context) { @@ -208,7 +208,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_relatedwork_clean: tool({ + copaper_relatedwork_clean: tool({ description: "Clean stale related-work entries (orphan PDFs/summaries, dropped catalog entries). Writes files. Requires explicit user confirmation.", args: { dryRun: tool.schema.boolean().optional().describe("Preview cleanup without applying changes"), @@ -218,7 +218,7 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderRelatedworkToolOutput(result) }, }), - vibepaper_checker_record: tool({ + copaper_checker_record: tool({ description: "Record a checker run summary after explicit user confirmation. Writes state.checkers and appends an event; does not resolve individual issues.", args: { checker: tool.schema.enum(CHECKER_RECORD_IDS).describe("Checker id to record"), @@ -242,8 +242,8 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderCheckerRecordOutput(result) }, }), - vibepaper_artifact_record: tool({ - description: "Record VibePaper artifact readiness after explicit user confirmation. Writes artifact state and appends an event record; does not modify workflow phases.", + copaper_artifact_record: tool({ + description: "Record CoPaper artifact readiness after explicit user confirmation. Writes artifact state and appends an event record; does not modify workflow phases.", args: { artifact: tool.schema.enum(ARTIFACT_RECORD_IDS).describe("Artifact id to record"), status: tool.schema.enum(ARTIFACT_STATUSES).describe("Recorded artifact readiness status"), @@ -257,16 +257,16 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderArtifactRecordOutput(result) }, }), - vibepaper_workflow_status: tool({ - description: "Show VibePaper workflow progress, phases, and next step recommendation. Read-only, does not modify files.", + copaper_workflow_status: tool({ + description: "Show CoPaper workflow progress, phases, and next step recommendation. Read-only, does not modify files.", args: {}, async execute(_args, context) { const result = await buildWorkflowStatus({ cwd: context.directory, worktree: context.worktree }) return renderWorkflowStatusOutput(result) }, }), - vibepaper_workflow_log: tool({ - description: "Show recent VibePaper workflow event records with optional filters. Read-only, does not modify files.", + copaper_workflow_log: tool({ + description: "Show recent CoPaper workflow event records with optional filters. Read-only, does not modify files.", args: { lastN: tool.schema.number().int().min(1).max(50).optional().describe("Maximum number of recent records to return, from 1 to 50"), phase: tool.schema.string().optional().describe("Optional workflow phase id filter"), @@ -277,8 +277,8 @@ export const VibePaperPlugin: Plugin = async ({ directory, worktree, client }) = return renderWorkflowLogOutput(result) }, }), - vibepaper_workflow_set_phase: tool({ - description: "Set a VibePaper workflow phase status after explicit user confirmation. Writes workflow state and appends an event record.", + copaper_workflow_set_phase: tool({ + description: "Set a CoPaper workflow phase status after explicit user confirmation. Writes workflow state and appends an event record.", args: { phase: tool.schema.string().describe("Workflow phase id to update"), status: tool.schema.enum(WORKFLOW_PHASE_STATUSES).describe("Next workflow phase status"), @@ -312,4 +312,4 @@ function isPlainObject(value: unknown): value is Record<string, unknown> { return typeof value === "object" && value !== null && !Array.isArray(value) } -export default VibePaperPlugin +export default CoPaperPlugin diff --git a/packages/opencode-plugin/src/installer.ts b/packages/opencode-plugin/src/installer.ts index 206ff89..68b7764 100644 --- a/packages/opencode-plugin/src/installer.ts +++ b/packages/opencode-plugin/src/installer.ts @@ -8,12 +8,12 @@ import { detectRoot } from "./root" import { hasManagedMarker, MANAGED_COMMAND_NAMES, renderCommandTemplate, type CommandName } from "./templates" import { DEFAULT_LOCALE, PACKAGE_NAME, type Locale } from "./types" -export const LOCAL_PLUGIN_RELATIVE_PATH = ".opencode/plugins/vibepaper.js" as const -export const LOCAL_PLUGIN_MARKER = "VibePaper managed local plugin: @vibepaper/opencode" as const -export const LOCAL_PLUGIN_IMPORT = "../../node_modules/@vibepaper/opencode/dist/index.js" as const +export const LOCAL_PLUGIN_RELATIVE_PATH = ".opencode/plugins/copaper.js" as const +export const LOCAL_PLUGIN_MARKER = "CoPaper managed local plugin: @copaper/opencode" as const +export const LOCAL_PLUGIN_IMPORT = "../../node_modules/@copaper/opencode/dist/index.js" as const export const LOCAL_PLUGIN_CONTENT = `// ${LOCAL_PLUGIN_MARKER} // Loaded by OpenCode from .opencode/plugins/ without absolute paths. -export { VibePaperPlugin, default } from "${LOCAL_PLUGIN_IMPORT}" +export { CoPaperPlugin, default } from "${LOCAL_PLUGIN_IMPORT}" ` export interface InitOptions { @@ -111,7 +111,7 @@ export function resolvePluginSpecifier(root: string, cliEntryPath?: string): str if (!cliEntryPath) return PACKAGE_NAME const indexPath = join(dirname(cliEntryPath), "index.js") if (!existsSync(indexPath)) return PACKAGE_NAME - if (!indexPath.endsWith(join("node_modules", "@vibepaper", "opencode", "dist", "index.js"))) return PACKAGE_NAME + if (!indexPath.endsWith(join("node_modules", "@copaper", "opencode", "dist", "index.js"))) return PACKAGE_NAME try { assertInsideRoot(root, indexPath) return pathToFileURL(indexPath).href diff --git a/packages/opencode-plugin/src/permission-profiles.ts b/packages/opencode-plugin/src/permission-profiles.ts index 32ecfba..5e02a38 100644 --- a/packages/opencode-plugin/src/permission-profiles.ts +++ b/packages/opencode-plugin/src/permission-profiles.ts @@ -26,29 +26,29 @@ const READ_ONLY_PROFILE: OpenCodePermissionConfig = { external_directory: "deny", task: "deny", skill: "deny", - vibepaper_dashboard: "allow", - vibepaper_artifact_status: "allow", - vibepaper_paper_structure_status: "allow", - vibepaper_storyline_structure_status: "allow", - vibepaper_pdf_extract: "allow", - vibepaper_ppt_extract: "allow", - vibepaper_checker_status: "allow", - vibepaper_relatedwork_status: "allow", - vibepaper_relatedwork_keywords: "deny", - vibepaper_relatedwork_search: "deny", - vibepaper_relatedwork_import: "deny", - vibepaper_relatedwork_sync_bib: "deny", - vibepaper_relatedwork_download: "deny", - vibepaper_relatedwork_summarize: "deny", - vibepaper_relatedwork_register_summary: "deny", - vibepaper_relatedwork_build_index: "deny", - vibepaper_relatedwork_clean: "deny", - vibepaper_workflow_status: "allow", - vibepaper_workflow_log: "allow", - vibepaper_init_apply: "deny", - vibepaper_artifact_record: "deny", - vibepaper_checker_record: "deny", - vibepaper_workflow_set_phase: "deny", + copaper_dashboard: "allow", + copaper_artifact_status: "allow", + copaper_paper_structure_status: "allow", + copaper_storyline_structure_status: "allow", + copaper_pdf_extract: "allow", + copaper_ppt_extract: "allow", + copaper_checker_status: "allow", + copaper_relatedwork_status: "allow", + copaper_relatedwork_keywords: "deny", + copaper_relatedwork_search: "deny", + copaper_relatedwork_import: "deny", + copaper_relatedwork_sync_bib: "deny", + copaper_relatedwork_download: "deny", + copaper_relatedwork_summarize: "deny", + copaper_relatedwork_register_summary: "deny", + copaper_relatedwork_build_index: "deny", + copaper_relatedwork_clean: "deny", + copaper_workflow_status: "allow", + copaper_workflow_log: "allow", + copaper_init_apply: "deny", + copaper_artifact_record: "deny", + copaper_checker_record: "deny", + copaper_workflow_set_phase: "deny", } const PERMISSION_PROFILES = { @@ -63,20 +63,20 @@ const PERMISSION_PROFILES = { }, stateRecord: { ...READ_ONLY_PROFILE, - vibepaper_artifact_record: "ask", - vibepaper_checker_record: "ask", + copaper_artifact_record: "ask", + copaper_checker_record: "ask", }, literatureWrite: { ...READ_ONLY_PROFILE, - vibepaper_relatedwork_keywords: "ask", - vibepaper_relatedwork_search: "ask", - vibepaper_relatedwork_import: "ask", - vibepaper_relatedwork_sync_bib: "ask", - vibepaper_relatedwork_download: "ask", - vibepaper_relatedwork_summarize: "ask", - vibepaper_relatedwork_register_summary: "ask", - vibepaper_relatedwork_build_index: "ask", - vibepaper_relatedwork_clean: "ask", + copaper_relatedwork_keywords: "ask", + copaper_relatedwork_search: "ask", + copaper_relatedwork_import: "ask", + copaper_relatedwork_sync_bib: "ask", + copaper_relatedwork_download: "ask", + copaper_relatedwork_summarize: "ask", + copaper_relatedwork_register_summary: "ask", + copaper_relatedwork_build_index: "ask", + copaper_relatedwork_clean: "ask", }, } satisfies Record<PermissionProfileName, OpenCodePermissionConfig> diff --git a/packages/opencode-plugin/src/project-templates.ts b/packages/opencode-plugin/src/project-templates.ts index adeb06f..3c4afdd 100644 --- a/packages/opencode-plugin/src/project-templates.ts +++ b/packages/opencode-plugin/src/project-templates.ts @@ -20,9 +20,9 @@ Use heading levels 1-5 only for structure. Place body text under level 6 heading const agentsTemplate = `# AGENTS.md ## OVERVIEW -###### VibePaper Project Guidance +###### CoPaper Project Guidance <!-- description: Local agent guidance --> -This project was initialized by VibePaper. Keep shared state in \`.agents/state.json\` and events in \`.agents/events.jsonl\`. +This project was initialized by CoPaper. Keep shared state in \`.agents/state.json\` and events in \`.agents/events.jsonl\`. ## CONVENTIONS ###### Document Structure @@ -60,8 +60,8 @@ export function buildProjectState(input: ProjectTemplateInput): ProjectState { auto_commit: false, identity: { role: "assistant", - git_name: "VibePaper Bot", - git_email: "bot@vibepaper.dev", + git_name: "CoPaper Bot", + git_email: "bot@copaper.dev", }, }, checkers: {}, diff --git a/packages/opencode-plugin/src/python-bridge.ts b/packages/opencode-plugin/src/python-bridge.ts index 2c977bf..c0d4f63 100644 --- a/packages/opencode-plugin/src/python-bridge.ts +++ b/packages/opencode-plugin/src/python-bridge.ts @@ -86,7 +86,7 @@ async function readStream(stream: ReadableStream<Uint8Array> | null | undefined) } function defaultResolveVenv(root: string): string | null { - const candidate = join(root, ".venv", "bin", "vibe") + const candidate = join(root, ".venv", "bin", "copaper") try { assertInsideRoot(root, candidate) } catch { @@ -120,13 +120,13 @@ export async function resolveBridge(root: string, deps: BridgeDeps = {}): Promis } const uv = (deps.resolveUv ?? defaultResolveUv)() if (uv !== null) { - return { ok: true, resolution: { kind: "uv-run", path: uv, args: ["run", "--project", root, "vibe"] } } + return { ok: true, resolution: { kind: "uv-run", path: uv, args: ["run", "--project", root, "copaper"] } } } return { ok: false, error: { - code: "vibe-cli-unavailable", - message: "vibe CLI not found: no executable at <root>/.venv/bin/vibe and `uv` is not on PATH", + code: "copaper-cli-unavailable", + message: "copaper CLI not found: no executable at <root>/.venv/bin/copaper and `uv` is not on PATH", }, } } @@ -160,7 +160,7 @@ export async function runBridge(options: BridgeOptions, deps: BridgeDeps = {}): ok: false, resolution, command, - error: { code: "bridge-spawn-failed", message: `Failed to spawn vibe CLI: ${errorMessage(error)}` }, + error: { code: "bridge-spawn-failed", message: `Failed to spawn copaper CLI: ${errorMessage(error)}` }, stdout: "", stderr: "", exitCode: null, @@ -173,7 +173,7 @@ export async function runBridge(options: BridgeOptions, deps: BridgeDeps = {}): ok: false, resolution, command, - error: { code: "bridge-timeout", message: `vibe CLI exceeded ${timeoutMs}ms timeout` }, + error: { code: "bridge-timeout", message: `copaper CLI exceeded ${timeoutMs}ms timeout` }, stdout: spawnResult.stdout, stderr: spawnResult.stderr, exitCode: spawnResult.exitCode, @@ -186,7 +186,7 @@ export async function runBridge(options: BridgeOptions, deps: BridgeDeps = {}): ok: false, resolution, command, - error: { code: "vibe-nonzero-exit", message: `vibe CLI exited with code ${exitCode}` }, + error: { code: "copaper-nonzero-exit", message: `copaper CLI exited with code ${exitCode}` }, stdout: spawnResult.stdout, stderr: spawnResult.stderr, exitCode, diff --git a/packages/opencode-plugin/src/readiness.ts b/packages/opencode-plugin/src/readiness.ts index 3601cf6..aedec56 100644 --- a/packages/opencode-plugin/src/readiness.ts +++ b/packages/opencode-plugin/src/readiness.ts @@ -64,7 +64,7 @@ function inspectAgentsFile(root: string): ReadinessItem { try { if (!statSync(fullPath).isFile()) return makeItem("agents", path, "conflict", false, `${path} should be reviewed.`) const content = readFileSync(fullPath, "utf8") - if (content.includes("VibePaper")) return makeItem("agents", path, "exists-managed", false, `${path} is managed by VibePaper.`) + if (content.includes("CoPaper")) return makeItem("agents", path, "exists-managed", false, `${path} is managed by CoPaper.`) } catch { return makeItem("agents", path, "conflict", false, `${path} cannot be inspected.`) } diff --git a/packages/opencode-plugin/src/relatedwork-tools.ts b/packages/opencode-plugin/src/relatedwork-tools.ts index 0b74f49..d7aa4aa 100644 --- a/packages/opencode-plugin/src/relatedwork-tools.ts +++ b/packages/opencode-plugin/src/relatedwork-tools.ts @@ -40,40 +40,40 @@ export async function runRelatedworkKeywords(options: RelatedworkKeywordsOptions const args: string[] = ["relatedwork", "keywords"] if (typeof options.source === "string" && options.source.trim() !== "") args.push("--from", options.source.trim()) if (typeof options.count === "number" && Number.isFinite(options.count)) args.push("--count", String(Math.max(1, Math.min(30, Math.trunc(options.count))))) - return invoke({ subcommand: "keywords", toolId: "vibepaper_relatedwork_keywords", args, options, deps }) + return invoke({ subcommand: "keywords", toolId: "copaper_relatedwork_keywords", args, options, deps }) } export async function runRelatedworkSearch(options: RelatedworkSearchOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { if (!Array.isArray(options.queries) || options.queries.length === 0) { - return immediateError("vibepaper_relatedwork_search", "invalid-args", "queries must be a non-empty array of strings", options) + return immediateError("copaper_relatedwork_search", "invalid-args", "queries must be a non-empty array of strings", options) } const args: string[] = ["relatedwork", "search"] for (const query of options.queries) { if (typeof query !== "string" || query.trim() === "") { - return immediateError("vibepaper_relatedwork_search", "invalid-args", "Every query must be a non-empty string", options) + return immediateError("copaper_relatedwork_search", "invalid-args", "Every query must be a non-empty string", options) } args.push("--query", query) } if (typeof options.queriesFile === "string" && options.queriesFile.trim() !== "") args.push("--queries-file", options.queriesFile.trim()) if (typeof options.limit === "number" && Number.isFinite(options.limit)) args.push("--limit", String(Math.max(1, Math.trunc(options.limit)))) - return invoke({ subcommand: "search", toolId: "vibepaper_relatedwork_search", args, options, deps }) + return invoke({ subcommand: "search", toolId: "copaper_relatedwork_search", args, options, deps }) } export async function runRelatedworkImport(options: RelatedworkImportOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { const args: string[] = ["relatedwork", "import"] if (typeof options.input === "string" && options.input.trim() !== "") args.push("--input", options.input.trim()) - return invoke({ subcommand: "import", toolId: "vibepaper_relatedwork_import", args, options, deps }) + return invoke({ subcommand: "import", toolId: "copaper_relatedwork_import", args, options, deps }) } export async function runRelatedworkSyncBib(options: RelatedworkSyncBibOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { const args: string[] = ["relatedwork", "sync-bib"] - return invoke({ subcommand: "sync-bib", toolId: "vibepaper_relatedwork_sync_bib", args, options, deps }) + return invoke({ subcommand: "sync-bib", toolId: "copaper_relatedwork_sync_bib", args, options, deps }) } export async function runRelatedworkDownload(options: RelatedworkDownloadOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { const args: string[] = ["relatedwork", "download"] if (typeof options.paperId === "string" && options.paperId.trim() !== "") args.push("--paper-id", options.paperId.trim()) - return invoke({ subcommand: "download", toolId: "vibepaper_relatedwork_download", args, options, deps }) + return invoke({ subcommand: "download", toolId: "copaper_relatedwork_download", args, options, deps }) } export async function runRelatedworkSummarize(options: RelatedworkSummarizeOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { @@ -81,23 +81,23 @@ export async function runRelatedworkSummarize(options: RelatedworkSummarizeOptio if (typeof options.paperId === "string" && options.paperId.trim() !== "") args.push("--paper-id", options.paperId.trim()) if (typeof options.storyline === "string" && options.storyline.trim() !== "") args.push("--storyline", options.storyline.trim()) if (typeof options.template === "string" && options.template.trim() !== "") args.push("--template", options.template.trim()) - return invoke({ subcommand: "summarize", toolId: "vibepaper_relatedwork_summarize", args, options, deps }) + return invoke({ subcommand: "summarize", toolId: "copaper_relatedwork_summarize", args, options, deps }) } export async function runRelatedworkRegisterSummary(options: RelatedworkRegisterSummaryOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { if (typeof options.paperId !== "string" || options.paperId.trim() === "") { - return immediateError("vibepaper_relatedwork_register_summary", "invalid-args", "paperId is required", options) + return immediateError("copaper_relatedwork_register_summary", "invalid-args", "paperId is required", options) } if (typeof options.path !== "string" || options.path.trim() === "") { - return immediateError("vibepaper_relatedwork_register_summary", "invalid-args", "path is required", options) + return immediateError("copaper_relatedwork_register_summary", "invalid-args", "path is required", options) } const args: string[] = ["relatedwork", "register-summary", "--paper-id", options.paperId.trim(), "--summary-path", options.path.trim()] - return invoke({ subcommand: "register-summary", toolId: "vibepaper_relatedwork_register_summary", args, options, deps }) + return invoke({ subcommand: "register-summary", toolId: "copaper_relatedwork_register_summary", args, options, deps }) } export async function runRelatedworkBuildIndex(options: RelatedworkBuildIndexOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { const args: string[] = ["relatedwork", "build-index"] - return invoke({ subcommand: "build-index", toolId: "vibepaper_relatedwork_build_index", args, options, deps }) + return invoke({ subcommand: "build-index", toolId: "copaper_relatedwork_build_index", args, options, deps }) } export async function runRelatedworkClean(options: RelatedworkCleanOptions, deps: RelatedworkToolDeps = {}): Promise<RelatedworkToolResult> { @@ -107,7 +107,7 @@ export async function runRelatedworkClean(options: RelatedworkCleanOptions, deps } else { args.push("--yes") } - return invoke({ subcommand: "clean", toolId: "vibepaper_relatedwork_clean", args, options, deps }) + return invoke({ subcommand: "clean", toolId: "copaper_relatedwork_clean", args, options, deps }) } async function invoke(input: PreparedInvocation): Promise<RelatedworkToolResult> { diff --git a/packages/opencode-plugin/src/root.ts b/packages/opencode-plugin/src/root.ts index e997970..734fa0f 100644 --- a/packages/opencode-plugin/src/root.ts +++ b/packages/opencode-plugin/src/root.ts @@ -34,19 +34,19 @@ function findOpenCodeRoot(start: string): RootDetection | null { while (true) { if (existsSync(join(current, "opencode.json"))) return { root: current, reason: "found opencode.json" } if (existsSync(join(current, "opencode.jsonc"))) return { root: current, reason: "found opencode.jsonc" } - if (hasVibeCommandMarker(current)) return { root: current, reason: "found VibePaper command marker" } + if (hasCoPaperCommandMarker(current)) return { root: current, reason: "found CoPaper command marker" } const parent = dirname(current) if (parent === current) return null current = parent } } -function hasVibeCommandMarker(current: string): boolean { - const vibeCommand = join(current, ".opencode", "commands", "vibe.md") +function hasCoPaperCommandMarker(current: string): boolean { + const copaperCommand = join(current, ".opencode", "commands", "copaper.md") try { - if (!statSync(vibeCommand).isFile()) return false - const content = readFileSync(vibeCommand, "utf8") - return hasManagedMarker(content, "vibe") + if (!statSync(copaperCommand).isFile()) return false + const content = readFileSync(copaperCommand, "utf8") + return hasManagedMarker(content, "copaper") } catch { return false } diff --git a/packages/opencode-plugin/src/templates.ts b/packages/opencode-plugin/src/templates.ts index b15a529..e7fb87f 100644 --- a/packages/opencode-plugin/src/templates.ts +++ b/packages/opencode-plugin/src/templates.ts @@ -1,11 +1,11 @@ -import { BUNX_CLI_COMMAND, DEFAULT_LOCALE, PACKAGE_NAME, SCHEMA_VERSION, VIBE_COMMAND, VIBE_DOCTOR_COMMAND, VIBE_RELATEDWORK_COMMAND, type Locale } from "./types" +import { BUNX_CLI_COMMAND, DEFAULT_LOCALE, PACKAGE_NAME, SCHEMA_VERSION, COPAPER_COMMAND, COPAPER_DOCTOR_COMMAND, COPAPER_RELATEDWORK_COMMAND, type Locale } from "./types" -export type CommandName = typeof VIBE_COMMAND | typeof VIBE_DOCTOR_COMMAND | typeof VIBE_RELATEDWORK_COMMAND +export type CommandName = typeof COPAPER_COMMAND | typeof COPAPER_DOCTOR_COMMAND | typeof COPAPER_RELATEDWORK_COMMAND -export const MANAGED_COMMAND_NAMES: readonly CommandName[] = [VIBE_COMMAND, VIBE_DOCTOR_COMMAND, VIBE_RELATEDWORK_COMMAND] +export const MANAGED_COMMAND_NAMES: readonly CommandName[] = [COPAPER_COMMAND, COPAPER_DOCTOR_COMMAND, COPAPER_RELATEDWORK_COMMAND] export function commandMarker(command: CommandName): string { - return `<!-- VibePaper managed: ${PACKAGE_NAME}; command=${command}; schemaVersion=${SCHEMA_VERSION} -->` + return `<!-- CoPaper managed: ${PACKAGE_NAME}; command=${command}; schemaVersion=${SCHEMA_VERSION} -->` } export function hasManagedMarker(content: string, command: CommandName): boolean { @@ -13,76 +13,76 @@ export function hasManagedMarker(content: string, command: CommandName): boolean } export function renderCommandTemplate(command: CommandName, locale: Locale = DEFAULT_LOCALE): string { - if (command === VIBE_COMMAND) return renderVibeCommand(locale) - if (command === VIBE_RELATEDWORK_COMMAND) return renderVibeRelatedworkCommand(locale) - return renderVibeDoctorCommand(locale) + if (command === COPAPER_COMMAND) return renderCoPaperCommand(locale) + if (command === COPAPER_RELATEDWORK_COMMAND) return renderCoPaperRelatedworkCommand(locale) + return renderCoPaperDoctorCommand(locale) } -function renderVibeCommand(locale: Locale): string { +function renderCoPaperCommand(locale: Locale): string { if (locale === "en-US") { - return `${commandMarker(VIBE_COMMAND)} + return `${commandMarker(COPAPER_COMMAND)} --- -description: Show VibePaper project dashboard +description: Show CoPaper project dashboard --- -Call the \`vibepaper_dashboard\` tool. After each VibePaper tool call, show the human-readable markdown body and tables in the final user-facing reply; omit fenced JSON blocks by default; do not summarize tool results instead or replace the markdown with a summary; only show JSON when the user explicitly asks for JSON, debug, raw output, or full tool output. +Call the \`copaper_dashboard\` tool. After each CoPaper tool call, show the human-readable markdown body and tables in the final user-facing reply; omit fenced JSON blocks by default; do not summarize tool results instead or replace the markdown with a summary; only show JSON when the user explicitly asks for JSON, debug, raw output, or full tool output. -If the Dashboard says the project needs initialization, use the question tool to ask whether to initialize, collect the project name and research domain, and confirm initialization details. If either project name or research domain is missing, use the question tool to ask for the missing field(s). Only after explicit confirmation and both values are known may you call the \`vibepaper_init_apply\` tool. Do not call the init tool without confirmation. +If the Dashboard says the project needs initialization, use the question tool to ask whether to initialize, collect the project name and research domain, and confirm initialization details. If either project name or research domain is missing, use the question tool to ask for the missing field(s). Only after explicit confirmation and both values are known may you call the \`copaper_init_apply\` tool. Do not call the init tool without confirmation. -If the Dashboard says the project is ready, call \`vibepaper_artifact_status\` first to show read-only artifact status, readiness evidence, and recommendations. Then call \`vibepaper_workflow_status\` to show progress, phases, and next steps, and call \`vibepaper_workflow_log\` for recent workflow records. +If the Dashboard says the project is ready, call \`copaper_artifact_status\` first to show read-only artifact status, readiness evidence, and recommendations. Then call \`copaper_workflow_status\` to show progress, phases, and next steps, and call \`copaper_workflow_log\` for recent workflow records. -If the user asks to find related work, drive a related-work step (search, import, download, summarize, register-summary, build-index, sync-bib, clean), or work the literature phase, route them to the dedicated \`/vibe-relatedwork\` slash command rather than running related-work tools from this template. +If the user asks to find related work, drive a related-work step (search, import, download, summarize, register-summary, build-index, sync-bib, clean), or work the literature phase, route them to the dedicated \`/copaper-relatedwork\` slash command rather than running related-work tools from this template. -Use dedicated VibePaper subagents when routing work: \`@vibepaper-coordinator\`, \`@vibepaper-storyline\`, \`@vibepaper-writer\`, \`@vibepaper-reviewer\`, \`@vibepaper-recorder\`, and \`@vibepaper-literature\`. If an agent profile warning or diagnostic appears, do not ignore it; run \`/vibe-doctor\` when needed before delegating. +Use dedicated CoPaper subagents when routing work: \`@copaper-coordinator\`, \`@copaper-storyline\`, \`@copaper-writer\`, \`@copaper-reviewer\`, \`@copaper-recorder\`, and \`@copaper-literature\`. If an agent profile warning or diagnostic appears, do not ignore it; run \`/copaper-doctor\` when needed before delegating. -\`vibepaper_artifact_status\` is read-only. It must not directly write state, install skills, run relatedwork/checker/report/git commands, or change phases without a separate explicit user request and confirmation. +\`copaper_artifact_status\` is read-only. It must not directly write state, install skills, run relatedwork/checker/report/git commands, or change phases without a separate explicit user request and confirmation. -If the user explicitly asks to record artifact readiness, restate the artifact, status, confidence, and reason, then wait for confirmation. Only after explicit confirmation may you call \`vibepaper_artifact_record\`. This tool writes artifact readiness state and appends an event, but it does not automatically advance phases or run checker/relatedwork/report/git/skills actions. +If the user explicitly asks to record artifact readiness, restate the artifact, status, confidence, and reason, then wait for confirmation. Only after explicit confirmation may you call \`copaper_artifact_record\`. This tool writes artifact readiness state and appends an event, but it does not automatically advance phases or run checker/relatedwork/report/git/skills actions. -Before you change a phase status, restate the phase, status, and reason when status is \`skipped\`, then wait for confirmation. Only after explicit confirmation may you call \`vibepaper_workflow_set_phase\`; never make unconfirmed phase status changes. +Before you change a phase status, restate the phase, status, and reason when status is \`skipped\`, then wait for confirmation. Only after explicit confirmation may you call \`copaper_workflow_set_phase\`; never make unconfirmed phase status changes. If the tool is unavailable, tell the user: -- Run \`/vibe-doctor\` to diagnose +- Run \`/copaper-doctor\` to diagnose - Or run in terminal: \`${BUNX_CLI_COMMAND} doctor\` -Do not invent VibePaper status. Only use information returned by tools, while still omitting fenced JSON blocks by default as instructed above. +Do not invent CoPaper status. Only use information returned by tools, while still omitting fenced JSON blocks by default as instructed above. ` } - return `${commandMarker(VIBE_COMMAND)} + return `${commandMarker(COPAPER_COMMAND)} --- -description: 显示 VibePaper 项目仪表盘 +description: 显示 CoPaper 项目仪表盘 --- -调用 \`vibepaper_dashboard\` 工具。每次调用 VibePaper 工具后,必须在最终给用户的回复中展示工具返回的人类可读 markdown 正文和表格,默认不要展示 fenced JSON block。不要只总结工具结果或用摘要替代工具输出。用户明确要求 JSON、debug 或原始输出时才展示 JSON;用户要求完整工具输出时也可包含 JSON。 +调用 \`copaper_dashboard\` 工具。每次调用 CoPaper 工具后,必须在最终给用户的回复中展示工具返回的人类可读 markdown 正文和表格,默认不要展示 fenced JSON block。不要只总结工具结果或用摘要替代工具输出。用户明确要求 JSON、debug 或原始输出时才展示 JSON;用户要求完整工具输出时也可包含 JSON。 -如果 Dashboard 显示项目需要初始化,必须使用 question tool 询问是否初始化,并收集项目名称和研究领域、确认初始化细节。如果缺少项目名称或研究领域,继续使用 question tool 询问缺失字段。只有用户明确确认且项目名称和研究领域都已知后,才可调用 \`vibepaper_init_apply\` 工具。不要在用户未确认时调用初始化工具。 +如果 Dashboard 显示项目需要初始化,必须使用 question tool 询问是否初始化,并收集项目名称和研究领域、确认初始化细节。如果缺少项目名称或研究领域,继续使用 question tool 询问缺失字段。只有用户明确确认且项目名称和研究领域都已知后,才可调用 \`copaper_init_apply\` 工具。不要在用户未确认时调用初始化工具。 -如果 Dashboard 显示项目已就绪,先调用 \`vibepaper_artifact_status\` 展示只读工件状态、就绪证据和建议;再调用 \`vibepaper_workflow_status\` 展示进度、阶段和下一步,并调用 \`vibepaper_workflow_log\` 查看最近工作流记录。 +如果 Dashboard 显示项目已就绪,先调用 \`copaper_artifact_status\` 展示只读工件状态、就绪证据和建议;再调用 \`copaper_workflow_status\` 展示进度、阶段和下一步,并调用 \`copaper_workflow_log\` 查看最近工作流记录。 -如果用户表达「找相关工作 / 跑 relatedwork / 检索文献 / 下载 PDF / 写摘要 / 注册摘要 / 建跨文献索引 / 同步 BibTeX / 清理文献条目」等意图,或想推进 literature 阶段,请引导用户使用专用的 \`/vibe-relatedwork\` 斜杠命令,不要在本模板中直接调用 relatedwork 工具。 +如果用户表达「找相关工作 / 跑 relatedwork / 检索文献 / 下载 PDF / 写摘要 / 注册摘要 / 建跨文献索引 / 同步 BibTeX / 清理文献条目」等意图,或想推进 literature 阶段,请引导用户使用专用的 \`/copaper-relatedwork\` 斜杠命令,不要在本模板中直接调用 relatedwork 工具。 -分派工作时使用专用 VibePaper subagents:\`@vibepaper-coordinator\`、\`@vibepaper-storyline\`、\`@vibepaper-writer\`、\`@vibepaper-reviewer\`、\`@vibepaper-recorder\` 和 \`@vibepaper-literature\`。如果出现 agent profile warning 或 diagnostic,不要忽略;需要时先运行 \`/vibe-doctor\` 再委派。 +分派工作时使用专用 CoPaper subagents:\`@copaper-coordinator\`、\`@copaper-storyline\`、\`@copaper-writer\`、\`@copaper-reviewer\`、\`@copaper-recorder\` 和 \`@copaper-literature\`。如果出现 agent profile warning 或 diagnostic,不要忽略;需要时先运行 \`/copaper-doctor\` 再委派。 -\`vibepaper_artifact_status\` 是只读工具。不得直接写入状态、安装技能、运行 relatedwork/checker/report/git 命令,或在没有单独明确用户请求和确认时改变阶段。 +\`copaper_artifact_status\` 是只读工具。不得直接写入状态、安装技能、运行 relatedwork/checker/report/git 命令,或在没有单独明确用户请求和确认时改变阶段。 -如果用户明确要求记录工件就绪度,必须先复述 artifact、status、confidence 和 reason,然后等待用户确认。只有用户明确确认后,才可调用 \`vibepaper_artifact_record\`。该工具会写入 artifact readiness state 并追加事件,但不会自动推进 phase,也不会运行 checker/relatedwork/report/git/skills 动作。 +如果用户明确要求记录工件就绪度,必须先复述 artifact、status、confidence 和 reason,然后等待用户确认。只有用户明确确认后,才可调用 \`copaper_artifact_record\`。该工具会写入 artifact readiness state 并追加事件,但不会自动推进 phase,也不会运行 checker/relatedwork/report/git/skills 动作。 -在修改阶段状态前,必须复述阶段、状态,以及 status 为 \`skipped\` 时的原因,然后等待用户确认。只有用户明确确认后,才可调用 \`vibepaper_workflow_set_phase\`;不得进行未经确认的阶段状态修改。 +在修改阶段状态前,必须复述阶段、状态,以及 status 为 \`skipped\` 时的原因,然后等待用户确认。只有用户明确确认后,才可调用 \`copaper_workflow_set_phase\`;不得进行未经确认的阶段状态修改。 如果工具不可用,请告诉用户: -- 运行 \`/vibe-doctor\` 进行诊断 +- 运行 \`/copaper-doctor\` 进行诊断 - 或在终端运行:\`${BUNX_CLI_COMMAND} doctor\` -不要编造 VibePaper 状态。只能使用工具返回的信息,同时按上文要求默认省略 fenced JSON block。 +不要编造 CoPaper 状态。只能使用工具返回的信息,同时按上文要求默认省略 fenced JSON block。 ` } -function renderVibeDoctorCommand(locale: Locale): string { +function renderCoPaperDoctorCommand(locale: Locale): string { if (locale === "en-US") { - return `${commandMarker(VIBE_DOCTOR_COMMAND)} + return `${commandMarker(COPAPER_DOCTOR_COMMAND)} --- -description: Diagnose VibePaper OpenCode plugin installation +description: Diagnose CoPaper OpenCode plugin installation --- Run this diagnostic and display the output verbatim: @@ -92,15 +92,15 @@ Run this diagnostic and display the output verbatim: This is a convenience wrapper. For authoritative diagnostics, run in terminal: \`${BUNX_CLI_COMMAND} doctor\` -The output includes agent profile diagnostics for VibePaper subagent injection, conflicts, and permission profile warnings. +The output includes agent profile diagnostics for CoPaper subagent injection, conflicts, and permission profile warnings. Do not interpret or modify the diagnostic output. ` } - return `${commandMarker(VIBE_DOCTOR_COMMAND)} + return `${commandMarker(COPAPER_DOCTOR_COMMAND)} --- -description: 诊断 VibePaper OpenCode 插件安装 +description: 诊断 CoPaper OpenCode 插件安装 --- 运行此诊断,并原样显示输出: @@ -110,51 +110,51 @@ description: 诊断 VibePaper OpenCode 插件安装 这是一个便捷包装命令。权威诊断请在终端运行: \`${BUNX_CLI_COMMAND} doctor\` -输出包含 agent profile diagnostics,用于检查 VibePaper subagent 注入、同名冲突和 permission profile 警告。 +输出包含 agent profile diagnostics,用于检查 CoPaper subagent 注入、同名冲突和 permission profile 警告。 不要解读或修改诊断输出。 ` } -function renderVibeRelatedworkCommand(locale: Locale): string { +function renderCoPaperRelatedworkCommand(locale: Locale): string { if (locale === "en-US") { - return `${commandMarker(VIBE_RELATEDWORK_COMMAND)} + return `${commandMarker(COPAPER_RELATEDWORK_COMMAND)} --- -description: Drive the VibePaper relatedwork (literature) workflow +description: Drive the CoPaper relatedwork (literature) workflow --- -You are the VibePaper relatedwork orchestrator. Every step of related-work work goes through dedicated \`vibepaper_relatedwork_*\` tools backed by the Python CLI; do not shell out to \`vibe relatedwork ...\` from this template, and do not fabricate catalog, BibTeX, PDF, or summary data. +You are the CoPaper relatedwork orchestrator. Every step of related-work work goes through dedicated \`copaper_relatedwork_*\` tools backed by the Python CLI; do not shell out to \`copaper relatedwork ...\` from this template, and do not fabricate catalog, BibTeX, PDF, or summary data. When invoked, follow this orchestration: -1. First call \`vibepaper_relatedwork_status\` to show the current catalog, BibTeX, PDF, summary, and cross-index state. Show its rendered markdown body in your reply. -2. Use the user's intent to pick the next tool. Read-only tools (no confirmation required): \`vibepaper_relatedwork_status\`. Write tools (must restate every argument and wait for explicit user confirmation before calling): \`vibepaper_relatedwork_keywords\`, \`vibepaper_relatedwork_search\`, \`vibepaper_relatedwork_import\`, \`vibepaper_relatedwork_sync_bib\`, \`vibepaper_relatedwork_download\`, \`vibepaper_relatedwork_summarize\`, \`vibepaper_relatedwork_register_summary\`, \`vibepaper_relatedwork_build_index\`, \`vibepaper_relatedwork_clean\`. -3. The typical full path is: \`keywords\` (extract keywords from storyline) → \`search\` (S2 / arXiv) → \`import\` (search cache into literature.json) → \`sync_bib\` (paper_list.bib parity) → \`download\` (PDFs) → \`summarize\` (LLM PDF summaries) → \`register_summary\` (register per paper) → \`build_index\` (cross_index.json). Run each step only after confirming with the user, and call \`vibepaper_relatedwork_status\` again after every write tool to surface the refreshed table. +1. First call \`copaper_relatedwork_status\` to show the current catalog, BibTeX, PDF, summary, and cross-index state. Show its rendered markdown body in your reply. +2. Use the user's intent to pick the next tool. Read-only tools (no confirmation required): \`copaper_relatedwork_status\`. Write tools (must restate every argument and wait for explicit user confirmation before calling): \`copaper_relatedwork_keywords\`, \`copaper_relatedwork_search\`, \`copaper_relatedwork_import\`, \`copaper_relatedwork_sync_bib\`, \`copaper_relatedwork_download\`, \`copaper_relatedwork_summarize\`, \`copaper_relatedwork_register_summary\`, \`copaper_relatedwork_build_index\`, \`copaper_relatedwork_clean\`. +3. The typical full path is: \`keywords\` (extract keywords from storyline) → \`search\` (S2 / arXiv) → \`import\` (search cache into literature.json) → \`sync_bib\` (paper_list.bib parity) → \`download\` (PDFs) → \`summarize\` (LLM PDF summaries) → \`register_summary\` (register per paper) → \`build_index\` (cross_index.json). Run each step only after confirming with the user, and call \`copaper_relatedwork_status\` again after every write tool to surface the refreshed table. 4. \`keywords\` writes \`relatedwork/queries.txt\` through the Python CLI and does not add an extra plugin-side phase-patch event. Other write tools refresh \`.agents/state.json.phases.literature\` counters (papers_found, papers_downloaded, download_failures, summaries_done, cross_index_built) and append a \`relatedwork.<subcommand>\` event to \`.agents/events.jsonl\`. Surface these patch diffs to the user when present. -5. When the user is satisfied that papers are imported, downloaded, summarized, and the cross-index is built, restate the proposed phase change and, only after explicit confirmation, call \`vibepaper_workflow_set_phase\` with \`phase=literature\` and \`status=complete\`. Never auto-advance. -6. If a tool returns \`vibe-cli-unavailable\`, tell the user to install the Python package (\`uv pip install -e .\` from the project root) and rerun \`/vibe-doctor\`. If it returns \`bridge-timeout\` or \`vibe-nonzero-exit\`, surface the stderr verbatim and stop; do not retry blindly. +5. When the user is satisfied that papers are imported, downloaded, summarized, and the cross-index is built, restate the proposed phase change and, only after explicit confirmation, call \`copaper_workflow_set_phase\` with \`phase=literature\` and \`status=complete\`. Never auto-advance. +6. If a tool returns \`copaper-cli-unavailable\`, tell the user to install the Python package (\`uv pip install -e .\` from the project root) and rerun \`/copaper-doctor\`. If it returns \`bridge-timeout\` or \`copaper-nonzero-exit\`, surface the stderr verbatim and stop; do not retry blindly. -Delegate complex steps to \`@vibepaper-literature\` when an agent profile is healthy. If an agent profile warning or diagnostic appears, run \`/vibe-doctor\` before delegating. +Delegate complex steps to \`@copaper-literature\` when an agent profile is healthy. If an agent profile warning or diagnostic appears, run \`/copaper-doctor\` before delegating. Do not invent relatedwork results. Only use information returned by the relatedwork tools. ` } - return `${commandMarker(VIBE_RELATEDWORK_COMMAND)} + return `${commandMarker(COPAPER_RELATEDWORK_COMMAND)} --- -description: 驱动 VibePaper 相关工作(文献)工作流 +description: 驱动 CoPaper 相关工作(文献)工作流 --- -你是 VibePaper 相关工作(relatedwork / literature 阶段)的编排者。所有相关工作步骤都必须通过专用的 \`vibepaper_relatedwork_*\` 工具完成,这些工具内部已经包装 Python CLI;不要在本模板中通过 \`bash\` 工具直接调用 \`vibe relatedwork ...\`,也不要凭空生成文献目录、BibTeX、PDF 或摘要内容。 +你是 CoPaper 相关工作(relatedwork / literature 阶段)的编排者。所有相关工作步骤都必须通过专用的 \`copaper_relatedwork_*\` 工具完成,这些工具内部已经包装 Python CLI;不要在本模板中通过 \`bash\` 工具直接调用 \`copaper relatedwork ...\`,也不要凭空生成文献目录、BibTeX、PDF 或摘要内容。 被调用时按下列编排执行: -1. 先调用 \`vibepaper_relatedwork_status\` 展示当前 catalog、BibTeX、PDF、summary 和 cross-index 状态,并在回复中显示其渲染后的 markdown。 -2. 根据用户意图选择下一步工具。只读工具(无需确认):\`vibepaper_relatedwork_status\`。写盘工具(必须复述完整参数,等待用户明确确认后才可调用):\`vibepaper_relatedwork_keywords\`、\`vibepaper_relatedwork_search\`、\`vibepaper_relatedwork_import\`、\`vibepaper_relatedwork_sync_bib\`、\`vibepaper_relatedwork_download\`、\`vibepaper_relatedwork_summarize\`、\`vibepaper_relatedwork_register_summary\`、\`vibepaper_relatedwork_build_index\`、\`vibepaper_relatedwork_clean\`。 -3. 典型完整路径:\`keywords\`(从 storyline 抽取关键词)→ \`search\`(S2 / arXiv 检索)→ \`import\`(把搜索缓存导入 literature.json)→ \`sync_bib\`(与 paper_list.bib 对齐)→ \`download\`(拉 PDF)→ \`summarize\`(LLM 生成 PDF 摘要)→ \`register_summary\`(注册每篇摘要)→ \`build_index\`(生成 cross_index.json)。每步都需用户确认后再执行;每个写盘工具跑完后必须再次调用 \`vibepaper_relatedwork_status\` 刷新表格。 +1. 先调用 \`copaper_relatedwork_status\` 展示当前 catalog、BibTeX、PDF、summary 和 cross-index 状态,并在回复中显示其渲染后的 markdown。 +2. 根据用户意图选择下一步工具。只读工具(无需确认):\`copaper_relatedwork_status\`。写盘工具(必须复述完整参数,等待用户明确确认后才可调用):\`copaper_relatedwork_keywords\`、\`copaper_relatedwork_search\`、\`copaper_relatedwork_import\`、\`copaper_relatedwork_sync_bib\`、\`copaper_relatedwork_download\`、\`copaper_relatedwork_summarize\`、\`copaper_relatedwork_register_summary\`、\`copaper_relatedwork_build_index\`、\`copaper_relatedwork_clean\`。 +3. 典型完整路径:\`keywords\`(从 storyline 抽取关键词)→ \`search\`(S2 / arXiv 检索)→ \`import\`(把搜索缓存导入 literature.json)→ \`sync_bib\`(与 paper_list.bib 对齐)→ \`download\`(拉 PDF)→ \`summarize\`(LLM 生成 PDF 摘要)→ \`register_summary\`(注册每篇摘要)→ \`build_index\`(生成 cross_index.json)。每步都需用户确认后再执行;每个写盘工具跑完后必须再次调用 \`copaper_relatedwork_status\` 刷新表格。 4. \`keywords\` 会通过 Python CLI 写入 \`relatedwork/queries.txt\`,但不会额外追加插件侧 phase-patch 事件。其他写盘工具会刷新 \`.agents/state.json.phases.literature\` 的计数(papers_found、papers_downloaded、download_failures、summaries_done、cross_index_built),并向 \`.agents/events.jsonl\` 追加一条 \`relatedwork.<子命令>\` 事件。有 phase patch 时请向用户展示这些字段的前后差异。 -5. 当用户确认论文已导入、PDF 已下载、摘要已注册、cross-index 已生成,复述拟切换的阶段状态,仅在用户明确确认后调用 \`vibepaper_workflow_set_phase\`(\`phase=literature\`、\`status=complete\`)。不得自动推进。 -6. 如果工具返回 \`vibe-cli-unavailable\`,提示用户在项目根运行 \`uv pip install -e .\` 安装 Python 包,并再次运行 \`/vibe-doctor\`。如果返回 \`bridge-timeout\` 或 \`vibe-nonzero-exit\`,原样展示 stderr 并停止,不得盲目重试。 +5. 当用户确认论文已导入、PDF 已下载、摘要已注册、cross-index 已生成,复述拟切换的阶段状态,仅在用户明确确认后调用 \`copaper_workflow_set_phase\`(\`phase=literature\`、\`status=complete\`)。不得自动推进。 +6. 如果工具返回 \`copaper-cli-unavailable\`,提示用户在项目根运行 \`uv pip install -e .\` 安装 Python 包,并再次运行 \`/copaper-doctor\`。如果返回 \`bridge-timeout\` 或 \`copaper-nonzero-exit\`,原样展示 stderr 并停止,不得盲目重试。 -健康 agent profile 下,把复杂步骤委派给 \`@vibepaper-literature\`。如果出现 agent profile warning 或 diagnostic,先运行 \`/vibe-doctor\` 再委派。 +健康 agent profile 下,把复杂步骤委派给 \`@copaper-literature\`。如果出现 agent profile warning 或 diagnostic,先运行 \`/copaper-doctor\` 再委派。 不要编造 relatedwork 结果。只能使用 relatedwork 工具实际返回的信息。 ` diff --git a/packages/opencode-plugin/src/types.ts b/packages/opencode-plugin/src/types.ts index bdc41e7..12208eb 100644 --- a/packages/opencode-plugin/src/types.ts +++ b/packages/opencode-plugin/src/types.ts @@ -1,10 +1,10 @@ -export const PACKAGE_NAME = "@vibepaper/opencode" as const -export const CLI_NAME = "vibepaper-opencode" as const +export const PACKAGE_NAME = "@copaper/opencode" as const +export const CLI_NAME = "copaper-opencode" as const export const BUNX_CLI_COMMAND = `bunx -p ${PACKAGE_NAME} ${CLI_NAME}` as const export const SCHEMA_VERSION = 1 as const -export const VIBE_COMMAND = "vibe" as const -export const VIBE_DOCTOR_COMMAND = "vibe-doctor" as const -export const VIBE_RELATEDWORK_COMMAND = "vibe-relatedwork" as const +export const COPAPER_COMMAND = "copaper" as const +export const COPAPER_DOCTOR_COMMAND = "copaper-doctor" as const +export const COPAPER_RELATEDWORK_COMMAND = "copaper-relatedwork" as const export const DEFAULT_LOCALE = "zh-CN" as const export const SUPPORTED_LOCALES = ["zh-CN", "en-US"] as const export type Locale = typeof SUPPORTED_LOCALES[number] @@ -21,8 +21,8 @@ export type ArtifactConfidence = typeof ARTIFACT_CONFIDENCE[number] export type ArtifactId = typeof ARTIFACT_IDS[number] export type ArtifactRecordId = typeof ARTIFACT_RECORD_IDS[number] -export function isVibePaperPluginSpecifier(value: unknown): value is string { - return typeof value === "string" && (value === PACKAGE_NAME || (value.startsWith("file://") && value.includes("/@vibepaper/opencode/dist/index.js"))) +export function isCoPaperPluginSpecifier(value: unknown): value is string { + return typeof value === "string" && (value === PACKAGE_NAME || (value.startsWith("file://") && value.includes("/@copaper/opencode/dist/index.js"))) } export type CheckStatus = "pass" | "warn" | "fail" | "info" @@ -56,10 +56,10 @@ export interface DashboardInstallation { configPresent: boolean configParseable: boolean pluginConfigured: boolean - vibeCommandPresent: boolean - vibeDoctorCommandPresent: boolean - vibeCommandManaged: boolean - vibeDoctorCommandManaged: boolean + copaperCommandPresent: boolean + copaperDoctorCommandPresent: boolean + copaperCommandManaged: boolean + copaperDoctorCommandManaged: boolean } export type DashboardRecommendationMessageKey = "recommendation.repairInstallation" | "recommendation.previewInit" | "recommendation.ready" @@ -323,8 +323,8 @@ export interface ProjectState { auto_commit: false identity: { role: "assistant" - git_name: "VibePaper Bot" - git_email: "bot@vibepaper.dev" + git_name: "CoPaper Bot" + git_email: "bot@copaper.dev" } } checkers: Record<string, never> @@ -893,7 +893,7 @@ export interface BridgeResolution { args: string[] } -export type BridgeErrorCode = "vibe-cli-unavailable" | "bridge-timeout" | "bridge-spawn-failed" | "vibe-nonzero-exit" +export type BridgeErrorCode = "copaper-cli-unavailable" | "bridge-timeout" | "bridge-spawn-failed" | "copaper-nonzero-exit" export interface BridgeError { code: BridgeErrorCode diff --git a/packages/opencode-plugin/tests/agent-config.test.ts b/packages/opencode-plugin/tests/agent-config.test.ts index 3781c2b..56305f7 100644 --- a/packages/opencode-plugin/tests/agent-config.test.ts +++ b/packages/opencode-plugin/tests/agent-config.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "bun:test" -import { buildVibePaperAgentConfig } from "../src/agent-config" +import { buildCoPaperAgentConfig } from "../src/agent-config" import { SCHEMA_VERSION } from "../src/types" import { makeTempProject } from "./fixtures" @@ -7,17 +7,17 @@ describe("agent config builder", () => { test("missing config injects default agents in order", () => { const project = makeTempProject("agent-config-defaults-") try { - const result = buildVibePaperAgentConfig({ root: project.root, existingAgents: {} }) + const result = buildCoPaperAgentConfig({ root: project.root, existingAgents: {} }) expect(Object.keys(result.injectedAgents)).toEqual([ - "vibepaper-coordinator", - "vibepaper-storyline", - "vibepaper-writer", - "vibepaper-reviewer", - "vibepaper-recorder", - "vibepaper-literature", + "copaper-coordinator", + "copaper-storyline", + "copaper-writer", + "copaper-reviewer", + "copaper-recorder", + "copaper-literature", ]) - expect(result.injectedAgents["vibepaper-writer"]?.permission.edit).toEqual({ "*": "deny", "paper.md": "ask" }) + expect(result.injectedAgents["copaper-writer"]?.permission.edit).toEqual({ "*": "deny", "paper.md": "ask" }) expect(result.runtime.agents.map((agent) => agent.name)).toEqual(Object.keys(result.injectedAgents)) expect(result.runtime.agents.every((agent) => agent.status === "injected")).toBe(true) } finally { @@ -29,7 +29,7 @@ describe("agent config builder", () => { const project = makeTempProject("agent-config-overrides-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, locale: "en-US", @@ -38,7 +38,7 @@ describe("agent config builder", () => { temperature: 0.9, }, agents: { - "vibepaper-writer": { + "copaper-writer": { model: "writer-model", temperature: 0.2, promptAppend: "Use short paragraphs.", @@ -47,17 +47,17 @@ describe("agent config builder", () => { }), ) - const result = buildVibePaperAgentConfig({ root: project.root, existingAgents: {} }) + const result = buildCoPaperAgentConfig({ root: project.root, existingAgents: {} }) - expect(result.injectedAgents["vibepaper-coordinator"]).toMatchObject({ + expect(result.injectedAgents["copaper-coordinator"]).toMatchObject({ model: "default-model", temperature: 0.9, }) - expect(result.injectedAgents["vibepaper-writer"]).toMatchObject({ + expect(result.injectedAgents["copaper-writer"]).toMatchObject({ model: "writer-model", temperature: 0.2, }) - expect(result.injectedAgents["vibepaper-writer"]?.prompt).toContain("## Project-specific preferences\nUse short paragraphs.") + expect(result.injectedAgents["copaper-writer"]?.prompt).toContain("## Project-specific preferences\nUse short paragraphs.") } finally { project.cleanup() } @@ -67,19 +67,19 @@ describe("agent config builder", () => { const project = makeTempProject("agent-config-disabled-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, agents: { - "vibepaper-writer": { enabled: false }, + "copaper-writer": { enabled: false }, }, }), ) - const result = buildVibePaperAgentConfig({ root: project.root, existingAgents: {} }) + const result = buildCoPaperAgentConfig({ root: project.root, existingAgents: {} }) - expect(result.injectedAgents["vibepaper-writer"]).toBeUndefined() - expect(result.runtime.agents.find((agent) => agent.name === "vibepaper-writer")).toMatchObject({ + expect(result.injectedAgents["copaper-writer"]).toBeUndefined() + expect(result.runtime.agents.find((agent) => agent.name === "copaper-writer")).toMatchObject({ status: "disabled", }) } finally { @@ -97,19 +97,19 @@ describe("agent config builder", () => { permission: { read: "allow" as const }, } - const result = buildVibePaperAgentConfig({ + const result = buildCoPaperAgentConfig({ root: project.root, - existingAgents: { "vibepaper-writer": userAgent }, + existingAgents: { "copaper-writer": userAgent }, }) - expect(result.injectedAgents["vibepaper-writer"]).toBeUndefined() + expect(result.injectedAgents["copaper-writer"]).toBeUndefined() expect(userAgent.prompt).toBe("Do not replace me.") - expect(result.runtime.agents.find((agent) => agent.name === "vibepaper-writer")).toMatchObject({ + expect(result.runtime.agents.find((agent) => agent.name === "copaper-writer")).toMatchObject({ status: "conflicted", }) expect(result.diagnostics.find((diagnostic) => diagnostic.code === "agent-name-conflict")).toMatchObject({ - path: ".opencode/vibepaper.json", - field: "agents.vibepaper-writer", + path: ".opencode/copaper.json", + field: "agents.copaper-writer", }) } finally { project.cleanup() @@ -120,23 +120,23 @@ describe("agent config builder", () => { const project = makeTempProject("agent-config-escalation-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, agents: { - "vibepaper-coordinator": { permissionProfile: "paperWrite" }, + "copaper-coordinator": { permissionProfile: "paperWrite" }, }, }), ) - const result = buildVibePaperAgentConfig({ root: project.root, existingAgents: {} }) - const runtimeRow = result.runtime.agents.find((agent) => agent.name === "vibepaper-coordinator") + const result = buildCoPaperAgentConfig({ root: project.root, existingAgents: {} }) + const runtimeRow = result.runtime.agents.find((agent) => agent.name === "copaper-coordinator") - expect(result.injectedAgents["vibepaper-coordinator"]?.permission.edit).toBe("deny") + expect(result.injectedAgents["copaper-coordinator"]?.permission.edit).toBe("deny") expect(runtimeRow).toMatchObject({ permissionProfile: "readOnly" }) expect(result.diagnostics.find((diagnostic) => diagnostic.code === "permission-escalation-denied")).toMatchObject({ - path: ".opencode/vibepaper.json", - field: "agents.vibepaper-coordinator.permissionProfile", + path: ".opencode/copaper.json", + field: "agents.copaper-coordinator.permissionProfile", }) } finally { project.cleanup() @@ -147,19 +147,19 @@ describe("agent config builder", () => { const project = makeTempProject("agent-config-downgrade-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, agents: { - "vibepaper-writer": { permissionProfile: "readOnly" }, + "copaper-writer": { permissionProfile: "readOnly" }, }, }), ) - const result = buildVibePaperAgentConfig({ root: project.root, existingAgents: {} }) + const result = buildCoPaperAgentConfig({ root: project.root, existingAgents: {} }) - expect(result.injectedAgents["vibepaper-writer"]?.permission.edit).toBe("deny") - expect(result.runtime.agents.find((agent) => agent.name === "vibepaper-writer")).toMatchObject({ + expect(result.injectedAgents["copaper-writer"]?.permission.edit).toBe("deny") + expect(result.runtime.agents.find((agent) => agent.name === "copaper-writer")).toMatchObject({ status: "injected", permissionProfile: "readOnly", }) diff --git a/packages/opencode-plugin/tests/agent-profiles.test.ts b/packages/opencode-plugin/tests/agent-profiles.test.ts index 626aae0..7a61c5f 100644 --- a/packages/opencode-plugin/tests/agent-profiles.test.ts +++ b/packages/opencode-plugin/tests/agent-profiles.test.ts @@ -1,33 +1,33 @@ import { describe, expect, test } from "bun:test" import { - VIBEPAPER_AGENT_NAMES, + COPAPER_AGENT_NAMES, buildDefaultAgentProfiles, getDefaultAgentProfile, - isVibePaperAgentName, + isCoPaperAgentName, } from "../src/agent-profiles" describe("agent profiles", () => { test("exports v1 agent names in exact order", () => { - expect(VIBEPAPER_AGENT_NAMES).toEqual([ - "vibepaper-coordinator", - "vibepaper-storyline", - "vibepaper-writer", - "vibepaper-reviewer", - "vibepaper-recorder", - "vibepaper-literature", + expect(COPAPER_AGENT_NAMES).toEqual([ + "copaper-coordinator", + "copaper-storyline", + "copaper-writer", + "copaper-reviewer", + "copaper-recorder", + "copaper-literature", ]) }) - test("builds enabled VibePaper subagent profiles", () => { + test("builds enabled CoPaper subagent profiles", () => { const profiles = buildDefaultAgentProfiles() - expect(Object.keys(profiles)).toEqual([...VIBEPAPER_AGENT_NAMES]) + expect(Object.keys(profiles)).toEqual([...COPAPER_AGENT_NAMES]) for (const profile of Object.values(profiles)) { expect(profile.enabled).toBe(true) expect(profile.mode).toBe("subagent") expect(profile.description.length).toBeGreaterThan(0) - expect(profile.prompt).toContain("VibePaper") + expect(profile.prompt).toContain("CoPaper") expect(profile.prompt).toContain("Role Boundary") expect(profile.prompt).toContain("Artifact Boundary") expect(profile.prompt).toContain("Workflow Rules") @@ -38,44 +38,44 @@ describe("agent profiles", () => { }) test("permission defaults and maximums match built-in roles", () => { - expect(getDefaultAgentProfile("vibepaper-coordinator")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-coordinator")).toMatchObject({ permissionProfile: "readOnly", maxPermissionProfile: "readOnly", }) - expect(getDefaultAgentProfile("vibepaper-storyline")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-storyline")).toMatchObject({ permissionProfile: "storylineWrite", maxPermissionProfile: "storylineWrite", }) - expect(getDefaultAgentProfile("vibepaper-writer")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-writer")).toMatchObject({ permissionProfile: "paperWrite", maxPermissionProfile: "paperWrite", }) - expect(getDefaultAgentProfile("vibepaper-reviewer")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-reviewer")).toMatchObject({ permissionProfile: "readOnly", maxPermissionProfile: "readOnly", }) - expect(getDefaultAgentProfile("vibepaper-recorder")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-recorder")).toMatchObject({ permissionProfile: "stateRecord", maxPermissionProfile: "stateRecord", }) - expect(getDefaultAgentProfile("vibepaper-literature")).toMatchObject({ + expect(getDefaultAgentProfile("copaper-literature")).toMatchObject({ permissionProfile: "literatureWrite", maxPermissionProfile: "literatureWrite", }) }) test("literature prompt enforces relatedwork orchestration rules", () => { - const prompt = getDefaultAgentProfile("vibepaper-literature").prompt + const prompt = getDefaultAgentProfile("copaper-literature").prompt - expect(prompt).toContain("vibepaper_relatedwork_status") - expect(prompt).toContain("vibepaper_workflow_set_phase") + expect(prompt).toContain("copaper_relatedwork_status") + expect(prompt).toContain("copaper_workflow_set_phase") expect(prompt.toLowerCase()).toContain("restate") expect(prompt).toContain("Never auto-advance the literature phase") - expect(prompt).toContain("vibe-cli-unavailable") + expect(prompt).toContain("copaper-cli-unavailable") }) test("writer prompt keeps paper.md and writing-rule boundaries", () => { - const prompt = getDefaultAgentProfile("vibepaper-writer").prompt + const prompt = getDefaultAgentProfile("copaper-writer").prompt expect(prompt).toContain("paper.md") expect(prompt).toContain("Read storyline.md before drafting") @@ -89,7 +89,7 @@ describe("agent profiles", () => { }) test("storyline and writer prompts include anti-fabrication boundaries", () => { - for (const agentName of ["vibepaper-storyline", "vibepaper-writer"] as const) { + for (const agentName of ["copaper-storyline", "copaper-writer"] as const) { const prompt = getDefaultAgentProfile(agentName).prompt expect(prompt).toContain("Do not fabricate experiments, data, citations, literature conclusions, or contributions") @@ -98,34 +98,34 @@ describe("agent profiles", () => { }) test("recorder prompt keeps artifact recording boundaries", () => { - const prompt = getDefaultAgentProfile("vibepaper-recorder").prompt + const prompt = getDefaultAgentProfile("copaper-recorder").prompt - expect(prompt).toContain("vibepaper_artifact_record") + expect(prompt).toContain("copaper_artifact_record") expect(prompt).toContain("Do not edit paper.md") expect(prompt).toContain("Do not edit storyline.md") }) test("reviewer prompt keeps checker review read-only", () => { - const prompt = getDefaultAgentProfile("vibepaper-reviewer").prompt + const prompt = getDefaultAgentProfile("copaper-reviewer").prompt expect(prompt).toContain("checker") expect(prompt).toContain("Do not edit paper.md") expect(prompt).toContain("Do not call state-writing tools") - expect(prompt).toContain("vibepaper_checker_status") - expect(prompt).toContain("@vibepaper-recorder") + expect(prompt).toContain("copaper_checker_status") + expect(prompt).toContain("@copaper-recorder") }) test("prompts avoid unsupported orchestration and external-operation claims", () => { - for (const profile of Object.values(buildDefaultAgentProfiles()).filter((profile) => profile.name !== "vibepaper-reviewer")) { + for (const profile of Object.values(buildDefaultAgentProfiles()).filter((profile) => profile.name !== "copaper-reviewer")) { expect(profile.prompt).not.toMatch(/automatic handoff|scheduler|web|network|shell|git|checker|report|provider|secret/i) } - expect(getDefaultAgentProfile("vibepaper-reviewer").prompt).not.toMatch(/automatic handoff|scheduler|web|network|shell|git|provider|secret/i) + expect(getDefaultAgentProfile("copaper-reviewer").prompt).not.toMatch(/automatic handoff|scheduler|web|network|shell|git|provider|secret/i) }) - test("identifies built-in VibePaper agent names", () => { - expect(isVibePaperAgentName("vibepaper-writer")).toBe(true) - expect(isVibePaperAgentName("writer")).toBe(false) - expect(isVibePaperAgentName(null)).toBe(false) + test("identifies built-in CoPaper agent names", () => { + expect(isCoPaperAgentName("copaper-writer")).toBe(true) + expect(isCoPaperAgentName("writer")).toBe(false) + expect(isCoPaperAgentName(null)).toBe(false) }) }) diff --git a/packages/opencode-plugin/tests/artifact-record.test.ts b/packages/opencode-plugin/tests/artifact-record.test.ts index fec1fe8..e782091 100644 --- a/packages/opencode-plugin/tests/artifact-record.test.ts +++ b/packages/opencode-plugin/tests/artifact-record.test.ts @@ -50,7 +50,7 @@ describe("artifact record", () => { expect(state.workflow.custom).toBe(true) expect(events[0].action).toBe("record_artifact_readiness") expect(events[0].metadata.artifact).toBe("paper") - expect(markdown).toContain("## VibePaper 工件就绪度记录") + expect(markdown).toContain("## CoPaper 工件就绪度记录") expect(markdown).toContain("paper") expect(markdown).toContain("record_artifact_readiness") expect(markdown).toContain("```json") diff --git a/packages/opencode-plugin/tests/artifacts.test.ts b/packages/opencode-plugin/tests/artifacts.test.ts index 468bae6..a23060a 100644 --- a/packages/opencode-plugin/tests/artifacts.test.ts +++ b/packages/opencode-plugin/tests/artifacts.test.ts @@ -53,7 +53,7 @@ describe("artifact status", () => { expect(result.summary.recommendedFocus).toBe("storyline") expect(result.recommendation.artifactId).toBe("storyline") expect("artifact" in (result.recommendation as unknown as Record<string, unknown>)).toBe(false) - expect(markdown).toContain("## VibePaper 工件状态") + expect(markdown).toContain("## CoPaper 工件状态") const tableSection = markdown.slice(markdown.indexOf("| 工件 |"), markdown.indexOf("### 警告")) expect(tableSection).toContain("| 工件 | 状态 | 置信度 | 证据 | 推荐下一步 |") expect(tableSection).toContain("| storyline | template | high |") diff --git a/packages/opencode-plugin/tests/checker-record.test.ts b/packages/opencode-plugin/tests/checker-record.test.ts index b581445..eae10ff 100644 --- a/packages/opencode-plugin/tests/checker-record.test.ts +++ b/packages/opencode-plugin/tests/checker-record.test.ts @@ -26,7 +26,7 @@ describe("checker record", () => { const result = await recordCheckerResult({ root: project.root, locale: "en-US", - agent: "vibepaper-recorder", + agent: "copaper-recorder", checker: "problem-checker", status: "issues_found", critical: 1, @@ -64,7 +64,7 @@ describe("checker record", () => { const record = await recordCheckerResult({ root: project.root, locale: "zh-CN", - agent: "vibepaper-recorder", + agent: "copaper-recorder", checker: "logic-checker", status: "clean", critical: 0, @@ -91,7 +91,7 @@ describe("checker record", () => { const unauthorized = await recordCheckerResult({ root: project.root, locale: "zh-CN", - agent: "vibepaper-writer", + agent: "copaper-writer", checker: "problem-checker", status: "clean", critical: 0, @@ -108,7 +108,7 @@ describe("checker record", () => { const invalid = await recordCheckerResult({ root: project.root, locale: "zh-CN", - agent: "vibepaper-recorder", + agent: "copaper-recorder", checker: "missing-checker", status: "done", critical: -1, @@ -134,7 +134,7 @@ describe("checker record", () => { const result = await recordCheckerResult({ root: project.root, locale: "zh-CN", - agent: "vibepaper-recorder", + agent: "copaper-recorder", checker: "data-checker", status: "issues_found", critical: 1, @@ -158,7 +158,7 @@ describe("checker record", () => { const result = await recordCheckerResult({ root: project.root, locale: "zh-CN", - agent: "vibepaper-recorder", + agent: "copaper-recorder", checker: "clarity-checker", status: "unknown", critical: 0, diff --git a/packages/opencode-plugin/tests/cli.test.ts b/packages/opencode-plugin/tests/cli.test.ts index 084f5f7..fd18951 100644 --- a/packages/opencode-plugin/tests/cli.test.ts +++ b/packages/opencode-plugin/tests/cli.test.ts @@ -11,11 +11,11 @@ function temp() { const p = makeTempProject(); projects.push(p); return p } const cli = join(import.meta.dir, "..", "src", "cli.ts") function runCli(args: string[], locale = "") { - return spawnSync("bun", [cli, ...args], { encoding: "utf8", env: locale ? cleanEnv({ VIBEPAPER_LANG: locale }) : cleanEnv() }) + return spawnSync("bun", [cli, ...args], { encoding: "utf8", env: locale ? cleanEnv({ COPAPER_LANG: locale }) : cleanEnv() }) } function cleanEnv(extra: NodeJS.ProcessEnv = {}) { - const { VIBEPAPER_LANG: _lang, ...env } = process.env + const { COPAPER_LANG: _lang, ...env } = process.env return { ...env, ...extra } } @@ -29,15 +29,15 @@ describe("CLI", () => { expect(project.read(LOCAL_PLUGIN_RELATIVE_PATH)).not.toContain(project.root) expect(result.stdout).toContain("重启 OpenCode") expect(result.stdout.match(/重启 OpenCode/g)?.length ?? 0).toBe(1) - expect(result.stdout).toContain("已安装 VibePaper OpenCode 集成。") + expect(result.stdout).toContain("已安装 CoPaper OpenCode 集成。") }) - test("init honors VIBEPAPER_LANG for English output", () => { + test("init honors COPAPER_LANG for English output", () => { const project = temp() const result = runCli(["init", "--root", project.root], "en-US") expect(result.status).toBe(0) expect(result.stdout).toContain("Restart OpenCode") - expect(result.stdout).toContain("Installed VibePaper OpenCode integration.") + expect(result.stdout).toContain("Installed CoPaper OpenCode integration.") }) test("init --dry-run writes nothing", () => { @@ -45,7 +45,7 @@ describe("CLI", () => { const result = runCli(["init", "--root", project.root, "--dry-run"]) expect(result.status).toBe(0) expect(result.stdout).toContain("演练模式") - expect(result.stdout).not.toContain("已安装 VibePaper OpenCode 集成。") + expect(result.stdout).not.toContain("已安装 CoPaper OpenCode 集成。") expect(result.stdout).not.toContain("重启 OpenCode") expect(result.stdout).toContain("没有修改任何文件。") expect(existsSync(project.path("opencode.json"))).toBe(false) @@ -63,7 +63,7 @@ describe("CLI", () => { const project = temp() const result = spawnSync("bun", [cli, "doctor", "--root", project.root], { encoding: "utf8", env: cleanEnv() }) expect(result.status).toBe(1) - expect(result.stdout).toContain("VibePaper OpenCode 诊断") + expect(result.stdout).toContain("CoPaper OpenCode 诊断") expect(result.stdout).toContain("下一步") }) @@ -71,15 +71,15 @@ describe("CLI", () => { const project = temp() const result = spawnSync("bun", [cli, "doctor", "--root", project.root, "--locale", "en-US"], { encoding: "utf8", env: cleanEnv() }) expect(result.status).toBe(1) - expect(result.stdout).toContain("VibePaper OpenCode Doctor") + expect(result.stdout).toContain("CoPaper OpenCode Doctor") expect(result.stdout).toContain("Next:") }) - test("doctor supports English locale via VIBEPAPER_LANG", () => { + test("doctor supports English locale via COPAPER_LANG", () => { const project = temp() - const result = spawnSync("bun", [cli, "doctor", "--root", project.root], { encoding: "utf8", env: cleanEnv({ VIBEPAPER_LANG: "en-US" }) }) + const result = spawnSync("bun", [cli, "doctor", "--root", project.root], { encoding: "utf8", env: cleanEnv({ COPAPER_LANG: "en-US" }) }) expect(result.status).toBe(1) - expect(result.stdout).toContain("VibePaper OpenCode Doctor") + expect(result.stdout).toContain("CoPaper OpenCode Doctor") }) test("doctor JSON keeps English field names and enum values with Chinese locale", () => { @@ -96,7 +96,7 @@ describe("CLI", () => { const project = temp() const result = spawnSync("bun", [cli, "doctor", "--root", project.root, "--locale", "fr-FR"], { encoding: "utf8", env: cleanEnv() }) expect(result.status).toBe(1) - expect(result.stdout).toContain("VibePaper OpenCode 诊断") + expect(result.stdout).toContain("CoPaper OpenCode 诊断") }) test("init supports English locale via flag", () => { diff --git a/packages/opencode-plugin/tests/command-templates.test.ts b/packages/opencode-plugin/tests/command-templates.test.ts index 9206dd5..18197e2 100644 --- a/packages/opencode-plugin/tests/command-templates.test.ts +++ b/packages/opencode-plugin/tests/command-templates.test.ts @@ -2,18 +2,18 @@ import { describe, expect, test } from "bun:test" import { commandMarker, hasManagedMarker, MANAGED_COMMAND_NAMES, renderCommandTemplate } from "../src/templates" describe("command templates", () => { - test("renders /vibe in Chinese by default", () => { - const output = renderCommandTemplate("vibe") - expect(output).toContain("<!-- VibePaper managed: @vibepaper/opencode; command=vibe; schemaVersion=1 -->") - expect(output).toContain("description: 显示 VibePaper 项目仪表盘") - expect(output).toContain("vibepaper_dashboard") - expect(output).toContain("/vibe-doctor") - expect(output).toContain("/vibe-relatedwork") - expect(output).toContain("bunx -p @vibepaper/opencode vibepaper-opencode doctor") + test("renders /copaper in Chinese by default", () => { + const output = renderCommandTemplate("copaper") + expect(output).toContain("<!-- CoPaper managed: @copaper/opencode; command=copaper; schemaVersion=1 -->") + expect(output).toContain("description: 显示 CoPaper 项目仪表盘") + expect(output).toContain("copaper_dashboard") + expect(output).toContain("/copaper-doctor") + expect(output).toContain("/copaper-relatedwork") + expect(output).toContain("bunx -p @copaper/opencode copaper-opencode doctor") expect(output).toContain("确认初始化") expect(output).toContain("项目名称") expect(output).toContain("研究领域") - expect(output).toContain("每次调用 VibePaper 工具后") + expect(output).toContain("每次调用 CoPaper 工具后") expect(output).toContain("展示工具返回的人类可读 markdown 正文和表格") expect(output).toContain("默认不要展示 fenced JSON block") expect(output).toContain("用户明确要求 JSON、debug 或原始输出时才展示") @@ -21,41 +21,41 @@ describe("command templates", () => { expect(output).toContain("question tool") expect(output).toContain("询问是否初始化") expect(output).toContain("收集项目名称和研究领域") - expect(output).toContain("vibepaper_init_apply") - expect(output).toContain("vibepaper_artifact_status") - expect(output).toContain("vibepaper_artifact_record") + expect(output).toContain("copaper_init_apply") + expect(output).toContain("copaper_artifact_status") + expect(output).toContain("copaper_artifact_record") expect(output).toContain("工件状态") expect(output).toContain("只读") expect(output).toContain("复述 artifact、status、confidence 和 reason") expect(output).toContain("不会自动推进 phase") expect(output).toContain("不会运行 checker/relatedwork/report/git/skills 动作") - expect(output).toContain("vibepaper_workflow_status") - expect(output).toContain("vibepaper_workflow_log") - expect(output).toContain("vibepaper_workflow_set_phase") + expect(output).toContain("copaper_workflow_status") + expect(output).toContain("copaper_workflow_log") + expect(output).toContain("copaper_workflow_set_phase") expect(output).toContain("修改阶段状态") expect(output).toContain("等待用户确认") expect(output).toContain("只能使用工具返回的信息") - expect(output).toContain("不要编造 VibePaper 状态") - expect(output).toContain("@vibepaper-coordinator") - expect(output).toContain("@vibepaper-storyline") - expect(output).toContain("@vibepaper-writer") - expect(output).toContain("@vibepaper-reviewer") - expect(output).toContain("@vibepaper-recorder") - expect(output).toContain("@vibepaper-literature") + expect(output).toContain("不要编造 CoPaper 状态") + expect(output).toContain("@copaper-coordinator") + expect(output).toContain("@copaper-storyline") + expect(output).toContain("@copaper-writer") + expect(output).toContain("@copaper-reviewer") + expect(output).toContain("@copaper-recorder") + expect(output).toContain("@copaper-literature") expect(output).toContain("agent profile") - expect(output).not.toContain("vibepaper_relatedwork_search") - expect(output).not.toContain("vibe --root <root> relatedwork") + expect(output).not.toContain("copaper_relatedwork_search") + expect(output).not.toContain("copaper --root <root> relatedwork") expect(output).not.toContain("!`") }) - test("renders /vibe in English when requested", () => { - const output = renderCommandTemplate("vibe", "en-US") - expect(output).toContain("description: Show VibePaper project dashboard") - expect(output).toContain("/vibe-relatedwork") + test("renders /copaper in English when requested", () => { + const output = renderCommandTemplate("copaper", "en-US") + expect(output).toContain("description: Show CoPaper project dashboard") + expect(output).toContain("/copaper-relatedwork") expect(output).toContain("confirm initialization") expect(output).toContain("project name") expect(output).toContain("research domain") - expect(output).toContain("After each VibePaper tool call") + expect(output).toContain("After each CoPaper tool call") expect(output).toContain("show the human-readable markdown body and tables") expect(output).toContain("omit fenced JSON blocks by default") expect(output).toContain("only show JSON when the user explicitly asks for JSON, debug, raw output, or full tool output") @@ -63,114 +63,114 @@ describe("command templates", () => { expect(output).toContain("question tool") expect(output).toContain("ask whether to initialize") expect(output).toContain("collect the project name and research domain") - expect(output).toContain("vibepaper_init_apply") - expect(output).toContain("vibepaper_artifact_status") - expect(output).toContain("vibepaper_artifact_record") + expect(output).toContain("copaper_init_apply") + expect(output).toContain("copaper_artifact_status") + expect(output).toContain("copaper_artifact_record") expect(output).toContain("artifact status") expect(output).toContain("read-only") expect(output).toContain("restate the artifact, status, confidence, and reason") expect(output).toContain("does not automatically advance phases") expect(output).toContain("does not automatically advance phases or run checker/relatedwork/report/git/skills actions") - expect(output).toContain("vibepaper_workflow_status") - expect(output).toContain("vibepaper_workflow_log") - expect(output).toContain("vibepaper_workflow_set_phase") + expect(output).toContain("copaper_workflow_status") + expect(output).toContain("copaper_workflow_log") + expect(output).toContain("copaper_workflow_set_phase") expect(output).toContain("change a phase status") expect(output).toContain("wait for confirmation") expect(output).toContain("Only use information returned by tools") - expect(output).toContain("Do not invent VibePaper status") - expect(output).toContain("@vibepaper-coordinator") - expect(output).toContain("@vibepaper-storyline") - expect(output).toContain("@vibepaper-writer") - expect(output).toContain("@vibepaper-reviewer") - expect(output).toContain("@vibepaper-recorder") - expect(output).toContain("@vibepaper-literature") + expect(output).toContain("Do not invent CoPaper status") + expect(output).toContain("@copaper-coordinator") + expect(output).toContain("@copaper-storyline") + expect(output).toContain("@copaper-writer") + expect(output).toContain("@copaper-reviewer") + expect(output).toContain("@copaper-recorder") + expect(output).toContain("@copaper-literature") expect(output).toContain("agent profile") - expect(output).not.toContain("vibepaper_relatedwork_search") - expect(output).not.toContain("vibe --root <root> relatedwork") + expect(output).not.toContain("copaper_relatedwork_search") + expect(output).not.toContain("copaper --root <root> relatedwork") }) - test("renders /vibe-doctor in Chinese by default", () => { - const output = renderCommandTemplate("vibe-doctor") - expect(output).toContain("<!-- VibePaper managed: @vibepaper/opencode; command=vibe-doctor; schemaVersion=1 -->") - expect(output).toContain("description: 诊断 VibePaper OpenCode 插件安装") - expect(output).toContain("bunx -p @vibepaper/opencode vibepaper-opencode doctor --format markdown 2>&1 || true") + test("renders /copaper-doctor in Chinese by default", () => { + const output = renderCommandTemplate("copaper-doctor") + expect(output).toContain("<!-- CoPaper managed: @copaper/opencode; command=copaper-doctor; schemaVersion=1 -->") + expect(output).toContain("description: 诊断 CoPaper OpenCode 插件安装") + expect(output).toContain("bunx -p @copaper/opencode copaper-opencode doctor --format markdown 2>&1 || true") expect(output).toContain("原样显示输出") expect(output).toContain("agent profile diagnostics") - expect(output).not.toContain("bunx @vibepaper/opencode doctor") + expect(output).not.toContain("bunx @copaper/opencode doctor") expect(output).not.toContain("$ARGUMENTS") }) - test("renders /vibe-doctor in English with agent diagnostics", () => { - const output = renderCommandTemplate("vibe-doctor", "en-US") + test("renders /copaper-doctor in English with agent diagnostics", () => { + const output = renderCommandTemplate("copaper-doctor", "en-US") expect(output).toContain("agent profile diagnostics") }) - test("renders /vibe-relatedwork in Chinese by default", () => { - const output = renderCommandTemplate("vibe-relatedwork") - expect(output).toContain("<!-- VibePaper managed: @vibepaper/opencode; command=vibe-relatedwork; schemaVersion=1 -->") - expect(output).toContain("description: 驱动 VibePaper 相关工作") - expect(output).toContain("vibepaper_relatedwork_status") - expect(output).toContain("vibepaper_relatedwork_keywords") - expect(output).toContain("只读工具(无需确认):`vibepaper_relatedwork_status`") - expect(output).toContain("写盘工具(必须复述完整参数,等待用户明确确认后才可调用):`vibepaper_relatedwork_keywords`") + test("renders /copaper-relatedwork in Chinese by default", () => { + const output = renderCommandTemplate("copaper-relatedwork") + expect(output).toContain("<!-- CoPaper managed: @copaper/opencode; command=copaper-relatedwork; schemaVersion=1 -->") + expect(output).toContain("description: 驱动 CoPaper 相关工作") + expect(output).toContain("copaper_relatedwork_status") + expect(output).toContain("copaper_relatedwork_keywords") + expect(output).toContain("只读工具(无需确认):`copaper_relatedwork_status`") + expect(output).toContain("写盘工具(必须复述完整参数,等待用户明确确认后才可调用):`copaper_relatedwork_keywords`") expect(output).toContain("`keywords` 会通过 Python CLI 写入 `relatedwork/queries.txt`") expect(output).toContain("不会额外追加插件侧 phase-patch 事件") - expect(output).toContain("vibepaper_relatedwork_search") - expect(output).toContain("vibepaper_relatedwork_import") - expect(output).toContain("vibepaper_relatedwork_sync_bib") - expect(output).toContain("vibepaper_relatedwork_download") - expect(output).toContain("vibepaper_relatedwork_summarize") - expect(output).toContain("vibepaper_relatedwork_register_summary") - expect(output).toContain("vibepaper_relatedwork_build_index") - expect(output).toContain("vibepaper_relatedwork_clean") - expect(output).toContain("@vibepaper-literature") - expect(output).toContain("vibepaper_workflow_set_phase") + expect(output).toContain("copaper_relatedwork_search") + expect(output).toContain("copaper_relatedwork_import") + expect(output).toContain("copaper_relatedwork_sync_bib") + expect(output).toContain("copaper_relatedwork_download") + expect(output).toContain("copaper_relatedwork_summarize") + expect(output).toContain("copaper_relatedwork_register_summary") + expect(output).toContain("copaper_relatedwork_build_index") + expect(output).toContain("copaper_relatedwork_clean") + expect(output).toContain("@copaper-literature") + expect(output).toContain("copaper_workflow_set_phase") expect(output).toContain("phase=literature") expect(output).toContain("status=complete") - expect(output).toContain("vibe-cli-unavailable") + expect(output).toContain("copaper-cli-unavailable") expect(output).toContain("uv pip install -e .") - expect(output).toContain("/vibe-doctor") - expect(output).not.toContain("vibe --root <root> relatedwork") + expect(output).toContain("/copaper-doctor") + expect(output).not.toContain("copaper --root <root> relatedwork") expect(output).not.toContain("!`") }) - test("renders /vibe-relatedwork in English when requested", () => { - const output = renderCommandTemplate("vibe-relatedwork", "en-US") - expect(output).toContain("description: Drive the VibePaper relatedwork") - expect(output).toContain("vibepaper_relatedwork_status") - expect(output).toContain("vibepaper_relatedwork_keywords") - expect(output).toContain("Read-only tools (no confirmation required): `vibepaper_relatedwork_status`") - expect(output).toContain("Write tools (must restate every argument and wait for explicit user confirmation before calling): `vibepaper_relatedwork_keywords`") + test("renders /copaper-relatedwork in English when requested", () => { + const output = renderCommandTemplate("copaper-relatedwork", "en-US") + expect(output).toContain("description: Drive the CoPaper relatedwork") + expect(output).toContain("copaper_relatedwork_status") + expect(output).toContain("copaper_relatedwork_keywords") + expect(output).toContain("Read-only tools (no confirmation required): `copaper_relatedwork_status`") + expect(output).toContain("Write tools (must restate every argument and wait for explicit user confirmation before calling): `copaper_relatedwork_keywords`") expect(output).toContain("`keywords` writes `relatedwork/queries.txt` through the Python CLI") expect(output).toContain("does not add an extra plugin-side phase-patch event") - expect(output).toContain("vibepaper_relatedwork_search") - expect(output).toContain("vibepaper_relatedwork_import") - expect(output).toContain("vibepaper_relatedwork_sync_bib") - expect(output).toContain("vibepaper_relatedwork_download") - expect(output).toContain("vibepaper_relatedwork_summarize") - expect(output).toContain("vibepaper_relatedwork_register_summary") - expect(output).toContain("vibepaper_relatedwork_build_index") - expect(output).toContain("vibepaper_relatedwork_clean") - expect(output).toContain("@vibepaper-literature") - expect(output).toContain("vibepaper_workflow_set_phase") + expect(output).toContain("copaper_relatedwork_search") + expect(output).toContain("copaper_relatedwork_import") + expect(output).toContain("copaper_relatedwork_sync_bib") + expect(output).toContain("copaper_relatedwork_download") + expect(output).toContain("copaper_relatedwork_summarize") + expect(output).toContain("copaper_relatedwork_register_summary") + expect(output).toContain("copaper_relatedwork_build_index") + expect(output).toContain("copaper_relatedwork_clean") + expect(output).toContain("@copaper-literature") + expect(output).toContain("copaper_workflow_set_phase") expect(output).toContain("phase=literature") expect(output).toContain("status=complete") - expect(output).toContain("vibe-cli-unavailable") + expect(output).toContain("copaper-cli-unavailable") expect(output).toContain("uv pip install -e .") - expect(output).not.toContain("vibe --root <root> relatedwork") + expect(output).not.toContain("copaper --root <root> relatedwork") }) - test("detects VibePaper-managed command markers", () => { - const marker = commandMarker("vibe") - expect(marker).toBe("<!-- VibePaper managed: @vibepaper/opencode; command=vibe; schemaVersion=1 -->") - expect(hasManagedMarker(`${marker}\nbody`, "vibe")).toBe(true) - expect(hasManagedMarker("# custom command", "vibe")).toBe(false) - expect(hasManagedMarker(commandMarker("vibe-doctor"), "vibe")).toBe(false) - expect(hasManagedMarker(commandMarker("vibe-relatedwork"), "vibe-relatedwork")).toBe(true) - expect(hasManagedMarker(commandMarker("vibe-relatedwork"), "vibe")).toBe(false) + test("detects CoPaper-managed command markers", () => { + const marker = commandMarker("copaper") + expect(marker).toBe("<!-- CoPaper managed: @copaper/opencode; command=copaper; schemaVersion=1 -->") + expect(hasManagedMarker(`${marker}\nbody`, "copaper")).toBe(true) + expect(hasManagedMarker("# custom command", "copaper")).toBe(false) + expect(hasManagedMarker(commandMarker("copaper-doctor"), "copaper")).toBe(false) + expect(hasManagedMarker(commandMarker("copaper-relatedwork"), "copaper-relatedwork")).toBe(true) + expect(hasManagedMarker(commandMarker("copaper-relatedwork"), "copaper")).toBe(false) }) test("MANAGED_COMMAND_NAMES includes all three managed commands", () => { - expect([...MANAGED_COMMAND_NAMES]).toEqual(["vibe", "vibe-doctor", "vibe-relatedwork"]) + expect([...MANAGED_COMMAND_NAMES]).toEqual(["copaper", "copaper-doctor", "copaper-relatedwork"]) }) }) diff --git a/packages/opencode-plugin/tests/config.test.ts b/packages/opencode-plugin/tests/config.test.ts index be36995..6d3b6b8 100644 --- a/packages/opencode-plugin/tests/config.test.ts +++ b/packages/opencode-plugin/tests/config.test.ts @@ -9,31 +9,31 @@ describe("mergePluginConfig", () => { expect(result.changed).toBe(true) const parsed = parse(result.output!) expect(parsed.model).toBe("x") - expect(parsed.plugin).toEqual(["@vibepaper/opencode"]) + expect(parsed.plugin).toEqual(["@copaper/opencode"]) }) test("appends plugin and deduplicates existing values", () => { const result = mergePluginConfig('{"plugin":["other"]}') expect(result.ok).toBe(true) - expect(parse(result.output!).plugin).toEqual(["other", "@vibepaper/opencode"]) + expect(parse(result.output!).plugin).toEqual(["other", "@copaper/opencode"]) }) test("uses an explicit plugin specifier for local package installs", () => { - const localSpecifier = "file:///tmp/project/node_modules/@vibepaper/opencode/dist/index.js" + const localSpecifier = "file:///tmp/project/node_modules/@copaper/opencode/dist/index.js" const result = mergePluginConfig('{"model":"x"}', localSpecifier) expect(result.ok).toBe(true) expect(parse(result.output!).plugin).toEqual([localSpecifier]) }) test("replaces package specifier with explicit local plugin specifier", () => { - const localSpecifier = "file:///tmp/project/node_modules/@vibepaper/opencode/dist/index.js" - const result = mergePluginConfig('{"plugin":["@vibepaper/opencode"]}', localSpecifier) + const localSpecifier = "file:///tmp/project/node_modules/@copaper/opencode/dist/index.js" + const result = mergePluginConfig('{"plugin":["@copaper/opencode"]}', localSpecifier) expect(result.ok).toBe(true) expect(parse(result.output!).plugin).toEqual([localSpecifier]) }) test("does not rewrite when plugin already exists", () => { - const input = '{"plugin":["@vibepaper/opencode"]}' + const input = '{"plugin":["@copaper/opencode"]}' const result = mergePluginConfig(input) expect(result.ok).toBe(true) expect(result.changed).toBe(false) @@ -51,7 +51,7 @@ describe("mergePluginConfig", () => { const result = mergePluginConfig(input) expect(result.ok).toBe(true) expect(result.changed).toBe(true) - expect(parse(result.output!).plugin).toEqual(["other", "@vibepaper/opencode"]) + expect(parse(result.output!).plugin).toEqual(["other", "@copaper/opencode"]) expect(result.output!).toContain("// user model") }) @@ -65,12 +65,12 @@ describe("mergePluginConfig", () => { const result = mergePluginConfig(input) expect(result.ok).toBe(true) expect(result.changed).toBe(true) - expect(parse(result.output!).plugin).toEqual(["other", "@vibepaper/opencode"]) + expect(parse(result.output!).plugin).toEqual(["other", "@copaper/opencode"]) expect(result.output!).toContain("// keep this plugin comment") }) test("fails closed when plugin is not an array", () => { - const result = mergePluginConfig('{"plugin":"@vibepaper/opencode"}') + const result = mergePluginConfig('{"plugin":"@copaper/opencode"}') expect(result.ok).toBe(false) expect(result.error).toContain("plugin must be an array") }) diff --git a/packages/opencode-plugin/tests/vibepaper-config.test.ts b/packages/opencode-plugin/tests/copaper-config.test.ts similarity index 75% rename from packages/opencode-plugin/tests/vibepaper-config.test.ts rename to packages/opencode-plugin/tests/copaper-config.test.ts index 9b2f719..4298976 100644 --- a/packages/opencode-plugin/tests/vibepaper-config.test.ts +++ b/packages/opencode-plugin/tests/copaper-config.test.ts @@ -1,20 +1,20 @@ import { describe, expect, test } from "bun:test" import { resolve } from "node:path" import { mkdirSync } from "node:fs" -import { loadVibePaperConfig } from "../src/vibepaper-config" +import { loadCoPaperConfig } from "../src/copaper-config" import { DEFAULT_LOCALE, SCHEMA_VERSION } from "../src/types" import { hashTree, makeTempProject } from "./fixtures" -describe("vibepaper config loader", () => { +describe("copaper config loader", () => { test("missing config returns defaults, diagnostic, and no mutation", () => { - const project = makeTempProject("vibepaper-config-missing-") + const project = makeTempProject("copaper-config-missing-") try { project.write("paper.md", "# Paper\n") const before = hashTree(project.root) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) - expect(result.path).toBe(resolve(project.root, ".opencode", "vibepaper.json")) + expect(result.path).toBe(resolve(project.root, ".opencode", "copaper.json")) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, locale: DEFAULT_LOCALE, @@ -34,13 +34,13 @@ describe("vibepaper config loader", () => { }) test("parses valid config with defaults and agent overrides", () => { - const project = makeTempProject("vibepaper-config-valid-") + const project = makeTempProject("copaper-config-valid-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", `{ // JSONC comments are supported. - "$schema": "https://vibepaper.dev/opencode.schema.json", + "$schema": "https://copaper.dev/opencode.schema.json", "schemaVersion": ${SCHEMA_VERSION}, "locale": "en-US", "defaults": { @@ -48,7 +48,7 @@ describe("vibepaper config loader", () => { "temperature": 0.4, }, "agents": { - "vibepaper-writer": { + "copaper-writer": { "enabled": false, "model": "writer-model", "temperature": 1.5, @@ -59,7 +59,7 @@ describe("vibepaper config loader", () => { }`, ) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.diagnostics).toEqual([]) expect(result.config).toEqual({ @@ -70,7 +70,7 @@ describe("vibepaper config loader", () => { temperature: 0.4, }, agents: { - "vibepaper-writer": { + "copaper-writer": { enabled: false, model: "writer-model", temperature: 1.5, @@ -85,11 +85,11 @@ describe("vibepaper config loader", () => { }) test("parse failure falls back to safe config with warning", () => { - const project = makeTempProject("vibepaper-config-parse-") + const project = makeTempProject("copaper-config-parse-") try { - project.write(".opencode/vibepaper.json", "{ invalid json") + project.write(".opencode/copaper.json", "{ invalid json") - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, @@ -109,19 +109,19 @@ describe("vibepaper config loader", () => { }) test("unsupported schema falls back to safe config with warning", () => { - const project = makeTempProject("vibepaper-config-schema-") + const project = makeTempProject("copaper-config-schema-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION + 1, locale: "en-US", defaults: { model: "unsafe-model", temperature: 2 }, - agents: { "vibepaper-writer": { enabled: false } }, + agents: { "copaper-writer": { enabled: false } }, }), ) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, @@ -141,29 +141,29 @@ describe("vibepaper config loader", () => { }) test("unknown fields and unknown agents are ignored with warnings", () => { - const project = makeTempProject("vibepaper-config-unknown-") + const project = makeTempProject("copaper-config-unknown-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, locale: DEFAULT_LOCALE, extraTop: true, defaults: { model: "default-model", unknownDefault: true }, agents: { - "vibepaper-storyline": { enabled: true, unknownOverride: "ignored" }, - "not-a-vibepaper-agent": { enabled: true }, + "copaper-storyline": { enabled: true, unknownOverride: "ignored" }, + "not-a-copaper-agent": { enabled: true }, }, }), ) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, locale: DEFAULT_LOCALE, defaults: { model: "default-model" }, - agents: { "vibepaper-storyline": { enabled: true } }, + agents: { "copaper-storyline": { enabled: true } }, }) expect(result.diagnostics.map((diagnostic) => diagnostic.code)).toEqual([ "unsupported-field", @@ -177,16 +177,16 @@ describe("vibepaper config loader", () => { }) test("invalid locale, temperature, and permission profile are ignored", () => { - const project = makeTempProject("vibepaper-config-invalid-") + const project = makeTempProject("copaper-config-invalid-") try { project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, locale: "fr-FR", defaults: { model: " ", temperature: 2.5 }, agents: { - "vibepaper-writer": { + "copaper-writer": { enabled: true, temperature: -0.1, promptAppend: "", @@ -196,13 +196,13 @@ describe("vibepaper config loader", () => { }), ) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, locale: DEFAULT_LOCALE, defaults: {}, - agents: { "vibepaper-writer": { enabled: true } }, + agents: { "copaper-writer": { enabled: true } }, }) expect(result.diagnostics.map((diagnostic) => diagnostic.code)).toEqual([ "invalid-field", @@ -218,11 +218,11 @@ describe("vibepaper config loader", () => { }) test("non-file config falls back to safe config with warning", () => { - const project = makeTempProject("vibepaper-config-non-file-") + const project = makeTempProject("copaper-config-non-file-") try { - mkdirSync(project.path(".opencode", "vibepaper.json"), { recursive: true }) + mkdirSync(project.path(".opencode", "copaper.json"), { recursive: true }) - const result = loadVibePaperConfig(project.root) + const result = loadCoPaperConfig(project.root) expect(result.config).toEqual({ schemaVersion: SCHEMA_VERSION, diff --git a/packages/opencode-plugin/tests/dashboard.test.ts b/packages/opencode-plugin/tests/dashboard.test.ts index 02d5f62..7dd65ed 100644 --- a/packages/opencode-plugin/tests/dashboard.test.ts +++ b/packages/opencode-plugin/tests/dashboard.test.ts @@ -29,7 +29,7 @@ describe("dashboard", () => { expect(result.locale).toBe("zh-CN") expect(result.readiness?.status).toBe("needs-init") expect(result.initPreview.items.find((item) => item.path === "paper.md")?.action).toBe("create") - expect(markdown).toContain("## VibePaper 项目仪表盘") + expect(markdown).toContain("## CoPaper 项目仪表盘") expect(markdown).toContain("**状态:") expect(markdown).toContain("项目就绪度") expect(markdown).toContain("就绪=") @@ -51,7 +51,7 @@ describe("dashboard", () => { const result = await buildDashboardResult({ root: project.root, packageVersion: "0.1.0", locale: "en-US" }) const markdown = renderDashboardOutput(result) expect(result.locale).toBe("en-US") - expect(markdown).toContain("## VibePaper Project Dashboard") + expect(markdown).toContain("## CoPaper Project Dashboard") expect(markdown).toContain("**Status:**") expect(markdown).toContain("ready=") expect(markdown).toContain("Init Preview") @@ -103,13 +103,13 @@ describe("dashboard", () => { project.write("writingrules.md", "# Rules\n") project.write(".agents/state.json", "{}\n") project.write(".agents/events.jsonl", "") - project.write("AGENTS.md", "# VibePaper project guide\n") + project.write("AGENTS.md", "# CoPaper project guide\n") const result = await buildDashboardResult({ root: project.root, packageVersion: "0.1.0", locale: "zh-CN" }) expect(result.ok).toBe(true) expect(result.readiness?.status).toBe("ready") expect(result.recommendation.id).toBe("continue-workflow") - expect(renderDashboardOutput(result)).toContain("项目已具备核心 VibePaper 文件") + expect(renderDashboardOutput(result)).toContain("项目已具备核心 CoPaper 文件") }) test("does not expose workflow section for ready files with invalid workflow state", async () => { @@ -122,7 +122,7 @@ describe("dashboard", () => { project.write("writingrules.md", "# Rules\n") project.write(".agents/state.json", "{}\n") project.write(".agents/events.jsonl", "") - project.write("AGENTS.md", "# VibePaper project guide\n") + project.write("AGENTS.md", "# CoPaper project guide\n") const result = await buildDashboardResult({ root: project.root, packageVersion: "0.1.0", locale: "zh-CN" }) const markdown = renderDashboardOutput(result) @@ -147,7 +147,7 @@ describe("dashboard", () => { expect(result.ok).toBe(true) expect(result.readiness?.status).toBe("ready") - expect(markdown).toContain("项目已具备核心 VibePaper 文件") + expect(markdown).toContain("项目已具备核心 CoPaper 文件") expect(initPreviewSection).toContain("relatedwork/") expect(initPreviewSection).not.toContain(".agents/skills") }) diff --git a/packages/opencode-plugin/tests/doctor.test.ts b/packages/opencode-plugin/tests/doctor.test.ts index 2eb7ed8..442e7e9 100644 --- a/packages/opencode-plugin/tests/doctor.test.ts +++ b/packages/opencode-plugin/tests/doctor.test.ts @@ -21,13 +21,13 @@ describe("doctor", () => { expect(result.ok).toBe(true) expect(result.checks.map((check) => check.id)).toContain("plugin.configured") expect(result.checks.find((check) => check.id === "plugin.configured")?.status).toBe("pass") - expect(renderDoctorText(result)).toContain("VibePaper OpenCode 诊断 v0.1.0") - expect(renderDoctorText(result, "en-US")).toContain("VibePaper OpenCode Doctor v0.1.0") + expect(renderDoctorText(result)).toContain("CoPaper OpenCode 诊断 v0.1.0") + expect(renderDoctorText(result, "en-US")).toContain("CoPaper OpenCode Doctor v0.1.0") expect(renderDoctorMarkdown(result)).toContain("| 检查项 | 状态 | 说明 |") expect(renderDoctorMarkdown(result, "en-US")).toContain("| Check | Status | Message |") - expect(result.checks.find((check) => check.id === "agents.vibepaper-coordinator")?.status).toBe("pass") - expect(result.checks.find((check) => check.id === "agents.vibepaper-writer")?.message).toContain("paperWrite") - expect(renderDoctorMarkdown(result)).toContain("agents.vibepaper-writer") + expect(result.checks.find((check) => check.id === "agents.copaper-coordinator")?.status).toBe("pass") + expect(result.checks.find((check) => check.id === "agents.copaper-writer")?.message).toContain("paperWrite") + expect(renderDoctorMarkdown(result)).toContain("agents.copaper-writer") expect(JSON.parse(renderDoctorJson(result)).ok).toBe(true) }) @@ -37,11 +37,11 @@ describe("doctor", () => { if (!plan.ok) throw new Error(plan.error) await applyInitPlan(plan) project.write( - ".opencode/vibepaper.json", + ".opencode/copaper.json", JSON.stringify({ schemaVersion: SCHEMA_VERSION, agents: { - "vibepaper-coordinator": { permissionProfile: "paperWrite" }, + "copaper-coordinator": { permissionProfile: "paperWrite" }, }, }), ) @@ -49,7 +49,7 @@ describe("doctor", () => { const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) expect(result.ok).toBe(true) - expect(result.checks.find((check) => check.id === "agents.vibepaper-coordinator")?.message).toContain("readOnly") + expect(result.checks.find((check) => check.id === "agents.copaper-coordinator")?.message).toContain("readOnly") expect(result.checks.find((check) => check.id === "agents.diagnostic.permission-escalation-denied")?.status).toBe("warn") }) @@ -61,9 +61,9 @@ describe("doctor", () => { project.write( "opencode.json", JSON.stringify({ - plugin: ["@vibepaper/opencode"], + plugin: ["@copaper/opencode"], agent: { - "vibepaper-writer": { prompt: "user writer" }, + "copaper-writer": { prompt: "user writer" }, }, }), ) @@ -71,7 +71,7 @@ describe("doctor", () => { const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) expect(result.ok).toBe(true) - expect(result.checks.find((check) => check.id === "agents.vibepaper-writer")?.status).toBe("fail") + expect(result.checks.find((check) => check.id === "agents.copaper-writer")?.status).toBe("fail") expect(result.checks.find((check) => check.id === "agents.diagnostic.agent-name-conflict")?.status).toBe("warn") }) @@ -96,7 +96,7 @@ describe("doctor", () => { test("reports ambiguous config files without throwing", async () => { const project = temp() mkdirSync(project.path("opencode.json")) - project.write("opencode.jsonc", `{"plugin":["@vibepaper/opencode"]}\n`) + project.write("opencode.jsonc", `{"plugin":["@copaper/opencode"]}\n`) const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) expect(result.ok).toBe(false) @@ -111,7 +111,7 @@ describe("doctor", () => { const plan = await planInit({ root: project.root }) if (!plan.ok) throw new Error(plan.error) await applyInitPlan(plan) - project.write("opencode.jsonc", `{"plugin":["@vibepaper/opencode"]}\n`) + project.write("opencode.jsonc", `{"plugin":["@copaper/opencode"]}\n`) const result = await runDoctor({ root: project.root, config: "opencode.jsonc", packageVersion: "0.1.0" }) expect(result.ok).toBe(true) @@ -122,9 +122,9 @@ describe("doctor", () => { test("accepts a local file URL plugin specifier", async () => { const project = temp() - project.write("opencode.json", JSON.stringify({ plugin: [`file://${project.path("node_modules", "@vibepaper", "opencode", "dist", "index.js")}`] })) - project.write(".opencode/commands/vibe.md", "<!-- VibePaper managed: @vibepaper/opencode; command=vibe; schemaVersion=1 -->\n") - project.write(".opencode/commands/vibe-doctor.md", "<!-- VibePaper managed: @vibepaper/opencode; command=vibe-doctor; schemaVersion=1 -->\n") + project.write("opencode.json", JSON.stringify({ plugin: [`file://${project.path("node_modules", "@copaper", "opencode", "dist", "index.js")}`] })) + project.write(".opencode/commands/copaper.md", "<!-- CoPaper managed: @copaper/opencode; command=copaper; schemaVersion=1 -->\n") + project.write(".opencode/commands/copaper-doctor.md", "<!-- CoPaper managed: @copaper/opencode; command=copaper-doctor; schemaVersion=1 -->\n") const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) expect(result.checks.find((check) => check.id === "plugin.configured")?.status).toBe("pass") @@ -133,14 +133,14 @@ describe("doctor", () => { test("accepts a managed project-local plugin wrapper", async () => { const project = temp() project.write("opencode.json", JSON.stringify({ $schema: "https://opencode.ai/config.json" })) - project.write(".opencode/plugins/vibepaper.js", [ - "// VibePaper managed local plugin: @vibepaper/opencode", + project.write(".opencode/plugins/copaper.js", [ + "// CoPaper managed local plugin: @copaper/opencode", "// Loaded by OpenCode from .opencode/plugins/ without absolute paths.", - 'export { VibePaperPlugin, default } from "../../node_modules/@vibepaper/opencode/dist/index.js"', + 'export { CoPaperPlugin, default } from "../../node_modules/@copaper/opencode/dist/index.js"', "", ].join("\n")) - project.write(".opencode/commands/vibe.md", "<!-- VibePaper managed: @vibepaper/opencode; command=vibe; schemaVersion=1 -->\n") - project.write(".opencode/commands/vibe-doctor.md", "<!-- VibePaper managed: @vibepaper/opencode; command=vibe-doctor; schemaVersion=1 -->\n") + project.write(".opencode/commands/copaper.md", "<!-- CoPaper managed: @copaper/opencode; command=copaper; schemaVersion=1 -->\n") + project.write(".opencode/commands/copaper-doctor.md", "<!-- CoPaper managed: @copaper/opencode; command=copaper-doctor; schemaVersion=1 -->\n") const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) @@ -152,7 +152,7 @@ describe("doctor", () => { test("rejects explicit config paths outside root without throwing", async () => { const project = temp() const outside = temp() - outside.write("opencode.json", `{"plugin":["@vibepaper/opencode"]}\n`) + outside.write("opencode.json", `{"plugin":["@copaper/opencode"]}\n`) const result = await runDoctor({ root: project.root, config: `../${basename(outside.root)}/opencode.json`, packageVersion: "0.1.0" }) expect(result.ok).toBe(false) @@ -160,7 +160,7 @@ describe("doctor", () => { const parse = result.checks.find((check) => check.id === "config.parse") expect(present?.status).toBe("fail") expect(parse?.status).toBe("fail") - expect(present?.remediation ?? parse?.remediation).toBe("Run: bunx -p @vibepaper/opencode vibepaper-opencode init") + expect(present?.remediation ?? parse?.remediation).toBe("Run: bunx -p @copaper/opencode copaper-opencode init") }) test("reports directory config as parse failure without throwing", async () => { @@ -177,13 +177,13 @@ describe("doctor", () => { const plan = await planInit({ root: project.root }) if (!plan.ok) throw new Error(plan.error) await applyInitPlan(plan) - rmSync(project.path(".opencode", "commands", "vibe.md")) - mkdirSync(project.path(".opencode", "commands", "vibe.md")) + rmSync(project.path(".opencode", "commands", "copaper.md")) + mkdirSync(project.path(".opencode", "commands", "copaper.md")) const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) expect(result.ok).toBe(false) - expect(result.checks.find((check) => check.id === "commands.vibe.present")?.status).toBe("fail") - expect(result.checks.find((check) => check.id === "commands.vibe.managed")?.status).toBe("warn") + expect(result.checks.find((check) => check.id === "commands.copaper.present")?.status).toBe("fail") + expect(result.checks.find((check) => check.id === "commands.copaper.managed")?.status).toBe("warn") }) test("reports top-level array config as parse failure", async () => { @@ -200,7 +200,7 @@ describe("doctor", () => { const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) const ids = result.checks .map((check) => check.id) - .filter((id) => !id.startsWith("agents.") && !id.startsWith("commands.") && id !== "vibe-cli.available") + .filter((id) => !id.startsWith("agents.") && !id.startsWith("commands.") && id !== "copaper-cli.available") .join("\n") expect(ids).not.toContain("paper") expect(ids).not.toContain("storyline") @@ -211,8 +211,8 @@ describe("doctor", () => { const project = temp() const result = await runDoctor({ root: project.root, packageVersion: "0.1.0" }) const text = renderDoctorText(result) - expect(text).toContain("VibePaper OpenCode 诊断 v0.1.0") + expect(text).toContain("CoPaper OpenCode 诊断 v0.1.0") expect(text).toContain("config.present") - expect(text).toContain("bunx -p @vibepaper/opencode vibepaper-opencode init") + expect(text).toContain("bunx -p @copaper/opencode copaper-opencode init") }) }) diff --git a/packages/opencode-plugin/tests/fixtures.ts b/packages/opencode-plugin/tests/fixtures.ts index 6275425..06d2404 100644 --- a/packages/opencode-plugin/tests/fixtures.ts +++ b/packages/opencode-plugin/tests/fixtures.ts @@ -3,7 +3,7 @@ import { join, relative } from "node:path" import { tmpdir } from "node:os" import { createHash } from "node:crypto" -export function makeTempProject(prefix = "vibepaper-opencode-") { +export function makeTempProject(prefix = "copaper-opencode-") { const root = mkdtempSync(join(tmpdir(), prefix)) return { root, diff --git a/packages/opencode-plugin/tests/i18n.test.ts b/packages/opencode-plugin/tests/i18n.test.ts index 60a8c7f..7d7b683 100644 --- a/packages/opencode-plugin/tests/i18n.test.ts +++ b/packages/opencode-plugin/tests/i18n.test.ts @@ -7,12 +7,12 @@ describe("i18n", () => { expect(resolveLocale(undefined, {}).fallback).toBe(false) }) - test("uses VIBEPAPER_LANG when explicit locale is absent", () => { - expect(resolveLocale(undefined, { VIBEPAPER_LANG: "en-US" }).locale).toBe("en-US") + test("uses COPAPER_LANG when explicit locale is absent", () => { + expect(resolveLocale(undefined, { COPAPER_LANG: "en-US" }).locale).toBe("en-US") }) - test("explicit locale takes precedence over VIBEPAPER_LANG", () => { - expect(resolveLocale("zh-CN", { VIBEPAPER_LANG: "en-US" }).locale).toBe("zh-CN") + test("explicit locale takes precedence over COPAPER_LANG", () => { + expect(resolveLocale("zh-CN", { COPAPER_LANG: "en-US" }).locale).toBe("zh-CN") }) test("falls back to zh-CN for unsupported locale values", () => { diff --git a/packages/opencode-plugin/tests/installer.test.ts b/packages/opencode-plugin/tests/installer.test.ts index e97c5ac..4245938 100644 --- a/packages/opencode-plugin/tests/installer.test.ts +++ b/packages/opencode-plugin/tests/installer.test.ts @@ -14,7 +14,7 @@ describe("filesystem safety helpers", () => { test("generates deterministic backup paths inside root", () => { const project = temp() const path = backupPathFor(project.root, "opencode.json", new Date("2026-04-29T12:00:00Z")) - expect(path).toBe(join(project.root, ".opencode", "vibepaper", "backups", "2026-04-29T12-00-00-000Z", "opencode.json")) + expect(path).toBe(join(project.root, ".opencode", "copaper", "backups", "2026-04-29T12-00-00-000Z", "opencode.json")) }) test("allows in-root names that start with dot dot text", () => { @@ -50,7 +50,7 @@ describe("filesystem safety helpers", () => { projects.push(outside) mkdirSync(project.path(".opencode"), { recursive: true }) symlinkSync(outside.root, project.path(".opencode", "commands"), "dir") - expect(() => assertInsideRoot(project.root, project.path(".opencode", "commands", "vibe.md"))).toThrow("outside root") + expect(() => assertInsideRoot(project.root, project.path(".opencode", "commands", "copaper.md"))).toThrow("outside root") expect(existsSync(project.path(".opencode", "commands"))).toBe(true) }) @@ -73,16 +73,16 @@ describe("installer", () => { expect(JSON.parse(project.read("opencode.json"))).toEqual({ $schema: "https://opencode.ai/config.json" }) expect(project.read(LOCAL_PLUGIN_RELATIVE_PATH)).toBe(LOCAL_PLUGIN_CONTENT) expect(project.read(LOCAL_PLUGIN_RELATIVE_PATH)).not.toContain(project.root) - expect(project.read(".opencode/commands/vibe.md")).toContain("command=vibe") - expect(project.read(".opencode/commands/vibe-doctor.md")).toContain("command=vibe-doctor") + expect(project.read(".opencode/commands/copaper.md")).toContain("command=copaper") + expect(project.read(".opencode/commands/copaper-doctor.md")).toContain("command=copaper-doctor") }) test("uses a file URL plugin specifier when the CLI runs from project node_modules", () => { const project = temp() - const cliPath = project.path("node_modules", "@vibepaper", "opencode", "dist", "cli.js") - const indexPath = project.path("node_modules", "@vibepaper", "opencode", "dist", "index.js") - project.write("node_modules/@vibepaper/opencode/dist/cli.js", "") - project.write("node_modules/@vibepaper/opencode/dist/index.js", "") + const cliPath = project.path("node_modules", "@copaper", "opencode", "dist", "cli.js") + const indexPath = project.path("node_modules", "@copaper", "opencode", "dist", "index.js") + project.write("node_modules/@copaper/opencode/dist/cli.js", "") + project.write("node_modules/@copaper/opencode/dist/index.js", "") expect(resolvePluginSpecifier(project.root, cliPath)).toBe(`file://${indexPath}`) }) @@ -90,11 +90,11 @@ describe("installer", () => { test("keeps the npm package specifier when the CLI is outside the target project", () => { const project = temp() const outside = temp() - const cliPath = outside.path("node_modules", "@vibepaper", "opencode", "dist", "cli.js") - outside.write("node_modules/@vibepaper/opencode/dist/cli.js", "") - outside.write("node_modules/@vibepaper/opencode/dist/index.js", "") + const cliPath = outside.path("node_modules", "@copaper", "opencode", "dist", "cli.js") + outside.write("node_modules/@copaper/opencode/dist/cli.js", "") + outside.write("node_modules/@copaper/opencode/dist/index.js", "") - expect(resolvePluginSpecifier(project.root, cliPath)).toBe("@vibepaper/opencode") + expect(resolvePluginSpecifier(project.root, cliPath)).toBe("@copaper/opencode") }) test("keeps existing JSON config unchanged when using the local plugin wrapper", async () => { @@ -109,20 +109,20 @@ describe("installer", () => { expect(parsed.plugin).toEqual(["other"]) expect(project.read("opencode.json")).toBe(original) expect(project.read(LOCAL_PLUGIN_RELATIVE_PATH)).toContain(LOCAL_PLUGIN_MARKER) - expect(existsSync(project.path(".opencode/vibepaper/backups/2026-04-29T12-00-00-000Z/opencode.json"))).toBe(false) + expect(existsSync(project.path(".opencode/copaper/backups/2026-04-29T12-00-00-000Z/opencode.json"))).toBe(false) }) test("merges existing JSON config and backs it up when explicit plugin specifier is requested", async () => { const project = temp() project.write("opencode.json", JSON.stringify({ model: "x", plugin: ["other"] }, null, 2)) const original = project.read("opencode.json") - const plan = await planInit({ root: project.root, pluginSpecifier: "@vibepaper/opencode", now: new Date("2026-04-29T12:00:00Z") }) + const plan = await planInit({ root: project.root, pluginSpecifier: "@copaper/opencode", now: new Date("2026-04-29T12:00:00Z") }) expect(plan.ok).toBe(true) await applyInitPlan(plan) const parsed = JSON.parse(project.read("opencode.json")) expect(parsed.model).toBe("x") - expect(parsed.plugin).toEqual(["other", "@vibepaper/opencode"]) - expect(project.read(".opencode/vibepaper/backups/2026-04-29T12-00-00-000Z/opencode.json")).toBe(original) + expect(parsed.plugin).toEqual(["other", "@copaper/opencode"]) + expect(project.read(".opencode/copaper/backups/2026-04-29T12-00-00-000Z/opencode.json")).toBe(original) }) test("dry-run is read-only", async () => { @@ -146,7 +146,7 @@ describe("installer", () => { test("fails on unmanaged command unless force is used", async () => { const project = temp() - project.write(".opencode/commands/vibe.md", "# user command") + project.write(".opencode/commands/copaper.md", "# user command") const plan = await planInit({ root: project.root }) expect(plan.ok).toBe(false) expect(plan.error).toContain("unmanaged command") @@ -154,8 +154,8 @@ describe("installer", () => { const forced = await planInit({ root: project.root, force: true, now: new Date("2026-04-29T12:00:00Z") }) expect(forced.ok).toBe(true) await applyInitPlan(forced) - expect(project.read(".opencode/commands/vibe.md")).toContain("command=vibe") - expect(project.read(".opencode/vibepaper/backups/2026-04-29T12-00-00-000Z/.opencode/commands/vibe.md")).toBe("# user command") + expect(project.read(".opencode/commands/copaper.md")).toContain("command=copaper") + expect(project.read(".opencode/copaper/backups/2026-04-29T12-00-00-000Z/.opencode/commands/copaper.md")).toBe("# user command") }) test("fails on unmanaged local plugin unless force is used", async () => { @@ -169,7 +169,7 @@ describe("installer", () => { expect(forced.ok).toBe(true) await applyInitPlan(forced) expect(project.read(LOCAL_PLUGIN_RELATIVE_PATH)).toBe(LOCAL_PLUGIN_CONTENT) - expect(project.read(".opencode/vibepaper/backups/2026-04-29T12-00-00-000Z/.opencode/plugins/vibepaper.js")).toBe("# user plugin") + expect(project.read(".opencode/copaper/backups/2026-04-29T12-00-00-000Z/.opencode/plugins/copaper.js")).toBe("# user plugin") }) test("rejects explicit config paths outside root during planning", async () => { @@ -193,7 +193,7 @@ describe("installer", () => { test("rejects symlinked command paths outside root during dry-run planning", async () => { const project = temp() const outside = temp() - outside.write("vibe.md", renderCommandTemplate("vibe")) + outside.write("copaper.md", renderCommandTemplate("copaper")) mkdirSync(project.path(".opencode"), { recursive: true }) symlinkSync(outside.root, project.path(".opencode", "commands"), "dir") @@ -207,7 +207,7 @@ describe("installer", () => { const project = temp() const outside = temp() outside.write("secret.txt", "secret") - const backupTo = project.path(".opencode", "vibepaper", "backups", "manual", "secret.txt") + const backupTo = project.path(".opencode", "copaper", "backups", "manual", "secret.txt") const plan: InitPlan = { ok: true, root: project.root, diff --git a/packages/opencode-plugin/tests/package-smoke.test.ts b/packages/opencode-plugin/tests/package-smoke.test.ts index deb92e7..3c79cb7 100644 --- a/packages/opencode-plugin/tests/package-smoke.test.ts +++ b/packages/opencode-plugin/tests/package-smoke.test.ts @@ -7,8 +7,8 @@ const pkg = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8")) describe("package metadata", () => { test("uses the expected npm package name and binary", () => { - expect(pkg.name).toBe("@vibepaper/opencode") - expect(pkg.bin).toEqual({ "vibepaper-opencode": "./dist/cli.js" }) + expect(pkg.name).toBe("@copaper/opencode") + expect(pkg.bin).toEqual({ "copaper-opencode": "./dist/cli.js" }) }) test("exports the OpenCode plugin entry separately from the CLI", () => { @@ -31,6 +31,6 @@ describe("built package smoke", () => { test("built plugin entry exists after build", () => { const entryPath = join(packageRoot, "dist", "index.js") expect(existsSync(entryPath)).toBe(true) - expect(readFileSync(entryPath, "utf8")).toContain("VibePaperPlugin") + expect(readFileSync(entryPath, "utf8")).toContain("CoPaperPlugin") }) }) diff --git a/packages/opencode-plugin/tests/permission-profiles.test.ts b/packages/opencode-plugin/tests/permission-profiles.test.ts index e35c0eb..2a2d649 100644 --- a/packages/opencode-plugin/tests/permission-profiles.test.ts +++ b/packages/opencode-plugin/tests/permission-profiles.test.ts @@ -8,35 +8,35 @@ import { } from "../src/permission-profiles" const SAFE_READ_TOOL_PERMISSIONS = [ - "vibepaper_dashboard", - "vibepaper_artifact_status", - "vibepaper_paper_structure_status", - "vibepaper_storyline_structure_status", - "vibepaper_pdf_extract", - "vibepaper_ppt_extract", - "vibepaper_checker_status", - "vibepaper_relatedwork_status", - "vibepaper_workflow_status", - "vibepaper_workflow_log", + "copaper_dashboard", + "copaper_artifact_status", + "copaper_paper_structure_status", + "copaper_storyline_structure_status", + "copaper_pdf_extract", + "copaper_ppt_extract", + "copaper_checker_status", + "copaper_relatedwork_status", + "copaper_workflow_status", + "copaper_workflow_log", ] as const const WRITE_TOOL_PERMISSIONS = [ - "vibepaper_init_apply", - "vibepaper_artifact_record", - "vibepaper_checker_record", - "vibepaper_workflow_set_phase", + "copaper_init_apply", + "copaper_artifact_record", + "copaper_checker_record", + "copaper_workflow_set_phase", ] as const const RELATEDWORK_WRITE_TOOL_PERMISSIONS = [ - "vibepaper_relatedwork_keywords", - "vibepaper_relatedwork_search", - "vibepaper_relatedwork_import", - "vibepaper_relatedwork_sync_bib", - "vibepaper_relatedwork_download", - "vibepaper_relatedwork_summarize", - "vibepaper_relatedwork_register_summary", - "vibepaper_relatedwork_build_index", - "vibepaper_relatedwork_clean", + "copaper_relatedwork_keywords", + "copaper_relatedwork_search", + "copaper_relatedwork_import", + "copaper_relatedwork_sync_bib", + "copaper_relatedwork_download", + "copaper_relatedwork_summarize", + "copaper_relatedwork_register_summary", + "copaper_relatedwork_build_index", + "copaper_relatedwork_clean", ] as const describe("permission profiles", () => { @@ -69,29 +69,29 @@ describe("permission profiles", () => { external_directory: "deny", task: "deny", skill: "deny", - vibepaper_dashboard: "allow", - vibepaper_artifact_status: "allow", - vibepaper_paper_structure_status: "allow", - vibepaper_storyline_structure_status: "allow", - vibepaper_pdf_extract: "allow", - vibepaper_ppt_extract: "allow", - vibepaper_checker_status: "allow", - vibepaper_relatedwork_status: "allow", - vibepaper_relatedwork_keywords: "deny", - vibepaper_relatedwork_search: "deny", - vibepaper_relatedwork_import: "deny", - vibepaper_relatedwork_sync_bib: "deny", - vibepaper_relatedwork_download: "deny", - vibepaper_relatedwork_summarize: "deny", - vibepaper_relatedwork_register_summary: "deny", - vibepaper_relatedwork_build_index: "deny", - vibepaper_relatedwork_clean: "deny", - vibepaper_workflow_status: "allow", - vibepaper_workflow_log: "allow", - vibepaper_init_apply: "deny", - vibepaper_artifact_record: "deny", - vibepaper_checker_record: "deny", - vibepaper_workflow_set_phase: "deny", + copaper_dashboard: "allow", + copaper_artifact_status: "allow", + copaper_paper_structure_status: "allow", + copaper_storyline_structure_status: "allow", + copaper_pdf_extract: "allow", + copaper_ppt_extract: "allow", + copaper_checker_status: "allow", + copaper_relatedwork_status: "allow", + copaper_relatedwork_keywords: "deny", + copaper_relatedwork_search: "deny", + copaper_relatedwork_import: "deny", + copaper_relatedwork_sync_bib: "deny", + copaper_relatedwork_download: "deny", + copaper_relatedwork_summarize: "deny", + copaper_relatedwork_register_summary: "deny", + copaper_relatedwork_build_index: "deny", + copaper_relatedwork_clean: "deny", + copaper_workflow_status: "allow", + copaper_workflow_log: "allow", + copaper_init_apply: "deny", + copaper_artifact_record: "deny", + copaper_checker_record: "deny", + copaper_workflow_set_phase: "deny", }) }) @@ -100,13 +100,13 @@ describe("permission profiles", () => { expect(profile.bash).toBe("deny") expect(profile.edit).toBe("deny") - expect(profile.vibepaper_relatedwork_status).toBe("allow") + expect(profile.copaper_relatedwork_status).toBe("allow") for (const permissionName of RELATEDWORK_WRITE_TOOL_PERMISSIONS) { expect(profile[permissionName]).toBe("ask") } - expect(profile.vibepaper_init_apply).toBe("deny") - expect(profile.vibepaper_workflow_set_phase).toBe("deny") - expect(profile.vibepaper_artifact_record).toBe("deny") + expect(profile.copaper_init_apply).toBe("deny") + expect(profile.copaper_workflow_set_phase).toBe("deny") + expect(profile.copaper_artifact_record).toBe("deny") }) test("non-literature profiles continue to deny relatedwork write tools", () => { @@ -133,7 +133,7 @@ describe("permission profiles", () => { }) }) - test("all profiles allow safe read-only VibePaper tools", () => { + test("all profiles allow safe read-only CoPaper tools", () => { for (const profileName of PERMISSION_PROFILE_NAMES) { const profile = getPermissionProfile(profileName) for (const permissionName of SAFE_READ_TOOL_PERMISSIONS) { @@ -142,7 +142,7 @@ describe("permission profiles", () => { } }) - test("non-recorder profiles deny VibePaper write and process tools", () => { + test("non-recorder profiles deny CoPaper write and process tools", () => { for (const profileName of ["readOnly", "storylineWrite", "paperWrite"] as const) { const profile = getPermissionProfile(profileName) for (const permissionName of WRITE_TOOL_PERMISSIONS) { @@ -175,10 +175,10 @@ describe("permission profiles", () => { expect(profile.edit).toBe("deny") expect(typeof profile.read).toBe("object") expect(profile.bash).toBe("deny") - expect(profile.vibepaper_artifact_record).toBe("ask") - expect(profile.vibepaper_checker_record).toBe("ask") - expect(profile.vibepaper_init_apply).toBe("deny") - expect(profile.vibepaper_workflow_set_phase).toBe("deny") + expect(profile.copaper_artifact_record).toBe("ask") + expect(profile.copaper_checker_record).toBe("ask") + expect(profile.copaper_init_apply).toBe("deny") + expect(profile.copaper_workflow_set_phase).toBe("deny") }) test("permission profile ordering only allows safe downgrades", () => { diff --git a/packages/opencode-plugin/tests/plugin.test.ts b/packages/opencode-plugin/tests/plugin.test.ts index ec5c95b..ac41896 100644 --- a/packages/opencode-plugin/tests/plugin.test.ts +++ b/packages/opencode-plugin/tests/plugin.test.ts @@ -1,10 +1,10 @@ import { describe, expect, test } from "bun:test" import type { ToolContext } from "@opencode-ai/plugin" import { existsSync, writeFileSync } from "node:fs" -import type { VibePaperAgentRuntimeState } from "../src/agent-config" -import { agentRuntimeToDoctorChecks, getLatestVibePaperAgentRuntimeState, setLatestVibePaperAgentRuntimeState } from "../src/agent-diagnostics" +import type { CoPaperAgentRuntimeState } from "../src/agent-config" +import { agentRuntimeToDoctorChecks, getLatestCoPaperAgentRuntimeState, setLatestCoPaperAgentRuntimeState } from "../src/agent-diagnostics" import { applyInitPlan, planInit } from "../src/installer" -import { VibePaperPlugin } from "../src/index" +import { CoPaperPlugin } from "../src/index" import { hashTree, makeTempProject } from "./fixtures" type PluginConfigInput = { @@ -14,7 +14,7 @@ type PluginConfigInput = { type PluginConfigHook = (input: PluginConfigInput) => void | PluginConfigInput | Promise<void | PluginConfigInput> async function buildHooks(root: string) { - return VibePaperPlugin({ + return CoPaperPlugin({ project: {}, directory: root, worktree: root, @@ -124,7 +124,7 @@ function makeZip(files: Record<string, string>): Buffer { } describe("OpenCode plugin", () => { - test("config hook injects VibePaper subagents into empty agent config", async () => { + test("config hook injects CoPaper subagents into empty agent config", async () => { const project = makeTempProject("plugin-config-empty-") try { const hooks = await buildHooks(project.root) @@ -133,12 +133,12 @@ describe("OpenCode plugin", () => { await configHook(hooks)(input) expect(Object.keys(input.agent ?? {})).toEqual([ - "vibepaper-coordinator", - "vibepaper-storyline", - "vibepaper-writer", - "vibepaper-reviewer", - "vibepaper-recorder", - "vibepaper-literature", + "copaper-coordinator", + "copaper-storyline", + "copaper-writer", + "copaper-reviewer", + "copaper-recorder", + "copaper-literature", ]) } finally { project.cleanup() @@ -154,14 +154,14 @@ describe("OpenCode plugin", () => { prompt: "Do not replace me.", permission: { read: "allow" }, } - const input: PluginConfigInput = { agent: { "vibepaper-writer": userAgent } } + const input: PluginConfigInput = { agent: { "copaper-writer": userAgent } } const hooks = await buildHooks(project.root) await configHook(hooks)(input) - expect(input.agent?.["vibepaper-writer"]).toBe(userAgent) - expect(input.agent?.["vibepaper-coordinator"]).toBeDefined() - expect(Object.keys(input.agent ?? {})).not.toContain("vibepaper-writer-copy") + expect(input.agent?.["copaper-writer"]).toBe(userAgent) + expect(input.agent?.["copaper-coordinator"]).toBeDefined() + expect(Object.keys(input.agent ?? {})).not.toContain("copaper-writer-copy") } finally { project.cleanup() } @@ -178,14 +178,14 @@ describe("OpenCode plugin", () => { await configure(input) expect(Object.keys(input.agent ?? {})).toEqual([ - "vibepaper-coordinator", - "vibepaper-storyline", - "vibepaper-writer", - "vibepaper-reviewer", - "vibepaper-recorder", - "vibepaper-literature", + "copaper-coordinator", + "copaper-storyline", + "copaper-writer", + "copaper-reviewer", + "copaper-recorder", + "copaper-literature", ]) - expect(getLatestVibePaperAgentRuntimeState(project.root).agents.every((agent) => agent.status !== "conflicted")).toBe(true) + expect(getLatestCoPaperAgentRuntimeState(project.root).agents.every((agent) => agent.status !== "conflicted")).toBe(true) } finally { project.cleanup() } @@ -200,11 +200,11 @@ describe("OpenCode plugin", () => { await configure(input) const userWriter = { prompt: "user writer" } - input.agent = { ...input.agent, "vibepaper-writer": userWriter } + input.agent = { ...input.agent, "copaper-writer": userWriter } await configure(input) - expect(input.agent?.["vibepaper-writer"]).toBe(userWriter) - expect(getLatestVibePaperAgentRuntimeState(project.root).agents.find((agent) => agent.name === "vibepaper-writer")?.status).toBe("conflicted") + expect(input.agent?.["copaper-writer"]).toBe(userWriter) + expect(getLatestCoPaperAgentRuntimeState(project.root).agents.find((agent) => agent.name === "copaper-writer")?.status).toBe("conflicted") } finally { project.cleanup() } @@ -214,24 +214,24 @@ describe("OpenCode plugin", () => { const firstProject = makeTempProject("runtime-state-first-") const secondProject = makeTempProject("runtime-state-second-") const missingProject = makeTempProject("runtime-state-missing-") - const firstRuntime: VibePaperAgentRuntimeState = { - agents: [{ name: "vibepaper-coordinator", status: "injected", description: "First root", permissionProfile: "readOnly", temperature: 0.2 }], + const firstRuntime: CoPaperAgentRuntimeState = { + agents: [{ name: "copaper-coordinator", status: "injected", description: "First root", permissionProfile: "readOnly", temperature: 0.2 }], diagnostics: [], } - const secondRuntime: VibePaperAgentRuntimeState = { - agents: [{ name: "vibepaper-writer", status: "disabled", description: "Second root", permissionProfile: "paperWrite", temperature: 0.4 }], + const secondRuntime: CoPaperAgentRuntimeState = { + agents: [{ name: "copaper-writer", status: "disabled", description: "Second root", permissionProfile: "paperWrite", temperature: 0.4 }], diagnostics: [], } try { - setLatestVibePaperAgentRuntimeState(firstRuntime, firstProject.root) - expect(getLatestVibePaperAgentRuntimeState(missingProject.root)).toEqual({ agents: [], diagnostics: [] }) + setLatestCoPaperAgentRuntimeState(firstRuntime, firstProject.root) + expect(getLatestCoPaperAgentRuntimeState(missingProject.root)).toEqual({ agents: [], diagnostics: [] }) - setLatestVibePaperAgentRuntimeState(secondRuntime, secondProject.root) + setLatestCoPaperAgentRuntimeState(secondRuntime, secondProject.root) - expect(getLatestVibePaperAgentRuntimeState(firstProject.root)).toBe(firstRuntime) - expect(getLatestVibePaperAgentRuntimeState(secondProject.root)).toBe(secondRuntime) - expect(getLatestVibePaperAgentRuntimeState()).toBe(secondRuntime) + expect(getLatestCoPaperAgentRuntimeState(firstProject.root)).toBe(firstRuntime) + expect(getLatestCoPaperAgentRuntimeState(secondProject.root)).toBe(secondRuntime) + expect(getLatestCoPaperAgentRuntimeState()).toBe(secondRuntime) } finally { firstProject.cleanup() secondProject.cleanup() @@ -242,9 +242,9 @@ describe("OpenCode plugin", () => { test("agent runtime maps to doctor checks and skips config missing", () => { const checks = agentRuntimeToDoctorChecks({ agents: [ - { name: "vibepaper-coordinator", status: "injected", description: "Coordinator", permissionProfile: "readOnly", temperature: 0.2 }, - { name: "vibepaper-storyline", status: "disabled", description: "Storyline", permissionProfile: "readOnly", temperature: 0.4 }, - { name: "vibepaper-writer", status: "conflicted", description: "Writer", permissionProfile: "paperWrite", temperature: 0.4 }, + { name: "copaper-coordinator", status: "injected", description: "Coordinator", permissionProfile: "readOnly", temperature: 0.2 }, + { name: "copaper-storyline", status: "disabled", description: "Storyline", permissionProfile: "readOnly", temperature: 0.4 }, + { name: "copaper-writer", status: "conflicted", description: "Writer", permissionProfile: "paperWrite", temperature: 0.4 }, ], diagnostics: [ { severity: "info", code: "config-missing", message: "Project config is missing; defaults are used." }, @@ -255,39 +255,39 @@ describe("OpenCode plugin", () => { expect(checks).toEqual([ { - id: "agents.vibepaper-coordinator", + id: "agents.copaper-coordinator", status: "pass", severity: "info", - message: "VibePaper agent \"vibepaper-coordinator\" is injected", + message: "CoPaper agent \"copaper-coordinator\" is injected", remediation: null, }, { - id: "agents.vibepaper-storyline", + id: "agents.copaper-storyline", status: "warn", severity: "warning", - message: "VibePaper agent \"vibepaper-storyline\" is disabled", - remediation: "Set agents.vibepaper-storyline.enabled to true in .opencode/vibepaper.json", + message: "CoPaper agent \"copaper-storyline\" is disabled", + remediation: "Set agents.copaper-storyline.enabled to true in .opencode/copaper.json", }, { - id: "agents.vibepaper-writer", + id: "agents.copaper-writer", status: "fail", severity: "warning", - message: "VibePaper agent \"vibepaper-writer\" conflicts with an existing OpenCode agent", - remediation: "Rename the existing agent or disable agents.vibepaper-writer in .opencode/vibepaper.json", + message: "CoPaper agent \"copaper-writer\" conflicts with an existing OpenCode agent", + remediation: "Rename the existing agent or disable agents.copaper-writer in .opencode/copaper.json", }, { id: "agent-config.unsupported-field.defaults.extra", status: "warn", severity: "warning", message: "Unsupported field is ignored.", - remediation: "Fix .opencode/vibepaper.json, then restart OpenCode", + remediation: "Fix .opencode/copaper.json, then restart OpenCode", }, { id: "agent-config.config-read-failed", status: "fail", severity: "error", message: "Project config could not be read.", - remediation: "Fix .opencode/vibepaper.json, then restart OpenCode", + remediation: "Fix .opencode/copaper.json, then restart OpenCode", }, ]) }) @@ -309,20 +309,20 @@ describe("OpenCode plugin", () => { test("registers dashboard init apply artifact checker and workflow tools", async () => { const hooks = await buildHooks(process.cwd()) - expect(hooks.tool.vibepaper_dashboard).toBeDefined() - expect(hooks.tool.vibepaper_init_apply).toBeDefined() - expect(hooks.tool.vibepaper_artifact_status).toBeDefined() - expect(hooks.tool.vibepaper_paper_structure_status).toBeDefined() - expect(hooks.tool.vibepaper_storyline_structure_status).toBeDefined() - expect(hooks.tool.vibepaper_pdf_extract).toBeDefined() - expect(hooks.tool.vibepaper_ppt_extract).toBeDefined() - expect(hooks.tool.vibepaper_checker_status).toBeDefined() - expect(hooks.tool.vibepaper_relatedwork_status).toBeDefined() - expect(hooks.tool.vibepaper_checker_record).toBeDefined() - expect(hooks.tool.vibepaper_artifact_record).toBeDefined() - expect(hooks.tool.vibepaper_workflow_status).toBeDefined() - expect(hooks.tool.vibepaper_workflow_log).toBeDefined() - expect(hooks.tool.vibepaper_workflow_set_phase).toBeDefined() + expect(hooks.tool.copaper_dashboard).toBeDefined() + expect(hooks.tool.copaper_init_apply).toBeDefined() + expect(hooks.tool.copaper_artifact_status).toBeDefined() + expect(hooks.tool.copaper_paper_structure_status).toBeDefined() + expect(hooks.tool.copaper_storyline_structure_status).toBeDefined() + expect(hooks.tool.copaper_pdf_extract).toBeDefined() + expect(hooks.tool.copaper_ppt_extract).toBeDefined() + expect(hooks.tool.copaper_checker_status).toBeDefined() + expect(hooks.tool.copaper_relatedwork_status).toBeDefined() + expect(hooks.tool.copaper_checker_record).toBeDefined() + expect(hooks.tool.copaper_artifact_record).toBeDefined() + expect(hooks.tool.copaper_workflow_status).toBeDefined() + expect(hooks.tool.copaper_workflow_log).toBeDefined() + expect(hooks.tool.copaper_workflow_set_phase).toBeDefined() }) test("init apply tool writes files when called with name and domain", async () => { @@ -332,9 +332,9 @@ describe("OpenCode plugin", () => { if (!plan.ok) throw new Error(plan.error) await applyInitPlan(plan) const hooks = await buildHooks(project.root) - const output = await (hooks.tool.vibepaper_init_apply as { execute(args: { name: string; domain: string }, context: ToolContext): Promise<string> }).execute({ name: "Demo Paper", domain: "software engineering" }, toolContext(project.root)) + const output = await (hooks.tool.copaper_init_apply as { execute(args: { name: string; domain: string }, context: ToolContext): Promise<string> }).execute({ name: "Demo Paper", domain: "software engineering" }, toolContext(project.root)) - expect(output).toContain("## VibePaper 初始化写入") + expect(output).toContain("## CoPaper 初始化写入") expect(output).toContain("paper.md") expect(JSON.parse(project.read(".agents/state.json")).project.name).toBe("Demo Paper") expect(JSON.parse(project.read(".agents/state.json")).project.domain).toBe("software engineering") @@ -348,7 +348,7 @@ describe("OpenCode plugin", () => { const runtimeProject = makeTempProject() try { const hooks = await buildHooks(capturedProject.root) - await (hooks.tool.vibepaper_init_apply as { execute(args: { name: string; domain: string }, context: ToolContext): Promise<string> }).execute( + await (hooks.tool.copaper_init_apply as { execute(args: { name: string; domain: string }, context: ToolContext): Promise<string> }).execute( { name: "Demo Paper", domain: "software engineering" }, toolContext(runtimeProject.root), ) @@ -368,7 +368,7 @@ describe("OpenCode plugin", () => { const runtimeProject = makeTempProject() try { const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_dashboard as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_dashboard as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).not.toContain(capturedProject.root) @@ -383,7 +383,7 @@ describe("OpenCode plugin", () => { const runtimeProject = makeTempProject() try { const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_artifact_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_artifact_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).toContain("storyline") @@ -401,7 +401,7 @@ describe("OpenCode plugin", () => { try { runtimeProject.write("paper.md", "# Runtime Paper\n## Intro\n##### Problem\n###### Runtime context\nA short paragraph.\n") const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_paper_structure_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_paper_structure_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).toContain("Problem") @@ -419,7 +419,7 @@ describe("OpenCode plugin", () => { try { runtimeProject.write("storyline.md", "# Storyline\n##### 问题描述\nConcrete problem.\n##### Insights\nTODO\n") const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_storyline_structure_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_storyline_structure_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).toContain("Insights") @@ -439,8 +439,8 @@ describe("OpenCode plugin", () => { writeFileSync(runtimeProject.path("slides.pptx"), makeTinyPptx()) const hooks = await buildHooks(capturedProject.root) - const pdfOutput = await (hooks.tool.vibepaper_pdf_extract as { execute(args: { path: string }, context: ToolContext): Promise<string> }).execute({ path: "draft.pdf" }, toolContext(runtimeProject.root)) - const pptOutput = await (hooks.tool.vibepaper_ppt_extract as { execute(args: { path: string }, context: ToolContext): Promise<string> }).execute({ path: "slides.pptx" }, toolContext(runtimeProject.root)) + const pdfOutput = await (hooks.tool.copaper_pdf_extract as { execute(args: { path: string }, context: ToolContext): Promise<string> }).execute({ path: "draft.pdf" }, toolContext(runtimeProject.root)) + const pptOutput = await (hooks.tool.copaper_ppt_extract as { execute(args: { path: string }, context: ToolContext): Promise<string> }).execute({ path: "slides.pptx" }, toolContext(runtimeProject.root)) expect(pdfOutput).toContain("Runtime PDF text") expect(pdfOutput).toContain(runtimeProject.root) @@ -470,7 +470,7 @@ describe("OpenCode plugin", () => { }, }, null, 2)}\n`) const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_checker_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_checker_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).toContain("problem-checker") @@ -501,7 +501,7 @@ describe("OpenCode plugin", () => { runtimeProject.write("relatedwork/pdfs/runtime2026paper.pdf", "%PDF-1.4\n") runtimeProject.write("relatedwork/papers/runtime2026paper.md", "# Runtime Related Work\n") const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_relatedwork_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const output = await (hooks.tool.copaper_relatedwork_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) expect(output).toContain(runtimeProject.root) expect(output).toContain("runtime2026paper") @@ -522,9 +522,9 @@ describe("OpenCode plugin", () => { runtimeProject.write(".agents/state.json", `${JSON.stringify(workflowState(), null, 2)}\n`) runtimeProject.write(".agents/events.jsonl", "") const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_artifact_record as { execute(args: { artifact: string; status: string; confidence: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( + const output = await (hooks.tool.copaper_artifact_record as { execute(args: { artifact: string; status: string; confidence: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( { artifact: "paper", status: "ready", confidence: "high", evidence: ["manual-review"], reason: "runtime root confirmed" }, - toolContext(runtimeProject.root, "vibepaper-recorder"), + toolContext(runtimeProject.root, "copaper-recorder"), ) expect(output).toContain(runtimeProject.root) @@ -546,9 +546,9 @@ describe("OpenCode plugin", () => { const beforeState = project.read(".agents/state.json") const hooks = await buildHooks(project.root) - const output = await (hooks.tool.vibepaper_artifact_record as { execute(args: { artifact: string; status: string; confidence: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( + const output = await (hooks.tool.copaper_artifact_record as { execute(args: { artifact: string; status: string; confidence: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( { artifact: "paper", status: "ready", confidence: "high", evidence: ["manual-review"], reason: "runtime root confirmed" }, - toolContext(project.root, "vibepaper-writer"), + toolContext(project.root, "copaper-writer"), ) expect(output).toContain("agent-not-authorized") @@ -566,9 +566,9 @@ describe("OpenCode plugin", () => { runtimeProject.write(".agents/state.json", `${JSON.stringify(workflowState(), null, 2)}\n`) runtimeProject.write(".agents/events.jsonl", "") const hooks = await buildHooks(capturedProject.root) - const output = await (hooks.tool.vibepaper_checker_record as { execute(args: { checker: string; status: string; critical: number; major: number; minor: number; summary: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( + const output = await (hooks.tool.copaper_checker_record as { execute(args: { checker: string; status: string; critical: number; major: number; minor: number; summary: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( { checker: "logic-checker", status: "issues_found", critical: 0, major: 1, minor: 0, summary: "One logic issue remains.", evidence: ["markdown-review-output"], reason: "runtime root confirmed" }, - toolContext(runtimeProject.root, "vibepaper-recorder"), + toolContext(runtimeProject.root, "copaper-recorder"), ) expect(output).toContain(runtimeProject.root) @@ -590,9 +590,9 @@ describe("OpenCode plugin", () => { const beforeState = project.read(".agents/state.json") const hooks = await buildHooks(project.root) - const output = await (hooks.tool.vibepaper_checker_record as { execute(args: { checker: string; status: string; critical: number; major: number; minor: number; summary: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( + const output = await (hooks.tool.copaper_checker_record as { execute(args: { checker: string; status: string; critical: number; major: number; minor: number; summary: string; evidence: string[]; reason: string }, context: ToolContext): Promise<string> }).execute( { checker: "logic-checker", status: "clean", critical: 0, major: 0, minor: 0, summary: "No logic issues.", evidence: ["markdown-review-output"], reason: "runtime root confirmed" }, - toolContext(project.root, "vibepaper-writer"), + toolContext(project.root, "copaper-writer"), ) expect(output).toContain("agent-not-authorized") @@ -611,8 +611,8 @@ describe("OpenCode plugin", () => { runtimeProject.write(".agents/events.jsonl", `${JSON.stringify({ timestamp: "2026-05-01T11:00:00.000Z", phase: "custom_phase", operator: "user", action: "create", result: "ok" })}\n`) const hooks = await buildHooks(capturedProject.root) - const statusOutput = await (hooks.tool.vibepaper_workflow_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) - const setPhaseOutput = await (hooks.tool.vibepaper_workflow_set_phase as { execute(args: { phase: string; status: string; reason?: string }, context: ToolContext): Promise<string> }).execute( + const statusOutput = await (hooks.tool.copaper_workflow_status as { execute(args: Record<string, never>, context: ToolContext): Promise<string> }).execute({}, toolContext(runtimeProject.root)) + const setPhaseOutput = await (hooks.tool.copaper_workflow_set_phase as { execute(args: { phase: string; status: string; reason?: string }, context: ToolContext): Promise<string> }).execute( { phase: "custom_phase", status: "in_progress" }, toolContext(runtimeProject.root), ) diff --git a/packages/opencode-plugin/tests/project-init.test.ts b/packages/opencode-plugin/tests/project-init.test.ts index 9bad415..c2985ee 100644 --- a/packages/opencode-plugin/tests/project-init.test.ts +++ b/packages/opencode-plugin/tests/project-init.test.ts @@ -116,9 +116,9 @@ describe("project init apply", () => { const result = await applyProjectInit({ root: project.root, name: "Demo Paper", domain: "software engineering", now: new Date("2026-05-01T10:00:00.000Z"), locale: "zh-CN" }) const markdown = renderProjectInitApplyOutput(result) - expect(markdown).toContain("## VibePaper 初始化写入") + expect(markdown).toContain("## CoPaper 初始化写入") expect(markdown).toContain("已写入") - expect(markdown).toContain("重新运行 `/vibe`") + expect(markdown).toContain("重新运行 `/copaper`") expect(markdown).toContain("```json") expect(markdown).toContain('"mode": "apply"') expect(markdown).toContain('"changedFiles"') diff --git a/packages/opencode-plugin/tests/project-templates.test.ts b/packages/opencode-plugin/tests/project-templates.test.ts index 3431d7c..71fd283 100644 --- a/packages/opencode-plugin/tests/project-templates.test.ts +++ b/packages/opencode-plugin/tests/project-templates.test.ts @@ -13,7 +13,7 @@ describe("project templates", () => { ".agents/state.json", ".agents/events.jsonl", ]) - expect(files.find((file) => file.path === "AGENTS.md")?.content).toContain("VibePaper") + expect(files.find((file) => file.path === "AGENTS.md")?.content).toContain("CoPaper") expect(files.find((file) => file.path === ".agents/events.jsonl")?.content).toBe("") expect(files.some((file) => file.path.startsWith(".agents/skills/"))).toBe(false) expect(files.some((file) => file.path.startsWith("relatedwork/"))).toBe(false) @@ -32,7 +32,7 @@ describe("project templates", () => { expect(Object.keys(state.phases)).toEqual(["storyline", "literature", "discussion", "experiments", "writing", "latex_review"]) expect(state.phases.storyline).toEqual({ status: "not_started", completed_at: null, metadata: {} }) expect(state.phases.literature.catalog_path).toBe("relatedwork/literature.json") - expect(state.git.identity.git_email).toBe("bot@vibepaper.dev") + expect(state.git.identity.git_email).toBe("bot@copaper.dev") expect(state.checkers).toEqual({}) }) }) diff --git a/packages/opencode-plugin/tests/python-bridge.test.ts b/packages/opencode-plugin/tests/python-bridge.test.ts index 393f34b..dd23641 100644 --- a/packages/opencode-plugin/tests/python-bridge.test.ts +++ b/packages/opencode-plugin/tests/python-bridge.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from "bun:test" import { resolveBridge, runBridge, type BridgeDeps, type SpawnFn, type SpawnResult } from "../src/python-bridge" -const ROOT = "/tmp/vibepaper-bridge-test" +const ROOT = "/tmp/copaper-bridge-test" function fakeNow(): { tick: () => number; reset: () => void } { let n = 0 @@ -18,13 +18,13 @@ function recordingSpawn(result: SpawnResult): { spawn: SpawnFn; calls: Array<{ c } describe("python-bridge", () => { - test("resolveBridge prefers .venv/bin/vibe when present", async () => { - const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/vibe", resolveUv: () => "/usr/bin/uv" } + test("resolveBridge prefers .venv/bin/copaper when present", async () => { + const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/copaper", resolveUv: () => "/usr/bin/uv" } const resolved = await resolveBridge(ROOT, deps) expect(resolved.ok).toBe(true) if (resolved.ok) { expect(resolved.resolution.kind).toBe("venv-bin") - expect(resolved.resolution.path).toBe("/venv/bin/vibe") + expect(resolved.resolution.path).toBe("/venv/bin/copaper") expect(resolved.resolution.args).toEqual([]) } }) @@ -36,27 +36,27 @@ describe("python-bridge", () => { if (resolved.ok) { expect(resolved.resolution.kind).toBe("uv-run") expect(resolved.resolution.path).toBe("/usr/bin/uv") - expect(resolved.resolution.args).toEqual(["run", "--project", ROOT, "vibe"]) + expect(resolved.resolution.args).toEqual(["run", "--project", ROOT, "copaper"]) } }) - test("resolveBridge fails with vibe-cli-unavailable when nothing found", async () => { + test("resolveBridge fails with copaper-cli-unavailable when nothing found", async () => { const deps: BridgeDeps = { resolveVenv: () => null, resolveUv: () => null } const resolved = await resolveBridge(ROOT, deps) expect(resolved.ok).toBe(false) if (!resolved.ok) { - expect(resolved.error.code).toBe("vibe-cli-unavailable") + expect(resolved.error.code).toBe("copaper-cli-unavailable") } }) test("runBridge spawns venv binary with --root and forwards args", async () => { const { spawn, calls } = recordingSpawn({ exitCode: 0, stdout: "hello\n", stderr: "", timedOut: false }) const clock = fakeNow() - const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/vibe", resolveUv: () => null, spawn, now: clock.tick } + const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/copaper", resolveUv: () => null, spawn, now: clock.tick } const result = await runBridge({ root: ROOT, args: ["relatedwork", "status", "--json"] }, deps) expect(result.ok).toBe(true) expect(calls.length).toBe(1) - expect(calls[0].command).toEqual(["/venv/bin/vibe", "--root", ROOT, "relatedwork", "status", "--json"]) + expect(calls[0].command).toEqual(["/venv/bin/copaper", "--root", ROOT, "relatedwork", "status", "--json"]) expect(calls[0].cwd).toBe(ROOT) if (result.ok) { expect(result.command).toContain("relatedwork status --json") @@ -70,16 +70,16 @@ describe("python-bridge", () => { const { spawn, calls } = recordingSpawn({ exitCode: 0, stdout: "", stderr: "", timedOut: false }) const deps: BridgeDeps = { resolveVenv: () => null, resolveUv: () => "/usr/bin/uv", spawn, now: fakeNow().tick } await runBridge({ root: ROOT, args: ["relatedwork", "keywords"] }, deps) - expect(calls[0].command).toEqual(["/usr/bin/uv", "run", "--project", ROOT, "vibe", "--root", ROOT, "relatedwork", "keywords"]) + expect(calls[0].command).toEqual(["/usr/bin/uv", "run", "--project", ROOT, "copaper", "--root", ROOT, "relatedwork", "keywords"]) }) test("runBridge surfaces non-zero exit", async () => { const { spawn } = recordingSpawn({ exitCode: 2, stdout: "", stderr: "boom\n", timedOut: false }) - const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/vibe", resolveUv: () => null, spawn, now: fakeNow().tick } + const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/copaper", resolveUv: () => null, spawn, now: fakeNow().tick } const result = await runBridge({ root: ROOT, args: ["relatedwork", "import"] }, deps) expect(result.ok).toBe(false) if (!result.ok) { - expect(result.error.code).toBe("vibe-nonzero-exit") + expect(result.error.code).toBe("copaper-nonzero-exit") expect(result.stderr).toBe("boom\n") expect(result.exitCode).toBe(2) } @@ -87,7 +87,7 @@ describe("python-bridge", () => { test("runBridge surfaces bridge-timeout when spawn reports timedOut", async () => { const { spawn } = recordingSpawn({ exitCode: null, stdout: "", stderr: "", timedOut: true }) - const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/vibe", resolveUv: () => null, spawn, now: fakeNow().tick } + const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/copaper", resolveUv: () => null, spawn, now: fakeNow().tick } const result = await runBridge({ root: ROOT, args: ["relatedwork", "download"], timeoutMs: 1_000 }, deps) expect(result.ok).toBe(false) if (!result.ok) { @@ -99,7 +99,7 @@ describe("python-bridge", () => { const spawn: SpawnFn = async () => { throw new Error("EACCES") } - const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/vibe", resolveUv: () => null, spawn, now: fakeNow().tick } + const deps: BridgeDeps = { resolveVenv: () => "/venv/bin/copaper", resolveUv: () => null, spawn, now: fakeNow().tick } const result = await runBridge({ root: ROOT, args: ["relatedwork", "status"] }, deps) expect(result.ok).toBe(false) if (!result.ok) { @@ -108,7 +108,7 @@ describe("python-bridge", () => { } }) - test("runBridge returns vibe-cli-unavailable without spawning when resolution fails", async () => { + test("runBridge returns copaper-cli-unavailable without spawning when resolution fails", async () => { let invoked = false const spawn: SpawnFn = async () => { invoked = true @@ -118,6 +118,6 @@ describe("python-bridge", () => { const result = await runBridge({ root: ROOT, args: ["relatedwork", "status"] }, deps) expect(invoked).toBe(false) expect(result.ok).toBe(false) - if (!result.ok) expect(result.error.code).toBe("vibe-cli-unavailable") + if (!result.ok) expect(result.error.code).toBe("copaper-cli-unavailable") }) }) diff --git a/packages/opencode-plugin/tests/readiness.test.ts b/packages/opencode-plugin/tests/readiness.test.ts index cf5c38d..2e895f7 100644 --- a/packages/opencode-plugin/tests/readiness.test.ts +++ b/packages/opencode-plugin/tests/readiness.test.ts @@ -26,7 +26,7 @@ describe("readiness", () => { project.write("writingrules.md", "# Rules\n") project.write(".agents/state.json", "{}\n") project.write(".agents/events.jsonl", "") - project.write("AGENTS.md", "# VibePaper project guide\n") + project.write("AGENTS.md", "# CoPaper project guide\n") const result = inspectReadiness(project.root) expect(result.ok).toBe(true) diff --git a/packages/opencode-plugin/tests/relatedwork-status.test.ts b/packages/opencode-plugin/tests/relatedwork-status.test.ts index 7df3882..ad376a1 100644 --- a/packages/opencode-plugin/tests/relatedwork-status.test.ts +++ b/packages/opencode-plugin/tests/relatedwork-status.test.ts @@ -72,7 +72,7 @@ describe("relatedwork status", () => { }) expect(result.papers.find((paper) => paper.paperId === "smith2026runtime")?.pdfExists).toBe(true) expect(result.papers.find((paper) => paper.paperId === "smith2026runtime")?.summaryExists).toBe(true) - expect(markdown).toContain("## VibePaper 相关工作状态") + expect(markdown).toContain("## CoPaper 相关工作状态") expect(markdown).toContain("smith2026runtime") expect(hashTree(project.root)).toBe(before) }) diff --git a/packages/opencode-plugin/tests/relatedwork-tools.test.ts b/packages/opencode-plugin/tests/relatedwork-tools.test.ts index 3ba554a..283bca9 100644 --- a/packages/opencode-plugin/tests/relatedwork-tools.test.ts +++ b/packages/opencode-plugin/tests/relatedwork-tools.test.ts @@ -31,7 +31,7 @@ function recordingSpawn(result: SpawnResult): { spawn: SpawnFn; calls: SpawnCall return { spawn, calls } } -const VENV_PATH = "/fake/.venv/bin/vibe" +const VENV_PATH = "/fake/.venv/bin/copaper" function commandTail(call: SpawnCall, length: number): string[] { return call.command.slice(-length) @@ -217,24 +217,24 @@ describe("relatedwork tools", () => { expect(commandTail(calls[0], 2)).toEqual(["relatedwork", "sync-bib"]) }) - test("vibe-cli-unavailable surfaces without phase patch", async () => { + test("copaper-cli-unavailable surfaces without phase patch", async () => { const result = await runRelatedworkSyncBib( { root: project.root }, { spawn: async () => ({ exitCode: 0, stdout: "", stderr: "", timedOut: false }), resolveVenv: () => null, resolveUv: () => null }, ) expect(result.ok).toBe(false) - expect(result.errors[0]?.code).toBe("vibe-cli-unavailable") + expect(result.errors[0]?.code).toBe("copaper-cli-unavailable") expect(result.phasePatch?.ok).toBe(true) // status refreshed and patch attempted (idempotent zeros) }) - test("non-zero exit surfaces vibe-nonzero-exit and still refreshes status", async () => { + test("non-zero exit surfaces copaper-nonzero-exit and still refreshes status", async () => { const { spawn } = recordingSpawn({ exitCode: 1, stdout: "", stderr: "no network\n", timedOut: false }) const result = await runRelatedworkDownload( { root: project.root }, { spawn, resolveVenv: () => VENV_PATH, resolveUv: () => null }, ) expect(result.ok).toBe(false) - expect(result.errors[0]?.code).toBe("vibe-nonzero-exit") + expect(result.errors[0]?.code).toBe("copaper-nonzero-exit") expect(result.stderr).toContain("no network") expect(result.statusAfter?.ok).toBe(true) }) @@ -303,7 +303,7 @@ describe("relatedwork tools", () => { { spawn, resolveVenv: () => VENV_PATH, resolveUv: () => null }, ) const rendered = renderRelatedworkToolOutput(result) - expect(rendered).toContain("vibepaper_relatedwork_import") + expect(rendered).toContain("copaper_relatedwork_import") expect(rendered).toContain("imported") expect(rendered).toContain("papers=2") expect(rendered).toContain("```json") diff --git a/packages/opencode-plugin/tests/root.test.ts b/packages/opencode-plugin/tests/root.test.ts index ef957fe..1ee4976 100644 --- a/packages/opencode-plugin/tests/root.test.ts +++ b/packages/opencode-plugin/tests/root.test.ts @@ -56,16 +56,16 @@ describe("detectRoot", () => { mkdirSync(project.path("repo", "sub", "deep"), { recursive: true }) mkdirSync(project.path("repo", "sub", ".opencode", "commands"), { recursive: true }) writeFileSync(project.path("repo", "opencode.json"), "{}") - writeFileSync(project.path("repo", "sub", ".opencode", "commands", "vibe.md"), `${commandMarker("vibe")}\n`) + writeFileSync(project.path("repo", "sub", ".opencode", "commands", "copaper.md"), `${commandMarker("copaper")}\n`) const result = await detectRoot({ cwd: project.path("repo", "sub", "deep") }) expect(result.root).toBe(project.path("repo", "sub")) - expect(result.reason).toBe("found VibePaper command marker") + expect(result.reason).toBe("found CoPaper command marker") }) test("malformed marker does not block ancestor opencode json", async () => { const project = temp() mkdirSync(project.path("repo", "sub", "deep"), { recursive: true }) - mkdirSync(project.path("repo", "sub", ".opencode", "commands", "vibe.md"), { recursive: true }) + mkdirSync(project.path("repo", "sub", ".opencode", "commands", "copaper.md"), { recursive: true }) writeFileSync(project.path("repo", "opencode.json"), "{}") const result = await detectRoot({ cwd: project.path("repo", "sub", "deep") }) expect(result.root).toBe(project.path("repo")) @@ -82,13 +82,13 @@ describe("detectRoot", () => { expect(result.reason).toBe("found opencode.json") }) - test("managed vibe command marker can identify root", async () => { + test("managed copaper command marker can identify root", async () => { const project = temp() mkdirSync(project.path("paper", ".opencode", "commands", "nested"), { recursive: true }) - writeFileSync(project.path("paper", ".opencode", "commands", "vibe.md"), `${commandMarker("vibe")}\n`) + writeFileSync(project.path("paper", ".opencode", "commands", "copaper.md"), `${commandMarker("copaper")}\n`) const result = await detectRoot({ cwd: project.path("paper", ".opencode", "commands", "nested") }) expect(result.root).toBe(project.path("paper")) - expect(result.reason).toBe("found VibePaper command marker") + expect(result.reason).toBe("found CoPaper command marker") }) test("falls back to worktree when no config marker exists", async () => { diff --git a/packages/opencode-plugin/tests/workflow.test.ts b/packages/opencode-plugin/tests/workflow.test.ts index b9c5311..7d7fcf2 100644 --- a/packages/opencode-plugin/tests/workflow.test.ts +++ b/packages/opencode-plugin/tests/workflow.test.ts @@ -73,7 +73,7 @@ describe("workflow", () => { discussion_evidence_mapping: ["discussion_problem_framing"], }) expect(result.warnings).toEqual([]) - expect(markdown).toContain("## VibePaper 工作流状态") + expect(markdown).toContain("## CoPaper 工作流状态") expect(markdown).toContain("discussion_problem_framing") expect(markdown).toContain("```json") expect(hashTree(project.root)).toBe(before) @@ -111,7 +111,7 @@ describe("workflow", () => { expect(result.events[0]?.operator).toBe("user") expect(result.skippedMalformed).toBe(1) expect(result.warnings).toContain("malformed-events-skipped") - expect(markdown).toContain("## VibePaper 工作流日志") + expect(markdown).toContain("## CoPaper 工作流日志") expect(markdown).toContain("discussion_problem_framing") expect(markdown).toContain("```json") }) @@ -284,7 +284,7 @@ describe("workflow", () => { const result = await setWorkflowPhase({ root: project.root, locale: "zh-CN", phase: "discussion_problem_framing", status: "complete", now: new Date("2026-05-01T19:00:00.000Z") }) const markdown = renderWorkflowSetPhaseOutput(result) - expect(markdown).toContain("## VibePaper 阶段状态更新") + expect(markdown).toContain("## CoPaper 阶段状态更新") expect(markdown).toContain("discussion_problem_framing") expect(markdown).toContain("complete") expect(markdown).toContain('"eventAppended": true') diff --git a/pyproject.toml b/pyproject.toml index 2c663fd..8a373db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,14 +3,14 @@ requires = ["setuptools>=68.0", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "vibepaper" +name = "copaper" version = "0.1.0" description = "AI-assisted academic writing framework with structured phase management" readme = "README.md" requires-python = ">=3.10" license = {text = "MIT"} authors = [ - {name = "VibePaper Team"}, + {name = "CoPaper Team"}, ] dependencies = [ "click>=8.0", @@ -27,17 +27,17 @@ dev = [ ] [project.scripts] -vibe = "vibepaper.cli:main" +copaper = "copaper.cli:main" [tool.setuptools.packages.find] -include = ["vibepaper*"] +include = ["copaper*"] [tool.setuptools.package-data] -vibepaper = ["scaffold/**/*", "scaffold/*"] +copaper = ["scaffold/**/*", "scaffold/*"] [tool.pytest.ini_options] testpaths = ["tests"] markers = [ "integration: marks tests as integration tests", "slow: marks tests as slow", -] \ No newline at end of file +] diff --git a/scripts/download_relatedwork_pdfs.py b/scripts/download_relatedwork_pdfs.py index 3d676a7..5f64c12 100644 --- a/scripts/download_relatedwork_pdfs.py +++ b/scripts/download_relatedwork_pdfs.py @@ -1,6 +1,6 @@ """Standalone wrapper for related-work PDF downloads.""" -from vibepaper.relatedwork_download import main +from copaper.relatedwork_download import main if __name__ == "__main__": diff --git a/tests/acceptance_checklist.md b/tests/acceptance_checklist.md index 96fc855..f696c7e 100644 --- a/tests/acceptance_checklist.md +++ b/tests/acceptance_checklist.md @@ -1,6 +1,6 @@ -# VibePaper Acceptance Checklist +# CoPaper Acceptance Checklist -Manual verification steps for each Phase of the VibePaper workflow. +Manual verification steps for each Phase of the CoPaper workflow. ## Phase A: Storyline (storyline-helper) @@ -47,18 +47,18 @@ Manual verification steps for each Phase of the VibePaper workflow. ## CLI Workflow -- [ ] `vibe init "My Paper" --domain SE` — creates project -- [ ] `vibe status` — shows all phases -- [ ] `vibe status --json` — outputs valid JSON -- [ ] `vibe commit storyline -m "draft"` — creates git commit -- [ ] `vibe log` — shows event entries -- [ ] `vibe log --phase storyline` — filters by phase -- [ ] `vibe rollback storyline` — resets phase -- [ ] `vibe report` — generates weekly report -- [ ] `vibe report --since 2024-01-01` — filters by date -- [ ] `vibe report --output report.md` — writes to file -- [ ] `vibe diff storyline literature` — shows phase diff -- [ ] `vibe skip literature --reason "not needed"` — skips phase +- [ ] `copaper init "My Paper" --domain SE` — creates project +- [ ] `copaper status` — shows all phases +- [ ] `copaper status --json` — outputs valid JSON +- [ ] `copaper commit storyline -m "draft"` — creates git commit +- [ ] `copaper log` — shows event entries +- [ ] `copaper log --phase storyline` — filters by phase +- [ ] `copaper rollback storyline` — resets phase +- [ ] `copaper report` — generates weekly report +- [ ] `copaper report --since 2024-01-01` — filters by date +- [ ] `copaper report --output report.md` — writes to file +- [ ] `copaper diff storyline literature` — shows phase diff +- [ ] `copaper skip literature --reason "not needed"` — skips phase ## Git Integration diff --git a/tests/conftest.py b/tests/conftest.py index 37dc9df..e2fcc6b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -"""Shared pytest fixtures for VibePaper test suite.""" +"""Shared pytest fixtures for CoPaper test suite.""" from __future__ import annotations @@ -8,14 +8,14 @@ import pytest -from vibepaper.schema import DEFAULT_STATE +from copaper.schema import DEFAULT_STATE @pytest.fixture def tmp_project_dir(tmp_path: Path) -> Path: """Create a temporary directory with .agents/ subdirectory. - Mimics the minimal VibePaper project structure needed for tests. + Mimics the minimal CoPaper project structure needed for tests. """ agents_dir = tmp_path / ".agents" agents_dir.mkdir() diff --git a/tests/test_checker_integration.py b/tests/test_checker_integration.py index 4be4120..b47430d 100644 --- a/tests/test_checker_integration.py +++ b/tests/test_checker_integration.py @@ -7,7 +7,7 @@ import pytest -from vibepaper.checker_integration import ( +from copaper.checker_integration import ( CHECKER_NAMES, CheckerHarness, CheckerTracker, diff --git a/tests/test_checker_main.py b/tests/test_checker_main.py index e46e0e5..fe22769 100644 --- a/tests/test_checker_main.py +++ b/tests/test_checker_main.py @@ -1,8 +1,8 @@ -"""Tests for vibepaper.checker_integration and vibepaper.__main__.""" +"""Tests for copaper.checker_integration and copaper.__main__.""" from __future__ import annotations -from vibepaper.checker_integration import run_checkers, format_checker_results +from copaper.checker_integration import run_checkers, format_checker_results class TestCheckerIntegration: @@ -21,4 +21,4 @@ def test_format_checker_results_callable(self) -> None: class TestMainEntryPoint: def test_main_module_importable(self) -> None: - import vibepaper.__main__ # noqa: F401 + import copaper.__main__ # noqa: F401 diff --git a/tests/test_cli.py b/tests/test_cli.py index fac69ac..9e5e79f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.cli module (Task 6).""" +"""Tests for copaper.cli module (Task 6).""" from __future__ import annotations @@ -7,7 +7,7 @@ from click.testing import CliRunner, Result -from vibepaper.cli import main +from copaper.cli import main def _invoke(runner: CliRunner, args: list[str]) -> Result: @@ -16,7 +16,7 @@ def _invoke(runner: CliRunner, args: list[str]) -> Result: class TestInit: - """Tests for the 'vibe init' command.""" + """Tests for the 'copaper init' command.""" def test_init_creates_project(self, tmp_path: Path) -> None: runner = CliRunner() @@ -48,7 +48,7 @@ def test_init_scaffolds_skills_storyline_and_paper(self, tmp_path: Path) -> None assert (skills_dir / "AGENTS.md").exists() assert (skills_dir / "storyline-helper").is_dir() assert (skills_dir / "markdown-helper").is_dir() - assert (skills_dir / "vibepaper-manage").is_dir() + assert (skills_dir / "copaper-manage").is_dir() assert (tmp_path / "storyline.md").exists() assert (tmp_path / "paper.md").exists() @@ -87,7 +87,7 @@ def test_init_creates_event_log(self, tmp_path: Path) -> None: class TestStatus: - """Tests for the 'vibe status' command.""" + """Tests for the 'copaper status' command.""" def test_status_shows_phases(self, tmp_path: Path) -> None: runner = CliRunner() @@ -155,7 +155,7 @@ def test_status_no_project_shows_error(self, tmp_path: Path) -> None: assert result.exit_code != 0 assert ( "No project found" in result.output - or "Run 'vibe init' first" in result.output + or "Run 'copaper init' first" in result.output ) @@ -213,7 +213,7 @@ def test_checkers_status_json(self, tmp_path: Path) -> None: class TestSkip: - """Tests for the 'vibe skip' command.""" + """Tests for the 'copaper skip' command.""" def test_skip_phase_updates_state(self, tmp_path: Path) -> None: runner = CliRunner() @@ -265,7 +265,7 @@ def test_skip_phase_updates_current_phase(self, tmp_path: Path) -> None: class TestSetPhase: - """Tests for the 'vibe set-phase' command.""" + """Tests for the 'copaper set-phase' command.""" def test_set_phase_complete_advances_current_phase(self, tmp_path: Path) -> None: runner = CliRunner() @@ -309,7 +309,7 @@ def test_set_phase_warns_on_unmet_dependencies(self, tmp_path: Path) -> None: class TestLog: - """Tests for the 'vibe log' command.""" + """Tests for the 'copaper log' command.""" def test_log_shows_entries(self, tmp_path: Path) -> None: runner = CliRunner() @@ -329,7 +329,7 @@ def test_log_empty(self, tmp_path: Path) -> None: class TestCommit: - """Tests for the 'vibe commit' command.""" + """Tests for the 'copaper commit' command.""" def test_commit_creates_phase_commit(self, tmp_path: Path) -> None: import git @@ -399,7 +399,7 @@ def test_commit_auto_detects_recomputed_current_phase(self, tmp_path: Path) -> N class TestRollback: - """Tests for the 'vibe rollback' command.""" + """Tests for the 'copaper rollback' command.""" def test_rollback_to_phase(self, tmp_path: Path) -> None: import git @@ -469,10 +469,10 @@ def test_rollback_resets_phase_state(self, tmp_path: Path) -> None: class TestReport: - """Tests for the 'vibe report' command.""" + """Tests for the 'copaper report' command.""" def test_report_generates_output(self, tmp_path: Path) -> None: - """Test that 'vibe report' generates markdown output.""" + """Test that 'copaper report' generates markdown output.""" runner = CliRunner() _ = _invoke( runner, @@ -514,7 +514,7 @@ def test_report_output_to_file(self, tmp_path: Path) -> None: class TestDiff: - """Tests for the 'vibe diff' command.""" + """Tests for the 'copaper diff' command.""" def test_diff_no_git_repo(self, tmp_path: Path) -> None: """Test diff command when no git repo exists.""" @@ -537,7 +537,7 @@ def test_diff_no_git_repo(self, tmp_path: Path) -> None: class TestRelatedwork: - """Tests for the 'vibe relatedwork' command group.""" + """Tests for the 'copaper relatedwork' command group.""" def test_relatedwork_import_updates_catalog_and_state(self, tmp_path: Path) -> None: runner = CliRunner() diff --git a/tests/test_crossindex.py b/tests/test_crossindex.py index 65ddbc7..27d3e24 100644 --- a/tests/test_crossindex.py +++ b/tests/test_crossindex.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.crossindex module (Task 7).""" +"""Tests for copaper.crossindex module (Task 7).""" from __future__ import annotations @@ -7,7 +7,7 @@ import pytest -from vibepaper.crossindex import CrossIndex +from copaper.crossindex import CrossIndex class TestAddPaperAndQuery: diff --git a/tests/test_dimensions.py b/tests/test_dimensions.py index 86b9035..fff9a5d 100644 --- a/tests/test_dimensions.py +++ b/tests/test_dimensions.py @@ -1,8 +1,8 @@ -"""Tests for vibepaper.dimensions module.""" +"""Tests for copaper.dimensions module.""" from __future__ import annotations -from vibepaper.dimensions import DimensionRegistry, QuestionType +from copaper.dimensions import DimensionRegistry, QuestionType class TestDimensionRegistry: diff --git a/tests/test_eventlog.py b/tests/test_eventlog.py index 8aa98ed..ea31765 100644 --- a/tests/test_eventlog.py +++ b/tests/test_eventlog.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.eventlog module (Task 5).""" +"""Tests for copaper.eventlog module (Task 5).""" from __future__ import annotations @@ -9,7 +9,7 @@ import pytest -from vibepaper.eventlog import EventLogger +from copaper.eventlog import EventLogger class TestLogCreatesValidJsonl: @@ -128,7 +128,7 @@ def test_log_rotation_at_10mb(self, tmp_project_dir: Path) -> None: logger = EventLogger(str(log_path)) # Use a small rotation threshold so the test runs fast - with patch("vibepaper.eventlog._MAX_LOG_SIZE", 500): + with patch("copaper.eventlog._MAX_LOG_SIZE", 500): # Write enough events to exceed 500 bytes for i in range(50): logger.log(action=f"bulk_{i}", operator="system", result="success") diff --git a/tests/test_git_ops.py b/tests/test_git_ops.py index ee86e08..2f5191a 100644 --- a/tests/test_git_ops.py +++ b/tests/test_git_ops.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.git_ops module (Task 8).""" +"""Tests for copaper.git_ops module (Task 8).""" from __future__ import annotations @@ -7,8 +7,8 @@ import git import pytest -from vibepaper.eventlog import EventLogger -from vibepaper.git_ops import GitManager +from copaper.eventlog import EventLogger +from copaper.git_ops import GitManager def _init_repo(tmp_path: Path) -> git.Repo: @@ -30,7 +30,7 @@ def test_commit_contains_phase_prefix_and_coauthor(self, tmp_path: Path): sha = gm.commit_phase("storyline", "add insight section") commit = gm.repo.commit(sha) assert commit.message.startswith("[storyline]") - assert "Co-authored-by: VibePaper AI <ai@vibepaper>" in commit.message + assert "Co-authored-by: CoPaper AI <ai@copaper>" in commit.message assert "add insight section" in commit.message diff --git a/tests/test_identity.py b/tests/test_identity.py index aa5d0cc..ef4247b 100644 --- a/tests/test_identity.py +++ b/tests/test_identity.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.identity module (Task 15).""" +"""Tests for copaper.identity module (Task 15).""" from __future__ import annotations @@ -7,7 +7,7 @@ import git import pytest -from vibepaper.identity import IdentityManager +from copaper.identity import IdentityManager class TestDetectFromGit: diff --git a/tests/test_literature.py b/tests/test_literature.py index 3ba1c66..f158ef6 100644 --- a/tests/test_literature.py +++ b/tests/test_literature.py @@ -5,8 +5,8 @@ import io from pathlib import Path -from vibepaper.literature import LiteratureCatalog, extract_bibtex_key -from vibepaper.relatedwork_download import download_papers, validate_pdf_file +from copaper.literature import LiteratureCatalog, extract_bibtex_key +from copaper.relatedwork_download import download_papers, validate_pdf_file class TestLiteratureCatalog: @@ -137,7 +137,7 @@ def test_validate_pdf_file_rejects_html(self, tmp_path: Path) -> None: def test_download_papers_marks_downloaded( self, tmp_path: Path, monkeypatch ) -> None: - from vibepaper import relatedwork_download + from copaper import relatedwork_download pdf_bytes = b"%PDF-1.4\n1 0 obj\n<<>>\nendobj\n%%EOF" monkeypatch.setattr( diff --git a/tests/test_relatedwork_clean.py b/tests/test_relatedwork_clean.py index d087476..3f0a7d1 100644 --- a/tests/test_relatedwork_clean.py +++ b/tests/test_relatedwork_clean.py @@ -1,4 +1,4 @@ -"""Tests for `vibe relatedwork clean`.""" +"""Tests for `copaper relatedwork clean`.""" from __future__ import annotations @@ -8,10 +8,10 @@ import pytest from click.testing import CliRunner -from vibepaper import relatedwork_clean -from vibepaper.cli import main as cli_main -from vibepaper.literature import LiteratureCatalog -from vibepaper.relatedwork_clean import ( +from copaper import relatedwork_clean +from copaper.cli import main as cli_main +from copaper.literature import LiteratureCatalog +from copaper.relatedwork_clean import ( CleanOutcome, clean_relatedwork, plan_targets, diff --git a/tests/test_relatedwork_llm.py b/tests/test_relatedwork_llm.py index a589826..60e3d0f 100644 --- a/tests/test_relatedwork_llm.py +++ b/tests/test_relatedwork_llm.py @@ -11,10 +11,10 @@ import pytest from click.testing import CliRunner -from vibepaper import relatedwork_keywords, relatedwork_summarize -from vibepaper.cli import main as cli_main -from vibepaper.literature import LiteratureCatalog -from vibepaper.llm_client import ( +from copaper import relatedwork_keywords, relatedwork_summarize +from copaper.cli import main as cli_main +from copaper.literature import LiteratureCatalog +from copaper.llm_client import ( LLMConfigError, TokenBucket, resolve_api_key, @@ -78,15 +78,15 @@ def _respond(_kwargs: dict[str, Any]) -> str: class TestLLMResolvers: def test_resolve_model_uses_env(self, monkeypatch) -> None: - monkeypatch.setenv("VIBEPAPER_MODEL", "gpt-4o-mini") + monkeypatch.setenv("COPAPER_MODEL", "gpt-4o-mini") assert resolve_model() == "gpt-4o-mini" def test_resolve_model_explicit_overrides_env(self, monkeypatch) -> None: - monkeypatch.setenv("VIBEPAPER_MODEL", "gpt-4o-mini") + monkeypatch.setenv("COPAPER_MODEL", "gpt-4o-mini") assert resolve_model("custom-model") == "custom-model" def test_resolve_model_missing_raises(self, monkeypatch) -> None: - monkeypatch.delenv("VIBEPAPER_MODEL", raising=False) + monkeypatch.delenv("COPAPER_MODEL", raising=False) with pytest.raises(LLMConfigError): resolve_model() @@ -166,7 +166,7 @@ def test_writes_queries_to_file( encoding="utf-8", ) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") responder = _make_responder( "streaming vision language action\n" @@ -198,7 +198,7 @@ def test_falls_back_to_paper_md( ) -> None: (tmp_path / "paper.md").write_text("# Draft\n\nIntro.\n", encoding="utf-8") monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") client = FakeOpenAIClient(_make_responder("only one query\n")) outcome = relatedwork_keywords.extract_keywords( @@ -211,7 +211,7 @@ def test_raises_when_model_returns_empty( ) -> None: (tmp_path / "storyline.md").write_text("something\n", encoding="utf-8") monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") client = FakeOpenAIClient(_make_responder(" \n \n")) with pytest.raises(LLMConfigError): @@ -304,7 +304,7 @@ def test_writes_summary_and_registers( _seed_catalog_with_paper(tmp_path) _seed_storyline_and_template(tmp_path) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") client = FakeOpenAIClient( _make_responder("# Demo Paper\n\n## 1. 文献核心\nFake summary body.\n") @@ -335,7 +335,7 @@ def test_skips_already_summarized_without_force( _seed_catalog_with_paper(tmp_path) _seed_storyline_and_template(tmp_path) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") existing = tmp_path / "relatedwork" / "papers" / "demo2025paper.md" existing.parent.mkdir(parents=True, exist_ok=True) @@ -360,7 +360,7 @@ def test_force_resummarizes(self, tmp_path: Path, monkeypatch) -> None: _seed_catalog_with_paper(tmp_path) _seed_storyline_and_template(tmp_path) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") existing = tmp_path / "relatedwork" / "papers" / "demo2025paper.md" existing.parent.mkdir(parents=True, exist_ok=True) @@ -393,7 +393,7 @@ def test_oversized_pdf_marked_failed( _seed_catalog_with_paper(tmp_path) _seed_storyline_and_template(tmp_path) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") client = FakeOpenAIClient(_make_responder("should not be called")) @@ -416,7 +416,7 @@ def test_paper_id_filter(self, tmp_path: Path, monkeypatch) -> None: _seed_catalog_with_paper(tmp_path, paper_id="beta") _seed_storyline_and_template(tmp_path) monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") client = FakeOpenAIClient(_make_responder("# Only Beta\nBody.")) @@ -455,13 +455,13 @@ def test_keywords_command_missing_model_errors( ) (tmp_path / "storyline.md").write_text("text\n", encoding="utf-8") monkeypatch.setenv("OPENAI_API_KEY", "test-key") - monkeypatch.delenv("VIBEPAPER_MODEL", raising=False) + monkeypatch.delenv("COPAPER_MODEL", raising=False) result = _invoke( runner, ["--root", str(tmp_path), "relatedwork", "keywords"] ) assert result.exit_code != 0 - assert "VIBEPAPER_MODEL" in result.output + assert "COPAPER_MODEL" in result.output def test_summarize_command_missing_api_key_errors( self, tmp_path: Path, monkeypatch @@ -475,7 +475,7 @@ def test_summarize_command_missing_api_key_errors( _seed_catalog_with_paper(tmp_path) _seed_storyline_and_template(tmp_path) monkeypatch.delenv("OPENAI_API_KEY", raising=False) - monkeypatch.setenv("VIBEPAPER_MODEL", "fake-model") + monkeypatch.setenv("COPAPER_MODEL", "fake-model") result = _invoke( runner, ["--root", str(tmp_path), "relatedwork", "summarize"] diff --git a/tests/test_relatedwork_search.py b/tests/test_relatedwork_search.py index 5dd6320..9eec82d 100644 --- a/tests/test_relatedwork_search.py +++ b/tests/test_relatedwork_search.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.relatedwork_search.""" +"""Tests for copaper.relatedwork_search.""" from __future__ import annotations @@ -10,9 +10,9 @@ import pytest from click.testing import CliRunner -from vibepaper import relatedwork_search -from vibepaper.cli import _load_env_file, main as cli_main -from vibepaper.relatedwork_search import ( +from copaper import relatedwork_search +from copaper.cli import _load_env_file, main as cli_main +from copaper.relatedwork_search import ( DEFAULT_S2_BASE, SemanticScholarError, _auth_headers, diff --git a/tests/test_report.py b/tests/test_report.py index 6e610fc..a4286aa 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.report module (Task 16).""" +"""Tests for copaper.report module (Task 16).""" from __future__ import annotations @@ -7,17 +7,17 @@ import git -from vibepaper.report import generate_weekly_report, generate_diff_report +from copaper.report import generate_weekly_report, generate_diff_report class TestGenerateWeeklyReport: def test_report_contains_phase_progress(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("TestPaper", "SE") - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger el = EventLogger(str(tmp_path / ".agents" / "events.jsonl")) el.log("init_project", "user", "success", phase="storyline") @@ -30,12 +30,12 @@ def test_report_contains_phase_progress(self, tmp_path: Path) -> None: assert "storyline" in report def test_report_with_since_date(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("P", "D") - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger el = EventLogger(str(tmp_path / ".agents" / "events.jsonl")) el.log("init_project", "user", "success", phase="storyline") @@ -44,12 +44,12 @@ def test_report_with_since_date(self, tmp_path: Path) -> None: assert "since 2020-01-01" in report def test_report_event_log_stats(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("P", "D") - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger el = EventLogger(str(tmp_path / ".agents" / "events.jsonl")) el.log("init_project", "user", "success", phase="storyline") @@ -60,7 +60,7 @@ def test_report_event_log_stats(self, tmp_path: Path) -> None: assert "init_project" in report def test_report_recomputes_current_phase_from_state(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("P", "D") @@ -75,7 +75,7 @@ def test_report_recomputes_current_phase_from_state(self, tmp_path: Path) -> Non encoding="utf-8", ) - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger EventLogger(str(tmp_path / ".agents" / "events.jsonl")) @@ -114,12 +114,12 @@ def test_diff_between_phases(self, tmp_path: Path) -> None: class TestWeeklyReportFormat: def test_report_is_valid_markdown(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("P", "D") - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger EventLogger(str(tmp_path / ".agents" / "events.jsonl")) @@ -130,12 +130,12 @@ def test_report_is_valid_markdown(self, tmp_path: Path) -> None: assert "## Event Log Statistics" in report def test_report_no_events(self, tmp_path: Path) -> None: - from vibepaper.state import StateManager + from copaper.state import StateManager sm = StateManager(str(tmp_path)) sm.init_project("P", "D") - from vibepaper.eventlog import EventLogger + from copaper.eventlog import EventLogger EventLogger(str(tmp_path / ".agents" / "events.jsonl")) diff --git a/tests/test_scaffold.py b/tests/test_scaffold.py index f79123b..27a7e00 100644 --- a/tests/test_scaffold.py +++ b/tests/test_scaffold.py @@ -1,10 +1,10 @@ -"""Tests for vibepaper.scaffold module.""" +"""Tests for copaper.scaffold module.""" from __future__ import annotations from pathlib import Path -from vibepaper.scaffold import ( +from copaper.scaffold import ( copy_agents_md, copy_paper, copy_skills, @@ -25,7 +25,7 @@ def test_copies_all_skill_directories(self, tmp_path: Path) -> None: assert "storyline-helper" in skill_dirs assert "markdown-helper" in skill_dirs assert "relatedwork-finder" in skill_dirs - assert "vibepaper-manage" in skill_dirs + assert "copaper-manage" in skill_dirs def test_copies_skills_agents_md(self, tmp_path: Path) -> None: _ = copy_skills(tmp_path) @@ -119,7 +119,7 @@ def test_copies_agents_md(self, tmp_path: Path) -> None: assert dst == tmp_path / "AGENTS.md" assert dst.exists() content = dst.read_text(encoding="utf-8") - assert "VibePaper" in content + assert "CoPaper" in content def test_does_not_overwrite_existing(self, tmp_path: Path) -> None: existing = tmp_path / "AGENTS.md" @@ -142,7 +142,7 @@ def test_creates_all_scaffold_files(self, tmp_path: Path) -> None: assert (tmp_path / "templates" / "latex" / "README.md").exists() scaffold_skills_dir = ( - Path(__file__).resolve().parent.parent / "vibepaper" / "scaffold" / "skills" + Path(__file__).resolve().parent.parent / "copaper" / "scaffold" / "skills" ) expected_skill_dirs = { d.name for d in scaffold_skills_dir.iterdir() if d.is_dir() diff --git a/tests/test_skill_conventions.py b/tests/test_skill_conventions.py index 528e929..0067b6c 100644 --- a/tests/test_skill_conventions.py +++ b/tests/test_skill_conventions.py @@ -9,7 +9,7 @@ REPO_ROOT = Path(__file__).resolve().parent.parent SOURCE_SKILLS_DIR = REPO_ROOT / ".agents" / "skills" -SCAFFOLD_SKILLS_DIR = REPO_ROOT / "vibepaper" / "scaffold" / "skills" +SCAFFOLD_SKILLS_DIR = REPO_ROOT / "copaper" / "scaffold" / "skills" ALL_SKILL_NAMES = sorted( d.name diff --git a/tests/test_state.py b/tests/test_state.py index 0673990..728a13d 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -1,4 +1,4 @@ -"""Tests for vibepaper.state module (Task 3).""" +"""Tests for copaper.state module (Task 3).""" from __future__ import annotations @@ -7,8 +7,8 @@ import pytest -from vibepaper.constants import Phase, PhaseStatus -from vibepaper.state import StateFileError, StateManager +from copaper.constants import Phase, PhaseStatus +from copaper.state import StateFileError, StateManager class TestInitProject: diff --git a/vibepaper.egg-info/SOURCES.txt b/vibepaper.egg-info/SOURCES.txt deleted file mode 100644 index b0a9d5a..0000000 --- a/vibepaper.egg-info/SOURCES.txt +++ /dev/null @@ -1,87 +0,0 @@ -README.md -pyproject.toml -tests/test_checker_integration.py -tests/test_checker_main.py -tests/test_cli.py -tests/test_crossindex.py -tests/test_dimensions.py -tests/test_eventlog.py -tests/test_git_ops.py -tests/test_identity.py -tests/test_literature.py -tests/test_relatedwork_search.py -tests/test_report.py -tests/test_scaffold.py -tests/test_skill_conventions.py -tests/test_state.py -vibepaper/__init__.py -vibepaper/__main__.py -vibepaper/checker_integration.py -vibepaper/cli.py -vibepaper/constants.py -vibepaper/crossindex.py -vibepaper/dimensions.py -vibepaper/eventlog.py -vibepaper/git_ops.py -vibepaper/identity.py -vibepaper/literature.py -vibepaper/llm_client.py -vibepaper/relatedwork_download.py -vibepaper/relatedwork_keywords.py -vibepaper/relatedwork_search.py -vibepaper/relatedwork_summarize.py -vibepaper/report.py -vibepaper/scaffold.py -vibepaper/schema.py -vibepaper/state.py -vibepaper.egg-info/PKG-INFO -vibepaper.egg-info/SOURCES.txt -vibepaper.egg-info/dependency_links.txt -vibepaper.egg-info/entry_points.txt -vibepaper.egg-info/requires.txt -vibepaper.egg-info/top_level.txt -vibepaper/scaffold/AGENTS.md -vibepaper/scaffold/paper.md -vibepaper/scaffold/storyline.md -vibepaper/scaffold/writingrules.md -vibepaper/scaffold/skills/AGENTS.md -vibepaper/scaffold/skills/auto-init/SKILL.md -vibepaper/scaffold/skills/bogus-data-helper/SKILL.md -vibepaper/scaffold/skills/clarity-checker/SKILL.md -vibepaper/scaffold/skills/clarity-checker/examples.md -vibepaper/scaffold/skills/data-checker/SKILL.md -vibepaper/scaffold/skills/data-checker/examples.md -vibepaper/scaffold/skills/evaluation-protocol-checker/SKILL.md -vibepaper/scaffold/skills/evaluation-protocol-checker/examples.md -vibepaper/scaffold/skills/experiment-analyzer/SKILL.md -vibepaper/scaffold/skills/human-comment-helper/SKILL.md -vibepaper/scaffold/skills/humanizer/LICENSE -vibepaper/scaffold/skills/humanizer/README.md -vibepaper/scaffold/skills/humanizer/SKILL.md -vibepaper/scaffold/skills/humanizer/WARP.md -vibepaper/scaffold/skills/latex2markdown/SKILL.md -vibepaper/scaffold/skills/logic-checker/SKILL.md -vibepaper/scaffold/skills/logic-checker/examples.md -vibepaper/scaffold/skills/mad-writer/SKILL.md -vibepaper/scaffold/skills/markdown-helper/SKILL.md -vibepaper/scaffold/skills/markdown-review/SKILL.md -vibepaper/scaffold/skills/markdown2latex/SKILL.md -vibepaper/scaffold/skills/novelty-checker/SKILL.md -vibepaper/scaffold/skills/novelty-checker/examples.md -vibepaper/scaffold/skills/pdf2paper/SKILL.md -vibepaper/scaffold/skills/ppt2storyline/SKILL.md -vibepaper/scaffold/skills/problem-checker/SKILL.md -vibepaper/scaffold/skills/problem-checker/examples.md -vibepaper/scaffold/skills/relatedwork-finder/SKILL.md -vibepaper/scaffold/skills/relatedwork-finder/template.md -vibepaper/scaffold/skills/relatedwork-summarizer/SKILL.md -vibepaper/scaffold/skills/relatedwork-summarizer/template.md -vibepaper/scaffold/skills/review-revise/SKILL.md -vibepaper/scaffold/skills/socratic-discussion/SKILL.md -vibepaper/scaffold/skills/state-machine-markdown-helper/SKILL.md -vibepaper/scaffold/skills/storyline-helper/SKILL.md -vibepaper/scaffold/skills/submission-precheck/SKILL.md -vibepaper/scaffold/skills/technical-depth-checker/SKILL.md -vibepaper/scaffold/skills/technical-depth-checker/examples.md -vibepaper/scaffold/skills/vibepaper-manage/SKILL.md -vibepaper/scaffold/skills/writing-orchestrator/SKILL.md \ No newline at end of file diff --git a/vibepaper.egg-info/entry_points.txt b/vibepaper.egg-info/entry_points.txt deleted file mode 100644 index 56740ec..0000000 --- a/vibepaper.egg-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[console_scripts] -vibe = vibepaper.cli:main diff --git a/vibepaper.egg-info/top_level.txt b/vibepaper.egg-info/top_level.txt deleted file mode 100644 index 27ceebb..0000000 --- a/vibepaper.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -vibepaper diff --git a/vibepaper/__init__.py b/vibepaper/__init__.py deleted file mode 100644 index 72e1cb4..0000000 --- a/vibepaper/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -"""VibePaper - AI-assisted academic writing framework.""" - -__version__ = "0.1.0" - -from vibepaper.constants import Phase, PhaseStatus, PHASE_ORDER, PHASE_DEPENDENCIES -from vibepaper.schema import STATE_SCHEMA - -__all__ = [ - "__version__", - "Phase", - "PhaseStatus", - "PHASE_ORDER", - "PHASE_DEPENDENCIES", - "STATE_SCHEMA", -] diff --git a/vibepaper/__main__.py b/vibepaper/__main__.py deleted file mode 100644 index 874008a..0000000 --- a/vibepaper/__main__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Entry point for `python -m vibepaper`.""" - -from vibepaper.cli import main - -if __name__ == "__main__": - main() diff --git a/workflow-dataflow.md b/workflow-dataflow.md index 6eb8aac..711daa0 100644 --- a/workflow-dataflow.md +++ b/workflow-dataflow.md @@ -1,13 +1,13 @@ -# VibePaper 工作流数据流分析 +# CoPaper 工作流数据流分析 ## 核心结论 -VibePaper 当前有两套需要区分的结构: +CoPaper 当前有两套需要区分的结构: 1. **阶段结构(phase model)**:`storyline → literature → discussion → experiments → writing → latex_review` 2. **工件结构(artifact model)**:`storyline.md`、`paper.md`、`relatedwork/`(含 `literature.json` / `paper_list.bib` / `pdfs/` / `papers/`)、`.agents/state.json`、`.agents/events.jsonl` -`vibepaper/constants.py` 中的 `PHASE_DEPENDENCIES` 只表达推荐正向顺序,不足以表达当前技能层面已经存在的“跳过、重入、补跑、逆向提炼”等真实工作流。 +`copaper/constants.py` 中的 `PHASE_DEPENDENCIES` 只表达推荐正向顺序,不足以表达当前技能层面已经存在的“跳过、重入、补跑、逆向提炼”等真实工作流。 ## 核心工件 @@ -15,9 +15,9 @@ VibePaper 当前有两套需要区分的结构: |---|---|---|---| | `storyline.md` | 研究问题、insight、设计与评测意图的高层叙事 | `storyline-helper`、用户 | `relatedwork-finder`、`socratic-discussion`、`experiment-analyzer`、`markdown-helper`、`writing-orchestrator` | | `paper.md` | 正式论文框架与段落级内容 | `markdown-helper`、`mad-writer`、`latex2markdown`、用户 | `writing-orchestrator`、`markdown-review`、7 checkers、`review-revise`、`submission-precheck`、`markdown2latex` | -| `relatedwork/literature.json` / `paper_list.bib` / `relatedwork/papers/*.md` / `relatedwork/summary.md` | 文献元数据、BibTeX、摘要与归纳 | `relatedwork-finder` + `vibe relatedwork` | `markdown-helper`、`markdown-review`、`review-revise`、`mad-writer` | -| `.agents/state.json` | 状态、checker 结果、技能中间状态 | `vibe init`、部分 skills | `vibe status`、`writing-orchestrator`、`review-revise`、`socratic-discussion`、`experiment-analyzer` | -| `.agents/events.jsonl` | CLI 操作日志 | `vibe` CLI | `vibe log`、`vibe report` | +| `relatedwork/literature.json` / `paper_list.bib` / `relatedwork/papers/*.md` / `relatedwork/summary.md` | 文献元数据、BibTeX、摘要与归纳 | `relatedwork-finder` + `copaper relatedwork` | `markdown-helper`、`markdown-review`、`review-revise`、`mad-writer` | +| `.agents/state.json` | 状态、checker 结果、技能中间状态 | `copaper init`、部分 skills | `copaper status`、`writing-orchestrator`、`review-revise`、`socratic-discussion`、`experiment-analyzer` | +| `.agents/events.jsonl` | CLI 操作日志 | `copaper` CLI | `copaper log`、`copaper report` | ## 哪些步骤 / skill 只需要 `storyline.md` @@ -62,7 +62,7 @@ VibePaper 当前有两套需要区分的结构: 3. **`LaTeX → paper.md`** - `latex2markdown` 已支持 - - 用途:已有旧论文或模板项目时导入 VibePaper 结构 + - 用途:已有旧论文或模板项目时导入 CoPaper 结构 4. **`checker results → paper.md`** - `review-revise` 已支持多轮修订 @@ -74,7 +74,7 @@ VibePaper 当前有两套需要区分的结构: 从 CLI 行为看,答案是 **可以**。 -- `vibe skip <phase>` 对所有有效 phase 名称都可执行 +- `copaper skip <phase>` 对所有有效 phase 名称都可执行 - 当前工具层没有对 `storyline` / `writing` 设置硬限制 - 因此“是否建议跳过”和“工具层是否允许跳过”是两回事 @@ -87,7 +87,7 @@ VibePaper 当前有两套需要区分的结构: - `experiment-analyzer` 可以在不同 mode 间多次进入 - `writing-orchestrator` / `markdown-helper` / `mad-writer` 本身就是循环式工作流 - `markdown-review` / `review-revise` 天然支持多轮迭代 -- `vibe rollback <phase>` 提供 Git 维度的阶段性回退 +- `copaper rollback <phase>` 提供 Git 维度的阶段性回退 ## 当前结构的其它问题 @@ -138,11 +138,11 @@ CLI 现在有:`init`、`status`、`set-phase`、`skip`、`log`、`report`、`c 仓库里同时存在: - `.agents/skills/*` -- `vibepaper/scaffold/skills/*` +- `copaper/scaffold/skills/*` -任何 skill 的更新都必须同步两份,否则 `vibe init` 初始化出来的项目会落后于仓库源码。 +任何 skill 的更新都必须同步两份,否则 `copaper init` 初始化出来的项目会落后于仓库源码。 -### 6. 之前 `vibe init` 没有复制 `paper.md` +### 6. 之前 `copaper init` 没有复制 `paper.md` 这个问题已修复,但它暴露了一个更深层问题: @@ -161,7 +161,7 @@ CLI 现在有:`init`、`status`、`set-phase`、`skip`、`log`、`report`、`c ## 当前实现后的结论 -修复 `vibe init` 复制 `paper.md` 后,初始化脚手架终于与当前 skill 生态基本一致: +修复 `copaper init` 复制 `paper.md` 后,初始化脚手架终于与当前 skill 生态基本一致: - storyline-first 可以直接开始 - paper-first 也可以成立 diff --git a/writingrules.md b/writingrules.md index 42a2748..69245ac 100644 --- a/writingrules.md +++ b/writingrules.md @@ -1,12 +1,12 @@ -# VibePaper GUI 写作规则指南 +# CoPaper GUI 写作规则指南 -本文档用于指导用户和 AI Agent 使用 VibePaper GUI 进行论文写作。 +本文档用于指导用户和 AI Agent 使用 CoPaper GUI 进行论文写作。 ## 项目概述 -VibePaper GUI 是一个基于树状结构的论文写作辅助工具,采用自顶向下的方式组织论文结构。论文以 Markdown 文件形式存储,通过标题层级组织结构,每个节点可包含描述、主题句、支撑句和图片等内容。 +CoPaper GUI 是一个基于树状结构的论文写作辅助工具,采用自顶向下的方式组织论文结构。论文以 Markdown 文件形式存储,通过标题层级组织结构,每个节点可包含描述、主题句、支撑句和图片等内容。 ## 项目文件夹概述