feat: 完成老项目文档化工作
- 新增 openspec-propose 技能,支持快速提案生成变更及相关文档。 - 新增接口汇总文档,整理后端接口及其用途。 - 新增页面功能说明文档,描述各页面的功能及路由。 - 新增项目总览文档,概述项目结构、技术栈及运行方式。 - 新增工具与非标准实现说明文档,记录项目中的特殊实现及约定。 - 创建 legacy-project-documentation 变更,整合现有文档并迁移至正式 OpenSpec 目录。 - 记录项目中的高风险历史实现特征,明确页面启用状态及接口调用关系。
This commit is contained in:
149
.github/prompts/opsx-apply.prompt.md
vendored
Normal file
149
.github/prompts/opsx-apply.prompt.md
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
description: Implement tasks from an OpenSpec change (Experimental)
|
||||
---
|
||||
|
||||
Implement tasks from an OpenSpec change.
|
||||
|
||||
**Input**: Optionally specify a change name (e.g., `/opsx:apply add-auth`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **Select the change**
|
||||
|
||||
If a name is provided, use it. Otherwise:
|
||||
- Infer from conversation context if the user mentioned a change
|
||||
- Auto-select if only one active change exists
|
||||
- If ambiguous, run `openspec list --json` to get available changes and use the **AskUserQuestion tool** to let the user select
|
||||
|
||||
Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).
|
||||
|
||||
2. **Check status to understand the schema**
|
||||
```bash
|
||||
openspec status --change "<name>" --json
|
||||
```
|
||||
Parse the JSON to understand:
|
||||
- `schemaName`: The workflow being used (e.g., "spec-driven")
|
||||
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
|
||||
|
||||
3. **Get apply instructions**
|
||||
|
||||
```bash
|
||||
openspec instructions apply --change "<name>" --json
|
||||
```
|
||||
|
||||
This returns:
|
||||
- Context file paths (varies by schema)
|
||||
- Progress (total, complete, remaining)
|
||||
- Task list with status
|
||||
- Dynamic instruction based on current state
|
||||
|
||||
**Handle states:**
|
||||
- If `state: "blocked"` (missing artifacts): show message, suggest using `/opsx:continue`
|
||||
- If `state: "all_done"`: congratulate, suggest archive
|
||||
- Otherwise: proceed to implementation
|
||||
|
||||
4. **Read context files**
|
||||
|
||||
Read the files listed in `contextFiles` from the apply instructions output.
|
||||
The files depend on the schema being used:
|
||||
- **spec-driven**: proposal, specs, design, tasks
|
||||
- Other schemas: follow the contextFiles from CLI output
|
||||
|
||||
5. **Show current progress**
|
||||
|
||||
Display:
|
||||
- Schema being used
|
||||
- Progress: "N/M tasks complete"
|
||||
- Remaining tasks overview
|
||||
- Dynamic instruction from CLI
|
||||
|
||||
6. **Implement tasks (loop until done or blocked)**
|
||||
|
||||
For each pending task:
|
||||
- Show which task is being worked on
|
||||
- Make the code changes required
|
||||
- Keep changes minimal and focused
|
||||
- Mark task complete in the tasks file: `- [ ]` → `- [x]`
|
||||
- Continue to next task
|
||||
|
||||
**Pause if:**
|
||||
- Task is unclear → ask for clarification
|
||||
- Implementation reveals a design issue → suggest updating artifacts
|
||||
- Error or blocker encountered → report and wait for guidance
|
||||
- User interrupts
|
||||
|
||||
7. **On completion or pause, show status**
|
||||
|
||||
Display:
|
||||
- Tasks completed this session
|
||||
- Overall progress: "N/M tasks complete"
|
||||
- If all done: suggest archive
|
||||
- If paused: explain why and wait for guidance
|
||||
|
||||
**Output During Implementation**
|
||||
|
||||
```
|
||||
## Implementing: <change-name> (schema: <schema-name>)
|
||||
|
||||
Working on task 3/7: <task description>
|
||||
[...implementation happening...]
|
||||
✓ Task complete
|
||||
|
||||
Working on task 4/7: <task description>
|
||||
[...implementation happening...]
|
||||
✓ Task complete
|
||||
```
|
||||
|
||||
**Output On Completion**
|
||||
|
||||
```
|
||||
## Implementation Complete
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Progress:** 7/7 tasks complete ✓
|
||||
|
||||
### Completed This Session
|
||||
- [x] Task 1
|
||||
- [x] Task 2
|
||||
...
|
||||
|
||||
All tasks complete! You can archive this change with `/opsx:archive`.
|
||||
```
|
||||
|
||||
**Output On Pause (Issue Encountered)**
|
||||
|
||||
```
|
||||
## Implementation Paused
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Progress:** 4/7 tasks complete
|
||||
|
||||
### Issue Encountered
|
||||
<description of the issue>
|
||||
|
||||
**Options:**
|
||||
1. <option 1>
|
||||
2. <option 2>
|
||||
3. Other approach
|
||||
|
||||
What would you like to do?
|
||||
```
|
||||
|
||||
**Guardrails**
|
||||
- Keep going through tasks until done or blocked
|
||||
- Always read context files before starting (from the apply instructions output)
|
||||
- If task is ambiguous, pause and ask before implementing
|
||||
- If implementation reveals issues, pause and suggest artifact updates
|
||||
- Keep code changes minimal and scoped to each task
|
||||
- Update task checkbox immediately after completing each task
|
||||
- Pause on errors, blockers, or unclear requirements - don't guess
|
||||
- Use contextFiles from CLI output, don't assume specific file names
|
||||
|
||||
**Fluid Workflow Integration**
|
||||
|
||||
This skill supports the "actions on a change" model:
|
||||
|
||||
- **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
|
||||
- **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly
|
||||
154
.github/prompts/opsx-archive.prompt.md
vendored
Normal file
154
.github/prompts/opsx-archive.prompt.md
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
---
|
||||
description: Archive a completed change in the experimental workflow
|
||||
---
|
||||
|
||||
Archive a completed change in the experimental workflow.
|
||||
|
||||
**Input**: Optionally specify a change name after `/opsx:archive` (e.g., `/opsx:archive add-auth`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **If no change name provided, prompt for selection**
|
||||
|
||||
Run `openspec list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select.
|
||||
|
||||
Show only active changes (not already archived).
|
||||
Include the schema used for each change if available.
|
||||
|
||||
**IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
|
||||
|
||||
2. **Check artifact completion status**
|
||||
|
||||
Run `openspec status --change "<name>" --json` to check artifact completion.
|
||||
|
||||
Parse the JSON to understand:
|
||||
- `schemaName`: The workflow being used
|
||||
- `artifacts`: List of artifacts with their status (`done` or other)
|
||||
|
||||
**If any artifacts are not `done`:**
|
||||
- Display warning listing incomplete artifacts
|
||||
- Prompt user for confirmation to continue
|
||||
- Proceed if user confirms
|
||||
|
||||
3. **Check task completion status**
|
||||
|
||||
Read the tasks file (typically `tasks.md`) to check for incomplete tasks.
|
||||
|
||||
Count tasks marked with `- [ ]` (incomplete) vs `- [x]` (complete).
|
||||
|
||||
**If incomplete tasks found:**
|
||||
- Display warning showing count of incomplete tasks
|
||||
- Prompt user for confirmation to continue
|
||||
- Proceed if user confirms
|
||||
|
||||
**If no tasks file exists:** Proceed without task-related warning.
|
||||
|
||||
4. **Assess delta spec sync state**
|
||||
|
||||
Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.
|
||||
|
||||
**If delta specs exist:**
|
||||
- Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`
|
||||
- Determine what changes would be applied (adds, modifications, removals, renames)
|
||||
- Show a combined summary before prompting
|
||||
|
||||
**Prompt options:**
|
||||
- If changes needed: "Sync now (recommended)", "Archive without syncing"
|
||||
- If already synced: "Archive now", "Sync anyway", "Cancel"
|
||||
|
||||
If user chooses sync, use Task tool (subagent_type: "general-purpose", prompt: "Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec analysis: <include the analyzed delta spec summary>"). Proceed to archive regardless of choice.
|
||||
|
||||
5. **Perform the archive**
|
||||
|
||||
Create the archive directory if it doesn't exist:
|
||||
```bash
|
||||
mkdir -p openspec/changes/archive
|
||||
```
|
||||
|
||||
Generate target name using current date: `YYYY-MM-DD-<change-name>`
|
||||
|
||||
**Check if target already exists:**
|
||||
- If yes: Fail with error, suggest renaming existing archive or using different date
|
||||
- If no: Move the change directory to archive
|
||||
|
||||
```bash
|
||||
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
|
||||
```
|
||||
|
||||
6. **Display summary**
|
||||
|
||||
Show archive completion summary including:
|
||||
- Change name
|
||||
- Schema that was used
|
||||
- Archive location
|
||||
- Spec sync status (synced / sync skipped / no delta specs)
|
||||
- Note about any warnings (incomplete artifacts/tasks)
|
||||
|
||||
**Output On Success**
|
||||
|
||||
```
|
||||
## Archive Complete
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
||||
**Specs:** ✓ Synced to main specs
|
||||
|
||||
All artifacts complete. All tasks complete.
|
||||
```
|
||||
|
||||
**Output On Success (No Delta Specs)**
|
||||
|
||||
```
|
||||
## Archive Complete
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
||||
**Specs:** No delta specs
|
||||
|
||||
All artifacts complete. All tasks complete.
|
||||
```
|
||||
|
||||
**Output On Success With Warnings**
|
||||
|
||||
```
|
||||
## Archive Complete (with warnings)
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
||||
**Specs:** Sync skipped (user chose to skip)
|
||||
|
||||
**Warnings:**
|
||||
- Archived with 2 incomplete artifacts
|
||||
- Archived with 3 incomplete tasks
|
||||
- Delta spec sync was skipped (user chose to skip)
|
||||
|
||||
Review the archive if this was not intentional.
|
||||
```
|
||||
|
||||
**Output On Error (Archive Exists)**
|
||||
|
||||
```
|
||||
## Archive Failed
|
||||
|
||||
**Change:** <change-name>
|
||||
**Target:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
||||
|
||||
Target archive directory already exists.
|
||||
|
||||
**Options:**
|
||||
1. Rename the existing archive
|
||||
2. Delete the existing archive if it's a duplicate
|
||||
3. Wait until a different date to archive
|
||||
```
|
||||
|
||||
**Guardrails**
|
||||
- Always prompt for change selection if not provided
|
||||
- Use artifact graph (openspec status --json) for completion checking
|
||||
- Don't block archive on warnings - just inform and confirm
|
||||
- Preserve .openspec.yaml when moving to archive (it moves with the directory)
|
||||
- Show clear summary of what happened
|
||||
- If sync is requested, use the Skill tool to invoke `openspec-sync-specs` (agent-driven)
|
||||
- If delta specs exist, always run the sync assessment and show the combined summary before prompting
|
||||
170
.github/prompts/opsx-explore.prompt.md
vendored
Normal file
170
.github/prompts/opsx-explore.prompt.md
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
description: Enter explore mode - think through ideas, investigate problems, clarify requirements
|
||||
---
|
||||
|
||||
Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
||||
|
||||
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
|
||||
|
||||
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
||||
|
||||
**Input**: The argument after `/opsx:explore` is whatever the user wants to think about. Could be:
|
||||
- A vague idea: "real-time collaboration"
|
||||
- A specific problem: "the auth system is getting unwieldy"
|
||||
- A change name: "add-dark-mode" (to explore in context of that change)
|
||||
- A comparison: "postgres vs sqlite for this"
|
||||
- Nothing (just enter explore mode)
|
||||
|
||||
---
|
||||
|
||||
## The Stance
|
||||
|
||||
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
|
||||
- **Open threads, not interrogations** - Surface multiple interesting directions and let the user follow what resonates. Don't funnel them through a single path of questions.
|
||||
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
|
||||
- **Adaptive** - Follow interesting threads, pivot when new information emerges
|
||||
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
|
||||
- **Grounded** - Explore the actual codebase when relevant, don't just theorize
|
||||
|
||||
---
|
||||
|
||||
## What You Might Do
|
||||
|
||||
Depending on what the user brings, you might:
|
||||
|
||||
**Explore the problem space**
|
||||
- Ask clarifying questions that emerge from what they said
|
||||
- Challenge assumptions
|
||||
- Reframe the problem
|
||||
- Find analogies
|
||||
|
||||
**Investigate the codebase**
|
||||
- Map existing architecture relevant to the discussion
|
||||
- Find integration points
|
||||
- Identify patterns already in use
|
||||
- Surface hidden complexity
|
||||
|
||||
**Compare options**
|
||||
- Brainstorm multiple approaches
|
||||
- Build comparison tables
|
||||
- Sketch tradeoffs
|
||||
- Recommend a path (if asked)
|
||||
|
||||
**Visualize**
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Use ASCII diagrams liberally │
|
||||
├─────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────┐ ┌────────┐ │
|
||||
│ │ State │────────▶│ State │ │
|
||||
│ │ A │ │ B │ │
|
||||
│ └────────┘ └────────┘ │
|
||||
│ │
|
||||
│ System diagrams, state machines, │
|
||||
│ data flows, architecture sketches, │
|
||||
│ dependency graphs, comparison tables │
|
||||
│ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Surface risks and unknowns**
|
||||
- Identify what could go wrong
|
||||
- Find gaps in understanding
|
||||
- Suggest spikes or investigations
|
||||
|
||||
---
|
||||
|
||||
## OpenSpec Awareness
|
||||
|
||||
You have full context of the OpenSpec system. Use it naturally, don't force it.
|
||||
|
||||
### Check for context
|
||||
|
||||
At the start, quickly check what exists:
|
||||
```bash
|
||||
openspec list --json
|
||||
```
|
||||
|
||||
This tells you:
|
||||
- If there are active changes
|
||||
- Their names, schemas, and status
|
||||
- What the user might be working on
|
||||
|
||||
If the user mentioned a specific change name, read its artifacts for context.
|
||||
|
||||
### When no change exists
|
||||
|
||||
Think freely. When insights crystallize, you might offer:
|
||||
|
||||
- "This feels solid enough to start a change. Want me to create a proposal?"
|
||||
- Or keep exploring - no pressure to formalize
|
||||
|
||||
### When a change exists
|
||||
|
||||
If the user mentions a change or you detect one is relevant:
|
||||
|
||||
1. **Read existing artifacts for context**
|
||||
- `openspec/changes/<name>/proposal.md`
|
||||
- `openspec/changes/<name>/design.md`
|
||||
- `openspec/changes/<name>/tasks.md`
|
||||
- etc.
|
||||
|
||||
2. **Reference them naturally in conversation**
|
||||
- "Your design mentions using Redis, but we just realized SQLite fits better..."
|
||||
- "The proposal scopes this to premium users, but we're now thinking everyone..."
|
||||
|
||||
3. **Offer to capture when decisions are made**
|
||||
|
||||
| Insight Type | Where to Capture |
|
||||
|--------------|------------------|
|
||||
| New requirement discovered | `specs/<capability>/spec.md` |
|
||||
| Requirement changed | `specs/<capability>/spec.md` |
|
||||
| Design decision made | `design.md` |
|
||||
| Scope changed | `proposal.md` |
|
||||
| New work identified | `tasks.md` |
|
||||
| Assumption invalidated | Relevant artifact |
|
||||
|
||||
Example offers:
|
||||
- "That's a design decision. Capture it in design.md?"
|
||||
- "This is a new requirement. Add it to specs?"
|
||||
- "This changes scope. Update the proposal?"
|
||||
|
||||
4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
|
||||
|
||||
---
|
||||
|
||||
## What You Don't Have To Do
|
||||
|
||||
- Follow a script
|
||||
- Ask the same questions every time
|
||||
- Produce a specific artifact
|
||||
- Reach a conclusion
|
||||
- Stay on topic if a tangent is valuable
|
||||
- Be brief (this is thinking time)
|
||||
|
||||
---
|
||||
|
||||
## Ending Discovery
|
||||
|
||||
There's no required ending. Discovery might:
|
||||
|
||||
- **Flow into a proposal**: "Ready to start? I can create a change proposal."
|
||||
- **Result in artifact updates**: "Updated design.md with these decisions"
|
||||
- **Just provide clarity**: User has what they need, moves on
|
||||
- **Continue later**: "We can pick this up anytime"
|
||||
|
||||
When things crystallize, you might offer a summary - but it's optional. Sometimes the thinking IS the value.
|
||||
|
||||
---
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not.
|
||||
- **Don't fake understanding** - If something is unclear, dig deeper
|
||||
- **Don't rush** - Discovery is thinking time, not task time
|
||||
- **Don't force structure** - Let patterns emerge naturally
|
||||
- **Don't auto-capture** - Offer to save insights, don't just do it
|
||||
- **Do visualize** - A good diagram is worth many paragraphs
|
||||
- **Do explore the codebase** - Ground discussions in reality
|
||||
- **Do question assumptions** - Including the user's and your own
|
||||
103
.github/prompts/opsx-propose.prompt.md
vendored
Normal file
103
.github/prompts/opsx-propose.prompt.md
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
description: Propose a new change - create it and generate all artifacts in one step
|
||||
---
|
||||
|
||||
Propose a new change - create the change and generate all artifacts in one step.
|
||||
|
||||
I'll create a change with artifacts:
|
||||
- proposal.md (what & why)
|
||||
- design.md (how)
|
||||
- tasks.md (implementation steps)
|
||||
|
||||
When ready to implement, run /opsx:apply
|
||||
|
||||
---
|
||||
|
||||
**Input**: The argument after `/opsx:propose` is the change name (kebab-case), OR a description of what the user wants to build.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **If no input provided, ask what they want to build**
|
||||
|
||||
Use the **AskUserQuestion tool** (open-ended, no preset options) to ask:
|
||||
> "What change do you want to work on? Describe what you want to build or fix."
|
||||
|
||||
From their description, derive a kebab-case name (e.g., "add user authentication" → `add-user-auth`).
|
||||
|
||||
**IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
|
||||
|
||||
2. **Create the change directory**
|
||||
```bash
|
||||
openspec new change "<name>"
|
||||
```
|
||||
This creates a scaffolded change at `openspec/changes/<name>/` with `.openspec.yaml`.
|
||||
|
||||
3. **Get the artifact build order**
|
||||
```bash
|
||||
openspec status --change "<name>" --json
|
||||
```
|
||||
Parse the JSON to get:
|
||||
- `applyRequires`: array of artifact IDs needed before implementation (e.g., `["tasks"]`)
|
||||
- `artifacts`: list of all artifacts with their status and dependencies
|
||||
|
||||
4. **Create artifacts in sequence until apply-ready**
|
||||
|
||||
Use the **TodoWrite tool** to track progress through the artifacts.
|
||||
|
||||
Loop through artifacts in dependency order (artifacts with no pending dependencies first):
|
||||
|
||||
a. **For each artifact that is `ready` (dependencies satisfied)**:
|
||||
- Get instructions:
|
||||
```bash
|
||||
openspec instructions <artifact-id> --change "<name>" --json
|
||||
```
|
||||
- The instructions JSON includes:
|
||||
- `context`: Project background (constraints for you - do NOT include in output)
|
||||
- `rules`: Artifact-specific rules (constraints for you - do NOT include in output)
|
||||
- `template`: The structure to use for your output file
|
||||
- `instruction`: Schema-specific guidance for this artifact type
|
||||
- `outputPath`: Where to write the artifact
|
||||
- `dependencies`: Completed artifacts to read for context
|
||||
- Read any completed dependency files for context
|
||||
- Create the artifact file using `template` as the structure
|
||||
- Apply `context` and `rules` as constraints - but do NOT copy them into the file
|
||||
- Show brief progress: "Created <artifact-id>"
|
||||
|
||||
b. **Continue until all `applyRequires` artifacts are complete**
|
||||
- After creating each artifact, re-run `openspec status --change "<name>" --json`
|
||||
- Check if every artifact ID in `applyRequires` has `status: "done"` in the artifacts array
|
||||
- Stop when all `applyRequires` artifacts are done
|
||||
|
||||
c. **If an artifact requires user input** (unclear context):
|
||||
- Use **AskUserQuestion tool** to clarify
|
||||
- Then continue with creation
|
||||
|
||||
5. **Show final status**
|
||||
```bash
|
||||
openspec status --change "<name>"
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
After completing all artifacts, summarize:
|
||||
- Change name and location
|
||||
- List of artifacts created with brief descriptions
|
||||
- What's ready: "All artifacts created! Ready for implementation."
|
||||
- Prompt: "Run `/opsx:apply` to start implementing."
|
||||
|
||||
**Artifact Creation Guidelines**
|
||||
|
||||
- Follow the `instruction` field from `openspec instructions` for each artifact type
|
||||
- The schema defines what each artifact should contain - follow it
|
||||
- Read dependency artifacts for context before creating new ones
|
||||
- Use `template` as the structure for your output file - fill in its sections
|
||||
- **IMPORTANT**: `context` and `rules` are constraints for YOU, not content for the file
|
||||
- Do NOT copy `<context>`, `<rules>`, `<project_context>` blocks into the artifact
|
||||
- These guide what you write, but should never appear in the output
|
||||
|
||||
**Guardrails**
|
||||
- Create ALL artifacts needed for implementation (as defined by schema's `apply.requires`)
|
||||
- Always read dependency artifacts before creating a new one
|
||||
- If context is critically unclear, ask the user - but prefer making reasonable decisions to keep momentum
|
||||
- If a change with that name already exists, ask if user wants to continue it or create a new one
|
||||
- Verify each artifact file exists after writing before proceeding to next
|
||||
156
.github/skills/openspec-apply-change/SKILL.md
vendored
Normal file
156
.github/skills/openspec-apply-change/SKILL.md
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
---
|
||||
name: openspec-apply-change
|
||||
description: Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: openspec
|
||||
version: "1.0"
|
||||
generatedBy: "1.2.0"
|
||||
---
|
||||
|
||||
Implement tasks from an OpenSpec change.
|
||||
|
||||
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **Select the change**
|
||||
|
||||
If a name is provided, use it. Otherwise:
|
||||
- Infer from conversation context if the user mentioned a change
|
||||
- Auto-select if only one active change exists
|
||||
- If ambiguous, run `openspec list --json` to get available changes and use the **AskUserQuestion tool** to let the user select
|
||||
|
||||
Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).
|
||||
|
||||
2. **Check status to understand the schema**
|
||||
```bash
|
||||
openspec status --change "<name>" --json
|
||||
```
|
||||
Parse the JSON to understand:
|
||||
- `schemaName`: The workflow being used (e.g., "spec-driven")
|
||||
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
|
||||
|
||||
3. **Get apply instructions**
|
||||
|
||||
```bash
|
||||
openspec instructions apply --change "<name>" --json
|
||||
```
|
||||
|
||||
This returns:
|
||||
- Context file paths (varies by schema - could be proposal/specs/design/tasks or spec/tests/implementation/docs)
|
||||
- Progress (total, complete, remaining)
|
||||
- Task list with status
|
||||
- Dynamic instruction based on current state
|
||||
|
||||
**Handle states:**
|
||||
- If `state: "blocked"` (missing artifacts): show message, suggest using openspec-continue-change
|
||||
- If `state: "all_done"`: congratulate, suggest archive
|
||||
- Otherwise: proceed to implementation
|
||||
|
||||
4. **Read context files**
|
||||
|
||||
Read the files listed in `contextFiles` from the apply instructions output.
|
||||
The files depend on the schema being used:
|
||||
- **spec-driven**: proposal, specs, design, tasks
|
||||
- Other schemas: follow the contextFiles from CLI output
|
||||
|
||||
5. **Show current progress**
|
||||
|
||||
Display:
|
||||
- Schema being used
|
||||
- Progress: "N/M tasks complete"
|
||||
- Remaining tasks overview
|
||||
- Dynamic instruction from CLI
|
||||
|
||||
6. **Implement tasks (loop until done or blocked)**
|
||||
|
||||
For each pending task:
|
||||
- Show which task is being worked on
|
||||
- Make the code changes required
|
||||
- Keep changes minimal and focused
|
||||
- Mark task complete in the tasks file: `- [ ]` → `- [x]`
|
||||
- Continue to next task
|
||||
|
||||
**Pause if:**
|
||||
- Task is unclear → ask for clarification
|
||||
- Implementation reveals a design issue → suggest updating artifacts
|
||||
- Error or blocker encountered → report and wait for guidance
|
||||
- User interrupts
|
||||
|
||||
7. **On completion or pause, show status**
|
||||
|
||||
Display:
|
||||
- Tasks completed this session
|
||||
- Overall progress: "N/M tasks complete"
|
||||
- If all done: suggest archive
|
||||
- If paused: explain why and wait for guidance
|
||||
|
||||
**Output During Implementation**
|
||||
|
||||
```
|
||||
## Implementing: <change-name> (schema: <schema-name>)
|
||||
|
||||
Working on task 3/7: <task description>
|
||||
[...implementation happening...]
|
||||
✓ Task complete
|
||||
|
||||
Working on task 4/7: <task description>
|
||||
[...implementation happening...]
|
||||
✓ Task complete
|
||||
```
|
||||
|
||||
**Output On Completion**
|
||||
|
||||
```
|
||||
## Implementation Complete
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Progress:** 7/7 tasks complete ✓
|
||||
|
||||
### Completed This Session
|
||||
- [x] Task 1
|
||||
- [x] Task 2
|
||||
...
|
||||
|
||||
All tasks complete! Ready to archive this change.
|
||||
```
|
||||
|
||||
**Output On Pause (Issue Encountered)**
|
||||
|
||||
```
|
||||
## Implementation Paused
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Progress:** 4/7 tasks complete
|
||||
|
||||
### Issue Encountered
|
||||
<description of the issue>
|
||||
|
||||
**Options:**
|
||||
1. <option 1>
|
||||
2. <option 2>
|
||||
3. Other approach
|
||||
|
||||
What would you like to do?
|
||||
```
|
||||
|
||||
**Guardrails**
|
||||
- Keep going through tasks until done or blocked
|
||||
- Always read context files before starting (from the apply instructions output)
|
||||
- If task is ambiguous, pause and ask before implementing
|
||||
- If implementation reveals issues, pause and suggest artifact updates
|
||||
- Keep code changes minimal and scoped to each task
|
||||
- Update task checkbox immediately after completing each task
|
||||
- Pause on errors, blockers, or unclear requirements - don't guess
|
||||
- Use contextFiles from CLI output, don't assume specific file names
|
||||
|
||||
**Fluid Workflow Integration**
|
||||
|
||||
This skill supports the "actions on a change" model:
|
||||
|
||||
- **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
|
||||
- **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly
|
||||
114
.github/skills/openspec-archive-change/SKILL.md
vendored
Normal file
114
.github/skills/openspec-archive-change/SKILL.md
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
---
|
||||
name: openspec-archive-change
|
||||
description: Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: openspec
|
||||
version: "1.0"
|
||||
generatedBy: "1.2.0"
|
||||
---
|
||||
|
||||
Archive a completed change in the experimental workflow.
|
||||
|
||||
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **If no change name provided, prompt for selection**
|
||||
|
||||
Run `openspec list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select.
|
||||
|
||||
Show only active changes (not already archived).
|
||||
Include the schema used for each change if available.
|
||||
|
||||
**IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
|
||||
|
||||
2. **Check artifact completion status**
|
||||
|
||||
Run `openspec status --change "<name>" --json` to check artifact completion.
|
||||
|
||||
Parse the JSON to understand:
|
||||
- `schemaName`: The workflow being used
|
||||
- `artifacts`: List of artifacts with their status (`done` or other)
|
||||
|
||||
**If any artifacts are not `done`:**
|
||||
- Display warning listing incomplete artifacts
|
||||
- Use **AskUserQuestion tool** to confirm user wants to proceed
|
||||
- Proceed if user confirms
|
||||
|
||||
3. **Check task completion status**
|
||||
|
||||
Read the tasks file (typically `tasks.md`) to check for incomplete tasks.
|
||||
|
||||
Count tasks marked with `- [ ]` (incomplete) vs `- [x]` (complete).
|
||||
|
||||
**If incomplete tasks found:**
|
||||
- Display warning showing count of incomplete tasks
|
||||
- Use **AskUserQuestion tool** to confirm user wants to proceed
|
||||
- Proceed if user confirms
|
||||
|
||||
**If no tasks file exists:** Proceed without task-related warning.
|
||||
|
||||
4. **Assess delta spec sync state**
|
||||
|
||||
Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.
|
||||
|
||||
**If delta specs exist:**
|
||||
- Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`
|
||||
- Determine what changes would be applied (adds, modifications, removals, renames)
|
||||
- Show a combined summary before prompting
|
||||
|
||||
**Prompt options:**
|
||||
- If changes needed: "Sync now (recommended)", "Archive without syncing"
|
||||
- If already synced: "Archive now", "Sync anyway", "Cancel"
|
||||
|
||||
If user chooses sync, use Task tool (subagent_type: "general-purpose", prompt: "Use Skill tool to invoke openspec-sync-specs for change '<name>'. Delta spec analysis: <include the analyzed delta spec summary>"). Proceed to archive regardless of choice.
|
||||
|
||||
5. **Perform the archive**
|
||||
|
||||
Create the archive directory if it doesn't exist:
|
||||
```bash
|
||||
mkdir -p openspec/changes/archive
|
||||
```
|
||||
|
||||
Generate target name using current date: `YYYY-MM-DD-<change-name>`
|
||||
|
||||
**Check if target already exists:**
|
||||
- If yes: Fail with error, suggest renaming existing archive or using different date
|
||||
- If no: Move the change directory to archive
|
||||
|
||||
```bash
|
||||
mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>
|
||||
```
|
||||
|
||||
6. **Display summary**
|
||||
|
||||
Show archive completion summary including:
|
||||
- Change name
|
||||
- Schema that was used
|
||||
- Archive location
|
||||
- Whether specs were synced (if applicable)
|
||||
- Note about any warnings (incomplete artifacts/tasks)
|
||||
|
||||
**Output On Success**
|
||||
|
||||
```
|
||||
## Archive Complete
|
||||
|
||||
**Change:** <change-name>
|
||||
**Schema:** <schema-name>
|
||||
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
|
||||
**Specs:** ✓ Synced to main specs (or "No delta specs" or "Sync skipped")
|
||||
|
||||
All artifacts complete. All tasks complete.
|
||||
```
|
||||
|
||||
**Guardrails**
|
||||
- Always prompt for change selection if not provided
|
||||
- Use artifact graph (openspec status --json) for completion checking
|
||||
- Don't block archive on warnings - just inform and confirm
|
||||
- Preserve .openspec.yaml when moving to archive (it moves with the directory)
|
||||
- Show clear summary of what happened
|
||||
- If sync is requested, use openspec-sync-specs approach (agent-driven)
|
||||
- If delta specs exist, always run the sync assessment and show the combined summary before prompting
|
||||
288
.github/skills/openspec-explore/SKILL.md
vendored
Normal file
288
.github/skills/openspec-explore/SKILL.md
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
---
|
||||
name: openspec-explore
|
||||
description: Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: openspec
|
||||
version: "1.0"
|
||||
generatedBy: "1.2.0"
|
||||
---
|
||||
|
||||
Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
||||
|
||||
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing.
|
||||
|
||||
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
||||
|
||||
---
|
||||
|
||||
## The Stance
|
||||
|
||||
- **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
|
||||
- **Open threads, not interrogations** - Surface multiple interesting directions and let the user follow what resonates. Don't funnel them through a single path of questions.
|
||||
- **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
|
||||
- **Adaptive** - Follow interesting threads, pivot when new information emerges
|
||||
- **Patient** - Don't rush to conclusions, let the shape of the problem emerge
|
||||
- **Grounded** - Explore the actual codebase when relevant, don't just theorize
|
||||
|
||||
---
|
||||
|
||||
## What You Might Do
|
||||
|
||||
Depending on what the user brings, you might:
|
||||
|
||||
**Explore the problem space**
|
||||
- Ask clarifying questions that emerge from what they said
|
||||
- Challenge assumptions
|
||||
- Reframe the problem
|
||||
- Find analogies
|
||||
|
||||
**Investigate the codebase**
|
||||
- Map existing architecture relevant to the discussion
|
||||
- Find integration points
|
||||
- Identify patterns already in use
|
||||
- Surface hidden complexity
|
||||
|
||||
**Compare options**
|
||||
- Brainstorm multiple approaches
|
||||
- Build comparison tables
|
||||
- Sketch tradeoffs
|
||||
- Recommend a path (if asked)
|
||||
|
||||
**Visualize**
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Use ASCII diagrams liberally │
|
||||
├─────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────┐ ┌────────┐ │
|
||||
│ │ State │────────▶│ State │ │
|
||||
│ │ A │ │ B │ │
|
||||
│ └────────┘ └────────┘ │
|
||||
│ │
|
||||
│ System diagrams, state machines, │
|
||||
│ data flows, architecture sketches, │
|
||||
│ dependency graphs, comparison tables │
|
||||
│ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Surface risks and unknowns**
|
||||
- Identify what could go wrong
|
||||
- Find gaps in understanding
|
||||
- Suggest spikes or investigations
|
||||
|
||||
---
|
||||
|
||||
## OpenSpec Awareness
|
||||
|
||||
You have full context of the OpenSpec system. Use it naturally, don't force it.
|
||||
|
||||
### Check for context
|
||||
|
||||
At the start, quickly check what exists:
|
||||
```bash
|
||||
openspec list --json
|
||||
```
|
||||
|
||||
This tells you:
|
||||
- If there are active changes
|
||||
- Their names, schemas, and status
|
||||
- What the user might be working on
|
||||
|
||||
### When no change exists
|
||||
|
||||
Think freely. When insights crystallize, you might offer:
|
||||
|
||||
- "This feels solid enough to start a change. Want me to create a proposal?"
|
||||
- Or keep exploring - no pressure to formalize
|
||||
|
||||
### When a change exists
|
||||
|
||||
If the user mentions a change or you detect one is relevant:
|
||||
|
||||
1. **Read existing artifacts for context**
|
||||
- `openspec/changes/<name>/proposal.md`
|
||||
- `openspec/changes/<name>/design.md`
|
||||
- `openspec/changes/<name>/tasks.md`
|
||||
- etc.
|
||||
|
||||
2. **Reference them naturally in conversation**
|
||||
- "Your design mentions using Redis, but we just realized SQLite fits better..."
|
||||
- "The proposal scopes this to premium users, but we're now thinking everyone..."
|
||||
|
||||
3. **Offer to capture when decisions are made**
|
||||
|
||||
| Insight Type | Where to Capture |
|
||||
|--------------|------------------|
|
||||
| New requirement discovered | `specs/<capability>/spec.md` |
|
||||
| Requirement changed | `specs/<capability>/spec.md` |
|
||||
| Design decision made | `design.md` |
|
||||
| Scope changed | `proposal.md` |
|
||||
| New work identified | `tasks.md` |
|
||||
| Assumption invalidated | Relevant artifact |
|
||||
|
||||
Example offers:
|
||||
- "That's a design decision. Capture it in design.md?"
|
||||
- "This is a new requirement. Add it to specs?"
|
||||
- "This changes scope. Update the proposal?"
|
||||
|
||||
4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
|
||||
|
||||
---
|
||||
|
||||
## What You Don't Have To Do
|
||||
|
||||
- Follow a script
|
||||
- Ask the same questions every time
|
||||
- Produce a specific artifact
|
||||
- Reach a conclusion
|
||||
- Stay on topic if a tangent is valuable
|
||||
- Be brief (this is thinking time)
|
||||
|
||||
---
|
||||
|
||||
## Handling Different Entry Points
|
||||
|
||||
**User brings a vague idea:**
|
||||
```
|
||||
User: I'm thinking about adding real-time collaboration
|
||||
|
||||
You: Real-time collab is a big space. Let me think about this...
|
||||
|
||||
COLLABORATION SPECTRUM
|
||||
════════════════════════════════════════════
|
||||
|
||||
Awareness Coordination Sync
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌────────┐ ┌────────┐ ┌────────┐
|
||||
│Presence│ │Cursors │ │ CRDT │
|
||||
│ "3 │ │ Multi │ │Conflict│
|
||||
│online" │ │ select │ │ free │
|
||||
└────────┘ └────────┘ └────────┘
|
||||
│ │ │
|
||||
trivial moderate complex
|
||||
|
||||
Where's your head at?
|
||||
```
|
||||
|
||||
**User brings a specific problem:**
|
||||
```
|
||||
User: The auth system is a mess
|
||||
|
||||
You: [reads codebase]
|
||||
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ CURRENT AUTH FLOW │
|
||||
└─────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
▼ ▼ ▼
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Google │ │ GitHub │ │ Email │
|
||||
│ OAuth │ │ OAuth │ │ Magic │
|
||||
└────┬────┘ └────┬────┘ └────┬────┘
|
||||
│ │ │
|
||||
└─────────────┼─────────────┘
|
||||
▼
|
||||
┌───────────┐
|
||||
│ Session │
|
||||
└─────┬─────┘
|
||||
│
|
||||
▼
|
||||
┌───────────┐
|
||||
│ Perms │
|
||||
└───────────┘
|
||||
|
||||
I see three tangles. Which one's burning?
|
||||
```
|
||||
|
||||
**User is stuck mid-implementation:**
|
||||
```
|
||||
User: /opsx:explore add-auth-system
|
||||
The OAuth integration is more complex than expected
|
||||
|
||||
You: [reads change artifacts]
|
||||
|
||||
You're on task 4: "Implement OAuth flow"
|
||||
|
||||
Let me trace what's involved...
|
||||
|
||||
[draws diagram, explores options, suggests paths]
|
||||
|
||||
Want to update the design to reflect this?
|
||||
Or add a spike task to investigate?
|
||||
```
|
||||
|
||||
**User wants to compare options:**
|
||||
```
|
||||
User: Should we use Postgres or SQLite?
|
||||
|
||||
You: Generic answer is boring. What's the context?
|
||||
|
||||
User: A CLI tool that tracks local dev environments
|
||||
|
||||
You: That changes everything.
|
||||
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ CLI TOOL DATA STORAGE │
|
||||
└─────────────────────────────────────────────────┘
|
||||
|
||||
Key constraints:
|
||||
• No daemon running
|
||||
• Must work offline
|
||||
• Single user
|
||||
|
||||
SQLite Postgres
|
||||
Deployment embedded ✓ needs server ✗
|
||||
Offline yes ✓ no ✗
|
||||
Single file yes ✓ no ✗
|
||||
|
||||
SQLite. Not even close.
|
||||
|
||||
Unless... is there a sync component?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ending Discovery
|
||||
|
||||
There's no required ending. Discovery might:
|
||||
|
||||
- **Flow into a proposal**: "Ready to start? I can create a change proposal."
|
||||
- **Result in artifact updates**: "Updated design.md with these decisions"
|
||||
- **Just provide clarity**: User has what they need, moves on
|
||||
- **Continue later**: "We can pick this up anytime"
|
||||
|
||||
When it feels like things are crystallizing, you might summarize:
|
||||
|
||||
```
|
||||
## What We Figured Out
|
||||
|
||||
**The problem**: [crystallized understanding]
|
||||
|
||||
**The approach**: [if one emerged]
|
||||
|
||||
**Open questions**: [if any remain]
|
||||
|
||||
**Next steps** (if ready):
|
||||
- Create a change proposal
|
||||
- Keep exploring: just keep talking
|
||||
```
|
||||
|
||||
But this summary is optional. Sometimes the thinking IS the value.
|
||||
|
||||
---
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not.
|
||||
- **Don't fake understanding** - If something is unclear, dig deeper
|
||||
- **Don't rush** - Discovery is thinking time, not task time
|
||||
- **Don't force structure** - Let patterns emerge naturally
|
||||
- **Don't auto-capture** - Offer to save insights, don't just do it
|
||||
- **Do visualize** - A good diagram is worth many paragraphs
|
||||
- **Do explore the codebase** - Ground discussions in reality
|
||||
- **Do question assumptions** - Including the user's and your own
|
||||
110
.github/skills/openspec-propose/SKILL.md
vendored
Normal file
110
.github/skills/openspec-propose/SKILL.md
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
name: openspec-propose
|
||||
description: Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation.
|
||||
license: MIT
|
||||
compatibility: Requires openspec CLI.
|
||||
metadata:
|
||||
author: openspec
|
||||
version: "1.0"
|
||||
generatedBy: "1.2.0"
|
||||
---
|
||||
|
||||
Propose a new change - create the change and generate all artifacts in one step.
|
||||
|
||||
I'll create a change with artifacts:
|
||||
- proposal.md (what & why)
|
||||
- design.md (how)
|
||||
- tasks.md (implementation steps)
|
||||
|
||||
When ready to implement, run /opsx:apply
|
||||
|
||||
---
|
||||
|
||||
**Input**: The user's request should include a change name (kebab-case) OR a description of what they want to build.
|
||||
|
||||
**Steps**
|
||||
|
||||
1. **If no clear input provided, ask what they want to build**
|
||||
|
||||
Use the **AskUserQuestion tool** (open-ended, no preset options) to ask:
|
||||
> "What change do you want to work on? Describe what you want to build or fix."
|
||||
|
||||
From their description, derive a kebab-case name (e.g., "add user authentication" → `add-user-auth`).
|
||||
|
||||
**IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
|
||||
|
||||
2. **Create the change directory**
|
||||
```bash
|
||||
openspec new change "<name>"
|
||||
```
|
||||
This creates a scaffolded change at `openspec/changes/<name>/` with `.openspec.yaml`.
|
||||
|
||||
3. **Get the artifact build order**
|
||||
```bash
|
||||
openspec status --change "<name>" --json
|
||||
```
|
||||
Parse the JSON to get:
|
||||
- `applyRequires`: array of artifact IDs needed before implementation (e.g., `["tasks"]`)
|
||||
- `artifacts`: list of all artifacts with their status and dependencies
|
||||
|
||||
4. **Create artifacts in sequence until apply-ready**
|
||||
|
||||
Use the **TodoWrite tool** to track progress through the artifacts.
|
||||
|
||||
Loop through artifacts in dependency order (artifacts with no pending dependencies first):
|
||||
|
||||
a. **For each artifact that is `ready` (dependencies satisfied)**:
|
||||
- Get instructions:
|
||||
```bash
|
||||
openspec instructions <artifact-id> --change "<name>" --json
|
||||
```
|
||||
- The instructions JSON includes:
|
||||
- `context`: Project background (constraints for you - do NOT include in output)
|
||||
- `rules`: Artifact-specific rules (constraints for you - do NOT include in output)
|
||||
- `template`: The structure to use for your output file
|
||||
- `instruction`: Schema-specific guidance for this artifact type
|
||||
- `outputPath`: Where to write the artifact
|
||||
- `dependencies`: Completed artifacts to read for context
|
||||
- Read any completed dependency files for context
|
||||
- Create the artifact file using `template` as the structure
|
||||
- Apply `context` and `rules` as constraints - but do NOT copy them into the file
|
||||
- Show brief progress: "Created <artifact-id>"
|
||||
|
||||
b. **Continue until all `applyRequires` artifacts are complete**
|
||||
- After creating each artifact, re-run `openspec status --change "<name>" --json`
|
||||
- Check if every artifact ID in `applyRequires` has `status: "done"` in the artifacts array
|
||||
- Stop when all `applyRequires` artifacts are done
|
||||
|
||||
c. **If an artifact requires user input** (unclear context):
|
||||
- Use **AskUserQuestion tool** to clarify
|
||||
- Then continue with creation
|
||||
|
||||
5. **Show final status**
|
||||
```bash
|
||||
openspec status --change "<name>"
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
After completing all artifacts, summarize:
|
||||
- Change name and location
|
||||
- List of artifacts created with brief descriptions
|
||||
- What's ready: "All artifacts created! Ready for implementation."
|
||||
- Prompt: "Run `/opsx:apply` or ask me to implement to start working on the tasks."
|
||||
|
||||
**Artifact Creation Guidelines**
|
||||
|
||||
- Follow the `instruction` field from `openspec instructions` for each artifact type
|
||||
- The schema defines what each artifact should contain - follow it
|
||||
- Read dependency artifacts for context before creating new ones
|
||||
- Use `template` as the structure for your output file - fill in its sections
|
||||
- **IMPORTANT**: `context` and `rules` are constraints for YOU, not content for the file
|
||||
- Do NOT copy `<context>`, `<rules>`, `<project_context>` blocks into the artifact
|
||||
- These guide what you write, but should never appear in the output
|
||||
|
||||
**Guardrails**
|
||||
- Create ALL artifacts needed for implementation (as defined by schema's `apply.requires`)
|
||||
- Always read dependency artifacts before creating a new one
|
||||
- If context is critically unclear, ask the user - but prefer making reasonable decisions to keep momentum
|
||||
- If a change with that name already exists, ask if user wants to continue it or create a new one
|
||||
- Verify each artifact file exists after writing before proceeding to next
|
||||
119
docs/api-summary.md
Normal file
119
docs/api-summary.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# 接口汇总
|
||||
|
||||
## 基础地址
|
||||
|
||||
`public/config.js` 当前定义的基础地址如下:
|
||||
|
||||
| 标识 | 地址 | 典型用途 |
|
||||
| ------------ | --------------------------------------- | ---------------------------------------- |
|
||||
| `ApiList[0]` | `http://blv-rd.tech:19088/api/` | UDP 日志、房态、功率、用户信息、配置字典 |
|
||||
| `ApiList[1]` | `http://blv-rd.tech:19055/api/` | 酒店列表、主机列表、黑名单、房间统计 |
|
||||
| `ApiList[2]` | `http://www.boonlive-rcu.com:7000/api/` | TFTP/RCU 特定操作 |
|
||||
| `config.Api` | `http://blv-rd.tech:19088/api/` | `fetch` 文件上传等直接调用 |
|
||||
|
||||
## 按接口前缀整理
|
||||
|
||||
### UDPPackage
|
||||
|
||||
主要由 `ApiList[0]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| -------------------------------------- | ------------ | ------------------ |
|
||||
| `UDPPackage/GetUDPTotalAnalysis` | UDP 监控 | 查询 UDP 汇总统计 |
|
||||
| `UDPPackage/ExportUDPTotalAnalysis` | UDP 监控 | 导出 UDP 汇总数据 |
|
||||
| `UDPPackage/ConfigParameterSet` | UDP 监控 | 设置监控参数 |
|
||||
| `UDPPackage/GetUDPPackageTimeAnalysis` | 线程耗时记录 | 获取线程步骤耗时 |
|
||||
| `UDPPackage/Get_IOTLog` | 语音助手日志 | 获取语音日志 |
|
||||
| `UDPPackage/Get_IOTLogCount` | 语音助手日志 | 获取日志总数 |
|
||||
| `UDPPackage/Get_BeforeTakeCardStatus` | 房态日志 | 查询某时刻前置房态 |
|
||||
| `UDPPackage/Get_RCUStatus` | 房态日志 | 查询在线/离线房态 |
|
||||
| `UDPPackage/Get_TakeCardStatus` | 房态日志 | 查询取断电状态 |
|
||||
|
||||
### LowerMachineLog
|
||||
|
||||
主要由 `ApiList[1]` 承载,少部分页面也通过默认 `$http` 调同名前缀。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| ------------------------------ | --------------------------------------------------------- | ------------------ |
|
||||
| `LowerMachineLog/GetHotelList` | UDP 监控、黑名单、TFTP 管理、语音日志、房态日志、功率记录 | 获取酒店列表 |
|
||||
| `LowerMachineLog/GetHostList` | UDP 监控、黑名单、TFTP 管理、语音日志、房态日志 | 获取主机或房间列表 |
|
||||
|
||||
调用特征:
|
||||
|
||||
- 多数页面用 `qs.stringify(getdate)` 作为请求体。
|
||||
- 典型场景是根据酒店代码换取房间、主机或设备列表。
|
||||
|
||||
### BlockIP
|
||||
|
||||
主要由 `ApiList[1]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| -------------------------------- | -------------------------------------- | ------------------ |
|
||||
| `BlockIP/BlockLWRemove` | 黑名单管理 | 取消酒店过滤 |
|
||||
| `BlockIP/BlockLWSet` | 黑名单管理 | 设置酒店或主机过滤 |
|
||||
| `BlockIP/GetBlockLWSetData` | 黑名单管理 | 获取黑名单数据 |
|
||||
| `BlockIP/GetConfigParameterList` | UDP 监控 | 获取监控配置参数 |
|
||||
| `BlockIP/GetRoomCount` | UDP 监控、语音日志、房态日志、功率记录 | 获取酒店房间总数 |
|
||||
|
||||
### values
|
||||
|
||||
由 `ApiList[2]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| ------------------------ | --------- | ------------------ |
|
||||
| `values/GetTFTPInfo` | TFTP 管理 | 获取当前 TFTP 设置 |
|
||||
| `values/TFTPSet_Execute` | TFTP 管理 | 下发 TFTP 设置 |
|
||||
|
||||
### iis
|
||||
|
||||
由 `ApiList[2]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| ----------- | -------- | ----------------------- |
|
||||
| `iis/Recly` | UDP 监控 | 触发远程回收/重启类操作 |
|
||||
|
||||
### Power
|
||||
|
||||
由 `ApiList[0]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| ------------------------ | -------- | ---------------- |
|
||||
| `Power/GetPowerAnalysis` | 功率记录 | 查询功率分析数据 |
|
||||
|
||||
### ConfigPY
|
||||
|
||||
由 `ApiList[0]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| -------------------------------- | -------- | -------------- |
|
||||
| `ConfigPY/GetConfigString` | 字典管理 | 获取配置字典 |
|
||||
| `ConfigPY/SaveOrAddConfigString` | 字典管理 | 保存配置字典 |
|
||||
| `ConfigPY/GetSingleValue` | 个人设置 | 获取单项配置值 |
|
||||
|
||||
### Users / Company
|
||||
|
||||
由 `ApiList[0]` 承载。
|
||||
|
||||
| 接口 | 调用页面 | 作用 |
|
||||
| -------------------- | -------- | ------------ |
|
||||
| `Company/GetComInfo` | 个人设置 | 获取公司信息 |
|
||||
| `Users/GetUserInfo` | 个人设置 | 获取用户详情 |
|
||||
| `Users/EditUser` | 个人设置 | 更新用户资料 |
|
||||
|
||||
### FileUpload
|
||||
|
||||
直接通过 `fetch(config.Api + 'FileUpload/UploadFile')` 调用。
|
||||
|
||||
| 接口 | 调用位置 | 作用 |
|
||||
| ----------------------- | --------------------------- | ------------------ |
|
||||
| `FileUpload/UploadFile` | `App.vue` 注入的 `ajaxfile` | 上传头像或其他文件 |
|
||||
|
||||
## 参数风格说明
|
||||
|
||||
项目接口调用参数并不统一,主要有三种:
|
||||
|
||||
- 直接传对象,让 axios 拦截器自动 `JSON.stringify`。
|
||||
- 调用方先手动 `JSON.stringify`,再传给 axios。
|
||||
- 用 `qs.stringify` 组装表单格式参数,并附带自定义 headers。
|
||||
|
||||
后续维护时,不要想当然把所有 POST 都改成传对象;必须先确认目标接口当前依赖的是哪一种风格。
|
||||
172
docs/page-functions.md
Normal file
172
docs/page-functions.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# 页面功能说明
|
||||
|
||||
## 页面总表
|
||||
|
||||
| 页面 | 路由 | 是否在主菜单展示 | 功能摘要 | 主要接口 |
|
||||
| ------------ | ------------------ | ---------------- | --------------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
| 登录 | `/login` | 否 | 账号密码验证码登录,支持记住我和错误次数锁定 | 当前未接正式后端登录接口 |
|
||||
| 主页 | `/home` | 否 | 中转页,进入后自动跳到 UDP 监控 | 无 |
|
||||
| UDP 监控 | `/udplog` | 是 | 查看 UDP 汇总指标、时间筛选、酒店筛选、导出、配置下发、主机详情 | `UDPPackage/*`、`LowerMachineLog/*`、`BlockIP/*`、`iis/Recly` |
|
||||
| 线程耗时记录 | `/tasktimelog` | 是 | 查询线程步骤耗时、分页、导出 | `UDPPackage/GetUDPPackageTimeAnalysis` |
|
||||
| 黑名单管理 | `/blacklist` | 是 | 酒店维度黑名单查看、过滤、取消过滤、按酒店查主机 | `BlockIP/*`、`LowerMachineLog/*` |
|
||||
| TFTP 管理 | `/tftpwhitelist` | 是 | 酒店和房间维度 TFTP 上传设置、白名单管理 | `values/*`、`LowerMachineLog/*` |
|
||||
| 语音助手日志 | `/voicelog` | 是 | 语音请求链路日志、异常筛选、懒加载 | `UDPPackage/Get_IOTLog*`、`LowerMachineLog/*` |
|
||||
| 房态日志 | `/statuslog` | 是 | 房态/取电/离在线统计、房间时序详情、历史状态查询 | `UDPPackage/Get_*Status`、`LowerMachineLog/*` |
|
||||
| 功率记录 | `/powerlog` | 否 | 查询酒店功率分析数据 | `Power/GetPowerAnalysis`、`LowerMachineLog/*` |
|
||||
| 字典管理 | 已注释 | 否 | 维护配置字典与区域字典 | `ConfigPY/GetConfigString`、`ConfigPY/SaveOrAddConfigString` |
|
||||
| 个人设置 | 未接路由 | 否 | 查看并修改当前用户资料,带头像上传 | `Company/*`、`Users/*`、`FileUpload/UploadFile` |
|
||||
| 404 | `/:pathMatch(.*)*` | 否 | 未匹配路由兜底页 | 无 |
|
||||
|
||||
## 登录页
|
||||
|
||||
文件:`src/pages/login/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 账号、密码、验证码三段式表单。
|
||||
- 支持“记住我”,将用户名和密码写入本地存储。
|
||||
- 连续输错达到阈值后锁定,锁定结束时间也写入本地存储。
|
||||
|
||||
关键注意事项:
|
||||
|
||||
- 当前登录是前端硬编码账号密码校验。
|
||||
- 注释里保留了旧的后端登录接口 `LeiDa/Login`,但未启用。
|
||||
- 登录成功后通过 `localStorage.login` 与 `localStorage.TokenT` 控制会话。
|
||||
|
||||
## UDP 监控页
|
||||
|
||||
文件:`src/pages/udplog/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 支持“今天 / 3 天内 / 更多”时间筛选。
|
||||
- 支持普通模式与全屏模式切换。
|
||||
- 支持按酒店查看聚合数据,也支持查看某酒店主机详情。
|
||||
- 支持导出 UDP 统计结果。
|
||||
- 支持获取和下发监控配置参数。
|
||||
- 包含对 RCU 侧 `iis/Recly` 的调用入口。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 统计与导出走 `UDPPackage`。
|
||||
- 酒店和主机信息来自 `LowerMachineLog`。
|
||||
- 参数配置和房间计数来自 `BlockIP`。
|
||||
|
||||
## 线程耗时记录页
|
||||
|
||||
文件:`src/pages/tasktimelog/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 根据起止时间查询 UDP 包各处理步骤耗时。
|
||||
- 表格列根据步骤动态展开。
|
||||
- 支持分页、快捷时间按钮、导出 Excel。
|
||||
|
||||
维护价值:
|
||||
|
||||
- 适合排查某条命令链路在哪一步耗时异常。
|
||||
- Popover 中能看到步骤描述、触发时间、部分消息内容。
|
||||
|
||||
## 黑名单管理页
|
||||
|
||||
文件:`src/pages/blacklist/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 查看所有酒店是否已进入过滤名单。
|
||||
- 可按酒店名称或编号搜索。
|
||||
- 支持“只显示过滤名单”。
|
||||
- 支持整酒店加入或移出黑名单。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 黑名单增删改查全部走 `BlockIP`。
|
||||
- 酒店列表与主机列表走 `LowerMachineLog`。
|
||||
|
||||
## TFTP 管理页
|
||||
|
||||
文件:`src/pages/tftpwhitelist/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 查看酒店维度 TFTP 上传白名单。
|
||||
- 支持整酒店上传和单房间上传。
|
||||
- 支持打开房间列表查看设备版本、机型、MAC。
|
||||
- 支持配置端口、域名、上传时长等 TFTP 设置。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 白名单和房间数据来自 `LowerMachineLog`。
|
||||
- RCU 侧配置由 `values/GetTFTPInfo` 与 `values/TFTPSet_Execute` 完成。
|
||||
|
||||
## 语音助手日志页
|
||||
|
||||
文件:`src/pages/voicelog/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 按酒店、房间和时间区间查询语音请求日志。
|
||||
- 日志按 `requestId` 折叠分组展示。
|
||||
- 支持异常过滤和“加载全部”开关。
|
||||
- 做了懒加载和时间片拉取,适合大数据量场景。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 主日志来自 `UDPPackage/Get_IOTLog` 与 `UDPPackage/Get_IOTLogCount`。
|
||||
- 酒店、房间、房间总数来自 `LowerMachineLog` 和 `BlockIP/GetRoomCount`。
|
||||
|
||||
## 房态日志页
|
||||
|
||||
文件:`src/pages/statuslog/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 可以按酒店、房间、多酒店、时间区间查询房态。
|
||||
- 汇总表展示当前在线状态、离线次数、当前取电状态、取断电次数。
|
||||
- 点击房间可进入时序详情弹窗,查看在线/离线与取电/断电时间轴。
|
||||
- 支持查询某个历史时刻的在线状态和取电状态。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 核心状态查询走 `UDPPackage/Get_RCUStatus`、`Get_TakeCardStatus`、`Get_BeforeTakeCardStatus`。
|
||||
- 酒店、房间基础数据走 `LowerMachineLog`。
|
||||
|
||||
## 功率记录页
|
||||
|
||||
文件:`src/pages/powerlog/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 当前实现较轻,核心是选择酒店并请求功率分析数据。
|
||||
- 页面代码更像实验或预研状态,尚未形成完整运营页面。
|
||||
|
||||
接口特征:
|
||||
|
||||
- 主数据接口是 `Power/GetPowerAnalysis`。
|
||||
- 酒店列表和房间总数仍来自 `LowerMachineLog` 与 `BlockIP/GetRoomCount`。
|
||||
|
||||
## 字典管理页
|
||||
|
||||
文件:`src/pages/dicmanage/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 展示并编辑通用字典值。
|
||||
- 对“区域”字典提供省份选择弹窗和结构化编辑能力。
|
||||
- 适合后台配置维护,但当前路由被注释,默认不可达。
|
||||
|
||||
## 个人设置页
|
||||
|
||||
文件:`src/pages/logsetup/index.vue`
|
||||
|
||||
主要内容:
|
||||
|
||||
- 展示登录用户信息。
|
||||
- 支持编辑真实姓名、手机号、邮箱、微信号。
|
||||
- 预留头像上传能力。
|
||||
|
||||
关键注意事项:
|
||||
|
||||
- 页面未接入当前路由。
|
||||
- 头像上传代码存在明显不完整逻辑,`filedata` 变量在启用分支中未定义。
|
||||
- 当前更像未完全收尾的个人中心页。
|
||||
123
docs/project-overview.md
Normal file
123
docs/project-overview.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# BLS Web Vue 项目总览
|
||||
|
||||
## 文档目标
|
||||
|
||||
本文档用于给后续维护人员快速建立认知,重点覆盖以下内容:
|
||||
|
||||
- 项目入口与运行方式
|
||||
- 路由、菜单和页面结构
|
||||
- 后端接口域名与调用分层
|
||||
- 当前项目中值得注意的非标准实现
|
||||
- 关联文档索引
|
||||
|
||||
## 技术栈
|
||||
|
||||
- 前端框架:Vue 3 + Vite
|
||||
- UI 组件:Element Plus
|
||||
- 路由:Vue Router 4
|
||||
- 国际化:vue-i18n
|
||||
- 数据请求:axios、fetch、jQuery.ajax 混用
|
||||
- 数据处理:dayjs、qs、xlsx
|
||||
|
||||
## 项目入口
|
||||
|
||||
- 页面入口:`src/main.js`
|
||||
- 根组件:`src/App.vue`
|
||||
- 路由定义:`src/router/index.js`
|
||||
- 请求封装:`src/axios.js`
|
||||
- 运行配置:`public/config.js`
|
||||
|
||||
## 运行说明
|
||||
|
||||
`package.json` 中当前可见脚本:
|
||||
|
||||
- `npm run dev`:启动本地开发环境
|
||||
- `npm run build`:构建生产包
|
||||
- `npm run preview`:本地预览构建结果
|
||||
- `npm run lint`:执行 eslint,并带 `--fix`
|
||||
|
||||
当前仓库没有现成的测试脚本,属于典型的“已交付老项目,缺少自动化回归”的状态。
|
||||
|
||||
## 认证与访问控制
|
||||
|
||||
项目的访问控制依赖浏览器存储,不是标准的后端 token 鉴权流:
|
||||
|
||||
- 路由守卫依据 `localStorage.TokenT` 判断是否已登录。
|
||||
- 登录页当前使用前端硬编码账号密码校验,而不是正式后端登录接口。
|
||||
- `TokenT` 实际保存的是一个时间字符串,用于计算“3 天内免密登录”。
|
||||
- `localStorage.login` 被用来控制布局切换与页面状态。
|
||||
- 菜单权限目前被写死为 `全选`,没有接入真实权限接口。
|
||||
|
||||
这意味着:后续如果要补安全能力,登录、权限、会话续期都需要整体重构,不能把当前实现视为最终鉴权方案。
|
||||
|
||||
## 路由与菜单概览
|
||||
|
||||
路由层当前启用的页面:
|
||||
|
||||
| 路由 | 页面名称 | 状态 |
|
||||
| ------------------ | ------------ | ------------------------------ |
|
||||
| `/login` | 登录 | 启用 |
|
||||
| `/home` | 主页 | 启用,进入后立即跳转 `/udplog` |
|
||||
| `/udplog` | UDP 监控 | 启用 |
|
||||
| `/tasktimelog` | 线程耗时记录 | 启用 |
|
||||
| `/blacklist` | 黑名单管理 | 启用 |
|
||||
| `/tftpwhitelist` | TFTP 管理 | 启用 |
|
||||
| `/voicelog` | 语音助手日志 | 启用 |
|
||||
| `/statuslog` | 房态日志 | 启用 |
|
||||
| `/powerlog` | 功率记录 | 路由启用,但菜单默认隐藏 |
|
||||
| `/:pathMatch(.*)*` | 404 | 启用 |
|
||||
|
||||
代码存在但默认未接入主流程的页面:
|
||||
|
||||
- `src/pages/dicmanage/index.vue`:路由被注释,属于后台字典管理页。
|
||||
- `src/pages/logsetup/index.vue`:未在路由中注册,属于个人资料维护页。
|
||||
- `src/pages/udpconn/index.vue`:目录存在,但当前未接入路由或菜单。
|
||||
|
||||
## 后端域名与调用层次
|
||||
|
||||
`public/config.js` 中定义了三套主要地址:
|
||||
|
||||
- `ApiList[0]`:`http://blv-rd.tech:19088/api/`,主日志平台接口。
|
||||
- `ApiList[1]`:`http://blv-rd.tech:19055/api/`,酒店/黑名单/主机相关接口。
|
||||
- `ApiList[2]`:`http://www.boonlive-rcu.com:7000/api/`,RCU/TFTP 相关接口。
|
||||
|
||||
请求层分为四种:
|
||||
|
||||
- 默认 `$http`:来自 `src/axios.js` 默认实例。
|
||||
- `createAxiosInstance(1)`:显式切到 `ApiList[1]`。
|
||||
- `createAxiosInstance(2)`:显式切到 `ApiList[2]`。
|
||||
- `fetch` / `$.ajax`:在 `App.vue` 中作为补充能力直接注入。
|
||||
|
||||
## 请求封装摘要
|
||||
|
||||
`src/axios.js` 的行为需要重点注意:
|
||||
|
||||
- `createAxiosInstance` 参数不是任意 `baseURL`,而是 `ApiList` 下标。
|
||||
- 请求拦截器会在 `config.data` 为对象时自动执行 `JSON.stringify`。
|
||||
- 项目内部大量页面又手动对参数做了一次 `JSON.stringify`,形成“调用方自己转 JSON,拦截器有时也会转”的混合风格。
|
||||
- 某些接口使用 `qs.stringify` 发 `application/x-www-form-urlencoded`,通过第三个参数传 headers。
|
||||
- 响应拦截器几乎不做统一错误处理,只是 `console.log` 后抛出异常。
|
||||
|
||||
## App.vue 提供的全局能力
|
||||
|
||||
根组件除了渲染菜单和布局,还承担了一些基础设施职责:
|
||||
|
||||
- 通过 provide 注入 `$http`、`config`、`checkLoginStatus`、`isMobile`、`fullScreen`。
|
||||
- 提供 `ajaxfile(form)`,以 `fetch + FormData` 上传文件到 `FileUpload/UploadFile`。
|
||||
- 提供 `ajax(api, form)`,使用 `jQuery.ajax` 发送 JSON POST 请求。
|
||||
- 管理深浅色主题、菜单切换、浏览器尺寸监听和基础登录状态刷新。
|
||||
|
||||
## 开发风险与维护建议
|
||||
|
||||
- 登录逻辑是前端硬编码,不能作为正式生产安全实现继续扩展。
|
||||
- 路由、菜单和页面目录存在不一致,新增功能前要先确认是否接入菜单、路由、缓存和权限。
|
||||
- 页面对后端接口依赖很分散,且经常跨三个基础域名切换,排查接口问题时必须先确认 axios 实例来源。
|
||||
- 代码中存在多套请求方式并存的情况,后续统一封装前应先做接口盘点。
|
||||
- 项目当前没有系统化的 API 文档,维护时应优先参考本次新增的接口汇总文档。
|
||||
|
||||
## 文档索引
|
||||
|
||||
- `docs/project-overview.md`:项目总览
|
||||
- `docs/page-functions.md`:页面功能说明
|
||||
- `docs/api-summary.md`:接口汇总
|
||||
- `docs/tooling-notes.md`:工具与非标准实现说明
|
||||
96
docs/tooling-notes.md
Normal file
96
docs/tooling-notes.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# 工具与非标准实现说明
|
||||
|
||||
## axios 封装
|
||||
|
||||
文件:`src/axios.js`
|
||||
|
||||
当前项目的 axios 封装与常规写法有几个明显差异:
|
||||
|
||||
1. `createAxiosInstance(urlnum)` 参数语义是“配置下标”,不是完整 URL。
|
||||
2. `baseURL` 固定取自 `config.ApiList[urlnum || 0]`。
|
||||
3. 请求拦截器会把对象类型的 `config.data` 自动转成 JSON 字符串。
|
||||
4. 如果页面已经手工 `JSON.stringify`,拦截器不会再重复转换,但代码阅读成本会升高。
|
||||
5. 响应拦截器没有统一消息提示,也没有 token 失效处理。
|
||||
|
||||
建议:如果后续要统一网络层,先做接口分组和参数样式清查,不要直接全局替换。
|
||||
|
||||
## 全局注入能力
|
||||
|
||||
文件:`src/main.js`、`src/App.vue`
|
||||
|
||||
项目通过 provide/inject 暴露了多项全局能力:
|
||||
|
||||
- `$http`:默认 axios 实例
|
||||
- `config`:运行配置
|
||||
- `checkLoginStatus`:登录状态检查
|
||||
- `calculateTimeDiff`:时间差辅助方法
|
||||
- `isMobile`:移动端状态
|
||||
- `fullScreen`:页面全屏状态
|
||||
- `ajaxfile`:`fetch + FormData` 文件上传
|
||||
- `ajax`:`jQuery.ajax` JSON 请求
|
||||
|
||||
这意味着很多页面不是从模块 import 工具函数,而是依赖根组件注入。迁移或拆分页面时需要同步处理这些依赖。
|
||||
|
||||
## 本地存储约定
|
||||
|
||||
项目大量依赖浏览器存储保存运行态:
|
||||
|
||||
- `TokenT`:保存时间字符串,用于免密登录窗口判断
|
||||
- `login`:字符串形式的登录标记
|
||||
- `username`:当前用户名
|
||||
- `url`:上次停留的页面路由
|
||||
- `rememberedUsername` / `rememberedPassword`:登录页记住我
|
||||
- `loginErrorAttempts` / `loginLockUntil`:登录错误计数和锁定信息
|
||||
- `currentRoute`:路由守卫中记录当前访问路径
|
||||
|
||||
这套约定分散在多个页面和根组件中,没有中心化状态管理。
|
||||
|
||||
## 非标准登录实现
|
||||
|
||||
登录页当前是演示型或临时型实现:
|
||||
|
||||
- 用户名和密码写在页面常量 `validUsers` 中。
|
||||
- 注释中保留了旧接口调用痕迹,但并未启用。
|
||||
- 路由守卫依赖 `TokenT` 时间串,而不是标准 JWT 或 session token。
|
||||
|
||||
如果未来要正式上线鉴权,应整体替换,而不是局部打补丁。
|
||||
|
||||
## jQuery.ajax 与 fetch 仍在使用
|
||||
|
||||
文件:`src/App.vue`
|
||||
|
||||
虽然项目主体已经使用 Vue 3,但根组件仍保留了旧式辅助方法:
|
||||
|
||||
- `ajaxfile`:手写 `fetch` 上传,额外拼接了 `Authorization` 请求头。
|
||||
- `ajax`:使用 `$.ajax` 发送 JSON 请求。
|
||||
|
||||
说明项目经历过多轮演化,存在旧工具与新工具并存的历史包袱。
|
||||
|
||||
## MinuteIndex 工具类
|
||||
|
||||
文件:`src/utils/index.js`
|
||||
|
||||
`MinuteIndex` 用于把日志对象按“分钟 + commandType”索引到 `Map` 中,便于高频查询:
|
||||
|
||||
- 适合按分钟级时间快速定位同一命令类型的数据。
|
||||
- 用 `WeakMap` 追踪对象位置,支持更新和移除。
|
||||
- 对时间字符串做了局部格式标准化处理。
|
||||
|
||||
该工具体现出页面中存在一定的前端侧数据索引需求,不完全依赖后端聚合。
|
||||
|
||||
## 页面状态与菜单控制
|
||||
|
||||
文件:`src/App.vue`
|
||||
|
||||
菜单、缓存、主题切换等逻辑都集中在根组件:
|
||||
|
||||
- 菜单项写死在 `menuValue`。
|
||||
- 页面权限目前默认全部开放。
|
||||
- 主题切换同时操作 Element Plus 深浅模式和自定义 CSS 变量。
|
||||
- `home` 实际只是跳转页,不是业务主页。
|
||||
|
||||
## 建议的维护策略
|
||||
|
||||
- 新增接口前,先决定接入哪一套 baseURL,再确定用默认 `$http` 还是 `createAxiosInstance`。
|
||||
- 新增页面前,先同时检查目录、路由、菜单、权限过滤和缓存策略。
|
||||
- 若要做重构,优先从登录、请求层、全局注入三块入手,因为它们是当前项目最明显的历史耦合点。
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-03-06
|
||||
72
openspec/changes/legacy-project-documentation/design.md
Normal file
72
openspec/changes/legacy-project-documentation/design.md
Normal file
@@ -0,0 +1,72 @@
|
||||
## Context
|
||||
|
||||
当前仓库是 Vue 3 + Vite 前端项目,核心业务页面主要集中在 UDP 监控、房态日志、语音助手日志、黑名单和 TFTP 管理等模块。项目已经交付使用,但存在典型老项目特征:
|
||||
|
||||
- 文档缺失,页面和接口关系需要靠读代码还原。
|
||||
- 登录与权限实现带有临时方案痕迹。
|
||||
- 请求层同时混用 axios、fetch、jQuery.ajax。
|
||||
- 路由、菜单与页面目录不完全一致,部分页面已经脱离主流程。
|
||||
|
||||
本次变更的目标不是重构实现,而是沉淀一份足够支撑后续维护的知识底座,并把文档化工作本身纳入 OpenSpec 变更流程。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 建立一个正式的 OpenSpec change,记录本次老项目文档化工作。
|
||||
- 产出面向维护的 Markdown 文档,帮助后续开发快速定位页面、接口和工具约定。
|
||||
- 明确当前项目中的高风险历史实现,为未来重构提供入口信息。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不修改任何业务页面逻辑。
|
||||
- 不修复历史遗留 bug。
|
||||
- 不统一重构 axios、登录或权限系统。
|
||||
- 不补充自动化测试或发布流程。
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1:文档按“总览 / 页面 / 接口 / 工具”四类拆分
|
||||
|
||||
理由:老项目维护时,最常见的问题分别是“项目怎么进”“页面做什么”“接口从哪来”“工具为什么这么写”。按这四个维度拆开,检索效率最高。
|
||||
|
||||
备选方案:
|
||||
|
||||
- 只保留一个总文档。缺点是后续持续扩展时会迅速膨胀,不利于查找。
|
||||
|
||||
### Decision 2:将旧规范草稿完全收敛到 `openspec/changes/` 正式资产
|
||||
|
||||
理由:项目已经具备正式的 OpenSpec 目录结构,继续保留额外的 `spec/` 目录只会制造双入口和歧义。统一到 `openspec/changes/` 后,后续维护路径更清晰。
|
||||
|
||||
备选方案:
|
||||
|
||||
- 保留旧 `spec/` 目录做兼容说明。缺点是会持续造成“哪里才是规范源”的认知负担。
|
||||
|
||||
### Decision 3:只做静态文档化,不试图在本次变更中修复源码问题
|
||||
|
||||
理由:用户明确要求不能修改代码;同时老项目中存在多个潜在问题点,若在同一次变更中混入修复,会扩大范围并提高风险。
|
||||
|
||||
备选方案:
|
||||
|
||||
- 在文档化时顺手修复明显问题。缺点是违反本次约束,也会让变更边界变得不清晰。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [风险] 文档来自静态代码阅读,无法覆盖运行期才会暴露的动态行为。 → 缓解:重点记录可确认的页面、接口和工具约定,不对未验证行为做过度推断。
|
||||
- [风险] 某些页面未接路由或菜单,文档内容可能与当前实际使用范围不完全一致。 → 缓解:在文档中显式区分“已启用”和“代码存在但未接入”。
|
||||
- [风险] 旧目录删除后,历史使用者可能短期内找不到原来的路径。 → 缓解:将有效内容全部并入 `openspec/changes/`,并确保当前 change 可被 OpenSpec CLI 正常识别。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
本次变更没有运行时迁移动作,只有文档与规范资产补齐:
|
||||
|
||||
1. 通过 OpenSpec CLI 初始化并更新仓库级规范资产。
|
||||
2. 创建正式 change:`legacy-project-documentation`。
|
||||
3. 输出文档文件到 `docs/`。
|
||||
4. 删除旧 `spec/` 目录,确保规范入口唯一。
|
||||
5. 后续新需求统一转到 `openspec/changes/` 下开展。
|
||||
|
||||
## Open Questions
|
||||
|
||||
- 登录与权限逻辑是否要单独立项做安全性重构。
|
||||
- 请求层是否需要拆分为“主平台 / 辅助平台 / RCU”三个显式 SDK。
|
||||
26
openspec/changes/legacy-project-documentation/proposal.md
Normal file
26
openspec/changes/legacy-project-documentation/proposal.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## Why
|
||||
|
||||
这个仓库是一个已经完成开发的老项目,现有代码能够运行,但缺少可持续维护所需的项目文档与正式的 OpenSpec 变更资产。当前维护者需要同时理解路由、页面能力、接口分布、请求封装和历史遗留实现,如果继续在无文档状态下迭代,后续开发和排障成本会持续升高。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 重新通过命令行初始化 OpenSpec CLI,并把当前仓库接入 GitHub Copilot 可识别的 OpenSpec 工作流。
|
||||
- 为现有 Vue 项目补齐开发文档,包括项目总览、页面功能说明、接口汇总和工具/约定说明。
|
||||
- 记录老项目中的关键历史实现特征,例如前端硬编码登录、axios 的下标式 baseURL 选择、请求参数风格混用等。
|
||||
- 明确哪些页面已启用、哪些页面存在代码但未接入路由或菜单,降低后续误判风险。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `project-documentation`: 为现有老项目提供结构化的维护文档,覆盖页面职责、接口来源、工具封装和后续维护注意事项。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- 无。
|
||||
|
||||
## Impact
|
||||
|
||||
- 影响目录:`.github/`、`openspec/`、`docs/`
|
||||
- 不影响目录:`src/`、`public/`、构建配置与运行逻辑
|
||||
- 影响对象:后续维护人员、接手开发人员、基于 GitHub Copilot/OpenSpec 的协作流程
|
||||
@@ -0,0 +1,37 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Maintainers can quickly understand project structure
|
||||
|
||||
The project SHALL provide a maintainer-facing overview document that explains the technical stack, application entry points, routing structure, backend endpoint groups, and major historical implementation constraints.
|
||||
|
||||
#### Scenario: New maintainer reads project overview
|
||||
|
||||
- **WHEN** a maintainer opens the project overview documentation
|
||||
- **THEN** the document SHALL describe the runtime stack, entry files, route map, backend base URLs, and high-level maintenance risks
|
||||
|
||||
### Requirement: Maintainers can identify page responsibilities
|
||||
|
||||
The project SHALL provide a page function document that maps routes and page files to their operational purpose, key UI behaviors, and primary backend dependencies.
|
||||
|
||||
#### Scenario: Developer investigates a page before making changes
|
||||
|
||||
- **WHEN** a developer needs to understand what a page does
|
||||
- **THEN** the documentation SHALL state whether the page is enabled, what data it presents, and which interfaces it uses
|
||||
|
||||
### Requirement: Maintainers can trace API usage by domain
|
||||
|
||||
The project SHALL provide an API summary that groups endpoints by backend domain or controller prefix and identifies where each endpoint is called.
|
||||
|
||||
#### Scenario: Developer checks where an endpoint is used
|
||||
|
||||
- **WHEN** a developer searches the API summary for a controller prefix or endpoint name
|
||||
- **THEN** the documentation SHALL show the target page and the purpose of that call
|
||||
|
||||
### Requirement: Maintainers can recognize non-standard project conventions
|
||||
|
||||
The project SHALL document non-standard request, login, storage, and global injection patterns that differ from typical Vue application conventions.
|
||||
|
||||
#### Scenario: Developer prepares a refactor plan
|
||||
|
||||
- **WHEN** a developer reviews tooling and implementation notes
|
||||
- **THEN** the documentation SHALL explain unusual patterns such as down-indexed axios base URL selection, mixed request styles, hardcoded login behavior, and root-level dependency injection
|
||||
22
openspec/changes/legacy-project-documentation/tasks.md
Normal file
22
openspec/changes/legacy-project-documentation/tasks.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## 1. OpenSpec 接入
|
||||
|
||||
- [x] 1.1 通过命令行在当前仓库重新初始化 OpenSpec CLI 资产
|
||||
- [x] 1.2 创建 `legacy-project-documentation` 正式 change
|
||||
- [x] 1.3 将旧 `spec/` 目录内容迁移并收敛到正式 `openspec/` 目录
|
||||
|
||||
## 2. 项目资料盘点
|
||||
|
||||
- [x] 2.1 梳理当前路由、菜单和页面启用状态
|
||||
- [x] 2.2 梳理主要接口分组、基础地址和调用页面
|
||||
- [x] 2.3 梳理 axios、fetch、jQuery.ajax、全局注入等工具约定
|
||||
|
||||
## 3. 文档输出
|
||||
|
||||
- [x] 3.1 输出项目总览文档
|
||||
- [x] 3.2 输出页面功能说明文档
|
||||
- [x] 3.3 输出接口汇总文档
|
||||
- [x] 3.4 输出工具与非标准实现说明文档
|
||||
|
||||
## 4. 规范校验
|
||||
|
||||
- [x] 4.1 运行 OpenSpec 校验并确认本次 change 结构可用
|
||||
Reference in New Issue
Block a user