openplanr 1.2.7 → 1.3.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 +41 -4
- package/dist/agents/task-parser.d.ts.map +1 -1
- package/dist/agents/task-parser.js +8 -34
- package/dist/agents/task-parser.js.map +1 -1
- package/dist/ai/prompts/prompt-builder.d.ts +48 -0
- package/dist/ai/prompts/prompt-builder.d.ts.map +1 -1
- package/dist/ai/prompts/prompt-builder.js +57 -1
- package/dist/ai/prompts/prompt-builder.js.map +1 -1
- package/dist/ai/prompts/system-prompts.d.ts +24 -1
- package/dist/ai/prompts/system-prompts.d.ts.map +1 -1
- package/dist/ai/prompts/system-prompts.js +104 -6
- package/dist/ai/prompts/system-prompts.js.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.d.ts +68 -0
- package/dist/ai/schemas/ai-response-schemas.d.ts.map +1 -1
- package/dist/ai/schemas/ai-response-schemas.js +81 -0
- package/dist/ai/schemas/ai-response-schemas.js.map +1 -1
- package/dist/ai/types.d.ts +2 -0
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/ai/types.js +4 -0
- package/dist/ai/types.js.map +1 -1
- package/dist/cli/commands/backlog.d.ts +12 -0
- package/dist/cli/commands/backlog.d.ts.map +1 -1
- package/dist/cli/commands/backlog.js +88 -2
- package/dist/cli/commands/backlog.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +8 -2
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/linear.d.ts +8 -0
- package/dist/cli/commands/linear.d.ts.map +1 -0
- package/dist/cli/commands/linear.js +550 -0
- package/dist/cli/commands/linear.js.map +1 -0
- package/dist/cli/commands/quick.d.ts +17 -0
- package/dist/cli/commands/quick.d.ts.map +1 -1
- package/dist/cli/commands/quick.js +31 -15
- package/dist/cli/commands/quick.js.map +1 -1
- package/dist/cli/commands/revise.d.ts +24 -0
- package/dist/cli/commands/revise.d.ts.map +1 -0
- package/dist/cli/commands/revise.js +570 -0
- package/dist/cli/commands/revise.js.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/models/schema.d.ts +43 -0
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +49 -0
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +296 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/artifact-gathering.d.ts +4 -0
- package/dist/services/artifact-gathering.d.ts.map +1 -1
- package/dist/services/artifact-gathering.js +1 -1
- package/dist/services/artifact-gathering.js.map +1 -1
- package/dist/services/artifact-service.d.ts +12 -1
- package/dist/services/artifact-service.d.ts.map +1 -1
- package/dist/services/artifact-service.js +49 -6
- package/dist/services/artifact-service.js.map +1 -1
- package/dist/services/atomic-write-service.d.ts +41 -0
- package/dist/services/atomic-write-service.d.ts.map +1 -0
- package/dist/services/atomic-write-service.js +87 -0
- package/dist/services/atomic-write-service.js.map +1 -0
- package/dist/services/audit-log-service.d.ts +47 -0
- package/dist/services/audit-log-service.d.ts.map +1 -0
- package/dist/services/audit-log-service.js +210 -0
- package/dist/services/audit-log-service.js.map +1 -0
- package/dist/services/cascade-service.d.ts +62 -0
- package/dist/services/cascade-service.d.ts.map +1 -0
- package/dist/services/cascade-service.js +189 -0
- package/dist/services/cascade-service.js.map +1 -0
- package/dist/services/credentials-service.js +2 -2
- package/dist/services/credentials-service.js.map +1 -1
- package/dist/services/diff-service.d.ts +18 -0
- package/dist/services/diff-service.d.ts.map +1 -0
- package/dist/services/diff-service.js +35 -0
- package/dist/services/diff-service.js.map +1 -0
- package/dist/services/evidence-verifier.d.ts +71 -0
- package/dist/services/evidence-verifier.d.ts.map +1 -0
- package/dist/services/evidence-verifier.js +174 -0
- package/dist/services/evidence-verifier.js.map +1 -0
- package/dist/services/git-service.d.ts +60 -0
- package/dist/services/git-service.d.ts.map +1 -0
- package/dist/services/git-service.js +137 -0
- package/dist/services/git-service.js.map +1 -0
- package/dist/services/graph-integrity.d.ts +35 -0
- package/dist/services/graph-integrity.d.ts.map +1 -0
- package/dist/services/graph-integrity.js +53 -0
- package/dist/services/graph-integrity.js.map +1 -0
- package/dist/services/linear/body-formatters.d.ts +69 -0
- package/dist/services/linear/body-formatters.d.ts.map +1 -0
- package/dist/services/linear/body-formatters.js +183 -0
- package/dist/services/linear/body-formatters.js.map +1 -0
- package/dist/services/linear/constants.d.ts +61 -0
- package/dist/services/linear/constants.d.ts.map +1 -0
- package/dist/services/linear/constants.js +84 -0
- package/dist/services/linear/constants.js.map +1 -0
- package/dist/services/linear/errors.d.ts +14 -0
- package/dist/services/linear/errors.d.ts.map +1 -0
- package/dist/services/linear/errors.js +106 -0
- package/dist/services/linear/errors.js.map +1 -0
- package/dist/services/linear/estimate-resolver.d.ts +50 -0
- package/dist/services/linear/estimate-resolver.d.ts.map +1 -0
- package/dist/services/linear/estimate-resolver.js +82 -0
- package/dist/services/linear/estimate-resolver.js.map +1 -0
- package/dist/services/linear/plan-builders.d.ts +64 -0
- package/dist/services/linear/plan-builders.d.ts.map +1 -0
- package/dist/services/linear/plan-builders.js +237 -0
- package/dist/services/linear/plan-builders.js.map +1 -0
- package/dist/services/linear/scope-loaders.d.ts +79 -0
- package/dist/services/linear/scope-loaders.d.ts.map +1 -0
- package/dist/services/linear/scope-loaders.js +227 -0
- package/dist/services/linear/scope-loaders.js.map +1 -0
- package/dist/services/linear/strategy-context.d.ts +66 -0
- package/dist/services/linear/strategy-context.d.ts.map +1 -0
- package/dist/services/linear/strategy-context.js +121 -0
- package/dist/services/linear/strategy-context.js.map +1 -0
- package/dist/services/linear-mapping-service.d.ts +11 -0
- package/dist/services/linear-mapping-service.d.ts.map +1 -0
- package/dist/services/linear-mapping-service.js +220 -0
- package/dist/services/linear-mapping-service.js.map +1 -0
- package/dist/services/linear-pull-service.d.ts +137 -0
- package/dist/services/linear-pull-service.d.ts.map +1 -0
- package/dist/services/linear-pull-service.js +720 -0
- package/dist/services/linear-pull-service.js.map +1 -0
- package/dist/services/linear-push-service.d.ts +86 -0
- package/dist/services/linear-push-service.d.ts.map +1 -0
- package/dist/services/linear-push-service.js +956 -0
- package/dist/services/linear-push-service.js.map +1 -0
- package/dist/services/linear-service.d.ts +122 -0
- package/dist/services/linear-service.d.ts.map +1 -0
- package/dist/services/linear-service.js +361 -0
- package/dist/services/linear-service.js.map +1 -0
- package/dist/services/prompt-service.d.ts +37 -0
- package/dist/services/prompt-service.d.ts.map +1 -1
- package/dist/services/prompt-service.js +111 -0
- package/dist/services/prompt-service.js.map +1 -1
- package/dist/services/revise-apply-service.d.ts +55 -0
- package/dist/services/revise-apply-service.d.ts.map +1 -0
- package/dist/services/revise-apply-service.js +255 -0
- package/dist/services/revise-apply-service.js.map +1 -0
- package/dist/services/revise-cache-service.d.ts +46 -0
- package/dist/services/revise-cache-service.d.ts.map +1 -0
- package/dist/services/revise-cache-service.js +88 -0
- package/dist/services/revise-cache-service.js.map +1 -0
- package/dist/services/revise-plan-service.d.ts +38 -0
- package/dist/services/revise-plan-service.d.ts.map +1 -0
- package/dist/services/revise-plan-service.js +151 -0
- package/dist/services/revise-plan-service.js.map +1 -0
- package/dist/services/revise-service.d.ts +115 -0
- package/dist/services/revise-service.d.ts.map +1 -0
- package/dist/services/revise-service.js +294 -0
- package/dist/services/revise-service.js.map +1 -0
- package/dist/services/template-sections.d.ts +28 -0
- package/dist/services/template-sections.d.ts.map +1 -0
- package/dist/services/template-sections.js +55 -0
- package/dist/services/template-sections.js.map +1 -0
- package/dist/templates/backlog/backlog-item.md.hbs +3 -0
- package/dist/templates/quick/quick-task.md.hbs +6 -0
- package/dist/utils/diff.d.ts +47 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +278 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/markdown.d.ts +23 -0
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js +79 -0
- package/dist/utils/markdown.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `planr linear` — Linear.app integration command tree.
|
|
3
|
+
* `init` stores a PAT, validates it, and saves the default team in
|
|
4
|
+
* `.planr/config.json`. See `planr linear --help` for the full subcommand list.
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { findArtifactTypeById, readArtifact } from '../../services/artifact-service.js';
|
|
8
|
+
import { loadConfig, saveConfig } from '../../services/config-service.js';
|
|
9
|
+
import { resolveApiKey, saveCredential } from '../../services/credentials-service.js';
|
|
10
|
+
import { isNonInteractive } from '../../services/interactive-state.js';
|
|
11
|
+
import { collectLinearMappingTable, formatLinearMappingTable, } from '../../services/linear-mapping-service.js';
|
|
12
|
+
import { formatLinearStatusSyncLine, runLinearTaskCheckboxSync, syncLinearStatusIntoArtifacts, } from '../../services/linear-pull-service.js';
|
|
13
|
+
import { buildLinearPushPlan, runLinearPush } from '../../services/linear-push-service.js';
|
|
14
|
+
import { createLinearClient, getAvailableTeams, LINEAR_CREDENTIAL_KEY, validateTeamAccess, validateToken, } from '../../services/linear-service.js';
|
|
15
|
+
import { promptMappingStrategy, promptSecret, promptSelect, promptStandaloneProject, } from '../../services/prompt-service.js';
|
|
16
|
+
import { display, logger } from '../../utils/logger.js';
|
|
17
|
+
/**
|
|
18
|
+
* Parse the `--as <strategy>` CLI flag value. Accepted forms:
|
|
19
|
+
* - `project`
|
|
20
|
+
* - `milestone-of:<projectId>`
|
|
21
|
+
* - `label-on:<projectId>`
|
|
22
|
+
* Returns `null` if the raw value doesn't match one of these shapes.
|
|
23
|
+
*/
|
|
24
|
+
function parseStrategyFlag(raw) {
|
|
25
|
+
if (!raw)
|
|
26
|
+
return null;
|
|
27
|
+
const trimmed = raw.trim();
|
|
28
|
+
if (trimmed === 'project')
|
|
29
|
+
return { strategy: 'project' };
|
|
30
|
+
const milestoneMatch = trimmed.match(/^milestone-of:([0-9a-f-]{36}|\S+)$/i);
|
|
31
|
+
if (milestoneMatch) {
|
|
32
|
+
return { strategy: 'milestone-of', targetProjectId: milestoneMatch[1] };
|
|
33
|
+
}
|
|
34
|
+
const labelMatch = trimmed.match(/^label-on:([0-9a-f-]{36}|\S+)$/i);
|
|
35
|
+
if (labelMatch) {
|
|
36
|
+
return { strategy: 'label-on', targetProjectId: labelMatch[1] };
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const PAT_HINT = 'Create one at https://linear.app/settings/account/security (read access to teams; write when pushing issues).';
|
|
41
|
+
const LINEAR_HELP = `
|
|
42
|
+
${chalk.bold('Subcommands:')}
|
|
43
|
+
init Store PAT, pick team, save linear.teamId
|
|
44
|
+
sync Pull workflow status (features/stories) + bidirectional task checkboxes
|
|
45
|
+
push <artifact> Create/update Linear entities at any granularity:
|
|
46
|
+
EPIC-XXX → project + features + stories + tasklists
|
|
47
|
+
FEAT-XXX → feature + its stories + its tasklist
|
|
48
|
+
US-XXX → one story sub-issue
|
|
49
|
+
TASK-XXX → one tasklist sub-issue
|
|
50
|
+
status Show local OpenPlanr ↔ Linear mapping (no API calls)
|
|
51
|
+
tasklist-sync Sync TASK checkbox lines with Linear task-list issues
|
|
52
|
+
|
|
53
|
+
${chalk.bold('Common flags:')}
|
|
54
|
+
--dry-run Show planned work without writes (push: no API; sync: read-only to Linear, no local writes)
|
|
55
|
+
--update-only push: only update existing linked entities, never create
|
|
56
|
+
--push-parents push: if a parent is not yet in Linear, push it first without prompting
|
|
57
|
+
|
|
58
|
+
${chalk.dim('Examples:')}
|
|
59
|
+
planr linear sync
|
|
60
|
+
planr linear sync --dry-run
|
|
61
|
+
planr linear push EPIC-001 --dry-run
|
|
62
|
+
planr linear push FEAT-XXX --dry-run
|
|
63
|
+
planr linear push US-054
|
|
64
|
+
planr linear push TASK-015 --push-parents
|
|
65
|
+
planr linear status --scope EPIC-001
|
|
66
|
+
`;
|
|
67
|
+
export function registerLinearCommand(program) {
|
|
68
|
+
const linear = program
|
|
69
|
+
.command('linear')
|
|
70
|
+
.description('Linear.app integration — init, push, sync, status mapping, task checklists')
|
|
71
|
+
.addHelpText('after', LINEAR_HELP);
|
|
72
|
+
linear
|
|
73
|
+
.command('init')
|
|
74
|
+
.description('Validate a Linear PAT, pick a team, and save settings to the project config')
|
|
75
|
+
.action(async () => {
|
|
76
|
+
const projectDir = program.opts().projectDir;
|
|
77
|
+
let config;
|
|
78
|
+
try {
|
|
79
|
+
config = await loadConfig(projectDir);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
logger.error('No OpenPlanr project in this directory. Run `planr init` first.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let token = (await resolveApiKey(LINEAR_CREDENTIAL_KEY))?.trim() ?? '';
|
|
87
|
+
if (!token) {
|
|
88
|
+
if (isNonInteractive()) {
|
|
89
|
+
logger.error(`Set PLANR_LINEAR_TOKEN or store a key with the credentials service after a successful interactive \`planr linear init\`. ${PAT_HINT}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
logger.dim(PAT_HINT);
|
|
94
|
+
token = (await promptSecret('Linear personal access token:')).trim();
|
|
95
|
+
}
|
|
96
|
+
if (!token) {
|
|
97
|
+
logger.error('A Linear personal access token is required.');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const client = createLinearClient(token);
|
|
102
|
+
let viewer;
|
|
103
|
+
try {
|
|
104
|
+
viewer = await validateToken(client);
|
|
105
|
+
logger.success(`Signed in to Linear as ${viewer.name}.`);
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
109
|
+
logger.error(msg);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
let teams;
|
|
114
|
+
try {
|
|
115
|
+
teams = await getAvailableTeams(client);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
119
|
+
logger.error(msg);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (teams.length === 0) {
|
|
124
|
+
logger.error('No teams found for this account. Create or join a team in Linear, then run `planr linear init` again.');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
let teamId;
|
|
129
|
+
if (teams.length === 1) {
|
|
130
|
+
teamId = teams[0].id;
|
|
131
|
+
display.line(`Using team ${teams[0].name} (${teams[0].key}) — the only team available to this user.`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
if (isNonInteractive()) {
|
|
135
|
+
logger.error('Multiple teams are available. Run `planr linear init` in an interactive terminal to choose a team, or set `linear.teamId` in `.planr/config.json` after selecting an id from the Linear UI.');
|
|
136
|
+
process.exit(1);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const choice = await promptSelect('Which Linear team should OpenPlanr use for pushes?', teams.map((t) => ({ name: `${t.name} (${t.key})`, value: t.id })));
|
|
140
|
+
teamId = choice;
|
|
141
|
+
}
|
|
142
|
+
let teamInfo;
|
|
143
|
+
try {
|
|
144
|
+
teamInfo = await validateTeamAccess(client, teamId);
|
|
145
|
+
logger.success(`Team access ok: ${teamInfo.name} (${teamInfo.key}).`);
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
149
|
+
logger.error(msg);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
await saveCredential(LINEAR_CREDENTIAL_KEY, token);
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
logger.error(`Failed to store credentials: ${e instanceof Error ? e.message : String(e)}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const next = {
|
|
162
|
+
...config,
|
|
163
|
+
linear: { teamId, teamKey: teamInfo.key },
|
|
164
|
+
};
|
|
165
|
+
try {
|
|
166
|
+
await saveConfig(projectDir, next);
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
logger.error(`Failed to save config: ${e instanceof Error ? e.message : String(e)}`);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
logger.success('Linear integration is ready.');
|
|
174
|
+
display.line('');
|
|
175
|
+
display.line(` teamId: ${teamId}`);
|
|
176
|
+
display.line(' config: .planr/config.json (linear.teamId, linear.teamKey)');
|
|
177
|
+
display.line(' token: credentials service (key: linear) or PLANR_LINEAR_TOKEN');
|
|
178
|
+
display.line('');
|
|
179
|
+
logger.dim('Next: `planr linear sync`, `planr linear push <epic>`, or `planr linear status`');
|
|
180
|
+
});
|
|
181
|
+
linear
|
|
182
|
+
.command('sync')
|
|
183
|
+
.description('Pull workflow status (features & stories) from Linear, then sync task checklists bidirectionally')
|
|
184
|
+
.option('--dry-run', 'Read from Linear to compare, but do not write local files or update Linear issue bodies', false)
|
|
185
|
+
.option('--update-only', 'Same as default for this command (only artifacts with Linear links are considered); reserved for future use', false)
|
|
186
|
+
.option('--on-conflict <mode>', 'Status + task-checkbox conflicts: prompt | local | linear (default: prompt; non-interactive runs default to linear)', 'prompt')
|
|
187
|
+
.action(async (o) => {
|
|
188
|
+
const projectDir = program.opts().projectDir;
|
|
189
|
+
let config;
|
|
190
|
+
try {
|
|
191
|
+
config = await loadConfig(projectDir);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
logger.error('No OpenPlanr project in this directory. Run `planr init` first.');
|
|
195
|
+
process.exit(1);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (!config.linear?.teamId) {
|
|
199
|
+
logger.error('Linear is not configured. Run `planr linear init` first.');
|
|
200
|
+
process.exit(1);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const dryRun = o.dryRun === true;
|
|
204
|
+
const rawC = o.onConflict;
|
|
205
|
+
const onConflict = rawC === 'local' || rawC === 'linear' ? rawC : 'prompt';
|
|
206
|
+
let token = (await resolveApiKey(LINEAR_CREDENTIAL_KEY))?.trim() ?? '';
|
|
207
|
+
if (!token) {
|
|
208
|
+
if (isNonInteractive()) {
|
|
209
|
+
logger.error(`Set PLANR_LINEAR_TOKEN or run \`planr linear init\` to store a token. ${PAT_HINT}`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
logger.dim(PAT_HINT);
|
|
214
|
+
token = (await promptSecret('Linear personal access token:')).trim();
|
|
215
|
+
}
|
|
216
|
+
if (!token) {
|
|
217
|
+
logger.error('A Linear personal access token is required.');
|
|
218
|
+
process.exit(1);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const client = createLinearClient(token);
|
|
222
|
+
try {
|
|
223
|
+
await validateToken(client);
|
|
224
|
+
await validateTeamAccess(client, config.linear.teamId);
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
228
|
+
process.exit(1);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const dryLabel = dryRun ? ' (dry run — no file or remote body writes)' : '';
|
|
232
|
+
logger.heading(`Linear sync — status + task checklists${dryLabel}`);
|
|
233
|
+
display.blank();
|
|
234
|
+
try {
|
|
235
|
+
display.line(`${chalk.cyan('[1/2]')} Workflow status: Linear ↔ OpenPlanr (features, stories, quick tasks, backlog)`);
|
|
236
|
+
const statusSummary = await syncLinearStatusIntoArtifacts(projectDir, config, client, {
|
|
237
|
+
dryRun,
|
|
238
|
+
onConflict,
|
|
239
|
+
});
|
|
240
|
+
display.line(formatLinearStatusSyncLine(statusSummary));
|
|
241
|
+
if (dryRun) {
|
|
242
|
+
logger.dim(' (dry run: no frontmatter `status` writes were applied)');
|
|
243
|
+
}
|
|
244
|
+
display.blank();
|
|
245
|
+
display.line(`${chalk.cyan('[2/2]')} Task checklists: local TASK files ↔ Linear`);
|
|
246
|
+
const t = await runLinearTaskCheckboxSync(projectDir, config, client, {
|
|
247
|
+
dryRun,
|
|
248
|
+
onConflict,
|
|
249
|
+
});
|
|
250
|
+
const taskLine = `Files processed: ${t.filesProcessed} | local ${dryRun ? 'would update' : 'updates'}: ${t.filesUpdatedLocal} | Linear ${dryRun ? 'would update' : 'updates'}: ${t.linearIssuesUpdated} | conflict decisions: ${t.conflictDecisions} | skipped (no issue id): ${t.skippedNoIssue} | skipped (stale id): ${t.skippedStaleId}`;
|
|
251
|
+
display.line(taskLine);
|
|
252
|
+
if (dryRun) {
|
|
253
|
+
logger.dim(' (dry run: no TASK file or Linear description writes were applied)');
|
|
254
|
+
}
|
|
255
|
+
display.blank();
|
|
256
|
+
if (statusSummary.updated === 0 &&
|
|
257
|
+
t.filesUpdatedLocal === 0 &&
|
|
258
|
+
t.linearIssuesUpdated === 0) {
|
|
259
|
+
logger.success(`Nothing to change${dryLabel || '.'}`);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
logger.success('Linear sync complete.');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (e) {
|
|
266
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
linear
|
|
271
|
+
.command('status')
|
|
272
|
+
.description('Show local OpenPlanr id ↔ Linear id/url mapping from frontmatter (no Linear API calls)')
|
|
273
|
+
.option('--scope <epicId>', 'Limit rows to an epic and its features, stories, and tasks in that scope')
|
|
274
|
+
.action(async (o) => {
|
|
275
|
+
const projectDir = program.opts().projectDir;
|
|
276
|
+
let config;
|
|
277
|
+
try {
|
|
278
|
+
config = await loadConfig(projectDir);
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
logger.error('No OpenPlanr project in this directory. Run `planr init` first.');
|
|
282
|
+
process.exit(1);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const scope = typeof o.scope === 'string' && o.scope.trim() ? o.scope.trim() : undefined;
|
|
286
|
+
try {
|
|
287
|
+
const rows = await collectLinearMappingTable(projectDir, config, scope);
|
|
288
|
+
if (rows.length === 0) {
|
|
289
|
+
display.line(scope
|
|
290
|
+
? 'No artifacts in this scope.'
|
|
291
|
+
: 'No epics, features, stories, or task files found.');
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
display.line(formatLinearMappingTable(rows));
|
|
295
|
+
}
|
|
296
|
+
display.blank();
|
|
297
|
+
logger.dim('Local frontmatter only — no network calls to Linear.');
|
|
298
|
+
}
|
|
299
|
+
catch (e) {
|
|
300
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
linear
|
|
305
|
+
.command('push')
|
|
306
|
+
.description('Create or update Linear project/issues for any planning artifact (EPIC/FEAT/US/TASK)')
|
|
307
|
+
.argument('<artifactId>', 'Artifact id — accepts EPIC-XXX (epic + subtree), FEAT-XXX (feature + stories + tasklist), US-XXX (one story), or TASK-XXX (one tasklist)')
|
|
308
|
+
.option('--dry-run', 'Show what would be created/updated without calling the Linear API', false)
|
|
309
|
+
.option('--update-only', 'Only update entities that already have Linear ids in frontmatter; never create new project/issues', false)
|
|
310
|
+
.option('--push-parents', 'If a parent in the chain is not yet pushed to Linear, push it first without prompting', false)
|
|
311
|
+
.option('--as <strategy>', 'Epic-only: mapping strategy. One of: project | milestone-of:<projectId> | label-on:<projectId>')
|
|
312
|
+
.action(async (artifactId, o) => {
|
|
313
|
+
const projectDir = program.opts().projectDir;
|
|
314
|
+
let config;
|
|
315
|
+
try {
|
|
316
|
+
config = await loadConfig(projectDir);
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
logger.error('No OpenPlanr project in this directory. Run `planr init` first.');
|
|
320
|
+
process.exit(1);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if (!config.linear?.teamId) {
|
|
324
|
+
logger.error('Linear is not configured. Run `planr linear init` first.');
|
|
325
|
+
process.exit(1);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const header = o.dryRun ? 'Linear push (dry run)' : 'Linear push';
|
|
329
|
+
logger.heading(`${header} — ${artifactId}`);
|
|
330
|
+
display.blank();
|
|
331
|
+
if (o.dryRun) {
|
|
332
|
+
try {
|
|
333
|
+
const plan = await buildLinearPushPlan(projectDir, config, artifactId, {
|
|
334
|
+
updateOnly: o.updateOnly,
|
|
335
|
+
});
|
|
336
|
+
if (!plan) {
|
|
337
|
+
logger.error(`Artifact not found or not supported for push: ${artifactId}. Supported prefixes: EPIC-/FEAT-/US-/TASK-.`);
|
|
338
|
+
process.exit(1);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const { counts, rows, scope } = plan;
|
|
342
|
+
display.line(`Scope: ${scope} — ${counts.total} item(s) (${counts.project} project + ${counts.features} feature(s) + ${counts.stories} stor(ies) + ${counts.taskLists} task list(s), excluding skips).`);
|
|
343
|
+
display.blank();
|
|
344
|
+
for (const r of rows) {
|
|
345
|
+
const act = r.action === 'create'
|
|
346
|
+
? chalk.green('create')
|
|
347
|
+
: r.action === 'update'
|
|
348
|
+
? chalk.yellow('update')
|
|
349
|
+
: chalk.dim('skip');
|
|
350
|
+
const extra = r.detail ? chalk.dim(` — ${r.detail}`) : '';
|
|
351
|
+
display.line(` [${r.kind}] ${act} ${r.title} (${r.artifactId})${extra}`);
|
|
352
|
+
}
|
|
353
|
+
display.blank();
|
|
354
|
+
logger.dim('No Linear API calls were made. Run without --dry-run to apply.');
|
|
355
|
+
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
let token = (await resolveApiKey(LINEAR_CREDENTIAL_KEY))?.trim() ?? '';
|
|
363
|
+
if (!token) {
|
|
364
|
+
if (isNonInteractive()) {
|
|
365
|
+
logger.error(`Set PLANR_LINEAR_TOKEN or run \`planr linear init\` to store a token. ${PAT_HINT}`);
|
|
366
|
+
process.exit(1);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
logger.dim(PAT_HINT);
|
|
370
|
+
token = (await promptSecret('Linear personal access token:')).trim();
|
|
371
|
+
}
|
|
372
|
+
if (!token) {
|
|
373
|
+
logger.error('A Linear personal access token is required.');
|
|
374
|
+
process.exit(1);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
const client = createLinearClient(token);
|
|
378
|
+
try {
|
|
379
|
+
await validateToken(client);
|
|
380
|
+
await validateTeamAccess(client, config.linear.teamId);
|
|
381
|
+
}
|
|
382
|
+
catch (e) {
|
|
383
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
384
|
+
process.exit(1);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
// --as flag parsing (epic-only; ignored with a warning on other types).
|
|
388
|
+
let strategyOverride = parseStrategyFlag(o.as);
|
|
389
|
+
if (o.as && !strategyOverride) {
|
|
390
|
+
logger.error(`Invalid --as value: "${o.as}". Expected "project", "milestone-of:<projectId>", or "label-on:<projectId>".`);
|
|
391
|
+
process.exit(1);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (strategyOverride && findArtifactTypeById(artifactId) !== 'epic') {
|
|
395
|
+
logger.warn('--as is epic-only; ignoring for this artifact.');
|
|
396
|
+
strategyOverride = null;
|
|
397
|
+
}
|
|
398
|
+
// First-time interactive mapping-strategy prompt (epic only; skipped
|
|
399
|
+
// when the epic already has a stored strategy, when --as is set, or in
|
|
400
|
+
// non-interactive mode where the fallback chain in the service
|
|
401
|
+
// handles it — config.defaultEpicStrategy, then 'project').
|
|
402
|
+
if (findArtifactTypeById(artifactId) === 'epic' &&
|
|
403
|
+
!strategyOverride &&
|
|
404
|
+
!isNonInteractive() &&
|
|
405
|
+
!config.linear.defaultEpicStrategy) {
|
|
406
|
+
try {
|
|
407
|
+
const existing = await readArtifact(projectDir, config, 'epic', artifactId);
|
|
408
|
+
const alreadyMapped = Boolean(existing?.data.linearMappingStrategy);
|
|
409
|
+
if (!alreadyMapped) {
|
|
410
|
+
const picked = await promptMappingStrategy(client, config.linear.teamId, artifactId);
|
|
411
|
+
if (picked)
|
|
412
|
+
strategyOverride = picked;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// Non-fatal: if the epic file can't be read, let the service surface the error.
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// First-time standalone-project prompt for QT / BL pushes.
|
|
420
|
+
// Runs only when no standalone project is configured yet and the user
|
|
421
|
+
// is on an interactive TTY. Non-interactive runs fall through to the
|
|
422
|
+
// service's actionable "set linear.standaloneProjectId" error.
|
|
423
|
+
const pushType = findArtifactTypeById(artifactId);
|
|
424
|
+
if ((pushType === 'quick' || pushType === 'backlog') &&
|
|
425
|
+
!config.linear.standaloneProjectId &&
|
|
426
|
+
!isNonInteractive()) {
|
|
427
|
+
try {
|
|
428
|
+
const picked = await promptStandaloneProject(client, config.linear.teamId);
|
|
429
|
+
if (picked) {
|
|
430
|
+
const next = {
|
|
431
|
+
...config,
|
|
432
|
+
linear: {
|
|
433
|
+
...config.linear,
|
|
434
|
+
standaloneProjectId: picked.projectId,
|
|
435
|
+
standaloneProjectName: picked.projectName,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
await saveConfig(projectDir, next);
|
|
439
|
+
config = next;
|
|
440
|
+
logger.success(`Saved to .planr/config.json → linear.standaloneProjectId = ${picked.projectName}.`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch (e) {
|
|
444
|
+
logger.warn(`Could not prompt for a standalone project: ${e instanceof Error ? e.message : String(e)}`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
const plan = await runLinearPush(projectDir, config, client, artifactId, {
|
|
449
|
+
updateOnly: o.updateOnly,
|
|
450
|
+
pushParents: o.pushParents,
|
|
451
|
+
strategyOverride: strategyOverride ?? undefined,
|
|
452
|
+
});
|
|
453
|
+
if (!plan) {
|
|
454
|
+
logger.error(`Artifact not found or not supported for push: ${artifactId}.`);
|
|
455
|
+
process.exit(1);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const { counts, rows, scope } = plan;
|
|
459
|
+
display.line(`Done (${scope} scope): ${counts.total} item(s) — ${counts.project} project + ${counts.features} feature(s) + ${counts.stories} stor(ies) + ${counts.taskLists} task list(s) (excluding skips).`);
|
|
460
|
+
display.blank();
|
|
461
|
+
for (const r of rows) {
|
|
462
|
+
const act = r.action === 'create'
|
|
463
|
+
? chalk.green('create')
|
|
464
|
+
: r.action === 'update'
|
|
465
|
+
? chalk.yellow('update')
|
|
466
|
+
: chalk.dim('skip');
|
|
467
|
+
const extra = r.detail ? chalk.dim(` — ${r.detail}`) : '';
|
|
468
|
+
display.line(` [${r.kind}] ${act} ${r.title} (${r.artifactId})${extra}`);
|
|
469
|
+
}
|
|
470
|
+
logger.success('Linear is up to date.');
|
|
471
|
+
}
|
|
472
|
+
catch (e) {
|
|
473
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
474
|
+
process.exit(1);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
linear
|
|
478
|
+
.command('tasklist-sync')
|
|
479
|
+
.description('Bidirectionally sync task checkbox state between local TASK files and Linear TaskList issues')
|
|
480
|
+
.option('--on-conflict <mode>', 'When local and Linear differ: prompt, local, or linear (default: prompt; in CI, linear is used when not set)', 'prompt')
|
|
481
|
+
.option('--dry-run', 'Show what would change without writing local files or mutating Linear issue bodies', false)
|
|
482
|
+
.action(async (o) => {
|
|
483
|
+
const projectDir = program.opts().projectDir;
|
|
484
|
+
let config;
|
|
485
|
+
try {
|
|
486
|
+
config = await loadConfig(projectDir);
|
|
487
|
+
}
|
|
488
|
+
catch {
|
|
489
|
+
logger.error('No OpenPlanr project in this directory. Run `planr init` first.');
|
|
490
|
+
process.exit(1);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (!config.linear?.teamId) {
|
|
494
|
+
logger.error('Linear is not configured. Run `planr linear init` first.');
|
|
495
|
+
process.exit(1);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
const raw = o.onConflict;
|
|
499
|
+
const onConflict = raw === 'local' || raw === 'linear' ? raw : 'prompt';
|
|
500
|
+
let token = (await resolveApiKey(LINEAR_CREDENTIAL_KEY))?.trim() ?? '';
|
|
501
|
+
if (!token) {
|
|
502
|
+
if (isNonInteractive()) {
|
|
503
|
+
logger.error(`Set PLANR_LINEAR_TOKEN or run \`planr linear init\` to store a token. ${PAT_HINT}`);
|
|
504
|
+
process.exit(1);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
logger.dim(PAT_HINT);
|
|
508
|
+
token = (await promptSecret('Linear personal access token:')).trim();
|
|
509
|
+
}
|
|
510
|
+
if (!token) {
|
|
511
|
+
logger.error('A Linear personal access token is required.');
|
|
512
|
+
process.exit(1);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const client = createLinearClient(token);
|
|
516
|
+
try {
|
|
517
|
+
await validateToken(client);
|
|
518
|
+
await validateTeamAccess(client, config.linear.teamId);
|
|
519
|
+
}
|
|
520
|
+
catch (e) {
|
|
521
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
522
|
+
process.exit(1);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const dryRun = o.dryRun === true;
|
|
526
|
+
logger.heading(`Task checkbox sync (local TASK ↔ Linear)${dryRun ? ' (dry run — no file or remote body writes)' : ''}`);
|
|
527
|
+
display.blank();
|
|
528
|
+
try {
|
|
529
|
+
const s = await runLinearTaskCheckboxSync(projectDir, config, client, {
|
|
530
|
+
onConflict,
|
|
531
|
+
dryRun,
|
|
532
|
+
});
|
|
533
|
+
const localVerb = dryRun ? 'would update' : 'updates';
|
|
534
|
+
const remoteVerb = dryRun ? 'would update' : 'updates';
|
|
535
|
+
display.line(`Files processed: ${s.filesProcessed} | local ${localVerb}: ${s.filesUpdatedLocal} | Linear ${remoteVerb}: ${s.linearIssuesUpdated} | conflict decisions: ${s.conflictDecisions} | skipped (no issue id): ${s.skippedNoIssue} | skipped (stale id): ${s.skippedStaleId}`);
|
|
536
|
+
display.blank();
|
|
537
|
+
if (dryRun) {
|
|
538
|
+
logger.dim('Dry run — no local files or Linear issues were modified.');
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
logger.success('Task list checkbox sync complete.');
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
catch (e) {
|
|
545
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
546
|
+
process.exit(1);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
//# sourceMappingURL=linear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../src/cli/commands/linear.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,5 +9,22 @@
|
|
|
9
9
|
* via `planr quick promote`.
|
|
10
10
|
*/
|
|
11
11
|
import type { Command } from 'commander';
|
|
12
|
+
import type { OpenPlanrConfig } from '../../models/types.js';
|
|
12
13
|
export declare function registerQuickCommand(program: Command): void;
|
|
14
|
+
export interface CreateQuickWithAIOptions {
|
|
15
|
+
/** When true, use the larger token budget (for spec/PRD input). */
|
|
16
|
+
fromFile?: boolean;
|
|
17
|
+
/** Link the new QT to this epic (frontmatter `epicId`). */
|
|
18
|
+
epicId?: string;
|
|
19
|
+
/** Provenance: which BL-XXX this QT was promoted from (frontmatter `sourceBacklog`). */
|
|
20
|
+
sourceBacklog?: string;
|
|
21
|
+
/** Optional override of the heading shown in the CLI preview. */
|
|
22
|
+
headingLabel?: string;
|
|
23
|
+
/** Optional override for the confirm prompt text. */
|
|
24
|
+
confirmLabel?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function createQuickWithAI(projectDir: string, config: OpenPlanrConfig, description: string, options?: CreateQuickWithAIOptions): Promise<{
|
|
27
|
+
id: string;
|
|
28
|
+
filePath: string;
|
|
29
|
+
} | undefined>;
|
|
13
30
|
//# sourceMappingURL=quick.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quick.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/quick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"quick.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/quick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AA8B7D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAkJpD;AAMD,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CA+EvD"}
|