openplanr 1.9.0 → 1.10.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 +21 -3
- package/dist/cli/commands/artifact.d.ts +3 -0
- package/dist/cli/commands/artifact.d.ts.map +1 -0
- package/dist/cli/commands/artifact.js +249 -0
- package/dist/cli/commands/artifact.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +43 -13
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/pipeline.d.ts.map +1 -1
- package/dist/cli/commands/pipeline.js +14 -10
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +122 -19
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/spec.js +5 -5
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/cli/index.js +10 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/services/artifact-pipeline-service.d.ts +82 -0
- package/dist/services/artifact-pipeline-service.d.ts.map +1 -0
- package/dist/services/artifact-pipeline-service.js +116 -0
- package/dist/services/artifact-pipeline-service.js.map +1 -0
- package/dist/services/runtime-manager-service.d.ts +20 -0
- package/dist/services/runtime-manager-service.d.ts.map +1 -1
- package/dist/services/runtime-manager-service.js +178 -16
- package/dist/services/runtime-manager-service.js.map +1 -1
- package/dist/templates/rules/claude/planr-pipeline.md.hbs +14 -13
- package/install.ps1 +7 -14
- package/install.sh +13 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://github.com/openplanr/planr-pipeline/tree/main/docs/protocol)
|
|
13
13
|
[](https://github.com/openplanr/planr-pipeline/blob/main/docs/compatibility-matrix.md)
|
|
14
14
|
|
|
15
|
-
**[Website](https://openplanr.dev)** · **[Setup guide](docs/CROSS_RUNTIME_SETUP.md)** · **[Compatibility matrix](https://github.com/openplanr/planr-pipeline/blob/main/docs/compatibility-matrix.md)** · **[Protocol spec](https://github.com/openplanr/planr-pipeline/tree/main/docs/protocol)** · **[CLI reference](docs/CLI.md)**
|
|
15
|
+
**[Website](https://openplanr.dev)** · **[Setup guide](docs/CROSS_RUNTIME_SETUP.md)** · **[Artifact review](docs/ARTIFACT_REVIEW.md)** · **[Compatibility matrix](https://github.com/openplanr/planr-pipeline/blob/main/docs/compatibility-matrix.md)** · **[Protocol spec](https://github.com/openplanr/planr-pipeline/tree/main/docs/protocol)** · **[CLI reference](docs/CLI.md)**
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
@@ -84,10 +84,13 @@ Same artifacts (`.planr/specs/SPEC-NNN-{slug}/`). Same `.pipeline-shipped` proof
|
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
86
|
curl -fsSL https://openplanr.dev/install.sh | sh
|
|
87
|
-
|
|
87
|
+
cd my-project
|
|
88
|
+
planr setup
|
|
88
89
|
planr doctor
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
The installer installs the CLI only. Guided setup detects coding agents and
|
|
93
|
+
prompts for workflow mode, runtimes, and scope; user scope is the safe default.
|
|
91
94
|
Use `planr setup --dry-run` to preview, `planr setup --minimal` for planning
|
|
92
95
|
only, and `planr runtime rollback` to restore exact pre-migration bytes.
|
|
93
96
|
|
|
@@ -136,6 +139,21 @@ planr pipeline plan auth
|
|
|
136
139
|
planr pipeline ship auth
|
|
137
140
|
```
|
|
138
141
|
|
|
142
|
+
### Review and privately share any HTML artifact
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
planr artifact ./artifact.html
|
|
146
|
+
# Add pins, threads, and an Approve or Request changes decision.
|
|
147
|
+
|
|
148
|
+
planr artifact share ./artifact.html --no-open
|
|
149
|
+
planr artifact import "<returned-review-url>"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Small reviews remain in the URL fragment and are never sent to the share host.
|
|
153
|
+
Large reviews use an explicitly confirmed, encrypted, expiring short link; the
|
|
154
|
+
decryption key remains in the fragment and the service stores ciphertext only.
|
|
155
|
+
See the [artifact review and privacy guide](docs/ARTIFACT_REVIEW.md).
|
|
156
|
+
|
|
139
157
|
---
|
|
140
158
|
|
|
141
159
|
## Commands
|
|
@@ -336,7 +354,7 @@ OpenPlanr is one of four components:
|
|
|
336
354
|
| Component | Role | Repo |
|
|
337
355
|
|---|---|---|
|
|
338
356
|
| **`planr` CLI** | Authoring surface — generates `.planr/` artifacts and runtime rule files | this repo |
|
|
339
|
-
| **`planr-pipeline`** |
|
|
357
|
+
| **`planr-pipeline`** | Portable PO → Design → Review → DEV → QA engine with nine canonical roles and runtime adapters | [openplanr/planr-pipeline](https://github.com/openplanr/planr-pipeline) |
|
|
340
358
|
| **`openplanr` skill** | Routing playbook — teaches Claude when to use which surface | [openplanr/skills](https://github.com/openplanr/skills) |
|
|
341
359
|
| **`openplanr/marketplace`** | Distribution — Claude Code plugin registry | [openplanr/marketplace](https://github.com/openplanr/marketplace) |
|
|
342
360
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/artifact.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwSzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsD9D"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ArtifactCommandError, loadArtifactPipeline, openExternalUrl, prepareArtifactEnvelope, withoutArtifactReview, } from '../../services/artifact-pipeline-service.js';
|
|
4
|
+
import { isNonInteractive } from '../../services/interactive-state.js';
|
|
5
|
+
import { promptConfirm } from '../../services/prompt-service.js';
|
|
6
|
+
import { display, logger } from '../../utils/logger.js';
|
|
7
|
+
function projectDir(program) {
|
|
8
|
+
return path.resolve(program.opts().projectDir);
|
|
9
|
+
}
|
|
10
|
+
function resolveInput(program, value) {
|
|
11
|
+
return path.resolve(projectDir(program), value);
|
|
12
|
+
}
|
|
13
|
+
function resolveRoot(program, value) {
|
|
14
|
+
return path.resolve(projectDir(program), value ?? '.');
|
|
15
|
+
}
|
|
16
|
+
function theme(value) {
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
return 'auto';
|
|
19
|
+
if (['auto', 'light', 'dark'].includes(value))
|
|
20
|
+
return value;
|
|
21
|
+
throw new ArtifactCommandError('E_ARTIFACT_INPUT_INVALID', 'Artifact theme must be auto, light, or dark.');
|
|
22
|
+
}
|
|
23
|
+
function port(value) {
|
|
24
|
+
if (value === undefined)
|
|
25
|
+
return 0;
|
|
26
|
+
const parsed = Number(value);
|
|
27
|
+
if (!Number.isInteger(parsed) || parsed < 0 || parsed > 65_535) {
|
|
28
|
+
throw new ArtifactCommandError('E_ARTIFACT_INPUT_INVALID', 'Artifact review port must be an integer from 0 through 65535.');
|
|
29
|
+
}
|
|
30
|
+
return parsed;
|
|
31
|
+
}
|
|
32
|
+
function confirmed(program, local) {
|
|
33
|
+
return Boolean(local || program.opts().yes);
|
|
34
|
+
}
|
|
35
|
+
async function openArtifact(program, file, options) {
|
|
36
|
+
const cwd = projectDir(program);
|
|
37
|
+
const prepared = await prepareArtifactEnvelope({
|
|
38
|
+
file: resolveInput(program, file),
|
|
39
|
+
root: resolveRoot(program, options.root),
|
|
40
|
+
title: options.title,
|
|
41
|
+
});
|
|
42
|
+
const session = await prepared.api.startArtifactReview({
|
|
43
|
+
envelope: prepared.envelope,
|
|
44
|
+
title: options.title,
|
|
45
|
+
theme: theme(options.theme),
|
|
46
|
+
port: port(options.port),
|
|
47
|
+
noOpen: options.open === false,
|
|
48
|
+
cwd,
|
|
49
|
+
openUrl: openExternalUrl,
|
|
50
|
+
});
|
|
51
|
+
if (options.json)
|
|
52
|
+
display.line(JSON.stringify(session));
|
|
53
|
+
else {
|
|
54
|
+
logger.success('Artifact review ready');
|
|
55
|
+
display.keyValue('Session', String(session.sessionId));
|
|
56
|
+
display.keyValue('URL', String(session.url));
|
|
57
|
+
display.keyValue('Files', String(prepared.bundle.fileCount));
|
|
58
|
+
display.keyValue('Bundled', `${prepared.bundle.bytes.toLocaleString()} bytes`);
|
|
59
|
+
display.blank();
|
|
60
|
+
logger.dim('Press Ctrl+C to stop the local review session.');
|
|
61
|
+
}
|
|
62
|
+
const close = typeof session.close === 'function' ? session.close.bind(session) : undefined;
|
|
63
|
+
if (close) {
|
|
64
|
+
const shutdown = async () => {
|
|
65
|
+
await close().catch(() => undefined);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
};
|
|
68
|
+
process.once('SIGINT', shutdown);
|
|
69
|
+
process.once('SIGTERM', shutdown);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function shareArtifact(program, file, options) {
|
|
73
|
+
const prepared = await prepareArtifactEnvelope({
|
|
74
|
+
file: resolveInput(program, file),
|
|
75
|
+
root: resolveRoot(program, options.root),
|
|
76
|
+
title: options.title,
|
|
77
|
+
});
|
|
78
|
+
const preview = prepared.api.createReviewLinkPreview(prepared.envelope);
|
|
79
|
+
const yes = confirmed(program, options.yes);
|
|
80
|
+
if (!preview.fragmentEligible && isNonInteractive() && !(options.short && yes)) {
|
|
81
|
+
throw new ArtifactCommandError('E_ARTIFACT_SHORT_CONFIRMATION_REQUIRED', 'This artifact is too large for a private fragment link.', 'Rerun with `planr artifact share <file> --short --yes` to upload encrypted ciphertext.');
|
|
82
|
+
}
|
|
83
|
+
const needsConsent = Boolean(options.short || !preview.fragmentEligible);
|
|
84
|
+
let allowShort = yes;
|
|
85
|
+
if (needsConsent && !allowShort) {
|
|
86
|
+
if (isNonInteractive()) {
|
|
87
|
+
throw new ArtifactCommandError('E_ARTIFACT_SHORT_CONFIRMATION_REQUIRED', 'Encrypted short-link creation requires explicit confirmation.', 'Rerun with `--short --yes`.');
|
|
88
|
+
}
|
|
89
|
+
display.keyValue('Encrypted size', `${preview.ciphertextBytes.toLocaleString()} bytes`);
|
|
90
|
+
display.keyValue('Expiry', options.ttl ?? '7d');
|
|
91
|
+
allowShort = await promptConfirm('Upload ciphertext to share.openplanr.dev? The decryption key remains in the URL fragment.', true);
|
|
92
|
+
}
|
|
93
|
+
const result = await prepared.api.createReviewLink(prepared.envelope, {
|
|
94
|
+
baseUrl: process.env.OPENPLANR_SHARE_BASE ?? 'https://share.openplanr.dev',
|
|
95
|
+
short: Boolean(options.short),
|
|
96
|
+
transport: options.short ? 'short' : 'auto',
|
|
97
|
+
ttl: options.ttl ?? '7d',
|
|
98
|
+
confirmed: allowShort,
|
|
99
|
+
yes: allowShort,
|
|
100
|
+
});
|
|
101
|
+
const url = String(result.url);
|
|
102
|
+
if (options.open !== false)
|
|
103
|
+
await openExternalUrl(url);
|
|
104
|
+
if (options.json)
|
|
105
|
+
display.line(JSON.stringify(result));
|
|
106
|
+
else {
|
|
107
|
+
logger.success(result.uploaded ? 'Encrypted short link created' : 'Private fragment link created');
|
|
108
|
+
display.keyValue('URL', url);
|
|
109
|
+
display.keyValue('Transport', String(result.transport));
|
|
110
|
+
if (result.expiresAt)
|
|
111
|
+
display.keyValue('Expires', String(result.expiresAt));
|
|
112
|
+
if (result.deletionToken) {
|
|
113
|
+
display.keyValue('Deletion token', String(result.deletionToken));
|
|
114
|
+
logger.warn('Save the deletion token now; it is shown only once and is not part of the review URL.');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function assertReviewEnvelope(value, artifactId) {
|
|
119
|
+
if (!value.review) {
|
|
120
|
+
throw new ArtifactCommandError('E_ARTIFACT_REVIEW_IMPORT', 'The supplied link contains an artifact but no returned review.');
|
|
121
|
+
}
|
|
122
|
+
if (artifactId && value.viewer.activeArtifactId !== artifactId) {
|
|
123
|
+
throw new ArtifactCommandError('E_ARTIFACT_REVIEW_IMPORT', 'All imported review links must target the same artifact.');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function importArtifactReviews(program, sources, options) {
|
|
127
|
+
const api = await loadArtifactPipeline();
|
|
128
|
+
const decoded = await Promise.all(sources.map((source) => api.decodeReviewLink(source)));
|
|
129
|
+
const artifactId = decoded[0]?.viewer.activeArtifactId;
|
|
130
|
+
for (const envelope of decoded)
|
|
131
|
+
assertReviewEnvelope(envelope, artifactId);
|
|
132
|
+
const currentEnvelope = withoutArtifactReview(decoded[0]);
|
|
133
|
+
const input = {
|
|
134
|
+
sources: decoded,
|
|
135
|
+
currentEnvelope,
|
|
136
|
+
cwd: projectDir(program),
|
|
137
|
+
};
|
|
138
|
+
let result;
|
|
139
|
+
try {
|
|
140
|
+
result = await api.importArtifactReview({ ...input, allowStale: false, persist: true });
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const value = error;
|
|
144
|
+
if (value.code !== 'E_ARTIFACT_STALE_REVIEW' || !options.allowStale)
|
|
145
|
+
throw error;
|
|
146
|
+
const yes = confirmed(program, options.yes);
|
|
147
|
+
if (!yes && isNonInteractive()) {
|
|
148
|
+
throw new ArtifactCommandError('E_ARTIFACT_CONFIRMATION_REQUIRED', 'Importing stale artifact feedback requires explicit confirmation.', 'Review the preview and rerun with `--allow-stale --yes`.');
|
|
149
|
+
}
|
|
150
|
+
if (!options.json) {
|
|
151
|
+
logger.warn('The returned review targets an older artifact digest and will remain marked stale.');
|
|
152
|
+
if (value.details?.localDigest)
|
|
153
|
+
display.keyValue('Current digest', value.details.localDigest);
|
|
154
|
+
if (value.details?.reviewDigest)
|
|
155
|
+
display.keyValue('Review digest', value.details.reviewDigest);
|
|
156
|
+
display.keyValue('Pins', String(value.details?.pinCount ?? 0));
|
|
157
|
+
display.keyValue('Replies', String(value.details?.replyCount ?? 0));
|
|
158
|
+
}
|
|
159
|
+
if (!yes &&
|
|
160
|
+
!(await promptConfirm('Import this stale review without changing its digest?', false))) {
|
|
161
|
+
if (options.json)
|
|
162
|
+
display.line(JSON.stringify({ ok: false, action: 'cancelled' }));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
result = await api.importArtifactReview({ ...input, allowStale: true, persist: true });
|
|
166
|
+
}
|
|
167
|
+
if (options.output) {
|
|
168
|
+
const output = path.resolve(projectDir(program), options.output);
|
|
169
|
+
mkdirSync(path.dirname(output), { recursive: true });
|
|
170
|
+
writeFileSync(output, `${JSON.stringify(result.reviewState, null, 2)}\n`, { mode: 0o600 });
|
|
171
|
+
}
|
|
172
|
+
if (options.json)
|
|
173
|
+
display.line(JSON.stringify(result));
|
|
174
|
+
else {
|
|
175
|
+
logger.success(`Imported ${String(result.imported?.length ?? 0)} review(s)`);
|
|
176
|
+
display.keyValue('Artifact', String(result.artifactId));
|
|
177
|
+
display.keyValue('Decision', String(result.effectiveDecision));
|
|
178
|
+
display.keyValue('Destination', String(result.destination?.kind ?? 'local'));
|
|
179
|
+
if (options.output)
|
|
180
|
+
display.keyValue('Output', path.resolve(projectDir(program), options.output));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function exportArtifactReview(program, sessionId, options) {
|
|
184
|
+
const format = options.format ?? 'json';
|
|
185
|
+
if (!['json', 'markdown'].includes(format)) {
|
|
186
|
+
throw new ArtifactCommandError('E_ARTIFACT_REVIEW_EXPORT', 'Artifact review export format must be json or markdown.');
|
|
187
|
+
}
|
|
188
|
+
const api = await loadArtifactPipeline();
|
|
189
|
+
const result = await api.exportArtifactReviewSession(sessionId, {
|
|
190
|
+
format: format,
|
|
191
|
+
});
|
|
192
|
+
if (!options.output) {
|
|
193
|
+
process.stdout.write(result.content);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const output = path.resolve(projectDir(program), options.output);
|
|
197
|
+
mkdirSync(path.dirname(output), { recursive: true });
|
|
198
|
+
writeFileSync(output, result.content, { mode: 0o600 });
|
|
199
|
+
logger.success(`Artifact review exported to ${output}`);
|
|
200
|
+
}
|
|
201
|
+
function addOpenOptions(command) {
|
|
202
|
+
return command
|
|
203
|
+
.option('--title <title>', 'review title')
|
|
204
|
+
.option('--root <asset-root>', 'root for local artifact dependencies')
|
|
205
|
+
.option('--theme <theme>', 'auto, light, or dark', 'auto')
|
|
206
|
+
.option('--port <port>', 'loopback review port')
|
|
207
|
+
.option('--no-open', 'do not open a browser')
|
|
208
|
+
.option('--json', 'emit machine-readable output', false);
|
|
209
|
+
}
|
|
210
|
+
export function registerArtifactCommand(program) {
|
|
211
|
+
const artifact = addOpenOptions(program
|
|
212
|
+
.command('artifact [file]')
|
|
213
|
+
.description('Review, share, import, and export HTML artifacts'));
|
|
214
|
+
artifact.enablePositionalOptions();
|
|
215
|
+
artifact.action(async (file, _options, command) => {
|
|
216
|
+
if (!file) {
|
|
217
|
+
artifact.help();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
await openArtifact(program, file, command.optsWithGlobals());
|
|
221
|
+
});
|
|
222
|
+
addOpenOptions(artifact.command('open <file>').description('Open a local HTML review session')).action((file, _options, command) => openArtifact(program, file, command.optsWithGlobals()));
|
|
223
|
+
artifact
|
|
224
|
+
.command('share <file>')
|
|
225
|
+
.description('Create an immutable private review link')
|
|
226
|
+
.option('--title <title>', 'review title')
|
|
227
|
+
.option('--root <asset-root>', 'root for local artifact dependencies')
|
|
228
|
+
.option('--short', 'create an encrypted expiring short link', false)
|
|
229
|
+
.option('--ttl <ttl>', '1d, 7d, or 30d', '7d')
|
|
230
|
+
.option('--no-open', 'do not open the review link')
|
|
231
|
+
.option('--json', 'emit machine-readable output', false)
|
|
232
|
+
.option('--yes', 'confirm encrypted upload non-interactively', false)
|
|
233
|
+
.action((file, _options, command) => shareArtifact(program, file, command.optsWithGlobals()));
|
|
234
|
+
artifact
|
|
235
|
+
.command('import <review-url...>')
|
|
236
|
+
.description('Import one or more immutable returned-review links')
|
|
237
|
+
.option('--output <path>', 'also write the merged review state to this path')
|
|
238
|
+
.option('--allow-stale', 'preview and explicitly accept stale feedback', false)
|
|
239
|
+
.option('--json', 'emit machine-readable output', false)
|
|
240
|
+
.option('--yes', 'confirm stale import non-interactively', false)
|
|
241
|
+
.action((sources, _options, command) => importArtifactReviews(program, sources, command.optsWithGlobals()));
|
|
242
|
+
artifact
|
|
243
|
+
.command('export <session-id>')
|
|
244
|
+
.description('Export feedback from a live local review session')
|
|
245
|
+
.option('--format <format>', 'json or markdown', 'json')
|
|
246
|
+
.option('--output <path>', 'write the export to a file')
|
|
247
|
+
.action((sessionId, _options, command) => exportArtifactReview(program, sessionId, command.optsWithGlobals()));
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../../src/cli/commands/artifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,QA4EzE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isNonInteractive } from '../../services/interactive-state.js';
|
|
1
2
|
import { promptConfirm } from '../../services/prompt-service.js';
|
|
2
|
-
import { applySetup, runtimeDoctor } from '../../services/runtime-manager-service.js';
|
|
3
|
+
import { applySetup, cleanupHomeProjectInstall, isOpenPlanrHome, managedRuntimesForProject, previewHomeProjectCleanup, runtimeDoctor, } from '../../services/runtime-manager-service.js';
|
|
3
4
|
import { display, logger } from '../../utils/logger.js';
|
|
4
5
|
export function registerDoctorCommand(program, cliVersion) {
|
|
5
6
|
program
|
|
@@ -13,24 +14,53 @@ export function registerDoctorCommand(program, cliVersion) {
|
|
|
13
14
|
const projectDir = program.opts().projectDir;
|
|
14
15
|
let result = await runtimeDoctor(projectDir);
|
|
15
16
|
if (opts.fix) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const homeCleanup = await previewHomeProjectCleanup();
|
|
18
|
+
const managedRuntimes = isOpenPlanrHome(projectDir)
|
|
19
|
+
? []
|
|
20
|
+
: await managedRuntimesForProject(projectDir);
|
|
21
|
+
const preview = managedRuntimes.length
|
|
22
|
+
? await applySetup({
|
|
23
|
+
projectDir,
|
|
24
|
+
cliVersion,
|
|
25
|
+
runtimes: managedRuntimes,
|
|
26
|
+
scope: 'user',
|
|
27
|
+
preserveExistingScopes: true,
|
|
28
|
+
dryRun: true,
|
|
29
|
+
})
|
|
30
|
+
: null;
|
|
23
31
|
if (!opts.json) {
|
|
24
32
|
logger.heading('Repair preview');
|
|
25
|
-
for (const
|
|
33
|
+
for (const target of homeCleanup)
|
|
34
|
+
display.bullet(`remove ${target}`);
|
|
35
|
+
for (const action of (preview?.actions ?? []).filter((item) => item.operation !== 'unchanged')) {
|
|
26
36
|
display.bullet(`${action.operation} ${action.target}`);
|
|
27
37
|
}
|
|
28
38
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
const hasRepairs = homeCleanup.length > 0 ||
|
|
40
|
+
(preview?.actions ?? []).some((item) => item.operation !== 'unchanged');
|
|
41
|
+
if (!hasRepairs) {
|
|
42
|
+
if (!opts.json)
|
|
43
|
+
logger.success('No owned-file repairs are needed.');
|
|
44
|
+
}
|
|
45
|
+
const confirmed = hasRepairs &&
|
|
46
|
+
(opts.yes ||
|
|
47
|
+
program.opts().yes ||
|
|
48
|
+
(!isNonInteractive() && (await promptConfirm('Apply owned-file repairs?', true))));
|
|
49
|
+
if (hasRepairs && !confirmed && isNonInteractive() && !opts.json) {
|
|
50
|
+
logger.warn('Repairs were not applied; rerun with --yes after reviewing the preview.');
|
|
51
|
+
}
|
|
32
52
|
if (confirmed) {
|
|
33
|
-
|
|
53
|
+
if (homeCleanup.length)
|
|
54
|
+
await cleanupHomeProjectInstall();
|
|
55
|
+
if (managedRuntimes.length) {
|
|
56
|
+
await applySetup({
|
|
57
|
+
projectDir,
|
|
58
|
+
cliVersion,
|
|
59
|
+
runtimes: managedRuntimes,
|
|
60
|
+
scope: 'user',
|
|
61
|
+
preserveExistingScopes: true,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
34
64
|
result = await runtimeDoctor(projectDir);
|
|
35
65
|
}
|
|
36
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EACL,UAAU,EACV,yBAAyB,EACzB,eAAe,EACf,yBAAyB,EACzB,yBAAyB,EACzB,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,UAAU,qBAAqB,CAAC,OAAgB,EAAE,UAAkB;IACxE,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mEAAmE,CAAC;SAChF,MAAM,CAAC,UAAU,EAAE,4BAA4B,EAAE,KAAK,CAAC;SACvD,MAAM,CAAC,OAAO,EAAE,0CAA0C,EAAE,KAAK,CAAC;SAClE,MAAM,CAAC,QAAQ,EAAE,yBAAyB,EAAE,KAAK,CAAC;SAClD,MAAM,CAAC,OAAO,EAAE,+CAA+C,EAAE,KAAK,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB,CAAC;QACvD,IAAI,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,WAAW,GAAG,MAAM,yBAAyB,EAAE,CAAC;YACtD,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC;gBACjD,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,MAAM,yBAAyB,CAAC,UAAU,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM;gBACpC,CAAC,CAAC,MAAM,UAAU,CAAC;oBACf,UAAU;oBACV,UAAU;oBACV,QAAQ,EAAE,eAAe;oBACzB,KAAK,EAAE,MAAM;oBACb,sBAAsB,EAAE,IAAI;oBAC5B,MAAM,EAAE,IAAI;iBACb,CAAC;gBACJ,CAAC,CAAC,IAAI,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACjC,KAAK,MAAM,MAAM,IAAI,WAAW;oBAAE,OAAO,CAAC,MAAM,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;gBACrE,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAClD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,WAAW,CACzC,EAAE,CAAC;oBACF,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;YACD,MAAM,UAAU,GACd,WAAW,CAAC,MAAM,GAAG,CAAC;gBACtB,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC;YAC1E,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,IAAI,CAAC,IAAI,CAAC,IAAI;oBAAE,MAAM,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;YACtE,CAAC;YACD,MAAM,SAAS,GACb,UAAU;gBACV,CAAC,IAAI,CAAC,GAAG;oBACP,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG;oBAClB,CAAC,CAAC,gBAAgB,EAAE,IAAI,CAAC,MAAM,aAAa,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACvF,IAAI,UAAU,IAAI,CAAC,SAAS,IAAI,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACjE,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;YACzF,CAAC;YACD,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,WAAW,CAAC,MAAM;oBAAE,MAAM,yBAAyB,EAAE,CAAC;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBAC3B,MAAM,UAAU,CAAC;wBACf,UAAU;wBACV,UAAU;wBACV,QAAQ,EAAE,eAAe;wBACzB,KAAK,EAAE,MAAM;wBACb,sBAAsB,EAAE,IAAI;qBAC7B,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;aAC/C,CAAC;YACJ,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YACnC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC5C,MAAM,KAAK,GACT,UAAU,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;gBACzF,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/E,IAAI,UAAU,CAAC,GAAG;oBAAE,OAAO,CAAC,IAAI,CAAC,eAAe,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,QA4BvD"}
|
|
@@ -10,34 +10,38 @@ const ACTIONS = [
|
|
|
10
10
|
'dashboard',
|
|
11
11
|
'sync',
|
|
12
12
|
'doctor',
|
|
13
|
+
'prepare-plan',
|
|
14
|
+
'complete-plan',
|
|
15
|
+
'prepare-ship',
|
|
16
|
+
'finalize-ship',
|
|
17
|
+
'design-engine',
|
|
13
18
|
];
|
|
14
19
|
export function registerPipelineCommand(program) {
|
|
15
20
|
program
|
|
16
|
-
.command('pipeline <action> [
|
|
21
|
+
.command('pipeline <action> [args...]')
|
|
17
22
|
.description('Route the complete PO, Design, DEV, and QA pipeline')
|
|
18
23
|
.option('--runtime <runtime>', 'auto, claude, codex, or cursor')
|
|
19
24
|
.option('--json', 'machine-readable output', false)
|
|
20
25
|
.option('--no-launch', 'return a runtime handoff instead of launching')
|
|
21
26
|
.option('--port <port>', 'dashboard port')
|
|
22
27
|
.option('--no-watch', 'disable dashboard file watching')
|
|
23
|
-
.
|
|
28
|
+
.allowUnknownOption(true)
|
|
29
|
+
.action((action, passthrough, opts) => {
|
|
24
30
|
if (!ACTIONS.includes(action))
|
|
25
31
|
throw new Error(`Unknown pipeline action: ${action}`);
|
|
26
32
|
const pipeline = resolvePipelinePackage();
|
|
27
33
|
if (!pipeline)
|
|
28
34
|
throw new Error('E_PIPELINE_NOT_INSTALLED');
|
|
29
|
-
const args = [pipeline.binPath, action];
|
|
30
|
-
if (
|
|
31
|
-
args.push(feature);
|
|
32
|
-
if (opts.runtime && opts.runtime !== 'auto')
|
|
35
|
+
const args = [pipeline.binPath, action, ...passthrough];
|
|
36
|
+
if (opts.runtime && opts.runtime !== 'auto' && !passthrough.includes('--runtime'))
|
|
33
37
|
args.push('--runtime', opts.runtime);
|
|
34
|
-
if (opts.json)
|
|
38
|
+
if (opts.json && !passthrough.includes('--json'))
|
|
35
39
|
args.push('--json');
|
|
36
|
-
if (opts.launch === false)
|
|
40
|
+
if (opts.launch === false && !passthrough.includes('--no-launch'))
|
|
37
41
|
args.push('--no-launch');
|
|
38
|
-
if (opts.port)
|
|
42
|
+
if (opts.port && !passthrough.includes('--port'))
|
|
39
43
|
args.push('--port', String(opts.port));
|
|
40
|
-
if (opts.watch === false)
|
|
44
|
+
if (opts.watch === false && !passthrough.includes('--no-watch'))
|
|
41
45
|
args.push('--no-watch');
|
|
42
46
|
const result = spawnSync(process.execPath, args, {
|
|
43
47
|
cwd: program.opts().projectDir,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/cli/commands/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,MAAM,OAAO,GAAG;IACd,MAAM;IACN,QAAQ;IACR,aAAa;IACb,eAAe;IACf,MAAM;IACN,QAAQ;IACR,WAAW;IACX,MAAM;IACN,QAAQ;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/cli/commands/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,MAAM,OAAO,GAAG;IACd,MAAM;IACN,QAAQ;IACR,aAAa;IACb,eAAe;IACf,MAAM;IACN,QAAQ;IACR,WAAW;IACX,MAAM;IACN,QAAQ;IACR,cAAc;IACd,eAAe;IACf,cAAc;IACd,eAAe;IACf,eAAe;CAChB,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,6BAA6B,CAAC;SACtC,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;SAC/D,MAAM,CAAC,QAAQ,EAAE,yBAAyB,EAAE,KAAK,CAAC;SAClD,MAAM,CAAC,aAAa,EAAE,+CAA+C,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;SACzC,MAAM,CAAC,YAAY,EAAE,iCAAiC,CAAC;SACvD,kBAAkB,CAAC,IAAI,CAAC;SACxB,MAAM,CAAC,CAAC,MAAc,EAAE,WAAqB,EAAE,IAAI,EAAE,EAAE;QACtD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAC;QACrF,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC;QACxD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC/E,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5F,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzF,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzF,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE;YAC/C,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,UAAoB;YACxC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,KAAK;YAAE,MAAM,MAAM,CAAC,KAAK,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2DzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,QAyJxE"}
|