planfs-cli 1.2.0
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/README.md +167 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +540 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ai.d.ts +27 -0
- package/dist/commands/ai.js +355 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/archive.d.ts +13 -0
- package/dist/commands/archive.js +176 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/backlog.d.ts +19 -0
- package/dist/commands/backlog.js +151 -0
- package/dist/commands/backlog.js.map +1 -0
- package/dist/commands/branch.d.ts +9 -0
- package/dist/commands/branch.js +59 -0
- package/dist/commands/branch.js.map +1 -0
- package/dist/commands/create.d.ts +17 -0
- package/dist/commands/create.js +157 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/git.d.ts +9 -0
- package/dist/commands/git.js +46 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.js +36 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +12 -0
- package/dist/commands/list.js +84 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/next.d.ts +15 -0
- package/dist/commands/next.js +82 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/pr.d.ts +11 -0
- package/dist/commands/pr.js +31 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/show.d.ts +8 -0
- package/dist/commands/show.js +76 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/validate.d.ts +9 -0
- package/dist/commands/validate.js +102 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# planfs-cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for PlanFS.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`planfs-cli` provides command-line tools for managing PlanFS repositories:
|
|
8
|
+
|
|
9
|
+
- **Validate** - Check repository integrity
|
|
10
|
+
- **Init** - Create repository structure
|
|
11
|
+
- **List** - Query entities with filtering
|
|
12
|
+
- **Backlog** - Capture, refine, order, and review backlog items
|
|
13
|
+
- **Next** - List ranked next-work candidates with explanations
|
|
14
|
+
- **Show** - Display entity details
|
|
15
|
+
- **Create** - Create new entities
|
|
16
|
+
- **PR** - Generate pull request planning context
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g planfs-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or use locally:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install planfs-cli
|
|
28
|
+
npx planfs --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
### Init
|
|
34
|
+
|
|
35
|
+
Initialize the repository structure:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
planfs init
|
|
39
|
+
planfs init --format json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Validate
|
|
43
|
+
|
|
44
|
+
Validate the repository for errors:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
planfs validate
|
|
48
|
+
planfs validate --verbose
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### List
|
|
52
|
+
|
|
53
|
+
List entities:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# List all tasks
|
|
57
|
+
planfs list tasks
|
|
58
|
+
|
|
59
|
+
# List tasks by status
|
|
60
|
+
planfs list tasks --status todo
|
|
61
|
+
|
|
62
|
+
# List tasks by assignee
|
|
63
|
+
planfs list tasks --assignee user@example.com
|
|
64
|
+
|
|
65
|
+
# List by epic
|
|
66
|
+
planfs list tasks --epic EPIC-auth-system
|
|
67
|
+
|
|
68
|
+
# Output as JSON
|
|
69
|
+
planfs list tasks --format json
|
|
70
|
+
|
|
71
|
+
# List other entity types
|
|
72
|
+
planfs list epics
|
|
73
|
+
planfs list milestones
|
|
74
|
+
planfs list decisions
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Next
|
|
78
|
+
|
|
79
|
+
List the most actionable work:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
planfs next
|
|
83
|
+
planfs next --assignee justin
|
|
84
|
+
planfs next --epic EPIC-auth-system --explain
|
|
85
|
+
planfs next --include-blocked
|
|
86
|
+
planfs next --format json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`planfs next` filters out completed work by default, ranks ready and active tasks, and explains blockers when `--include-blocked` is used.
|
|
90
|
+
|
|
91
|
+
### Backlog
|
|
92
|
+
|
|
93
|
+
Capture and refine work before it becomes actionable:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
planfs backlog capture --title "Investigate import workflow"
|
|
97
|
+
planfs backlog list
|
|
98
|
+
planfs backlog list --state needs-refinement --assignee justin
|
|
99
|
+
planfs backlog set-state --id TASK-060 --state ready
|
|
100
|
+
planfs backlog review
|
|
101
|
+
planfs backlog list --format json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Backlog refinement states are `captured`, `needs-refinement`, `ready`, `deferred`, and `discarded`. Explicit non-ready backlog items are separate from next-work recommendations.
|
|
105
|
+
|
|
106
|
+
### Show
|
|
107
|
+
|
|
108
|
+
Display entity details:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
planfs show TASK-001
|
|
112
|
+
planfs show TASK-001 --format json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Create
|
|
116
|
+
|
|
117
|
+
Create new entities:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Create task
|
|
121
|
+
planfs create task --title "Implement feature X" --priority high
|
|
122
|
+
|
|
123
|
+
# With assignee
|
|
124
|
+
planfs create task --title "Fix bug" --status todo --assignee user@example.com
|
|
125
|
+
|
|
126
|
+
# Create epic
|
|
127
|
+
planfs create epic --title "Phase 6 - Polish" --owner justin
|
|
128
|
+
|
|
129
|
+
# Create milestone
|
|
130
|
+
planfs create milestone --title "v0.2" --target-date 2026-09-01 --owner justin
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Pull Requests
|
|
134
|
+
|
|
135
|
+
Generate pull request planning context from the current branch:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
planfs pr summary
|
|
139
|
+
planfs pr summary --format json
|
|
140
|
+
planfs pr providers --format json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Usage
|
|
144
|
+
|
|
145
|
+
### As a Module
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { validateCommand, listCommand } from 'planfs-cli';
|
|
149
|
+
|
|
150
|
+
// Validate repository
|
|
151
|
+
const exitCode = await validateCommand('/path/to/repo', { verbose: true });
|
|
152
|
+
|
|
153
|
+
// List tasks
|
|
154
|
+
const code = await listCommand('/path/to/repo', {
|
|
155
|
+
type: 'tasks',
|
|
156
|
+
status: 'todo',
|
|
157
|
+
format: 'json'
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Architecture
|
|
162
|
+
|
|
163
|
+
See [Architecture Documentation](../../docs/ARCHITECTURE.md) for system design.
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Main CLI entry point
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.main = main;
|
|
11
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
12
|
+
const helpers_1 = require("yargs/helpers");
|
|
13
|
+
const validate_1 = require("./commands/validate");
|
|
14
|
+
const ai_1 = require("./commands/ai");
|
|
15
|
+
const init_1 = require("./commands/init");
|
|
16
|
+
const list_1 = require("./commands/list");
|
|
17
|
+
const next_1 = require("./commands/next");
|
|
18
|
+
const show_1 = require("./commands/show");
|
|
19
|
+
const create_1 = require("./commands/create");
|
|
20
|
+
const backlog_1 = require("./commands/backlog");
|
|
21
|
+
const archive_1 = require("./commands/archive");
|
|
22
|
+
const branch_1 = require("./commands/branch");
|
|
23
|
+
const git_1 = require("./commands/git");
|
|
24
|
+
const pr_1 = require("./commands/pr");
|
|
25
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
26
|
+
async function main() {
|
|
27
|
+
await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
28
|
+
.version(package_json_1.default.version)
|
|
29
|
+
.command('ai <action>', 'AI-oriented planning summary and update helpers', (y) => y
|
|
30
|
+
.positional('action', {
|
|
31
|
+
describe: 'AI helper to run',
|
|
32
|
+
choices: ['summary', 'update-task', 'bulk-update-tasks', 'initialize']
|
|
33
|
+
})
|
|
34
|
+
.option('id', {
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Task ID to update'
|
|
37
|
+
})
|
|
38
|
+
.option('ids', {
|
|
39
|
+
type: 'array',
|
|
40
|
+
string: true,
|
|
41
|
+
description: 'Task IDs to bulk update, comma-separated or repeated'
|
|
42
|
+
})
|
|
43
|
+
.option('assignee', {
|
|
44
|
+
type: 'string',
|
|
45
|
+
description: 'Scope summary or set task assignee'
|
|
46
|
+
})
|
|
47
|
+
.option('epic', {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'Scope summary or set task epic'
|
|
50
|
+
})
|
|
51
|
+
.option('milestone', {
|
|
52
|
+
type: 'string',
|
|
53
|
+
description: 'Scope summary or set task milestone'
|
|
54
|
+
})
|
|
55
|
+
.option('estimate', {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Set task estimate'
|
|
58
|
+
})
|
|
59
|
+
.option('status', {
|
|
60
|
+
type: 'array',
|
|
61
|
+
string: true,
|
|
62
|
+
choices: ['todo', 'in-progress', 'review', 'done'],
|
|
63
|
+
description: 'Scope summary by status or set task status'
|
|
64
|
+
})
|
|
65
|
+
.option('priority', {
|
|
66
|
+
type: 'string',
|
|
67
|
+
choices: ['low', 'medium', 'high', 'critical'],
|
|
68
|
+
description: 'Set task priority'
|
|
69
|
+
})
|
|
70
|
+
.option('refinement-state', {
|
|
71
|
+
type: 'array',
|
|
72
|
+
string: true,
|
|
73
|
+
choices: ['captured', 'needs-refinement', 'ready', 'deferred', 'discarded'],
|
|
74
|
+
description: 'Scope summary by refinement state or set task refinement state'
|
|
75
|
+
})
|
|
76
|
+
.option('due-date', {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'Set task due date'
|
|
79
|
+
})
|
|
80
|
+
.option('tags', {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Set task tags as a comma-separated list'
|
|
83
|
+
})
|
|
84
|
+
.option('limit', {
|
|
85
|
+
type: 'number',
|
|
86
|
+
description: 'Maximum number of summary items per list'
|
|
87
|
+
})
|
|
88
|
+
.option('only', {
|
|
89
|
+
type: 'string',
|
|
90
|
+
choices: ['open', 'ready', 'blocked', 'review', 'stale', 'recent'],
|
|
91
|
+
description: 'Return only one planning summary section'
|
|
92
|
+
})
|
|
93
|
+
.option('compact', {
|
|
94
|
+
type: 'boolean',
|
|
95
|
+
default: false,
|
|
96
|
+
description: 'Emit minified JSON for lower-overhead agent context'
|
|
97
|
+
})
|
|
98
|
+
.option('expected-updated-at', {
|
|
99
|
+
type: 'string',
|
|
100
|
+
description: 'Refuse a task update if updatedAt changed since preview (use none for an unset timestamp)'
|
|
101
|
+
})
|
|
102
|
+
.option('command', {
|
|
103
|
+
type: 'string',
|
|
104
|
+
description: 'CLI command written by ai initialize (default: planfs)'
|
|
105
|
+
})
|
|
106
|
+
.option('dry-run', {
|
|
107
|
+
type: 'boolean',
|
|
108
|
+
default: false,
|
|
109
|
+
description: 'Preview task updates or awareness initialization without writing files'
|
|
110
|
+
})
|
|
111
|
+
.option('file', {
|
|
112
|
+
type: 'string',
|
|
113
|
+
default: 'AGENTS.md',
|
|
114
|
+
description: 'Agent instruction file to create or update'
|
|
115
|
+
})
|
|
116
|
+
.option('format', {
|
|
117
|
+
type: 'string',
|
|
118
|
+
choices: ['json', 'text'],
|
|
119
|
+
default: 'json',
|
|
120
|
+
description: 'Output format'
|
|
121
|
+
}), async (args) => {
|
|
122
|
+
const exitCode = await (0, ai_1.aiCommand)(process.cwd(), args.action, {
|
|
123
|
+
id: args.id,
|
|
124
|
+
ids: args.ids,
|
|
125
|
+
assignee: args.assignee,
|
|
126
|
+
epic: args.epic,
|
|
127
|
+
milestone: args.milestone,
|
|
128
|
+
estimate: args.estimate,
|
|
129
|
+
status: args.status,
|
|
130
|
+
priority: args.priority,
|
|
131
|
+
refinementState: args.refinementState,
|
|
132
|
+
dueDate: args.dueDate,
|
|
133
|
+
tags: args.tags,
|
|
134
|
+
limit: args.limit,
|
|
135
|
+
dryRun: args.dryRun,
|
|
136
|
+
file: args.file,
|
|
137
|
+
format: args.format,
|
|
138
|
+
only: args.only,
|
|
139
|
+
compact: args.compact,
|
|
140
|
+
expectedUpdatedAt: args.expectedUpdatedAt,
|
|
141
|
+
command: args.command
|
|
142
|
+
});
|
|
143
|
+
process.exit(exitCode);
|
|
144
|
+
})
|
|
145
|
+
.command('init', 'Initialize PlanFS repository structure', (y) => y.option('format', {
|
|
146
|
+
type: 'string',
|
|
147
|
+
choices: ['text', 'json'],
|
|
148
|
+
default: 'text',
|
|
149
|
+
description: 'Output format'
|
|
150
|
+
}), async (args) => {
|
|
151
|
+
const exitCode = await (0, init_1.initCommand)(process.cwd(), {
|
|
152
|
+
format: args.format
|
|
153
|
+
});
|
|
154
|
+
process.exit(exitCode);
|
|
155
|
+
})
|
|
156
|
+
.command('validate', 'Validate the PlanFS repository', (y) => y
|
|
157
|
+
.option('verbose', {
|
|
158
|
+
alias: 'v',
|
|
159
|
+
type: 'boolean',
|
|
160
|
+
description: 'Show detailed output',
|
|
161
|
+
default: false
|
|
162
|
+
})
|
|
163
|
+
.option('format', {
|
|
164
|
+
type: 'string',
|
|
165
|
+
choices: ['text', 'json'],
|
|
166
|
+
default: 'text',
|
|
167
|
+
description: 'Output format'
|
|
168
|
+
}), async (args) => {
|
|
169
|
+
const exitCode = await (0, validate_1.validateCommand)(process.cwd(), {
|
|
170
|
+
verbose: args.verbose,
|
|
171
|
+
format: args.format
|
|
172
|
+
});
|
|
173
|
+
process.exit(exitCode);
|
|
174
|
+
})
|
|
175
|
+
.command('branch', 'Show PlanFS changes on the current Git branch', (y) => y
|
|
176
|
+
.option('base', {
|
|
177
|
+
type: 'string',
|
|
178
|
+
description: 'Base branch or ref to compare against'
|
|
179
|
+
})
|
|
180
|
+
.option('format', {
|
|
181
|
+
type: 'string',
|
|
182
|
+
choices: ['text', 'json'],
|
|
183
|
+
default: 'text',
|
|
184
|
+
description: 'Output format'
|
|
185
|
+
}), async (args) => {
|
|
186
|
+
const exitCode = await (0, branch_1.branchCommand)(process.cwd(), {
|
|
187
|
+
base: args.base,
|
|
188
|
+
format: args.format
|
|
189
|
+
});
|
|
190
|
+
process.exit(exitCode);
|
|
191
|
+
})
|
|
192
|
+
.command('git <action> [message..]', 'Use Git-aware PlanFS helpers', (y) => y
|
|
193
|
+
.positional('action', {
|
|
194
|
+
describe: 'Git helper to run',
|
|
195
|
+
choices: ['commit-message', 'validate-message']
|
|
196
|
+
})
|
|
197
|
+
.positional('message', {
|
|
198
|
+
describe: 'Commit message to validate',
|
|
199
|
+
type: 'string'
|
|
200
|
+
})
|
|
201
|
+
.option('base', {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'Base branch or ref for commit message suggestions'
|
|
204
|
+
})
|
|
205
|
+
.option('format', {
|
|
206
|
+
type: 'string',
|
|
207
|
+
choices: ['text', 'json'],
|
|
208
|
+
default: 'text',
|
|
209
|
+
description: 'Output format'
|
|
210
|
+
}), async (args) => {
|
|
211
|
+
const message = Array.isArray(args.message)
|
|
212
|
+
? args.message.join(' ')
|
|
213
|
+
: args.message;
|
|
214
|
+
const exitCode = await (0, git_1.gitCommand)(process.cwd(), args.action, message, {
|
|
215
|
+
base: args.base,
|
|
216
|
+
format: args.format
|
|
217
|
+
});
|
|
218
|
+
process.exit(exitCode);
|
|
219
|
+
})
|
|
220
|
+
.command('pr <action>', 'Generate pull request planning context', (y) => y
|
|
221
|
+
.positional('action', {
|
|
222
|
+
describe: 'Pull request helper to run',
|
|
223
|
+
choices: ['summary', 'providers']
|
|
224
|
+
})
|
|
225
|
+
.option('base', {
|
|
226
|
+
type: 'string',
|
|
227
|
+
description: 'Base branch or ref to compare against'
|
|
228
|
+
})
|
|
229
|
+
.option('provider', {
|
|
230
|
+
type: 'string',
|
|
231
|
+
choices: ['github', 'gitlab', 'azure-devops'],
|
|
232
|
+
default: 'github',
|
|
233
|
+
description: 'Pull request provider'
|
|
234
|
+
})
|
|
235
|
+
.option('format', {
|
|
236
|
+
type: 'string',
|
|
237
|
+
choices: ['markdown', 'json'],
|
|
238
|
+
default: 'markdown',
|
|
239
|
+
description: 'Output format'
|
|
240
|
+
}), async (args) => {
|
|
241
|
+
const exitCode = await (0, pr_1.pullRequestCommand)(process.cwd(), args.action, {
|
|
242
|
+
base: args.base,
|
|
243
|
+
provider: args.provider,
|
|
244
|
+
format: args.format
|
|
245
|
+
});
|
|
246
|
+
process.exit(exitCode);
|
|
247
|
+
})
|
|
248
|
+
.command('archive <action>', 'Archive, restore, and browse hidden PlanFS tasks and epics', (y) => y
|
|
249
|
+
.positional('action', {
|
|
250
|
+
describe: 'Archive workflow to run',
|
|
251
|
+
choices: ['list', 'archive', 'restore', 'delete']
|
|
252
|
+
})
|
|
253
|
+
.option('id', {
|
|
254
|
+
type: 'string',
|
|
255
|
+
description: 'Task or epic ID'
|
|
256
|
+
})
|
|
257
|
+
.option('include-children', {
|
|
258
|
+
type: 'boolean',
|
|
259
|
+
default: false,
|
|
260
|
+
description: 'When archiving an epic, also archive child tasks'
|
|
261
|
+
})
|
|
262
|
+
.option('dry-run', {
|
|
263
|
+
type: 'boolean',
|
|
264
|
+
default: false,
|
|
265
|
+
description: 'Preview archive changes without writing files'
|
|
266
|
+
})
|
|
267
|
+
.option('expected-updated-at', {
|
|
268
|
+
type: 'string',
|
|
269
|
+
description: 'Refuse archive if the target updatedAt has changed'
|
|
270
|
+
})
|
|
271
|
+
.option('yes', {
|
|
272
|
+
type: 'boolean',
|
|
273
|
+
default: false,
|
|
274
|
+
description: 'Confirm permanent archive deletion'
|
|
275
|
+
})
|
|
276
|
+
.option('format', {
|
|
277
|
+
type: 'string',
|
|
278
|
+
choices: ['text', 'json'],
|
|
279
|
+
default: 'text',
|
|
280
|
+
description: 'Output format'
|
|
281
|
+
}), async (args) => {
|
|
282
|
+
const exitCode = await (0, archive_1.archiveCommand)(process.cwd(), args.action, {
|
|
283
|
+
id: args.id,
|
|
284
|
+
includeChildren: args.includeChildren,
|
|
285
|
+
dryRun: args.dryRun,
|
|
286
|
+
expectedUpdatedAt: args.expectedUpdatedAt,
|
|
287
|
+
yes: args.yes,
|
|
288
|
+
format: args.format
|
|
289
|
+
});
|
|
290
|
+
process.exit(exitCode);
|
|
291
|
+
})
|
|
292
|
+
.command('backlog <action>', 'Manage backlog intake, refinement, and hygiene', (y) => y
|
|
293
|
+
.positional('action', {
|
|
294
|
+
describe: 'Backlog workflow to run',
|
|
295
|
+
choices: ['list', 'capture', 'set-state', 'review']
|
|
296
|
+
})
|
|
297
|
+
.option('title', {
|
|
298
|
+
alias: 't',
|
|
299
|
+
type: 'string',
|
|
300
|
+
description: 'Title for captured backlog items'
|
|
301
|
+
})
|
|
302
|
+
.option('id', {
|
|
303
|
+
type: 'string',
|
|
304
|
+
description: 'Task ID to update'
|
|
305
|
+
})
|
|
306
|
+
.option('state', {
|
|
307
|
+
type: 'string',
|
|
308
|
+
choices: ['captured', 'needs-refinement', 'ready', 'deferred', 'discarded'],
|
|
309
|
+
description: 'Backlog refinement state'
|
|
310
|
+
})
|
|
311
|
+
.option('assignee', {
|
|
312
|
+
type: 'string',
|
|
313
|
+
description: 'Filter or set assignee'
|
|
314
|
+
})
|
|
315
|
+
.option('epic', {
|
|
316
|
+
type: 'string',
|
|
317
|
+
description: 'Filter or set epic'
|
|
318
|
+
})
|
|
319
|
+
.option('milestone', {
|
|
320
|
+
type: 'string',
|
|
321
|
+
description: 'Filter or set milestone'
|
|
322
|
+
})
|
|
323
|
+
.option('priority', {
|
|
324
|
+
type: 'string',
|
|
325
|
+
choices: ['low', 'medium', 'high', 'critical'],
|
|
326
|
+
description: 'Filter or set priority'
|
|
327
|
+
})
|
|
328
|
+
.option('tag', {
|
|
329
|
+
type: 'array',
|
|
330
|
+
string: true,
|
|
331
|
+
description: 'Filter by tag'
|
|
332
|
+
})
|
|
333
|
+
.option('query', {
|
|
334
|
+
type: 'string',
|
|
335
|
+
description: 'Filter by text query'
|
|
336
|
+
})
|
|
337
|
+
.option('body', {
|
|
338
|
+
type: 'string',
|
|
339
|
+
description: 'Markdown body for captured backlog items'
|
|
340
|
+
})
|
|
341
|
+
.option('limit', {
|
|
342
|
+
type: 'number',
|
|
343
|
+
description: 'Maximum number of items to show'
|
|
344
|
+
})
|
|
345
|
+
.option('format', {
|
|
346
|
+
type: 'string',
|
|
347
|
+
choices: ['text', 'json'],
|
|
348
|
+
default: 'text',
|
|
349
|
+
description: 'Output format'
|
|
350
|
+
}), async (args) => {
|
|
351
|
+
const exitCode = await (0, backlog_1.backlogCommand)(process.cwd(), args.action, {
|
|
352
|
+
title: args.title,
|
|
353
|
+
id: args.id,
|
|
354
|
+
state: args.state,
|
|
355
|
+
assignee: args.assignee,
|
|
356
|
+
epic: args.epic,
|
|
357
|
+
milestone: args.milestone,
|
|
358
|
+
priority: args.priority,
|
|
359
|
+
tag: args.tag,
|
|
360
|
+
query: args.query,
|
|
361
|
+
body: args.body,
|
|
362
|
+
limit: args.limit,
|
|
363
|
+
format: args.format
|
|
364
|
+
});
|
|
365
|
+
process.exit(exitCode);
|
|
366
|
+
})
|
|
367
|
+
.command('next', 'List ranked next-work candidates', (y) => y
|
|
368
|
+
.option('assignee', {
|
|
369
|
+
type: 'string',
|
|
370
|
+
description: 'Filter by assignee'
|
|
371
|
+
})
|
|
372
|
+
.option('epic', {
|
|
373
|
+
type: 'string',
|
|
374
|
+
description: 'Filter by epic'
|
|
375
|
+
})
|
|
376
|
+
.option('milestone', {
|
|
377
|
+
type: 'string',
|
|
378
|
+
description: 'Filter by milestone'
|
|
379
|
+
})
|
|
380
|
+
.option('tag', {
|
|
381
|
+
type: 'array',
|
|
382
|
+
string: true,
|
|
383
|
+
description: 'Filter by tag'
|
|
384
|
+
})
|
|
385
|
+
.option('status', {
|
|
386
|
+
type: 'array',
|
|
387
|
+
string: true,
|
|
388
|
+
choices: ['todo', 'in-progress', 'review', 'done'],
|
|
389
|
+
description: 'Filter by status'
|
|
390
|
+
})
|
|
391
|
+
.option('include-blocked', {
|
|
392
|
+
type: 'boolean',
|
|
393
|
+
default: false,
|
|
394
|
+
description: 'Include blocked and missing-dependency tasks'
|
|
395
|
+
})
|
|
396
|
+
.option('explain', {
|
|
397
|
+
type: 'boolean',
|
|
398
|
+
default: false,
|
|
399
|
+
description: 'Show all ranking reasons'
|
|
400
|
+
})
|
|
401
|
+
.option('limit', {
|
|
402
|
+
type: 'number',
|
|
403
|
+
description: 'Maximum number of candidates to show'
|
|
404
|
+
})
|
|
405
|
+
.option('format', {
|
|
406
|
+
type: 'string',
|
|
407
|
+
choices: ['text', 'json'],
|
|
408
|
+
default: 'text',
|
|
409
|
+
description: 'Output format'
|
|
410
|
+
}), async (args) => {
|
|
411
|
+
const exitCode = await (0, next_1.nextCommand)(process.cwd(), {
|
|
412
|
+
assignee: args.assignee,
|
|
413
|
+
epic: args.epic,
|
|
414
|
+
milestone: args.milestone,
|
|
415
|
+
tag: args.tag,
|
|
416
|
+
status: args.status,
|
|
417
|
+
includeBlocked: args.includeBlocked,
|
|
418
|
+
explain: args.explain,
|
|
419
|
+
limit: args.limit,
|
|
420
|
+
format: args.format
|
|
421
|
+
});
|
|
422
|
+
process.exit(exitCode);
|
|
423
|
+
})
|
|
424
|
+
.command('list [type]', 'List entities', (y) => y
|
|
425
|
+
.positional('type', {
|
|
426
|
+
describe: 'Entity type to list',
|
|
427
|
+
choices: ['tasks', 'epics', 'milestones', 'decisions'],
|
|
428
|
+
default: 'tasks'
|
|
429
|
+
})
|
|
430
|
+
.option('status', {
|
|
431
|
+
type: 'string',
|
|
432
|
+
description: 'Filter by status'
|
|
433
|
+
})
|
|
434
|
+
.option('assignee', {
|
|
435
|
+
type: 'string',
|
|
436
|
+
description: 'Filter by assignee'
|
|
437
|
+
})
|
|
438
|
+
.option('epic', {
|
|
439
|
+
type: 'string',
|
|
440
|
+
description: 'Filter by epic'
|
|
441
|
+
})
|
|
442
|
+
.option('format', {
|
|
443
|
+
type: 'string',
|
|
444
|
+
choices: ['table', 'json'],
|
|
445
|
+
default: 'table',
|
|
446
|
+
description: 'Output format'
|
|
447
|
+
}), async (args) => {
|
|
448
|
+
const exitCode = await (0, list_1.listCommand)(process.cwd(), {
|
|
449
|
+
type: args.type,
|
|
450
|
+
status: args.status,
|
|
451
|
+
assignee: args.assignee,
|
|
452
|
+
epic: args.epic,
|
|
453
|
+
format: args.format
|
|
454
|
+
});
|
|
455
|
+
process.exit(exitCode);
|
|
456
|
+
})
|
|
457
|
+
.command('show <id>', 'Show entity details', (y) => y
|
|
458
|
+
.positional('id', {
|
|
459
|
+
describe: 'Entity ID to show'
|
|
460
|
+
})
|
|
461
|
+
.option('format', {
|
|
462
|
+
type: 'string',
|
|
463
|
+
choices: ['pretty', 'json'],
|
|
464
|
+
default: 'pretty'
|
|
465
|
+
}), async (args) => {
|
|
466
|
+
const exitCode = await (0, show_1.showCommand)(process.cwd(), args.id, {
|
|
467
|
+
format: args.format
|
|
468
|
+
});
|
|
469
|
+
process.exit(exitCode);
|
|
470
|
+
})
|
|
471
|
+
.command('create <type>', 'Create new entity', (y) => y
|
|
472
|
+
.positional('type', {
|
|
473
|
+
describe: 'Entity type to create',
|
|
474
|
+
choices: ['task', 'epic', 'milestone']
|
|
475
|
+
})
|
|
476
|
+
.option('title', {
|
|
477
|
+
alias: 't',
|
|
478
|
+
type: 'string',
|
|
479
|
+
description: 'Entity title'
|
|
480
|
+
})
|
|
481
|
+
.option('status', {
|
|
482
|
+
type: 'string',
|
|
483
|
+
description: 'Initial status'
|
|
484
|
+
})
|
|
485
|
+
.option('priority', {
|
|
486
|
+
type: 'string',
|
|
487
|
+
description: 'Priority (for tasks)'
|
|
488
|
+
})
|
|
489
|
+
.option('assignee', {
|
|
490
|
+
type: 'string',
|
|
491
|
+
description: 'Assignee'
|
|
492
|
+
})
|
|
493
|
+
.option('owner', {
|
|
494
|
+
type: 'string',
|
|
495
|
+
description: 'Owner for epics and milestones'
|
|
496
|
+
})
|
|
497
|
+
.option('description', {
|
|
498
|
+
type: 'string',
|
|
499
|
+
description: 'Description/body for epics and milestones'
|
|
500
|
+
})
|
|
501
|
+
.option('target-date', {
|
|
502
|
+
type: 'string',
|
|
503
|
+
description: 'Target date for milestones'
|
|
504
|
+
})
|
|
505
|
+
.option('dry-run', {
|
|
506
|
+
type: 'boolean',
|
|
507
|
+
default: false,
|
|
508
|
+
description: 'Preview created Markdown without writing files'
|
|
509
|
+
})
|
|
510
|
+
.option('format', {
|
|
511
|
+
type: 'string',
|
|
512
|
+
choices: ['text', 'json'],
|
|
513
|
+
default: 'text',
|
|
514
|
+
description: 'Output format'
|
|
515
|
+
}), async (args) => {
|
|
516
|
+
const exitCode = await (0, create_1.createCommand)(process.cwd(), args.type, {
|
|
517
|
+
title: args.title,
|
|
518
|
+
status: args.status,
|
|
519
|
+
priority: args.priority,
|
|
520
|
+
assignee: args.assignee,
|
|
521
|
+
owner: args.owner,
|
|
522
|
+
description: args.description,
|
|
523
|
+
targetDate: args.targetDate,
|
|
524
|
+
dryRun: args.dryRun,
|
|
525
|
+
format: args.format
|
|
526
|
+
});
|
|
527
|
+
process.exit(exitCode);
|
|
528
|
+
})
|
|
529
|
+
.demandCommand(1, 'You must provide a command')
|
|
530
|
+
.help()
|
|
531
|
+
.strict()
|
|
532
|
+
.parseAsync();
|
|
533
|
+
}
|
|
534
|
+
if (require.main === module) {
|
|
535
|
+
main().catch((error) => {
|
|
536
|
+
console.error('Fatal error:', error);
|
|
537
|
+
process.exit(1);
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
//# sourceMappingURL=cli.js.map
|