gm-copilot-cli 2.0.132 → 2.0.133
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/copilot-profile.md +1 -1
- package/manifest.yml +1 -1
- package/package.json +1 -1
- package/skills/planning/SKILL.md +39 -304
- package/tools.json +1 -1
- package/skills/process-management/SKILL.md +0 -207
package/copilot-profile.md
CHANGED
package/manifest.yml
CHANGED
package/package.json
CHANGED
package/skills/planning/SKILL.md
CHANGED
|
@@ -1,335 +1,70 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: planning
|
|
3
|
-
description: PRD construction for work planning.
|
|
3
|
+
description: PRD construction for work planning. Compulsory in PLAN phase. Builds .prd file as frozen dependency graph of every possible work item before execution begins. Triggers on any new task, multi-step work, or when gm enters PLAN state.
|
|
4
4
|
allowed-tools: Write
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# PRD Construction
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Purpose
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The `.prd` is the single source of truth for remaining work. It is a frozen dependency graph created in PLAN phase before any execution. It captures every possible item — steps, substeps, edge cases, corner cases, dependencies, transitive dependencies, unknowns, assumptions to validate, decisions, trade-offs, factors, variables, acceptance criteria, scenarios, failure paths, recovery paths, integration points, state transitions, race conditions, concurrency concerns, input variations, output validations, error conditions, boundary conditions, configuration variants, environment differences, platform concerns, backwards compatibility, data migration, rollback paths, monitoring checkpoints, verification steps.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Longer is better. Missing items means missing work. Err towards every possible item.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## File Rules
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- Starting a new task or initiative
|
|
19
|
-
- User requests multiple items/features/fixes that need coordination
|
|
20
|
-
- Work has dependencies, parallellizable items, or complex stages
|
|
21
|
-
- You need to track progress across multiple independent work streams
|
|
17
|
+
Path: exactly `./.prd` in current working directory. No variants (.prd-rename, .prd-temp, .prd-backup), no subdirectories, no path transformations, no extensions. Valid JSON.
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## PRD Structure
|
|
26
|
-
|
|
27
|
-
Each PRD contains:
|
|
28
|
-
- **items**: Array of work items with dependencies
|
|
29
|
-
- **completed**: Empty list (populated as items finish)
|
|
30
|
-
- **metadata**: Total estimates, phases, notes
|
|
31
|
-
|
|
32
|
-
### Item Fields
|
|
19
|
+
## Item Schema
|
|
33
20
|
|
|
34
21
|
```json
|
|
35
22
|
{
|
|
36
|
-
"id": "
|
|
37
|
-
"subject": "
|
|
23
|
+
"id": "descriptive-kebab-id",
|
|
24
|
+
"subject": "Imperative verb describing outcome",
|
|
38
25
|
"status": "pending",
|
|
39
|
-
"description": "
|
|
40
|
-
"blocking": ["
|
|
41
|
-
"blockedBy": ["
|
|
26
|
+
"description": "What must be true when this is done",
|
|
27
|
+
"blocking": ["ids-this-prevents"],
|
|
28
|
+
"blockedBy": ["ids-that-must-finish-first"],
|
|
42
29
|
"effort": "small|medium|large",
|
|
43
|
-
"category": "feature|bug|refactor|docs",
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Key Rules
|
|
49
|
-
|
|
50
|
-
**Subject**: Use imperative form - "Fix auth bug", "Add webhook support", "Consolidate templates", not "Bug: auth", "New feature", etc.
|
|
51
|
-
|
|
52
|
-
**Blocking/Blocked By**: Map dependency graph
|
|
53
|
-
- If item 2 waits for item 1: `"blockedBy": ["1"]`
|
|
54
|
-
- If item 1 blocks items 2 & 3: `"blocking": ["2", "3"]`
|
|
55
|
-
|
|
56
|
-
**Status**: Only three values
|
|
57
|
-
- `pending` - not started
|
|
58
|
-
- `in_progress` - currently working
|
|
59
|
-
- `completed` - fully done
|
|
60
|
-
|
|
61
|
-
**Effort**: Estimate relative scope
|
|
62
|
-
- `small`: 1-2 items in 15 min
|
|
63
|
-
- `medium`: 3-5 items in 30-45 min
|
|
64
|
-
- `large`: 6+ items or 1+ hours
|
|
65
|
-
|
|
66
|
-
## Complete Item Template
|
|
67
|
-
|
|
68
|
-
Use this when planning complex work:
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"id": "task-name-1",
|
|
73
|
-
"subject": "Consolidate duplicate template builders",
|
|
74
|
-
"status": "pending",
|
|
75
|
-
"description": "Extract shared generatePackageJson() and buildHooksMap() logic from cli-adapter.js and extension-adapter.js into TemplateBuilder methods. Current duplication causes maintenance burden.",
|
|
76
|
-
"category": "refactor",
|
|
77
|
-
"effort": "medium",
|
|
78
|
-
"blocking": ["task-name-2"],
|
|
79
|
-
"blockedBy": [],
|
|
80
|
-
"acceptance": [
|
|
81
|
-
"Single generatePackageJson() method in TemplateBuilder",
|
|
82
|
-
"Both adapters call TemplateBuilder methods",
|
|
83
|
-
"All 9 platforms generate identical package.json structure",
|
|
84
|
-
"No duplication in adapter code"
|
|
85
|
-
],
|
|
86
|
-
"edge_cases": [
|
|
87
|
-
"Platforms without package.json (JetBrains IDE)",
|
|
88
|
-
"Custom fields for CLI vs extension platforms"
|
|
89
|
-
],
|
|
90
|
-
"verification": "All 9 build outputs pass validation, adapters <150 lines each"
|
|
30
|
+
"category": "feature|bug|refactor|docs|infra",
|
|
31
|
+
"acceptance": ["measurable criteria"],
|
|
32
|
+
"edge_cases": ["known complications"]
|
|
91
33
|
}
|
|
92
34
|
```
|
|
93
35
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
When creating PRD, cover:
|
|
97
|
-
|
|
98
|
-
### Requirements
|
|
99
|
-
- [ ] Main objective clearly stated
|
|
100
|
-
- [ ] Success criteria defined
|
|
101
|
-
- [ ] User-facing changes vs internal
|
|
102
|
-
- [ ] Backwards compatibility implications
|
|
103
|
-
- [ ] Data migration needed?
|
|
104
|
-
|
|
105
|
-
### Edge Cases
|
|
106
|
-
- [ ] Empty inputs/missing files
|
|
107
|
-
- [ ] Large scale (1000s of items?)
|
|
108
|
-
- [ ] Concurrent access patterns
|
|
109
|
-
- [ ] Timeout/hang scenarios
|
|
110
|
-
- [ ] Recovery from failures
|
|
111
|
-
|
|
112
|
-
### Dependencies
|
|
113
|
-
- [ ] External services/APIs required?
|
|
114
|
-
- [ ] Third-party library versions
|
|
115
|
-
- [ ] Environment setup (DB, redis, etc)
|
|
116
|
-
- [ ] Breaking changes from upgrades?
|
|
117
|
-
|
|
118
|
-
### Acceptance Criteria
|
|
119
|
-
- [ ] Code changed meets goal
|
|
120
|
-
- [ ] Tests pass (if applicable)
|
|
121
|
-
- [ ] Performance requirements met
|
|
122
|
-
- [ ] Security concerns addressed
|
|
123
|
-
- [ ] Documentation updated
|
|
124
|
-
|
|
125
|
-
### Integration Points
|
|
126
|
-
- [ ] Does it touch other systems?
|
|
127
|
-
- [ ] API compatibility impacts?
|
|
128
|
-
- [ ] Database schema changes?
|
|
129
|
-
- [ ] Message queue formats?
|
|
130
|
-
- [ ] Configuration propagation?
|
|
131
|
-
|
|
132
|
-
### Error Handling
|
|
133
|
-
- [ ] What fails gracefully?
|
|
134
|
-
- [ ] What fails hard?
|
|
135
|
-
- [ ] Recovery mechanisms?
|
|
136
|
-
- [ ] Fallback options?
|
|
137
|
-
- [ ] User notification strategy?
|
|
138
|
-
|
|
139
|
-
## PRD Lifecycle
|
|
140
|
-
|
|
141
|
-
### Creation Phase
|
|
142
|
-
1. Enumerate **every possible unknown** as work item
|
|
143
|
-
2. Map dependencies (blocking/blockedBy)
|
|
144
|
-
3. Group parallelizable items into waves
|
|
145
|
-
4. Verify all edge cases captured
|
|
146
|
-
5. Write `./.prd` to disk
|
|
147
|
-
6. **FREEZE** - no modifications except item removal
|
|
148
|
-
|
|
149
|
-
### Execution Phase
|
|
150
|
-
1. Read `.prd`
|
|
151
|
-
2. Find all `pending` items with no `blockedBy`
|
|
152
|
-
3. Launch ≤3 parallel workers (gm:gm subagents) per wave
|
|
153
|
-
4. As items complete, update status to `completed`
|
|
154
|
-
5. Remove completed items from `.prd` file
|
|
155
|
-
6. Launch next wave when previous completes
|
|
156
|
-
7. Continue until `.prd` is empty
|
|
157
|
-
|
|
158
|
-
### Completion Phase
|
|
159
|
-
- `.prd` file is empty (all items removed)
|
|
160
|
-
- All work committed and pushed
|
|
161
|
-
- Tests passing
|
|
162
|
-
- No remaining `pending` or `in_progress` items
|
|
163
|
-
|
|
164
|
-
## File Location
|
|
165
|
-
|
|
166
|
-
**CRITICAL**: PRD must be at exactly `./.prd` (current working directory root).
|
|
167
|
-
|
|
168
|
-
- ✅ `/home/user/plugforge/.prd`
|
|
169
|
-
- ❌ `/home/user/plugforge/.prd-temp`
|
|
170
|
-
- ❌ `/home/user/plugforge/build/.prd`
|
|
171
|
-
- ❌ `/home/user/plugforge/.prd.json`
|
|
172
|
-
|
|
173
|
-
No variants, no subdirectories, no extensions. Absolute path must resolve to `cwd + .prd`.
|
|
174
|
-
|
|
175
|
-
## JSON Format
|
|
176
|
-
|
|
177
|
-
PRD files are **valid JSON** for easy parsing and manipulation.
|
|
178
|
-
|
|
179
|
-
```json
|
|
180
|
-
{
|
|
181
|
-
"project": "plugforge",
|
|
182
|
-
"created": "2026-02-24",
|
|
183
|
-
"objective": "Unify agent tooling and planning infrastructure",
|
|
184
|
-
"items": [
|
|
185
|
-
{
|
|
186
|
-
"id": "1",
|
|
187
|
-
"subject": "Update agent-browser skill documentation",
|
|
188
|
-
"status": "pending",
|
|
189
|
-
"description": "Add complete command reference with all 100+ commands",
|
|
190
|
-
"blocking": ["2"],
|
|
191
|
-
"blockedBy": [],
|
|
192
|
-
"effort": "small",
|
|
193
|
-
"category": "docs"
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
"id": "2",
|
|
197
|
-
"subject": "Create planning skill for PRD construction",
|
|
198
|
-
"status": "pending",
|
|
199
|
-
"description": "New skill that creates .prd files with dependency graphs",
|
|
200
|
-
"blocking": ["3"],
|
|
201
|
-
"blockedBy": ["1"],
|
|
202
|
-
"effort": "medium",
|
|
203
|
-
"category": "feature"
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
"id": "3",
|
|
207
|
-
"subject": "Update gm.md agent instructions",
|
|
208
|
-
"status": "pending",
|
|
209
|
-
"description": "Reference new skills, emphasize codesearch over cli tools",
|
|
210
|
-
"blocking": [],
|
|
211
|
-
"blockedBy": ["2"],
|
|
212
|
-
"effort": "medium",
|
|
213
|
-
"category": "docs"
|
|
214
|
-
}
|
|
215
|
-
],
|
|
216
|
-
"completed": []
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Execution Guidelines
|
|
221
|
-
|
|
222
|
-
**Wave Orchestration**: Maximum 3 subagents per wave (gm:gm agents via Task tool).
|
|
223
|
-
|
|
224
|
-
```
|
|
225
|
-
Wave 1: Items 1, 2, 3 (all pending, no dependencies)
|
|
226
|
-
└─ 3 subagents launched in parallel
|
|
227
|
-
|
|
228
|
-
Wave 2: Items 4, 5 (depend on Wave 1 completion)
|
|
229
|
-
└─ Items 6, 7 (wait for Wave 2)
|
|
230
|
-
|
|
231
|
-
Wave 3: Items 6, 7
|
|
232
|
-
└─ 2 subagents (since only 2 items)
|
|
233
|
-
|
|
234
|
-
Wave 4: Item 8 (depends on Wave 3)
|
|
235
|
-
└─ Completes work
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
After each wave completes:
|
|
239
|
-
1. Remove finished items from `.prd`
|
|
240
|
-
2. Write `.prd` (now shorter)
|
|
241
|
-
3. Check for newly unblocked items
|
|
242
|
-
4. Launch next wave
|
|
243
|
-
|
|
244
|
-
## Example: Multi-Platform Builder Updates
|
|
245
|
-
|
|
246
|
-
```json
|
|
247
|
-
{
|
|
248
|
-
"project": "plugforge",
|
|
249
|
-
"objective": "Add hooks support to 5 CLI platforms",
|
|
250
|
-
"items": [
|
|
251
|
-
{
|
|
252
|
-
"id": "hooks-cc",
|
|
253
|
-
"subject": "Add hooks to gm-cc platform",
|
|
254
|
-
"status": "pending",
|
|
255
|
-
"blocking": ["test-hooks"],
|
|
256
|
-
"blockedBy": [],
|
|
257
|
-
"effort": "small"
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
"id": "hooks-gc",
|
|
261
|
-
"subject": "Add hooks to gm-gc platform",
|
|
262
|
-
"status": "pending",
|
|
263
|
-
"blocking": ["test-hooks"],
|
|
264
|
-
"blockedBy": [],
|
|
265
|
-
"effort": "small"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"id": "hooks-oc",
|
|
269
|
-
"subject": "Add hooks to gm-oc platform",
|
|
270
|
-
"status": "pending",
|
|
271
|
-
"blocking": ["test-hooks"],
|
|
272
|
-
"blockedBy": [],
|
|
273
|
-
"effort": "small"
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
"id": "test-hooks",
|
|
277
|
-
"subject": "Test all 5 platforms with hooks",
|
|
278
|
-
"status": "pending",
|
|
279
|
-
"blocking": [],
|
|
280
|
-
"blockedBy": ["hooks-cc", "hooks-gc", "hooks-oc"],
|
|
281
|
-
"effort": "large"
|
|
282
|
-
}
|
|
283
|
-
]
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
**Execution**:
|
|
288
|
-
- Wave 1: Launch 3 subagents for `hooks-cc`, `hooks-gc`, `hooks-oc` in parallel
|
|
289
|
-
- After all 3 complete, launch `test-hooks`
|
|
290
|
-
|
|
291
|
-
This cuts wall-clock time from 45 min (sequential) to ~15 min (parallel).
|
|
36
|
+
**Subject**: imperative form — "Fix auth bug", "Add webhook support", "Consolidate templates". Never "Bug: auth" or "New feature".
|
|
292
37
|
|
|
293
|
-
|
|
38
|
+
**Blocking/blockedBy**: bidirectional. If A blocks B, then B blockedBy A. Every dependency explicit.
|
|
294
39
|
|
|
295
|
-
|
|
296
|
-
Don't under-estimate work. If you think it's 3 items, list 8. Missing items cause restarts.
|
|
40
|
+
**Status**: `pending` → `in_progress` → `completed`. No other values.
|
|
297
41
|
|
|
298
|
-
|
|
299
|
-
- `blocking`: What does THIS item prevent?
|
|
300
|
-
- `blockedBy`: What must complete before THIS?
|
|
301
|
-
- Bidirectional: If A blocks B, then B blockedBy A
|
|
42
|
+
**Effort**: `small` (one attempt, <15min), `medium` (2 rounds, <45min), `large` (multiple rounds, 1h+).
|
|
302
43
|
|
|
303
|
-
|
|
304
|
-
- `feature`: New capability
|
|
305
|
-
- `bug`: Fix broken behavior
|
|
306
|
-
- `refactor`: Improve structure without changing behavior
|
|
307
|
-
- `docs`: Documentation
|
|
308
|
-
- `infra`: Build, CI, deployment
|
|
44
|
+
## Construction
|
|
309
45
|
|
|
310
|
-
|
|
311
|
-
|
|
46
|
+
1. Enumerate every possible unknown as a work item.
|
|
47
|
+
2. Map every possible dependency (blocking/blockedBy).
|
|
48
|
+
3. Group independent items into parallel waves (max 3 per wave).
|
|
49
|
+
4. Capture every possible edge case as either a separate item or an edge_case field.
|
|
50
|
+
5. Write `./.prd` to disk.
|
|
51
|
+
6. **FREEZE** — no additions or reorganizations after creation. Only mutation: removing finished items.
|
|
312
52
|
|
|
313
|
-
|
|
314
|
-
- `small`: Coding + testing in 1 attempt
|
|
315
|
-
- `medium`: May need 2 rounds of refinement
|
|
316
|
-
- `large`: Multiple rounds, unexpected issues likely
|
|
53
|
+
## Execution
|
|
317
54
|
|
|
318
|
-
|
|
55
|
+
1. Find all `pending` items with empty `blockedBy`.
|
|
56
|
+
2. Launch ≤3 parallel subagents (`subagent_type: gm:gm`) per wave.
|
|
57
|
+
3. Each subagent completes one item, verifies via witnessed execution.
|
|
58
|
+
4. On completion: remove item from `.prd`, write updated file.
|
|
59
|
+
5. Check for newly unblocked items. Launch next wave.
|
|
60
|
+
6. Continue until `.prd` is empty.
|
|
319
61
|
|
|
320
|
-
|
|
62
|
+
Never execute independent items sequentially. Never launch more than 3 at once.
|
|
321
63
|
|
|
322
|
-
|
|
64
|
+
## Completion
|
|
323
65
|
|
|
324
|
-
|
|
66
|
+
`.prd` must be empty at COMPLETE — zero pending, zero in_progress items. The stop hook blocks session end when items remain. Empty `.prd` = all work done.
|
|
325
67
|
|
|
326
|
-
|
|
327
|
-
1. Verifies `.prd` exists and has valid JSON
|
|
328
|
-
2. Extracts items with `status: pending`
|
|
329
|
-
3. Finds items with no `blockedBy` constraints
|
|
330
|
-
4. Launches ≤3 gm:gm subagents per wave
|
|
331
|
-
5. Each subagent completes one item
|
|
332
|
-
6. On completion, PRD is updated (item removed)
|
|
333
|
-
7. Process repeats until `.prd` is empty
|
|
68
|
+
## Do Not Use
|
|
334
69
|
|
|
335
|
-
|
|
70
|
+
Skip this skill if the task is trivially single-step (under 5 minutes, no dependencies, no unknowns).
|
package/tools.json
CHANGED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: process-management
|
|
3
|
-
description: >-
|
|
4
|
-
PM2 process management for all running applications. Enforces: pre-check for
|
|
5
|
-
running processes before start, watch enabled, autorestart disabled, lifecycle
|
|
6
|
-
cleanup when done. Use for all servers, workers, agents, background processes.
|
|
7
|
-
Triggers: start server, run application, background process, pm2, keep alive,
|
|
8
|
-
process manager, daemon, monitor logs.
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Process Management — PM2
|
|
12
|
-
|
|
13
|
-
All applications MUST run through PM2. Direct invocations (node, bun, python) are forbidden for any process that produces output or has a lifecycle.
|
|
14
|
-
|
|
15
|
-
## Installation (First Time Only)
|
|
16
|
-
|
|
17
|
-
Check if PM2 is installed:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
pm2 --version
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
If command not found, install globally:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm install -g pm2
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Verify installation:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
pm2 --version # should print version number
|
|
33
|
-
pm2 ping # should respond "pong"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Pre-Start Check (MANDATORY)
|
|
37
|
-
|
|
38
|
-
Before starting any process, check what is already running:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
pm2 jlist
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- `online` → already running, use `pm2 logs <name>` to observe
|
|
45
|
-
- `stopped` → use `pm2 restart <name>`
|
|
46
|
-
- Not in list → proceed to start
|
|
47
|
-
|
|
48
|
-
Never start a duplicate process. Always check first.
|
|
49
|
-
|
|
50
|
-
## Start a Process
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# CLI (quick)
|
|
54
|
-
pm2 start app.js --name myapp --watch --no-autorestart
|
|
55
|
-
|
|
56
|
-
# With interpreter
|
|
57
|
-
pm2 start script.py --interpreter python3 --name worker --watch --no-autorestart
|
|
58
|
-
|
|
59
|
-
# From ecosystem config (preferred for reproducibility)
|
|
60
|
-
pm2 start ecosystem.config.cjs
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Ecosystem Config (Standard Template)
|
|
64
|
-
|
|
65
|
-
`autorestart: false` — process stops on crash, no automatic recovery
|
|
66
|
-
`watch: true` — restarts on file changes in watched directories only
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
// ecosystem.config.cjs
|
|
70
|
-
module.exports = {
|
|
71
|
-
apps: [{
|
|
72
|
-
name: "myapp",
|
|
73
|
-
script: "src/index.js",
|
|
74
|
-
watch: ["src", "config"],
|
|
75
|
-
watch_delay: 1000,
|
|
76
|
-
autorestart: false,
|
|
77
|
-
ignore_watch: [
|
|
78
|
-
"node_modules",
|
|
79
|
-
".git",
|
|
80
|
-
"logs",
|
|
81
|
-
"*.log",
|
|
82
|
-
".pm2",
|
|
83
|
-
"public",
|
|
84
|
-
"uploads"
|
|
85
|
-
],
|
|
86
|
-
watch_options: {
|
|
87
|
-
followSymlinks: false,
|
|
88
|
-
usePolling: false
|
|
89
|
-
},
|
|
90
|
-
log_date_format: "YYYY-MM-DD HH:mm:ss",
|
|
91
|
-
out_file: "./logs/out.log",
|
|
92
|
-
error_file: "./logs/error.log"
|
|
93
|
-
}]
|
|
94
|
-
};
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Log Viewing
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
pm2 logs <name> # stream live (Ctrl+C to stop)
|
|
101
|
-
pm2 logs <name> --lines 100 # last 100 lines then stream
|
|
102
|
-
pm2 logs <name> --err # errors only
|
|
103
|
-
pm2 logs <name> --out # stdout only
|
|
104
|
-
pm2 logs <name> --nostream --lines 200 # dump without follow
|
|
105
|
-
pm2 logs --json # structured JSON output
|
|
106
|
-
pm2 flush # clear all log files
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Log files: `~/.pm2/logs/<name>-out.log` / `<name>-error.log`
|
|
110
|
-
Windows path: `C:\Users\<user>\.pm2\logs\`
|
|
111
|
-
|
|
112
|
-
## Lifecycle Management
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
pm2 list # view all processes and status
|
|
116
|
-
pm2 jlist # JSON output for scripting
|
|
117
|
-
pm2 info <name> # detailed process info
|
|
118
|
-
pm2 stop <name> # stop (keeps in list)
|
|
119
|
-
pm2 restart <name> # restart
|
|
120
|
-
pm2 delete <name> # stop + remove from list
|
|
121
|
-
pm2 delete all # remove all processes
|
|
122
|
-
pm2 ping # check if PM2 daemon is alive
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**When work is complete: always `pm2 delete <name>` to clean up orphaned processes.**
|
|
126
|
-
|
|
127
|
-
Stopping a watched process: `pm2 stop` while watch is active restarts on next file change.
|
|
128
|
-
To fully halt: `pm2 delete <name>` (removes it entirely).
|
|
129
|
-
|
|
130
|
-
## Windows vs Linux
|
|
131
|
-
|
|
132
|
-
### File Watching
|
|
133
|
-
|
|
134
|
-
| Environment | Config |
|
|
135
|
-
|---|---|
|
|
136
|
-
| Linux native | `usePolling: false` (inotify kernel events) |
|
|
137
|
-
| WSL watching `/mnt/c/...` | `usePolling: true, interval: 1000` |
|
|
138
|
-
| Windows native | `usePolling: false` (ReadDirectoryChangesW) |
|
|
139
|
-
| Network / NFS / Docker volumes | `usePolling: true, interval: 1000` |
|
|
140
|
-
|
|
141
|
-
Linux inotify exhaustion fix (symptom: watch silently stops working):
|
|
142
|
-
```bash
|
|
143
|
-
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Windows: npm Scripts and .cmd Wrappers
|
|
147
|
-
|
|
148
|
-
PM2 cannot spawn `.cmd` shims (npm, npx, etc.) directly — they require `cmd.exe`.
|
|
149
|
-
|
|
150
|
-
```javascript
|
|
151
|
-
// ecosystem.config.cjs — Windows npm script
|
|
152
|
-
{
|
|
153
|
-
name: "myapp",
|
|
154
|
-
script: "npm",
|
|
155
|
-
args: "start",
|
|
156
|
-
interpreter: "cmd",
|
|
157
|
-
interpreter_args: "/c"
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
For globally installed CLIs, find the real `.js` entry point:
|
|
162
|
-
```bash
|
|
163
|
-
# Linux/macOS
|
|
164
|
-
cat "$(which myapp)" | head -5
|
|
165
|
-
|
|
166
|
-
# Windows PowerShell
|
|
167
|
-
Get-Command myapp | Select-Object -ExpandProperty Source
|
|
168
|
-
```
|
|
169
|
-
Point `script` at the resolved `.js` file — never at the `.cmd` wrapper.
|
|
170
|
-
|
|
171
|
-
### Terminal Suppression on Windows (CRITICAL)
|
|
172
|
-
|
|
173
|
-
All code that spawns subprocesses MUST use `windowsHide: true` to prevent popup windows.
|
|
174
|
-
|
|
175
|
-
```javascript
|
|
176
|
-
// ❌ WRONG - will show popup windows on Windows
|
|
177
|
-
spawn('node', ['script.js']);
|
|
178
|
-
|
|
179
|
-
// ✅ CORRECT - hides windows, safe for all platforms
|
|
180
|
-
spawn('node', ['script.js'], { windowsHide: true });
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
Applies to all subprocess execution:
|
|
184
|
-
- `child_process.spawn()` → `{ windowsHide: true }`
|
|
185
|
-
- `child_process.exec()` → `{ windowsHide: true }`
|
|
186
|
-
- `child_process.execFile()` → `{ windowsHide: true }`
|
|
187
|
-
- `child_process.fork()` → `{ silent: true }` (alternative for fork)
|
|
188
|
-
|
|
189
|
-
PM2-started processes automatically hide windows. Code-spawned subprocesses must explicitly set this. Forgetting creates visible popups during automation—unacceptable UX.
|
|
190
|
-
|
|
191
|
-
### Windows 11+ wmic Error
|
|
192
|
-
|
|
193
|
-
PM2 uses `wmic` for process stats — removed in Windows 11+.
|
|
194
|
-
Symptom: `Error: spawn wmic ENOENT` in `~/.pm2/pm2.log`.
|
|
195
|
-
Fix: `npm install -g pm2@latest`. App processes continue working despite the error.
|
|
196
|
-
|
|
197
|
-
### Persistence on Reboot
|
|
198
|
-
|
|
199
|
-
| Platform | Method |
|
|
200
|
-
|---|---|
|
|
201
|
-
| Linux | `pm2 startup && pm2 save` (auto-detects systemd/upstart/openrc) |
|
|
202
|
-
| Windows | [pm2-installer](https://github.com/jessety/pm2-installer) (Windows Service) |
|
|
203
|
-
|
|
204
|
-
```bash
|
|
205
|
-
pm2 save # snapshot current process list to ~/.pm2/dump.pm2
|
|
206
|
-
pm2 resurrect # restore saved list after manual daemon restart
|
|
207
|
-
```
|