@wwkit/harness 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/extract.md +2 -14
- package/agents/lint.md +367 -0
- package/agents/pyit.md +361 -0
- package/agents/pyut.md +347 -0
- package/agents/query.md +2 -14
- package/agents/revise.md +2 -14
- package/agents/work.md +151 -0
- package/commands/git-sync.md +218 -0
- package/commands/net-port.md +364 -0
- package/commands/pyit.md +6 -0
- package/commands/pyut.md +6 -0
- package/commands/resume.md +104 -0
- package/package.json +2 -2
- package/skills/better-skill/SKILL.md +124 -0
- package/skills/blame-skill/SKILL.md +201 -0
- package/skills/lint-ai-fix/SKILL.md +141 -0
- package/skills/lint-config-setup/SKILL.md +106 -0
- package/skills/lint-config-setup/references/languages/js.md +110 -0
- package/skills/lint-config-setup/references/languages/py.md +89 -0
- package/skills/lint-env-ensure/SKILL.md +92 -0
- package/skills/lint-env-ensure/references/config.md +65 -0
- package/skills/lint-language-detect/SKILL.md +79 -0
- package/skills/lint-language-detect/references/detect-language.js +65 -0
- package/skills/lint-rules-analyze/SKILL.md +129 -0
- package/skills/lint-suitability-check/SKILL.md +84 -0
- package/skills/lint-tool-fix/SKILL.md +94 -0
- package/skills/new-skill/SKILL.md +227 -0
- package/skills/new-skill/references/template.md +53 -0
- package/skills/new-skill/references/workflow-patterns.md +104 -0
- package/skills/pytest-case-create/SKILL.md +327 -0
- package/skills/pytest-case-create/references/test-standards.md +244 -0
- package/skills/pytest-case-fix/SKILL.md +274 -0
- package/skills/pytest-coverage-analyze/SKILL.md +226 -0
- package/skills/pytest-coverage-analyze/references/scoring-rules.md +57 -0
- package/skills/pytest-env-ensure/SKILL.md +198 -0
- package/skills/pytest-env-ensure/references/config.md +145 -0
- package/skills/pytest-execute/SKILL.md +155 -0
- package/skills/pytest-sample/SKILL.md +164 -0
- package/skills/pytest-sample/references/src/pytest-sample/Calculator.py +67 -0
- package/skills/pytest-sample/references/src/pytest-sample/ConfigManager.py +68 -0
- package/skills/pytest-sample/references/src/pytest-sample/FileProcessor.py +53 -0
- package/skills/pytest-sample/references/src/pytest-sample/OrderService.py +82 -0
- package/skills/pytest-sample/references/src/pytest-sample/TokenGenerator.py +50 -0
- package/skills/pytest-sample/references/src/pytest-sample/UserService.py +45 -0
- package/skills/pytest-sample/references/src/pytest-sample/__init__.py +0 -0
- package/skills/pytest-suitability-check/SKILL.md +224 -0
- package/skills/read-docs/SKILL.md +134 -0
- package/skills/read-docs/references/opencode/agents/cases.md +206 -0
- package/skills/read-docs/references/opencode/agents/design-pattern.md +47 -0
- package/skills/read-docs/references/opencode/agents/detail.md +191 -0
- package/skills/read-docs/references/opencode/agents/examples.md +100 -0
- package/skills/read-docs/references/opencode/agents/index.md +307 -0
- package/skills/read-docs/references/opencode/agents/workflow.md +161 -0
- package/skills/read-docs/references/opencode/cli/commands/acp.md +32 -0
- package/skills/read-docs/references/opencode/cli/commands/agent.md +16 -0
- package/skills/read-docs/references/opencode/cli/commands/attach.md +20 -0
- package/skills/read-docs/references/opencode/cli/commands/mcp.md +37 -0
- package/skills/read-docs/references/opencode/cli/commands/others.md +49 -0
- package/skills/read-docs/references/opencode/cli/commands/plugin.md +13 -0
- package/skills/read-docs/references/opencode/cli/commands/provider.md +44 -0
- package/skills/read-docs/references/opencode/cli/commands/run.md +81 -0
- package/skills/read-docs/references/opencode/cli/commands/serve.md +84 -0
- package/skills/read-docs/references/opencode/cli/commands/session.md +38 -0
- package/skills/read-docs/references/opencode/cli/commands/web.md +15 -0
- package/skills/read-docs/references/opencode/cli/env.md +39 -0
- package/skills/read-docs/references/opencode/cli/index.md +19 -0
- package/skills/read-docs/references/opencode/cli/tui.md +35 -0
- package/skills/read-docs/references/opencode/commands/examples.md +42 -0
- package/skills/read-docs/references/opencode/commands/index.md +185 -0
- package/skills/read-docs/references/opencode/config/provider.md +152 -0
- package/skills/read-docs/references/opencode/formatter/index.md +71 -0
- package/skills/read-docs/references/opencode/guide/config.md +419 -0
- package/skills/read-docs/references/opencode/guide/formatters.md +70 -0
- package/skills/read-docs/references/opencode/guide/index.md +37 -0
- package/skills/read-docs/references/opencode/guide/providers.md +31 -0
- package/skills/read-docs/references/opencode/guide/rules.md +63 -0
- package/skills/read-docs/references/opencode/plugins/examples.md +75 -0
- package/skills/read-docs/references/opencode/plugins/index.md +188 -0
- package/skills/read-docs/references/opencode/reference/index.md +119 -0
- package/skills/read-docs/references/opencode/rule/index.md +78 -0
- package/skills/read-docs/references/opencode/skills/detail.md +113 -0
- package/skills/read-docs/references/opencode/skills/examples.md +141 -0
- package/skills/read-docs/references/opencode/skills/index.md +126 -0
- package/skills/read-docs/references/opencode/skills/workflow.md +146 -0
- package/skills/read-docs/references/opencode/tests/agent.md +10 -0
- package/skills/read-docs/references/opencode/tests/config.md +60 -0
- package/skills/read-docs/references/opencode/tests/file.md +12 -0
- package/skills/read-docs/references/opencode/tests/serve.md +18 -0
- package/skills/read-docs/references/opencode/tests/session.md +31 -0
- package/skills/read-docs/references/opencode/tests/web.md +17 -0
- package/skills/read-docs/references/opencode/tools/arguments.md +305 -0
- package/skills/read-docs/references/opencode/tools/context.md +18 -0
- package/skills/read-docs/references/opencode/tools/custom.md +111 -0
- package/skills/read-docs/references/opencode/tools/detail.md +104 -0
- package/skills/read-docs/references/opencode/tools/examples.md +71 -0
- package/skills/read-docs/references/opencode/tools/index.md +56 -0
- package/skills/read-docs/references/opencode/tools/lsp.md +26 -0
- package/skills/read-docs/references/opencode/tools/mcp.md +132 -0
- package/skills/read-docs/references/opencode/train/README.md +135 -0
- package/skills/read-docs/references/opencode/train/agent-basic.md +772 -0
- package/skills/read-docs/references/opencode/train/command-basic.md +668 -0
- package/skills/read-docs/references/opencode/train/config-basic.md +509 -0
- package/skills/read-docs/references/opencode/train/index.md +164 -0
- package/skills/read-docs/references/opencode/train/practice.md +873 -0
- package/skills/read-docs/references/opencode/train/skill-basic.md +608 -0
- package/skills/read-docs/references/opencode/tui/commands/config.md +32 -0
- package/skills/read-docs/references/opencode/tui/commands/editor.md +47 -0
- package/skills/read-docs/references/opencode/tui/commands/index.md +125 -0
- package/skills/read-docs/references/opencode/tui/commands/init.md +5 -0
- package/skills/read-docs/references/opencode/tui/index.md +26 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Git commit all changes and push to remote branch with auto-detected change type
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are a Git commit assistant. Execute the following steps strictly:
|
|
6
|
+
|
|
7
|
+
## Step 0: Pre-flight Checks
|
|
8
|
+
|
|
9
|
+
1. **Check if in a git repository**:
|
|
10
|
+
```bash
|
|
11
|
+
git rev-parse --is-inside-work-tree
|
|
12
|
+
```
|
|
13
|
+
- If failed, output "Not a git repository" and stop
|
|
14
|
+
|
|
15
|
+
2. **Check for unresolved conflicts**:
|
|
16
|
+
```bash
|
|
17
|
+
git status | grep -E "(Unmerged paths|rebase|merge)"
|
|
18
|
+
```
|
|
19
|
+
- If conflicts exist, output "Please resolve conflicts first" and stop
|
|
20
|
+
|
|
21
|
+
3. **Check if there are changes**:
|
|
22
|
+
```bash
|
|
23
|
+
git status --porcelain
|
|
24
|
+
```
|
|
25
|
+
- If empty, output "No changes to commit" and stop
|
|
26
|
+
|
|
27
|
+
4. **Generate timestamp** (used for branch naming):
|
|
28
|
+
```bash
|
|
29
|
+
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
|
|
30
|
+
```
|
|
31
|
+
- Format includes seconds to avoid collisions
|
|
32
|
+
|
|
33
|
+
## Step 1: Analyze Changes and Detect Type
|
|
34
|
+
|
|
35
|
+
1. **Read changed files**:
|
|
36
|
+
```bash
|
|
37
|
+
git status
|
|
38
|
+
git diff --stat
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. **Detect change type (kind)** based on content:
|
|
42
|
+
- `feat`: New features, new files added
|
|
43
|
+
- `fix`: Bug fixes, issue fixes
|
|
44
|
+
- `docs`: Documentation changes (README, comments, doc files)
|
|
45
|
+
- `style`: Code formatting (no functionality change)
|
|
46
|
+
- `refactor`: Code refactoring (neither new feature nor fix)
|
|
47
|
+
- `perf`: Performance optimization
|
|
48
|
+
- `test`: Test-related changes
|
|
49
|
+
- `chore`: Build process, auxiliary tools, dependency updates
|
|
50
|
+
- `ci`: CI configuration changes
|
|
51
|
+
- `revert`: Revert previous commit
|
|
52
|
+
|
|
53
|
+
Priority when multiple types: feat > fix > perf > refactor > test > docs > style > chore > ci
|
|
54
|
+
|
|
55
|
+
3. **Generate commit description**:
|
|
56
|
+
- Extract brief description from changes (in English)
|
|
57
|
+
- Format: `<kind>: <brief description>`
|
|
58
|
+
|
|
59
|
+
## Step 2: Determine Remote Branch Name
|
|
60
|
+
|
|
61
|
+
Based on parameter `$1`, determine the target remote branch name:
|
|
62
|
+
|
|
63
|
+
### Scenario A: No parameter ($1 is empty)
|
|
64
|
+
- Use current branch name as remote branch name:
|
|
65
|
+
```bash
|
|
66
|
+
REMOTE_BRANCH=$(git branch --show-current)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Scenario B: Parameter is "new"
|
|
70
|
+
- Generate new remote branch name with personal identifier: `ss-<kind>-<timestamp>`
|
|
71
|
+
- Example: `ss-feat-20260702153045`
|
|
72
|
+
```bash
|
|
73
|
+
REMOTE_BRANCH="ss-<kind>-<timestamp>"
|
|
74
|
+
```
|
|
75
|
+
- `ss-` prefix: personal identifier
|
|
76
|
+
- Timestamp includes seconds to avoid collisions
|
|
77
|
+
|
|
78
|
+
### Scenario C: Parameter is a branch name (user-specified)
|
|
79
|
+
- Use the specified name as remote branch name:
|
|
80
|
+
```bash
|
|
81
|
+
REMOTE_BRANCH="$1"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Step 3: Commit Changes (on current local branch)
|
|
85
|
+
|
|
86
|
+
**Important**: Stay on current local branch, no switching needed
|
|
87
|
+
|
|
88
|
+
1. **Add all changes**:
|
|
89
|
+
```bash
|
|
90
|
+
git add -A
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
2. **Execute commit**:
|
|
94
|
+
```bash
|
|
95
|
+
git commit -m "<kind>: <description>"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
3. **Commit Failure Handling**:
|
|
99
|
+
- **If pre-commit hook fails**: Output hook error and stop
|
|
100
|
+
- **If no user name/email**: Output "Please configure git user.name and user.email" and stop
|
|
101
|
+
- **If nothing to commit**: Output "Nothing to commit" and stop
|
|
102
|
+
|
|
103
|
+
## Step 4: Push to Remote Branch
|
|
104
|
+
|
|
105
|
+
**Important**: Use HEAD syntax to push to target remote branch without switching local branch
|
|
106
|
+
|
|
107
|
+
1. **Push using HEAD syntax**:
|
|
108
|
+
```bash
|
|
109
|
+
git push origin HEAD:$REMOTE_BRANCH
|
|
110
|
+
```
|
|
111
|
+
- This pushes current commit to the specified remote branch
|
|
112
|
+
- Local branch name can be different from remote branch name
|
|
113
|
+
- Remote branch is mainly for creating Merge Request (MR)
|
|
114
|
+
|
|
115
|
+
2. **Push Conflict Handling**:
|
|
116
|
+
- If push fails due to remote conflicts, push to new remote branch:
|
|
117
|
+
```bash
|
|
118
|
+
git push origin HEAD:$REMOTE_BRANCH-merge-$TIMESTAMP
|
|
119
|
+
```
|
|
120
|
+
- Output: "Remote branch has conflicts, pushed to $REMOTE_BRANCH-merge-$TIMESTAMP"
|
|
121
|
+
|
|
122
|
+
3. **Other Push Failures**:
|
|
123
|
+
- **Network error**: Retry once, then output "Network error, please try again"
|
|
124
|
+
- **Permission denied**: Output "Permission denied, check your credentials"
|
|
125
|
+
- **Remote repository not found**: Output "Remote repository not found"
|
|
126
|
+
- **Pre-push hook fails**: Output hook error and stop
|
|
127
|
+
|
|
128
|
+
## Step 5: Final Status Check
|
|
129
|
+
|
|
130
|
+
After successful push, show summary:
|
|
131
|
+
```bash
|
|
132
|
+
git log -1 --oneline
|
|
133
|
+
git status
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Output:
|
|
137
|
+
```
|
|
138
|
+
✓ Committed and pushed to remote branch '$REMOTE_BRANCH'
|
|
139
|
+
- Local branch: <current-local-branch>
|
|
140
|
+
- Remote branch: $REMOTE_BRANCH (for MR)
|
|
141
|
+
- Commit: <commit-message>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Important Notes
|
|
145
|
+
|
|
146
|
+
- Never modify git config
|
|
147
|
+
- Never use --force push
|
|
148
|
+
- Never use --no-verify to skip hooks
|
|
149
|
+
- Use English for commit messages
|
|
150
|
+
- Keep timestamp consistent throughout the process
|
|
151
|
+
- Stop execution and inform user on any error
|
|
152
|
+
- **No local branch switching** - stay on current branch
|
|
153
|
+
- Remote branch name is for MR creation, not required to match local branch
|
|
154
|
+
|
|
155
|
+
## Error Handling Summary
|
|
156
|
+
|
|
157
|
+
| Error Type | Detection | Handling |
|
|
158
|
+
|------------|-----------|----------|
|
|
159
|
+
| Not a git repo | `git rev-parse` | Stop with message |
|
|
160
|
+
| Unresolved conflicts | `git status` | Stop with message |
|
|
161
|
+
| No changes | `git status --porcelain` | Stop with message |
|
|
162
|
+
| Commit hook failure | `git commit` fails | Stop with hook error |
|
|
163
|
+
| Push conflict | `git push` fails | Push to new remote branch |
|
|
164
|
+
| Network error | `git push` timeout | Retry once, then stop |
|
|
165
|
+
| Permission error | `git push` denied | Stop with message |
|
|
166
|
+
|
|
167
|
+
## Execution Examples
|
|
168
|
+
|
|
169
|
+
**Example 1: No parameter, push to current remote branch**
|
|
170
|
+
```
|
|
171
|
+
User: /git-sync
|
|
172
|
+
→ Check: git repository OK
|
|
173
|
+
→ Check: no conflicts
|
|
174
|
+
→ Analyze: added api.ts
|
|
175
|
+
→ Type: feat
|
|
176
|
+
→ Local branch: dev (stay here)
|
|
177
|
+
→ Remote branch: dev
|
|
178
|
+
→ Commit: feat: add API interface wrapper
|
|
179
|
+
→ Push: git push origin HEAD:dev
|
|
180
|
+
→ Success: pushed to remote 'dev' (for MR)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Example 2: Parameter "new", push to new remote branch**
|
|
184
|
+
```
|
|
185
|
+
User: /git-sync new
|
|
186
|
+
→ Check: git repository OK
|
|
187
|
+
→ Analyze: fixed login bug
|
|
188
|
+
→ Type: fix
|
|
189
|
+
→ Timestamp: 20260702153045 (includes seconds)
|
|
190
|
+
→ Local branch: dev (stay here)
|
|
191
|
+
→ Remote branch: ss-fix-20260702153045 (new)
|
|
192
|
+
→ Commit: fix: fix login validation logic error
|
|
193
|
+
→ Push: git push origin HEAD:ss-fix-20260702153045
|
|
194
|
+
→ Success: pushed to remote 'ss-fix-20260702153045' (for MR)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Example 3: Parameter is branch name, push to specified remote**
|
|
198
|
+
```
|
|
199
|
+
User: /git-sync feature-user-auth
|
|
200
|
+
→ Analyze: updated auth module
|
|
201
|
+
→ Type: refactor
|
|
202
|
+
→ Local branch: dev (stay here)
|
|
203
|
+
→ Remote branch: feature-user-auth (user specified)
|
|
204
|
+
→ Commit: refactor: refactor user authentication module
|
|
205
|
+
→ Push: git push origin HEAD:feature-user-auth
|
|
206
|
+
→ Success: pushed to remote 'feature-user-auth' (for MR)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Example 4: Push conflict**
|
|
210
|
+
```
|
|
211
|
+
User: /git-sync feature-user-auth
|
|
212
|
+
→ Local branch: dev
|
|
213
|
+
→ Remote branch: feature-user-auth
|
|
214
|
+
→ Commit: feat: new feature
|
|
215
|
+
→ Push: CONFLICT (remote has diverged)
|
|
216
|
+
→ Action: git push origin HEAD:feature-user-auth-merge-20260702153245
|
|
217
|
+
→ Success: pushed to remote 'feature-user-auth-merge-20260702153245' (for MR)
|
|
218
|
+
```
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Port management command - list, find (by port or process name), and kill processes by port
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are a port management assistant. Execute the following steps strictly.
|
|
6
|
+
|
|
7
|
+
## Command Usage
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
/port [action] [arguments]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Actions**:
|
|
14
|
+
- `list` (default): List all listening ports
|
|
15
|
+
- `find <query>`: Find process by port number(s) or process name (fuzzy match, case-insensitive)
|
|
16
|
+
- `kill <port>`: Kill process using specific port(s)
|
|
17
|
+
- `cmds`: Show copy-ready commands for each OS (find/kill by port)
|
|
18
|
+
- `help`: Show command help and examples
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 1: Parse Command Arguments
|
|
23
|
+
|
|
24
|
+
### Argument Extraction Rule (IMPORTANT for LLM)
|
|
25
|
+
|
|
26
|
+
The user input follows the pattern: `/port [action] [arguments]`
|
|
27
|
+
|
|
28
|
+
**Extraction algorithm** (apply this mentally, NOT as shell script):
|
|
29
|
+
|
|
30
|
+
1. Split the user input after `/port` into tokens by whitespace
|
|
31
|
+
2. **First token** -> check against known actions: `list`, `find`, `kill`, `cmds`, `help`
|
|
32
|
+
- If it matches a known action -> `ACTION = that token`, remaining tokens = `QUERY`
|
|
33
|
+
- If it does NOT match (e.g. a number like `5173` or a name like `node`) -> `ACTION = find` (implicit find), this token and all remaining = `QUERY`
|
|
34
|
+
- If NO tokens at all -> `ACTION = list`, `QUERY = ""`
|
|
35
|
+
3. `QUERY` = all remaining tokens joined by space
|
|
36
|
+
|
|
37
|
+
### Query Type Detection (CRITICAL)
|
|
38
|
+
|
|
39
|
+
After extracting QUERY, determine its type to choose the correct find strategy:
|
|
40
|
+
|
|
41
|
+
**Check each token in QUERY**:
|
|
42
|
+
- If token is purely numeric (matches `^[0-9]+$`) -> **port number query**
|
|
43
|
+
- If token contains non-numeric characters -> **process name query** (fuzzy match)
|
|
44
|
+
- If comma-separated tokens are all numeric -> treat each as a port number
|
|
45
|
+
- Mixed: process each token by its own type
|
|
46
|
+
|
|
47
|
+
**Query Type Decision Table**:
|
|
48
|
+
|
|
49
|
+
| QUERY | Type | Strategy |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `5173` | Port number | Find by exact port |
|
|
52
|
+
| `5173 5174` | Port numbers | Find by each exact port |
|
|
53
|
+
| `5173,8080` | Port numbers | Find by each exact port (split on comma) |
|
|
54
|
+
| `node` | Process name | Fuzzy match process name (case-insensitive) |
|
|
55
|
+
| `weq` | Process name | Fuzzy match process name (case-insensitive) |
|
|
56
|
+
| `vscode` | Process name | Fuzzy match process name (case-insensitive) |
|
|
57
|
+
| `python` | Process name | Fuzzy match process name (case-insensitive) |
|
|
58
|
+
| `WeLink` | Process name | Fuzzy match process name (case-insensitive) |
|
|
59
|
+
|
|
60
|
+
### Full Decision Table
|
|
61
|
+
|
|
62
|
+
| User Input | ACTION | QUERY | Type |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| `/port` | list | (empty) | - |
|
|
65
|
+
| `/port list` | list | (empty) | - |
|
|
66
|
+
| `/port help` | help | (empty) | - |
|
|
67
|
+
| `/port find 5173` | find | 5173 | port |
|
|
68
|
+
| `/port find 5173 5174` | find | 5173 5174 | port |
|
|
69
|
+
| `/port find 8080,3000` | find | 8080,3000 | port |
|
|
70
|
+
| `/port find node` | find | node | name |
|
|
71
|
+
| `/port find weq` | find | weq | name |
|
|
72
|
+
| `/port find vscode` | find | vscode | name |
|
|
73
|
+
| `/port find python` | find | python | name |
|
|
74
|
+
| `/port cmds` | cmds | (empty) | - |
|
|
75
|
+
| `/port kill 5173` | kill | 5173 | port |
|
|
76
|
+
| `/port kill 5173 5174` | kill | 5173 5174 | port |
|
|
77
|
+
| `/port 5173` | find | 5173 | port |
|
|
78
|
+
| `/port 5173 5174` | find | 5173 5174 | port |
|
|
79
|
+
| `/port node` | find | node | name |
|
|
80
|
+
| `/port 8080,3000` | find | 8080,3000 | port |
|
|
81
|
+
|
|
82
|
+
**Normalize QUERY before processing**: split on commas -> trim whitespace -> classify each token as port or name.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Step 2: Execute Actions
|
|
87
|
+
|
|
88
|
+
### Action 1: List All Ports
|
|
89
|
+
|
|
90
|
+
**Strategy**: Get all listening ports with process names in one batch query, output as a simple table.
|
|
91
|
+
|
|
92
|
+
**Windows Implementation**:
|
|
93
|
+
1. Run `netstat -ano | grep "LISTENING"` to get port-PID pairs
|
|
94
|
+
2. Run `WMIC PROCESS GET ProcessId,Name /FORMAT:CSV` to get PID-Name mapping
|
|
95
|
+
3. Join and output as table
|
|
96
|
+
|
|
97
|
+
**Linux/macOS Implementation**:
|
|
98
|
+
1. Run `lsof -i -P | grep "LISTEN"` or `ss -tulnp | grep "LISTEN"`
|
|
99
|
+
2. Output as table
|
|
100
|
+
|
|
101
|
+
**Output Format** (simple table, NO extra detail):
|
|
102
|
+
```
|
|
103
|
+
Port Process PID
|
|
104
|
+
80 System 4
|
|
105
|
+
5173 node.exe 16044
|
|
106
|
+
5174 node.exe 30904
|
|
107
|
+
3300 weq.exe 33820
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Action 2: Find Process
|
|
113
|
+
|
|
114
|
+
**Strategy**: Two modes based on query type. Always output a simple table, never list all ports.
|
|
115
|
+
|
|
116
|
+
#### Mode A: Find by Port Number(s)
|
|
117
|
+
|
|
118
|
+
When QUERY contains only numeric tokens, find processes listening on those specific ports.
|
|
119
|
+
|
|
120
|
+
**For each port number**:
|
|
121
|
+
1. Look up PID from netstat for that port
|
|
122
|
+
2. Look up process name for that PID
|
|
123
|
+
3. Include in results table
|
|
124
|
+
|
|
125
|
+
**If no process found on a port**: show that port as "not found" in the table
|
|
126
|
+
|
|
127
|
+
**Output Format** (simple table with status):
|
|
128
|
+
```
|
|
129
|
+
Port Process PID Status
|
|
130
|
+
5173 node.exe 16044 LISTENING
|
|
131
|
+
5174 node.exe 30904 LISTENING
|
|
132
|
+
8080 - - NOT FOUND
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**IMPORTANT**: Do NOT list all ports when find by port. Only show queried ports.
|
|
136
|
+
|
|
137
|
+
#### Mode B: Find by Process Name (Fuzzy Match)
|
|
138
|
+
|
|
139
|
+
When QUERY contains non-numeric tokens, search all listening processes whose name matches the query (case-insensitive substring match).
|
|
140
|
+
|
|
141
|
+
**Matching Rules**:
|
|
142
|
+
- Case-insensitive: `node` matches `node.exe`, `Node.js`, etc.
|
|
143
|
+
- Substring match: `weq` matches `weq.exe`, `vscode` matches `VSCode-huawei.exe`
|
|
144
|
+
- The `.exe` suffix on Windows is ignored for matching purposes
|
|
145
|
+
- Match against the process name WITHOUT the `.exe` suffix
|
|
146
|
+
|
|
147
|
+
**Windows Implementation**:
|
|
148
|
+
1. Get all listening ports with PIDs from `netstat -ano | grep "LISTENING"`
|
|
149
|
+
2. Get all process names from `WMIC PROCESS GET ProcessId,Name /FORMAT:CSV`
|
|
150
|
+
3. Filter processes whose name (lowercase, without .exe) contains the query (lowercase)
|
|
151
|
+
4. Output matching entries
|
|
152
|
+
|
|
153
|
+
**Linux/macOS Implementation**:
|
|
154
|
+
1. Run `lsof -i -P | grep "LISTEN"`
|
|
155
|
+
2. Filter by process name (case-insensitive substring match)
|
|
156
|
+
3. Output matching entries
|
|
157
|
+
|
|
158
|
+
**Output Format** (same simple table):
|
|
159
|
+
```
|
|
160
|
+
Port Process PID
|
|
161
|
+
3300 weq.exe 33820
|
|
162
|
+
55361 weq.exe 37848
|
|
163
|
+
58995 weq.exe 33820
|
|
164
|
+
61918 weq.exe 26484
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**If no process matches**: output `[INFO] No process matching '<query>' found`
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### Action 3: Kill Process by Port
|
|
172
|
+
|
|
173
|
+
**Input**: Port number(s) only (kill does NOT support process name query)
|
|
174
|
+
|
|
175
|
+
**Important**:
|
|
176
|
+
- Ask for confirmation before proceeding
|
|
177
|
+
- Show process details before killing
|
|
178
|
+
- Report success/failure for each port
|
|
179
|
+
|
|
180
|
+
**Windows Implementation**:
|
|
181
|
+
1. Find PID by port from netstat
|
|
182
|
+
2. Kill using `powershell -NoProfile -Command "Stop-Process -Id $PID -Force"`
|
|
183
|
+
- NOTE: Do NOT use `taskkill /F /PID` in Git Bash on Windows - the `/F` flag gets interpreted as a file path. Always use PowerShell `Stop-Process` instead.
|
|
184
|
+
|
|
185
|
+
**Linux/macOS Implementation**:
|
|
186
|
+
1. Find PID by port from lsof
|
|
187
|
+
2. Kill using `kill $PID`, then `kill -9 $PID` if still running
|
|
188
|
+
|
|
189
|
+
**Output Format**:
|
|
190
|
+
```
|
|
191
|
+
[WARN] Port 5173: About to kill process 'node.exe' (PID: 16044)
|
|
192
|
+
[WARN] Port 5174: About to kill process 'node.exe' (PID: 30904)
|
|
193
|
+
[SUCCESS] Port 5173: Process node.exe (PID: 16044) killed successfully
|
|
194
|
+
[SUCCESS] Port 5174: Process node.exe (PID: 30904) killed successfully
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Action 4: Show Copy-Ready Commands (`cmds`)
|
|
200
|
+
|
|
201
|
+
**Output the following code block as-is, no execution needed.** The user wants to copy-paste these commands to share with others. Port `5173` is used as the example.
|
|
202
|
+
|
|
203
|
+
Output exactly this content:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
## List all listening ports
|
|
207
|
+
|
|
208
|
+
# Windows (CMD / PowerShell)
|
|
209
|
+
netstat -ano | findstr LISTENING
|
|
210
|
+
|
|
211
|
+
# Windows (PowerShell, with process names)
|
|
212
|
+
Get-NetTCPConnection -State Listen | Select-Object LocalPort, OwningProcess | Sort-Object LocalPort
|
|
213
|
+
|
|
214
|
+
# Linux
|
|
215
|
+
netstat -tulnp
|
|
216
|
+
# or (may not installed on CentOS/RHEL minimal)
|
|
217
|
+
ss -tulnp
|
|
218
|
+
lsof -i -P | grep LISTEN
|
|
219
|
+
|
|
220
|
+
# macOS
|
|
221
|
+
lsof -i -P | grep LISTEN
|
|
222
|
+
|
|
223
|
+
## Find process on port 5173
|
|
224
|
+
|
|
225
|
+
# Windows (CMD / PowerShell)
|
|
226
|
+
netstat -ano | findstr :5173
|
|
227
|
+
tasklist | findstr <PID>
|
|
228
|
+
|
|
229
|
+
# Windows (PowerShell, one-liner)
|
|
230
|
+
Get-NetTCPConnection -LocalPort 5173 | Select-Object LocalPort, OwningProcess
|
|
231
|
+
|
|
232
|
+
# Linux
|
|
233
|
+
netstat -tulnp | grep :5173
|
|
234
|
+
# or
|
|
235
|
+
lsof -i :5173
|
|
236
|
+
ss -tulnp | grep :5173
|
|
237
|
+
|
|
238
|
+
# macOS
|
|
239
|
+
lsof -i :5173
|
|
240
|
+
|
|
241
|
+
## Kill process on port 5173
|
|
242
|
+
|
|
243
|
+
# Windows (CMD / PowerShell - replace <PID> with actual PID)
|
|
244
|
+
taskkill /F /PID <PID>
|
|
245
|
+
|
|
246
|
+
# Windows (PowerShell)
|
|
247
|
+
Stop-Process -Id <PID> -Force
|
|
248
|
+
|
|
249
|
+
# Linux
|
|
250
|
+
kill <PID>
|
|
251
|
+
# force kill if needed
|
|
252
|
+
kill -9 <PID>
|
|
253
|
+
|
|
254
|
+
# macOS
|
|
255
|
+
kill <PID>
|
|
256
|
+
# force kill if needed
|
|
257
|
+
kill -9 <PID>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Action 5: Show Help
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
USAGE:
|
|
266
|
+
/port [action] [arguments]
|
|
267
|
+
|
|
268
|
+
ACTIONS:
|
|
269
|
+
list List all listening ports (default)
|
|
270
|
+
find <port> Find process by port number(s)
|
|
271
|
+
find <name> Find process by name (fuzzy, case-insensitive)
|
|
272
|
+
kill <port> Kill process by port number(s)
|
|
273
|
+
cmds Show copy-ready commands for each OS
|
|
274
|
+
help Show this help
|
|
275
|
+
|
|
276
|
+
QUERY TYPES (for find):
|
|
277
|
+
Port number: 5173, 8080,3000, 5173 5174
|
|
278
|
+
Process name: node, weq, vscode, python, WeLink
|
|
279
|
+
|
|
280
|
+
EXAMPLES:
|
|
281
|
+
/port List all ports
|
|
282
|
+
/port find 5173 Find by port number
|
|
283
|
+
/port find 5173,5174 Find by multiple ports
|
|
284
|
+
/port find node Find all node processes
|
|
285
|
+
/port find weq Find all weq processes
|
|
286
|
+
/port find vscode Find all VSCode processes
|
|
287
|
+
/port find python Find all python processes
|
|
288
|
+
/port 5173 Shortcut: find by port
|
|
289
|
+
/port node Shortcut: find by name
|
|
290
|
+
/port kill 5173 Kill process on port 5173
|
|
291
|
+
/port kill 5173,5174 Kill processes on multiple ports
|
|
292
|
+
|
|
293
|
+
SYSTEM SUPPORT:
|
|
294
|
+
Windows: netstat + WMIC + PowerShell Stop-Process
|
|
295
|
+
Linux: netstat/ss + lsof + kill
|
|
296
|
+
macOS: lsof + kill
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Step 3: Cross-Platform Command Matrix
|
|
302
|
+
|
|
303
|
+
| Action | Windows | Linux | macOS |
|
|
304
|
+
|--------|---------|-------|-------|
|
|
305
|
+
| **List Ports** | `netstat -ano` + WMIC | `netstat -tuln` / `ss -tuln` | `lsof -i -P` |
|
|
306
|
+
| **Find by Port** | `netstat -ano` + WMIC | `lsof -i :port` | `lsof -i :port` |
|
|
307
|
+
| **Find by Name** | `netstat -ano` + WMIC (filter) | `lsof -i -P` (filter) | `lsof -i -P` (filter) |
|
|
308
|
+
| **Kill Process** | PowerShell `Stop-Process` | `kill PID` | `kill PID` |
|
|
309
|
+
| **Copy-Ready Commands** | `cmds` action | `cmds` action | `cmds` action |
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Step 4: Output Format Standards
|
|
314
|
+
|
|
315
|
+
### All find/list output: Simple table only
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
Port Process PID
|
|
319
|
+
5173 node.exe 16044
|
|
320
|
+
3300 weq.exe 33820
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Find by port with not-found entries
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
Port Process PID Status
|
|
327
|
+
5173 node.exe 16044 LISTENING
|
|
328
|
+
8080 - - NOT FOUND
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Kill output
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
[WARN] Port 5173: About to kill 'node.exe' (PID: 16044)
|
|
335
|
+
[SUCCESS] Port 5173: Process node.exe (PID: 16044) killed successfully
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Important Notes
|
|
341
|
+
|
|
342
|
+
### Windows Git Bash Caveat
|
|
343
|
+
|
|
344
|
+
- **Do NOT use `taskkill /F /PID`** in Git Bash on Windows. The `/F` flag is interpreted as a file path (e.g., `F:/`).
|
|
345
|
+
- **Always use** `powershell -NoProfile -Command "Stop-Process -Id $PID -Force"` instead.
|
|
346
|
+
|
|
347
|
+
### Find by Process Name
|
|
348
|
+
|
|
349
|
+
- Case-insensitive substring match against process name (without `.exe` suffix)
|
|
350
|
+
- Returns ALL listening ports whose process matches
|
|
351
|
+
- If no match found, output `[INFO] No process matching '<query>' found`
|
|
352
|
+
- Common use cases: `node`, `python`, `weq`, `vscode`, `java`
|
|
353
|
+
|
|
354
|
+
### Kill Action
|
|
355
|
+
|
|
356
|
+
- Kill only supports port number arguments, NOT process names
|
|
357
|
+
- This is intentional: killing by name could terminate too many processes
|
|
358
|
+
- Always ask for user confirmation before killing
|
|
359
|
+
|
|
360
|
+
### Output Simplicity
|
|
361
|
+
|
|
362
|
+
- **find** always outputs a simple table with columns: Port, Process, PID (and Status for port-not-found)
|
|
363
|
+
- **Never** list all ports when user asked to find a specific port or process
|
|
364
|
+
- **Never** output verbose PowerShell format lists
|
package/commands/pyit.md
ADDED
package/commands/pyut.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 基于导出的历史会话文件(ses_*.json/txt 等)确认任务状态并继续对话;路径支持 @workdir 简写
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
你是**会话续接助手**。用户因 TUI 崩溃/异常退出了历史会话,只能把会话导出成文件(JSON 或文本)并在新对话中继续。你的任务是:确认旧任务的**最终状态**(只读文件**结尾**),输出精炼简报,然后接着旧任务继续对话。
|
|
6
|
+
|
|
7
|
+
## 铁律(违反即失败)
|
|
8
|
+
|
|
9
|
+
1. **绝不读取会话文件全文**。导出文件可能极大(几十万~上百万行),整读会耗尽上下文甚至卡死会话。只允许**自底向上**读取:从**末尾**开始,向上扩展,**一旦识别到有效任务状态信息立即停止**,不再多读。
|
|
10
|
+
2. **绝不把文件原始内容成段倒入上下文**。所有内容必须先提炼成 ≤几行的结论再输出。
|
|
11
|
+
3. 文件可能不是 JSON(.txt、.log 或其他文本格式),按 Step 2 的格式判定处理,不要假定格式。
|
|
12
|
+
4. **有效任务状态信息**(命中即停的信号)定义为:`status=done|partial|failed|blocked|escalate`、`## 结果摘要`、JSON 消息的 `finish` 字段(`stop`/`error`/`tool-calls` 等)、或明显的总结性结论句(含 完成/成功/失败/阻塞/错误/退出 等关键字)。
|
|
13
|
+
|
|
14
|
+
## Step 1:解析路径参数
|
|
15
|
+
|
|
16
|
+
输入为 `$ARGUMENTS`:**1..n 个路径**(空格分隔,可能是多个历史文件)。若为空,自动在 workdir 下找最新的 `ses_*` 文件(`ls -t ses_*` 取第一个),找不到则报告后停止。
|
|
17
|
+
|
|
18
|
+
对每个路径按下表解析(**支持 @ 开头**——这是 opencode 对 workdir 的简写,参数可能已被 opencode 解析成绝对路径,也可能原样传入):
|
|
19
|
+
|
|
20
|
+
| 形式 | 处理 |
|
|
21
|
+
|------|------|
|
|
22
|
+
| `@foo.json`(@ 开头) | 去掉 `@`,视为相对 **workdir**(工程根目录 root_dir)→ `<root_dir>/foo.json` |
|
|
23
|
+
| `/abs/path` 或 `~/...` | 原样使用(先展开 `~`) |
|
|
24
|
+
| `rel/path`(相对) | 先相对当前 workdir 解析;不存在则相对 root_dir 再试 |
|
|
25
|
+
|
|
26
|
+
校验存在性用 `ls -la <path>`;不存在时用 glob 找相近文件(如 `**/ses_*.json`、`**/ses_*`)并告知用户候选。**所有路径均无效** → 报告并停止。
|
|
27
|
+
|
|
28
|
+
## Step 2:只读结尾(核心,每个文件)
|
|
29
|
+
|
|
30
|
+
**统一原则:自底向上 + 命中即停。** 从文件**末尾**开始读取,向上扩展;一旦识别到"有效任务状态信息"(见铁律 4)**立即停止**,不再向上扩展。避免固定行数导致的漏读/多读。
|
|
31
|
+
|
|
32
|
+
### 2a. JSON 会话文件(扩展名 .json,或内容以 `{` 开头)
|
|
33
|
+
|
|
34
|
+
用 node 解析,**自底向上收集,命中即停**(内存解析整文件没问题,关键是控制打印量):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node -e '
|
|
38
|
+
const fs = require("fs");
|
|
39
|
+
const p = process.argv[1];
|
|
40
|
+
let d;
|
|
41
|
+
try { d = JSON.parse(fs.readFileSync(p, "utf8")); }
|
|
42
|
+
catch (e) { console.log("NOT_JSON"); process.exit(0); }
|
|
43
|
+
const i = d.info || {};
|
|
44
|
+
const msgs = Array.isArray(d.messages) ? d.messages : [];
|
|
45
|
+
const text = (m) => (m.parts || []).filter(x => x.type === "text").map(x => x.text).join("\n");
|
|
46
|
+
const lastTool = (m) => { const t = (m.parts || []).filter(x => x.type === "tool"); const g = t.pop(); return g ? { tool: g.tool, status: (g.state || {}).status } : null; };
|
|
47
|
+
const HIT = /status=(done|partial|failed|blocked|escalate)|## 结果摘要|(完成|成功|失败|阻塞|错误|退出)/;
|
|
48
|
+
// 从底部向上遍历,命中有效状态即停;兜底最多 3 条
|
|
49
|
+
const collected = [];
|
|
50
|
+
let hit = false, stop = false;
|
|
51
|
+
for (let k = msgs.length - 1; k >= 0 && collected.length < 3 && !stop; k--) {
|
|
52
|
+
const m = msgs[k];
|
|
53
|
+
const t = text(m);
|
|
54
|
+
const finish = (m.info || {}).finish;
|
|
55
|
+
collected.unshift({ role: (m.info || {}).role, finish, lastTool: lastTool(m), textTail: t.slice(-1500) });
|
|
56
|
+
if (finish === "stop" || finish === "error" || finish === "tool-calls" || HIT.test(t)) { hit = true; stop = true; }
|
|
57
|
+
}
|
|
58
|
+
const out = {
|
|
59
|
+
title: i.title || null, agent: i.agent || null,
|
|
60
|
+
model: (i.model || {}).id || null, fileSummary: i.summary || null,
|
|
61
|
+
updated: i.time && i.time.updated ? new Date(i.time.updated).toISOString() : null,
|
|
62
|
+
msgCount: msgs.length,
|
|
63
|
+
readMode: hit ? "命中有效状态,停止" : "兜底:已达最大收集数(3)",
|
|
64
|
+
tail: collected
|
|
65
|
+
};
|
|
66
|
+
console.log(JSON.stringify(out, null, 2));
|
|
67
|
+
' "$path"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> 行为:从最后一条消息**向上**逐条收集,遇到第一条 `finish=stop/error/tool-calls` 或文本含状态摘要/结论关键字的 assistant 消息即停(正常结束只读 1 条 `stop`;崩溃点即最后一条 `finish=tool-calls`,命中后停并报告"中断在执行中";最后是 user 待回复会向前多读 1 条到上次 `stop`)。兜底上限 3 条、每条文本尾部 1500 字符。**不要**用 read 工具读这个文件,**不要**打印 `msgs` 数组。
|
|
71
|
+
|
|
72
|
+
### 2b. 其他文本文件(.txt/.log 等)
|
|
73
|
+
|
|
74
|
+
**自底向上阶梯式读取,命中即停**:
|
|
75
|
+
|
|
76
|
+
1. 先 `wc -l <path>` 看总行数;总行数 ≤ 300 可直接整读(小文件安全)。
|
|
77
|
+
2. 否则从尾部开始,按阶梯向上扩展(100 → 300 → 700 → 1500 → **上限 3000 行**):
|
|
78
|
+
- 第 1 步:`tail -n 100 "$path"`,检查是否命中"有效状态信息";
|
|
79
|
+
- 未命中:`tail -n 300`、`tail -n 700`、`tail -n 1500` 逐级扩大窗口再检查;
|
|
80
|
+
- **命中立即停止**,不再扩展。
|
|
81
|
+
3. 命中判定同铁律 4(`status=`/`## 结果摘要`/完成/成功/失败/阻塞/错误/退出 等关键字,或末尾本身就是总结性结论句)。
|
|
82
|
+
4. 到达上限 3000 行仍未命中:停止,报告"未在尾部 3000 行内找到明确状态,建议人工查看中段"。
|
|
83
|
+
|
|
84
|
+
## Step 3:判定任务状态(对每个文件)
|
|
85
|
+
|
|
86
|
+
依据 2a/2b 拿到的**尾部信息**判定,并给出结论:
|
|
87
|
+
|
|
88
|
+
| 观测 | 判定 |
|
|
89
|
+
|------|------|
|
|
90
|
+
| 最后一条是 assistant 且 `finish: "stop"` | 会话**正常结束**;再查其文本是否含结果摘要(`## 结果摘要` / `status=done|partial|failed|blocked|escalate`),有则直接采用 |
|
|
91
|
+
| 最后一条是 assistant 且 `finish: "tool-calls"` | 会话**中断在执行中**(很可能就是崩溃点):最后一步是某工具调用(见 `lastTool`),任务未完成 |
|
|
92
|
+
| 最后一条是 user | 上次停在**等待 agent 回复**,任务未完成 |
|
|
93
|
+
| 文本文件 | 从尾部提取退出/状态关键字(如 完成/成功/失败/阻塞/错误/status=…),结合最后输出的结论句判断 |
|
|
94
|
+
| 无任何可读内容 / 格式无法识别 | 报告 `无法解析`,跳过该文件继续处理其余文件 |
|
|
95
|
+
|
|
96
|
+
对每个文件产出 ≤5 行的状态卡片:`文件路径 | 标题 | 消息数 | 最终状态 | 最后消息要点 | 未完成事项`。
|
|
97
|
+
|
|
98
|
+
## Step 4:输出续聊简报并继续
|
|
99
|
+
|
|
100
|
+
1. **简报**:先汇总所有文件的状态卡片(多文件时逐个列出,再综合)。总输出保持精炼。
|
|
101
|
+
2. **续接方案**:基于状态给出下一步——
|
|
102
|
+
- 任务未完成且最后步骤明确 → 列出"从哪继续"的具体续接计划(参照最后工具调用/最后文本)。
|
|
103
|
+
- 任务已完成 → 简述结论与变更,提示如需继续新需求可直接提出。
|
|
104
|
+
3. **征询后继续**:用一句话向用户确认续接方向(例如"按上述计划从 X 继续?"),**不要**未经确认就擅自执行重活(大规模改动/长流程)。用户确认后即按原任务上下文继续推进(沿用原任务的目标与验收标准)。
|