@planu/cli 5.7.4 → 5.7.6
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/CHANGELOG.md +85 -0
- package/README.md +3 -3
- package/dist/.planu-build.json +1 -1
- package/dist/cli/commands/package-handoff.js +30 -5
- package/dist/config/compliance-profiles.json +36 -3
- package/dist/config/environment-schema.json +21 -0
- package/dist/config/hook-templates/planu-session-safeguard.sh +22 -15
- package/dist/config/official-sdd-tools.d.ts +1 -1
- package/dist/config/official-sdd-tools.js +11 -24
- package/dist/config/registries/hosts/codex.json +14 -30
- package/dist/config/registries/hosts/opencode.json +1 -6
- package/dist/config/registries/legacy-guidance.json +26 -0
- package/dist/config/server-instructions.js +0 -21
- package/dist/config/skill-templates/planu-context-assets.md +3 -6
- package/dist/config/skill-templates/planu-implement.md +2 -2
- package/dist/config/skill-templates/planu-multi-teammate-review.md +1 -1
- package/dist/config/skill-templates/planu-release.md +2 -7
- package/dist/config/skill-templates/planu-validate.md +3 -3
- package/dist/config/spec-templates/crud-rest-api/template.json +5 -1
- package/dist/config/spec-templates/file-upload-s3/template.json +5 -1
- package/dist/config/spec-templates/stripe-payments/template.json +5 -1
- package/dist/config/spec-templates/webhook-system/template.json +5 -1
- package/dist/config/subagent-templates/planu-challenger.md +4 -9
- package/dist/config/subagent-templates/planu-spec-implementer.md +2 -4
- package/dist/config/subagent-templates/planu-validator.md +5 -8
- package/dist/config/tool-groups.json +6 -144
- package/dist/engine/ambiguity-scorer.js +40 -1
- package/dist/engine/autopilot/bootstrap.js +1 -1
- package/dist/engine/code-impact-analyzer.js +2 -6
- package/dist/engine/context-orchestrator/index.js +2 -2
- package/dist/engine/convention-scanner/codebase-scanner.js +2 -2
- package/dist/engine/dogfooding/runtime-gap-detector.js +2 -2
- package/dist/engine/evidence-gates/artifact-reader.d.ts +1 -0
- package/dist/engine/evidence-gates/artifact-reader.js +1 -1
- package/dist/engine/evidence-gates/evidence-autofill.d.ts +13 -5
- package/dist/engine/evidence-gates/evidence-autofill.js +106 -43
- package/dist/engine/evidence-gates/lifecycle-gate.js +7 -4
- package/dist/engine/evidence-index/index-builder.js +21 -4
- package/dist/engine/execution/job-runtime.js +1 -1
- package/dist/engine/execution/package-handoff-job-executor.d.ts +22 -0
- package/dist/engine/execution/package-handoff-job-executor.js +490 -0
- package/dist/engine/execution/validate-job-executor.js +20 -8
- package/dist/engine/git/exec-git.d.ts +4 -0
- package/dist/engine/git/exec-git.js +14 -0
- package/dist/engine/handoff-artifacts/implementation-review-reader.js +15 -2
- package/dist/engine/handoff-artifacts/schemas.d.ts +2 -0
- package/dist/engine/handoff-artifacts/schemas.js +1 -0
- package/dist/engine/handoff-format.d.ts +36 -0
- package/dist/engine/handoff-format.js +314 -0
- package/dist/engine/handoff-packager.d.ts +5 -3
- package/dist/engine/handoff-packager.js +89 -32
- package/dist/engine/host-tool-filter.js +20 -49
- package/dist/engine/human-summary.js +14 -3
- package/dist/engine/implementation-contract/common.d.ts +8 -3
- package/dist/engine/implementation-contract/common.js +9 -6
- package/dist/engine/implementation-contract/evaluator.js +4 -6
- package/dist/engine/implementation-contract/renderer.js +18 -23
- package/dist/engine/project-health-checker.js +2 -2
- package/dist/engine/readiness-checker.js +27 -0
- package/dist/engine/reconcile/apply-changes.js +4 -0
- package/dist/engine/reconcile/propagate-mirrors.d.ts +3 -0
- package/dist/engine/reconcile/propagate-mirrors.js +311 -0
- package/dist/engine/self-healing/healer.js +12 -5
- package/dist/engine/self-healing/strategies/lint-fix.d.ts +1 -1
- package/dist/engine/self-healing/strategies/lint-fix.js +4 -1
- package/dist/engine/self-healing/strategies/test-fix.d.ts +4 -3
- package/dist/engine/self-healing/strategies/test-fix.js +32 -14
- package/dist/engine/self-healing/strategies/typescript-fix.d.ts +1 -1
- package/dist/engine/self-healing/strategies/typescript-fix.js +28 -10
- package/dist/engine/session/checkpoint-writer.js +8 -4
- package/dist/engine/session/session-tracker.d.ts +5 -16
- package/dist/engine/session/session-tracker.js +29 -26
- package/dist/engine/session-state/writer.js +3 -11
- package/dist/engine/skill-generator/workflow-skill-generator.d.ts +4 -2
- package/dist/engine/skill-generator/workflow-skill-generator.js +113 -38
- package/dist/engine/spec-format/bdd-parser.d.ts +1 -11
- package/dist/engine/spec-format/bdd-parser.js +40 -11
- package/dist/engine/spec-format/lean-spec-generator.js +30 -10
- package/dist/engine/spec-format/retired-scaffold.d.ts +3 -0
- package/dist/engine/spec-format/retired-scaffold.js +5 -0
- package/dist/engine/spec-format/technical-md-populator.d.ts +1 -0
- package/dist/engine/spec-format/technical-md-populator.js +27 -0
- package/dist/engine/spec-format/unified-spec-builder.d.ts +1 -0
- package/dist/engine/spec-format/unified-spec-builder.js +30 -20
- package/dist/engine/spec-grounding/contract.js +115 -1
- package/dist/engine/spec-migrator/fold-technical.js +60 -19
- package/dist/engine/spec-migrator/placeholder-technical.d.ts +2 -0
- package/dist/engine/spec-migrator/placeholder-technical.js +18 -0
- package/dist/engine/spec-quality/generic-output-gate.js +37 -3
- package/dist/engine/technical-enricher/index.js +4 -1
- package/dist/engine/type-safety-gate.js +3 -11
- package/dist/engine/universal-rules/catalog.js +0 -2
- package/dist/engine/universal-rules/rules/planu-workflow.js +1 -1
- package/dist/engine/validation/durable-validation.d.ts +3 -2
- package/dist/engine/validation/durable-validation.js +106 -40
- package/dist/engine/validation/validation-freshness.d.ts +3 -2
- package/dist/engine/validation/validation-freshness.js +22 -16
- package/dist/engine/validation/validation-worktree.js +34 -0
- package/dist/hosts/claude-code/ux/mcp-prompts.js +8 -8
- package/dist/index.js +3 -17
- package/dist/resources/process.js +38 -65
- package/dist/storage/session-state-store.js +2 -0
- package/dist/tools/challenge-spec/scenarios-utils.js +2 -2
- package/dist/tools/configure-checkpoint-policy.js +3 -3
- package/dist/tools/create-spec-helpers.js +2 -5
- package/dist/tools/create-spec.js +21 -4
- package/dist/tools/facilitate.js +3 -6
- package/dist/tools/git/branch-ops.js +16 -4
- package/dist/tools/github-release-handler.js +1 -20
- package/dist/tools/heal-spec-docs.js +1 -13
- package/dist/tools/init-project/agents-md-writer.js +6 -6
- package/dist/tools/init-project/claude-md-generator.d.ts +0 -1
- package/dist/tools/init-project/claude-md-generator.js +0 -35
- package/dist/tools/init-project/handler.js +24 -49
- package/dist/tools/init-project/legacy-guidance-scanner.d.ts +12 -0
- package/dist/tools/init-project/legacy-guidance-scanner.js +176 -0
- package/dist/tools/init-project/per-client-files-writer.js +5 -5
- package/dist/tools/init-project/planu-workflow-generator.js +2 -13
- package/dist/tools/init-project/portable-index-reconciler.d.ts +21 -1
- package/dist/tools/init-project/portable-index-reconciler.js +66 -0
- package/dist/tools/init-project/rules-generator.d.ts +0 -11
- package/dist/tools/init-project/rules-generator.js +4 -85
- package/dist/tools/init-project/scaffold-writer.d.ts +0 -1
- package/dist/tools/init-project/scaffold-writer.js +1 -12
- package/dist/tools/jobs/handlers.d.ts +0 -6
- package/dist/tools/jobs/handlers.js +13 -40
- package/dist/tools/list-specs.js +6 -21
- package/dist/tools/package-handoff.d.ts +3 -2
- package/dist/tools/package-handoff.js +153 -427
- package/dist/tools/reconcile-session-safeguard-hook.js +22 -15
- package/dist/tools/register-sdd-tools.js +0 -23
- package/dist/tools/register-spec-tools/core-spec-tools.js +18 -27
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/output-schemas.d.ts +1 -18
- package/dist/tools/schemas/output-schemas.js +1 -11
- package/dist/tools/schemas/package-handoff-output-schema.d.ts +40 -0
- package/dist/tools/schemas/package-handoff-output-schema.js +68 -0
- package/dist/tools/schemas/validate-output-schema.d.ts +1 -2
- package/dist/tools/schemas/validate-output-schema.js +3 -2
- package/dist/tools/session-checkpoint.js +2 -2
- package/dist/tools/skill-registry/index.d.ts +0 -1
- package/dist/tools/skill-registry/index.js +0 -1
- package/dist/tools/sync-spec-state-handler.d.ts +2 -2
- package/dist/tools/sync-spec-state-handler.js +23 -3
- package/dist/tools/tool-registry/core-tools.js +1 -140
- package/dist/tools/tool-registry/group-infra.js +2 -39
- package/dist/tools/tool-registry/group-quality-compliance.js +9 -1
- package/dist/tools/update-status/batch.js +17 -0
- package/dist/tools/update-status/dod-gates.js +14 -1
- package/dist/tools/update-status/done-receipt-verifier.d.ts +22 -0
- package/dist/tools/update-status/done-receipt-verifier.js +56 -26
- package/dist/tools/update-status/evidence-gate.js +10 -21
- package/dist/tools/update-status/file-sync.d.ts +1 -0
- package/dist/tools/update-status/file-sync.js +6 -0
- package/dist/tools/update-status/index.d.ts +6 -0
- package/dist/tools/update-status/index.js +39 -44
- package/dist/tools/update-status-actions.js +2 -7
- package/dist/tools/validate.js +34 -28
- package/dist/transports/oauth-validator.js +12 -1
- package/dist/transports/transport-factory.d.ts +2 -1
- package/dist/transports/transport-factory.js +19 -0
- package/dist/types/common/primitives.d.ts +2 -0
- package/dist/types/durable-job.d.ts +45 -0
- package/dist/types/durable-validation.d.ts +1 -1
- package/dist/types/evidence-autofill.d.ts +13 -1
- package/dist/types/handoff-artifacts.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/legacy-guidance.d.ts +20 -0
- package/dist/types/legacy-guidance.js +3 -0
- package/dist/types/readiness.d.ts +8 -1
- package/dist/types/reconcile.d.ts +6 -0
- package/dist/types/skill-registry.d.ts +26 -1
- package/dist/types/spec/core.d.ts +5 -0
- package/dist/types/spec/inputs.d.ts +2 -2
- package/dist/types/spec-format.d.ts +11 -1
- package/dist/types/spec-grounding.d.ts +12 -0
- package/dist/types/ssr-migration.d.ts +1 -1
- package/dist/types/transport.d.ts +1 -0
- package/dist/types/validation-receipt.d.ts +27 -0
- package/package.json +3 -2
- package/planu-plugin.json +13 -26
- package/src/i18n/messages/en.json +1 -1
- package/src/i18n/messages/es.json +1 -1
- package/src/i18n/messages/pt.json +1 -1
- package/dist/engine/skill-generator/conventions-hasher.d.ts +0 -7
- package/dist/engine/skill-generator/conventions-hasher.js +0 -24
- package/dist/engine/universal-rules/rules/agent-teams.d.ts +0 -3
- package/dist/engine/universal-rules/rules/agent-teams.js +0 -63
- package/dist/tools/clarify-requirements/multiple-choice.d.ts +0 -30
- package/dist/tools/clarify-requirements/multiple-choice.js +0 -306
- package/dist/tools/clarify-requirements/questions-context.d.ts +0 -9
- package/dist/tools/clarify-requirements/questions-context.js +0 -74
- package/dist/tools/clarify-requirements/questions.d.ts +0 -16
- package/dist/tools/clarify-requirements/questions.js +0 -96
- package/dist/tools/clarify-requirements.d.ts +0 -4
- package/dist/tools/clarify-requirements.js +0 -314
- package/dist/tools/code-graph-handler.d.ts +0 -6
- package/dist/tools/code-graph-handler.js +0 -72
- package/dist/tools/create-rule.d.ts +0 -4
- package/dist/tools/create-rule.js +0 -107
- package/dist/tools/feedback-handler.d.ts +0 -7
- package/dist/tools/feedback-handler.js +0 -150
- package/dist/tools/semantic-search-handler.d.ts +0 -7
- package/dist/tools/semantic-search-handler.js +0 -71
- package/dist/tools/skill-registry/search.d.ts +0 -11
- package/dist/tools/skill-registry/search.js +0 -159
package/dist/tools/validate.js
CHANGED
|
@@ -162,10 +162,15 @@ export async function handleValidate(args) {
|
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
const knowledge = await knowledgeStore.getKnowledge(projectId);
|
|
166
|
+
if (!knowledge) {
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: 'text', text: t('project.notFound') }],
|
|
169
|
+
isError: true,
|
|
170
|
+
structuredContent: { error: 'project_not_found', code: 404, context: { projectId } },
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const spec = await specStore.getSpec(projectId, args.specId, knowledge.projectPath);
|
|
169
174
|
if (!spec) {
|
|
170
175
|
return {
|
|
171
176
|
content: [{ type: 'text', text: ti('spec.notFound', { id: args.specId }) }],
|
|
@@ -177,13 +182,6 @@ export async function handleValidate(args) {
|
|
|
177
182
|
},
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
|
-
if (!knowledge) {
|
|
181
|
-
return {
|
|
182
|
-
content: [{ type: 'text', text: t('project.notFound') }],
|
|
183
|
-
isError: true,
|
|
184
|
-
structuredContent: { error: 'project_not_found', code: 404, context: { projectId } },
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
185
|
let validationWorktree;
|
|
188
186
|
try {
|
|
189
187
|
validationWorktree = await resolveValidationWorktree({
|
|
@@ -259,6 +257,11 @@ function validationWorktreeErrorResult(error, specId) {
|
|
|
259
257
|
specId: failure.specId,
|
|
260
258
|
...(failure.relativeSpecPath ? { path: failure.relativeSpecPath } : {}),
|
|
261
259
|
},
|
|
260
|
+
...(failure.code === 'VALIDATION_STALE_SPEC_PATH'
|
|
261
|
+
? {
|
|
262
|
+
fixHint: `The spec registry still points at a stale checkout for ${failure.relativeSpecPath ?? 'this spec'}. Re-run validate from the canonical checkout (or call list_specs against the canonical projectPath) to self-heal the registry entry, then retry.`,
|
|
263
|
+
}
|
|
264
|
+
: {}),
|
|
262
265
|
},
|
|
263
266
|
};
|
|
264
267
|
}
|
|
@@ -281,27 +284,30 @@ async function acquireValidationSubmissionLock(projectId, specId) {
|
|
|
281
284
|
}
|
|
282
285
|
function validationAcceptedResult(job, projectId, runtime, { justCreated }) {
|
|
283
286
|
const observation = runtime.observe(job);
|
|
287
|
+
const reused = !justCreated;
|
|
284
288
|
const accepted = {
|
|
285
289
|
schemaVersion: 1,
|
|
286
290
|
operationId: job.id,
|
|
287
291
|
projectId,
|
|
288
292
|
workspaceId: job.workspaceId,
|
|
289
293
|
state: job.state,
|
|
290
|
-
submittedAt: job.createdAt,
|
|
291
|
-
attachedAt: justCreated ? job.
|
|
294
|
+
submittedAt: justCreated ? job.updatedAt : job.createdAt,
|
|
295
|
+
attachedAt: justCreated ? job.updatedAt : new Date().toISOString(),
|
|
296
|
+
reused,
|
|
292
297
|
cursor: publicJobCursor(observation),
|
|
293
298
|
queue: observation.queue,
|
|
294
299
|
terminalStates: ['completed', 'failed', 'cancelled', 'dead-letter'],
|
|
295
300
|
resultSchema: 'validate-completion/v1',
|
|
296
301
|
observation: {
|
|
297
302
|
get: 'get_job',
|
|
298
|
-
watch: 'watch_job',
|
|
299
|
-
cancel: 'cancel_job',
|
|
300
303
|
restart: 'restart_job',
|
|
301
304
|
},
|
|
302
305
|
};
|
|
306
|
+
const text = reused
|
|
307
|
+
? `Attached to already-running validation job ${job.id}; no new work was scheduled. Follow it with get_job. To force re-execution after it reaches a terminal state, run validate again.`
|
|
308
|
+
: `Validation accepted as durable job ${job.id}.`;
|
|
303
309
|
return {
|
|
304
|
-
content: [{ type: 'text', text
|
|
310
|
+
content: [{ type: 'text', text }],
|
|
305
311
|
structuredContent: accepted,
|
|
306
312
|
};
|
|
307
313
|
}
|
|
@@ -313,29 +319,29 @@ export async function executeValidate(args, server, onProgress) {
|
|
|
313
319
|
if (!projectId) {
|
|
314
320
|
return missingProjectIdError;
|
|
315
321
|
}
|
|
316
|
-
const
|
|
317
|
-
if (!
|
|
322
|
+
const knowledge = await knowledgeStore.getKnowledge(projectId);
|
|
323
|
+
if (!knowledge) {
|
|
318
324
|
return {
|
|
319
|
-
content: [{ type: 'text', text:
|
|
325
|
+
content: [{ type: 'text', text: t('project.notFound') }],
|
|
320
326
|
isError: true,
|
|
321
327
|
structuredContent: {
|
|
322
|
-
error: '
|
|
328
|
+
error: 'project_not_found',
|
|
323
329
|
code: 404,
|
|
324
|
-
context: {
|
|
325
|
-
fixHint:
|
|
330
|
+
context: { projectId },
|
|
331
|
+
fixHint: 'Run init_project first to initialize the project knowledge.',
|
|
326
332
|
},
|
|
327
333
|
};
|
|
328
334
|
}
|
|
329
|
-
const
|
|
330
|
-
if (!
|
|
335
|
+
const spec = await specStore.getSpec(projectId, specId, knowledge.projectPath);
|
|
336
|
+
if (!spec) {
|
|
331
337
|
return {
|
|
332
|
-
content: [{ type: 'text', text:
|
|
338
|
+
content: [{ type: 'text', text: ti('spec.notFound', { id: specId }) }],
|
|
333
339
|
isError: true,
|
|
334
340
|
structuredContent: {
|
|
335
|
-
error: '
|
|
341
|
+
error: 'spec_not_found',
|
|
336
342
|
code: 404,
|
|
337
|
-
context: { projectId },
|
|
338
|
-
fixHint:
|
|
343
|
+
context: { specId, projectId },
|
|
344
|
+
fixHint: `Verify the specId is correct and the spec exists in project ${projectId}.`,
|
|
339
345
|
},
|
|
340
346
|
};
|
|
341
347
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// 1. API key (SDD_OAUTH_API_KEY) — simplest: token must match env var
|
|
4
4
|
// 2. HMAC-signed JWT (SDD_OAUTH_JWT_SECRET) — validates HS256 JWT signature
|
|
5
5
|
// Configure via environment variables — no accounts or external services needed.
|
|
6
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
6
7
|
export function loadOAuthConfig() {
|
|
7
8
|
const apiKey = process.env.SDD_OAUTH_API_KEY;
|
|
8
9
|
const jwtSecret = process.env.SDD_OAUTH_JWT_SECRET;
|
|
@@ -32,13 +33,23 @@ export async function validateToken(token, config) {
|
|
|
32
33
|
return { valid: true };
|
|
33
34
|
}
|
|
34
35
|
if (config.mode === 'api-key') {
|
|
35
|
-
return token
|
|
36
|
+
return isMatchingApiKey(token, config.apiKey ?? '')
|
|
37
|
+
? { valid: true }
|
|
38
|
+
: { valid: false, reason: 'Invalid API key' };
|
|
36
39
|
}
|
|
37
40
|
if (config.mode === 'jwt-hmac') {
|
|
38
41
|
return validateHmacJwt(token, config);
|
|
39
42
|
}
|
|
40
43
|
return { valid: false, reason: 'Unknown auth mode' };
|
|
41
44
|
}
|
|
45
|
+
function isMatchingApiKey(token, apiKey) {
|
|
46
|
+
const tokenBuffer = Buffer.from(token);
|
|
47
|
+
const apiKeyBuffer = Buffer.from(apiKey);
|
|
48
|
+
if (tokenBuffer.byteLength !== apiKeyBuffer.byteLength) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return timingSafeEqual(tokenBuffer, apiKeyBuffer);
|
|
52
|
+
}
|
|
42
53
|
// Validate HS256 JWT using Node.js built-in crypto (no external deps).
|
|
43
54
|
async function validateHmacJwt(token, config) {
|
|
44
55
|
const parts = token.split('.');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type { TransportConfig } from '../types/index.js';
|
|
2
|
+
import type { TransportConfig, OAuthConfig } from '../types/index.js';
|
|
3
3
|
export declare function parseTransportConfig(args: string[]): TransportConfig;
|
|
4
|
+
export declare function assertHttpExposureAllowed(config: TransportConfig, oauth: OAuthConfig): void;
|
|
4
5
|
export declare function selectTransport(server: McpServer, args: string[], serverFactory?: () => McpServer): Promise<void>;
|
|
5
6
|
//# sourceMappingURL=transport-factory.d.ts.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { execFileSync } from 'node:child_process';
|
|
4
4
|
import { createHttpTransport } from './http-transport.js';
|
|
5
|
+
import { loadOAuthConfig } from './oauth-validator.js';
|
|
5
6
|
import { compactToolsListMessage, isToolsListResponse, } from '../engine/compact/tool-list-compactor.js';
|
|
6
7
|
import { reportClassifiedDegradation } from '../errors/classified-degradation.js';
|
|
7
8
|
const VALID_TRANSPORTS = ['stdio', 'http'];
|
|
@@ -84,8 +85,25 @@ export function parseTransportConfig(args) {
|
|
|
84
85
|
port,
|
|
85
86
|
host: getFlag(args, 'host') ?? process.env.HOST ?? DEFAULT_HOST,
|
|
86
87
|
corsOrigin: getFlag(args, 'cors-origin') ?? process.env.CORS_ORIGIN,
|
|
88
|
+
insecure: args.includes('--insecure'),
|
|
87
89
|
};
|
|
88
90
|
}
|
|
91
|
+
const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
|
|
92
|
+
function isLoopbackHost(host) {
|
|
93
|
+
return LOOPBACK_HOSTS.has(host);
|
|
94
|
+
}
|
|
95
|
+
export function assertHttpExposureAllowed(config, oauth) {
|
|
96
|
+
if (config.transport !== 'http' || isLoopbackHost(config.host) || oauth.enabled) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (config.insecure) {
|
|
100
|
+
console.error(`[Planu] WARNING: running UNAUTHENTICATED on non-loopback host "${config.host}" because --insecure was passed.`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.error(`[Planu] Refusing to start: HTTP transport on non-loopback host "${config.host}" has no authentication configured. ` +
|
|
104
|
+
'Set SDD_OAUTH_API_KEY or SDD_OAUTH_JWT_SECRET, or pass --insecure to bypass this at your own risk.');
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
89
107
|
export async function selectTransport(server, args, serverFactory) {
|
|
90
108
|
const config = parseTransportConfig(args);
|
|
91
109
|
if (config.transport === 'stdio') {
|
|
@@ -102,6 +120,7 @@ export async function selectTransport(server, args, serverFactory) {
|
|
|
102
120
|
return;
|
|
103
121
|
}
|
|
104
122
|
// HTTP mode: each session needs its own McpServer instance
|
|
123
|
+
assertHttpExposureAllowed(config, loadOAuthConfig());
|
|
105
124
|
const factory = serverFactory ?? (() => server);
|
|
106
125
|
await createHttpTransport(factory, config);
|
|
107
126
|
}
|
|
@@ -3,6 +3,8 @@ export type Difficulty = 1 | 2 | 3 | 4 | 5;
|
|
|
3
3
|
export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
4
4
|
export type SupportedLocale = 'en' | 'es' | 'pt';
|
|
5
5
|
export type ExperienceLevel = 'beginner' | 'intermediate' | 'expert';
|
|
6
|
+
/** SDD model tier evidence for lifecycle transitions. */
|
|
7
|
+
export type ModelTierUsed = 'max' | 'implementation' | 'review';
|
|
6
8
|
/** SPEC-313: Preferred interaction style with Planu (stored in planu.json) */
|
|
7
9
|
export type WorkMode = 'guided' | 'standard' | 'expert';
|
|
8
10
|
export type SpecType = 'feature' | 'refactor' | 'bugfix' | 'infra' | 'docs' | 'project' | 'agent' | 'tech-debt';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ValidationArtifactDigests, ValidationFreshnessLease } from './validation-receipt.js';
|
|
2
|
+
import type { HandoffPackage } from './readiness.js';
|
|
2
3
|
export interface DurableJobIdentity {
|
|
3
4
|
readonly operationId: string;
|
|
4
5
|
readonly projectId: string;
|
|
@@ -35,6 +36,50 @@ export interface ValidateDurableJobPayload {
|
|
|
35
36
|
readonly freshnessLease?: ValidationFreshnessLease;
|
|
36
37
|
readonly specPath: string;
|
|
37
38
|
}
|
|
39
|
+
export interface PackageHandoffDurableJobPayload {
|
|
40
|
+
readonly kind: 'package-handoff';
|
|
41
|
+
readonly schemaVersion: 1;
|
|
42
|
+
readonly projectId: string;
|
|
43
|
+
readonly specId: string;
|
|
44
|
+
readonly specVersion: string;
|
|
45
|
+
}
|
|
46
|
+
/** Outcome of one deadline-bounded package-handoff stage execution. */
|
|
47
|
+
export interface PackageHandoffStageOutcome<T> {
|
|
48
|
+
readonly ok: boolean;
|
|
49
|
+
readonly value?: T;
|
|
50
|
+
readonly timedOut: boolean;
|
|
51
|
+
readonly error?: unknown;
|
|
52
|
+
}
|
|
53
|
+
export interface PackageHandoffStageResult<T> {
|
|
54
|
+
readonly stage: string;
|
|
55
|
+
readonly durationMs: number;
|
|
56
|
+
readonly outcome: PackageHandoffStageOutcome<T>;
|
|
57
|
+
}
|
|
58
|
+
export interface PackageHandoffDegradation {
|
|
59
|
+
readonly stage: string;
|
|
60
|
+
readonly code: 'HANDOFF_ENRICHMENT_TIMEOUT' | 'HANDOFF_ENRICHMENT_FAILURE' | 'HANDOFF_STALE_VERSION_SKIPPED';
|
|
61
|
+
readonly remediation: string;
|
|
62
|
+
}
|
|
63
|
+
export interface PackageHandoffCoreStageOutput {
|
|
64
|
+
readonly readinessScore: number;
|
|
65
|
+
readonly pkg: HandoffPackage & {
|
|
66
|
+
readonly staleVersionSkipped?: boolean;
|
|
67
|
+
};
|
|
68
|
+
readonly stageTimings: Record<string, number>;
|
|
69
|
+
}
|
|
70
|
+
export interface PackageHandoffEnrichmentOutput {
|
|
71
|
+
readonly pkgWithConstraints: HandoffPackage;
|
|
72
|
+
readonly graphContext: {
|
|
73
|
+
text: string;
|
|
74
|
+
structured: unknown;
|
|
75
|
+
} | null;
|
|
76
|
+
readonly minimalityBlocked: boolean | null;
|
|
77
|
+
readonly minimalitySummary: Record<string, unknown> | undefined;
|
|
78
|
+
readonly tokenWasteRiskCount: number | null;
|
|
79
|
+
readonly tokenWasteSummary: Record<string, unknown> | undefined;
|
|
80
|
+
readonly stageTimings: Record<string, number>;
|
|
81
|
+
readonly degradations: readonly PackageHandoffDegradation[];
|
|
82
|
+
}
|
|
38
83
|
export declare const DURABLE_JOB_STATES: readonly ['accepted', 'running', 'checkpointed', 'cancelled', 'failed', 'dead-letter', 'completed'];
|
|
39
84
|
export type DurableJobState = (typeof DURABLE_JOB_STATES)[number];
|
|
40
85
|
export interface DurableJobRecord {
|
|
@@ -9,7 +9,7 @@ export interface DurableValidationBindings {
|
|
|
9
9
|
readonly policyHash: string;
|
|
10
10
|
readonly toolchainHash: string;
|
|
11
11
|
}
|
|
12
|
-
export type ValidationWorktreeErrorCode = 'VALIDATION_PAYLOAD_VERSION_UNSUPPORTED' | 'VALIDATION_ROOT_ID_MALFORMED' | 'VALIDATION_ROOT_ID_MISMATCH' | 'VALIDATION_ROOT_BUSY' | 'VALIDATION_ROOT_NOT_GIT_WORKTREE' | 'VALIDATION_COMMON_DIR_MISMATCH' | 'VALIDATION_SPEC_PATH_TRAVERSAL' | 'VALIDATION_SPEC_PATH_SYMLINK' | 'VALIDATION_SPEC_NOT_FOUND' | 'VALIDATION_SPEC_ID_MISMATCH';
|
|
12
|
+
export type ValidationWorktreeErrorCode = 'VALIDATION_PAYLOAD_VERSION_UNSUPPORTED' | 'VALIDATION_ROOT_ID_MALFORMED' | 'VALIDATION_ROOT_ID_MISMATCH' | 'VALIDATION_ROOT_BUSY' | 'VALIDATION_ROOT_NOT_GIT_WORKTREE' | 'VALIDATION_COMMON_DIR_MISMATCH' | 'VALIDATION_SPEC_PATH_TRAVERSAL' | 'VALIDATION_STALE_SPEC_PATH' | 'VALIDATION_SPEC_PATH_SYMLINK' | 'VALIDATION_SPEC_NOT_FOUND' | 'VALIDATION_SPEC_ID_MISMATCH';
|
|
13
13
|
export interface ResolvedValidationWorktree {
|
|
14
14
|
readonly projectPath: string;
|
|
15
15
|
readonly gitCommonDir: string;
|
|
@@ -28,9 +28,21 @@ export type AutofillTraceabilityMatrixResult = {
|
|
|
28
28
|
written: true;
|
|
29
29
|
path: string;
|
|
30
30
|
rowCount: number;
|
|
31
|
+
reason?: 'regenerated-stale';
|
|
31
32
|
} | {
|
|
32
33
|
written: false;
|
|
33
|
-
reason: 'already-exists' | 'no-criteria' | 'write-failed';
|
|
34
|
+
reason: 'already-exists-manual' | 'already-exists-current' | 'no-criteria' | 'write-failed';
|
|
34
35
|
error?: string;
|
|
35
36
|
};
|
|
37
|
+
/** Classification of an on-disk traceability-matrix.json relative to the
|
|
38
|
+
* generator's own prose templates: absent, hand-written/mixed/unparseable
|
|
39
|
+
* ("manual" — never touched), or autofill-shaped and safe to regenerate. */
|
|
40
|
+
export type ExistingMatrixLookup = {
|
|
41
|
+
kind: 'absent';
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'manual';
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'autofill-shaped';
|
|
46
|
+
raw: string;
|
|
47
|
+
};
|
|
36
48
|
//# sourceMappingURL=evidence-autofill.d.ts.map
|
|
@@ -48,6 +48,7 @@ export interface ImplementationReviewV1 {
|
|
|
48
48
|
kind: 'implementation-review-agent' | 'human';
|
|
49
49
|
agent: string;
|
|
50
50
|
verdict: 'approved' | 'changes-requested';
|
|
51
|
+
sessionId?: string;
|
|
51
52
|
};
|
|
52
53
|
blockers: string[];
|
|
53
54
|
suggestions: string[];
|
|
@@ -147,7 +148,7 @@ export interface ArtifactPayloadMap {
|
|
|
147
148
|
}
|
|
148
149
|
export type ArtifactPayload<K extends ArtifactKind> = ArtifactPayloadMap[K];
|
|
149
150
|
import type { MinimalImplementationReport } from './minimal-implementation-gate.js';
|
|
150
|
-
export type ImplementationReviewRejectionReason = 'missing' | 'unreadable' | 'schema_invalid' | 'stub_body' | 'wrong_agent_or_kind' | 'not_approved' | 'self_review' | 'actor_unreadable' | 'wrong_spec';
|
|
151
|
+
export type ImplementationReviewRejectionReason = 'missing' | 'unreadable' | 'schema_invalid' | 'stub_body' | 'wrong_agent_or_kind' | 'not_approved' | 'self_review' | 'actor_unreadable' | 'wrong_spec' | 'identity_unverifiable';
|
|
151
152
|
export interface VerifiedImplementationReviewOk {
|
|
152
153
|
ok: true;
|
|
153
154
|
review: ImplementationReviewV1;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -278,6 +278,7 @@ export * from './reviewer-tokens.js';
|
|
|
278
278
|
export * from './coach.js';
|
|
279
279
|
export * from './tdd-strict.js';
|
|
280
280
|
export * from './ssr-migration.js';
|
|
281
|
+
export * from './legacy-guidance.js';
|
|
281
282
|
export * from './workspace-overview.js';
|
|
282
283
|
export * from './mcp-config.js';
|
|
283
284
|
export * from './security/index.js';
|
package/dist/types/index.js
CHANGED
|
@@ -275,6 +275,7 @@ export * from './reviewer-tokens.js';
|
|
|
275
275
|
export * from './coach.js';
|
|
276
276
|
export * from './tdd-strict.js';
|
|
277
277
|
export * from './ssr-migration.js';
|
|
278
|
+
export * from './legacy-guidance.js';
|
|
278
279
|
// SPEC-753: workspace_overview + reconcile_status_json types
|
|
279
280
|
export * from './workspace-overview.js';
|
|
280
281
|
// SPEC-756: MCP config auto-update types
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface LegacyGuidanceWarning {
|
|
2
|
+
file: string;
|
|
3
|
+
reason: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LegacyGuidanceScanResult {
|
|
6
|
+
healed: string[];
|
|
7
|
+
warnings: LegacyGuidanceWarning[];
|
|
8
|
+
}
|
|
9
|
+
export interface LegacyGuidanceRegistry {
|
|
10
|
+
hostSurfaceFiles: string[];
|
|
11
|
+
hostSurfaceDirectories: {
|
|
12
|
+
dir: string;
|
|
13
|
+
extension: string;
|
|
14
|
+
}[];
|
|
15
|
+
legacyFilenameAllowlist: string[];
|
|
16
|
+
managedByMarkers: string[];
|
|
17
|
+
contradictoryPhrases: string[];
|
|
18
|
+
replacementGuidance: string;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=legacy-guidance.d.ts.map
|
|
@@ -63,8 +63,15 @@ export interface AmbiguityReport {
|
|
|
63
63
|
violations: AmbiguityViolation[];
|
|
64
64
|
blockers: string[];
|
|
65
65
|
}
|
|
66
|
+
/** Version fence for the durable executor: skip publishing a stale-version artifact. */
|
|
67
|
+
export interface HandoffVersionFence {
|
|
68
|
+
readonly specVersion: string;
|
|
69
|
+
readonly getCurrentSpecVersion: () => Promise<string | undefined>;
|
|
70
|
+
readonly signal?: AbortSignal;
|
|
71
|
+
}
|
|
66
72
|
export interface PackageHandoffInput {
|
|
67
|
-
projectId
|
|
73
|
+
projectId?: string;
|
|
74
|
+
projectPath?: string;
|
|
68
75
|
specId: string;
|
|
69
76
|
}
|
|
70
77
|
/**
|
|
@@ -26,6 +26,12 @@ export interface SectionBounds {
|
|
|
26
26
|
start: number;
|
|
27
27
|
end: number;
|
|
28
28
|
}
|
|
29
|
+
export type AppliedSections = ReadonlySet<string>;
|
|
30
|
+
export interface ParsedFilesSection {
|
|
31
|
+
create: string[];
|
|
32
|
+
modify: string[];
|
|
33
|
+
test: string[];
|
|
34
|
+
}
|
|
29
35
|
export interface CurrentStatus {
|
|
30
36
|
totalSpecs: number;
|
|
31
37
|
content: Record<string, unknown>;
|
|
@@ -398,9 +398,34 @@ export interface WorkflowSkillGenerationOptions {
|
|
|
398
398
|
export interface WorkflowSkillGenerationResult {
|
|
399
399
|
/** Skill names that were written (new or updated). */
|
|
400
400
|
written: string[];
|
|
401
|
-
/** Skill names that were skipped (
|
|
401
|
+
/** Skill names that were skipped (content unchanged). */
|
|
402
402
|
skipped: string[];
|
|
403
|
+
/** Skill names left untouched because the on-disk file was user-authored or user-edited. */
|
|
404
|
+
userModified: string[];
|
|
403
405
|
/** Any non-fatal errors (skill name → error message). */
|
|
404
406
|
errors: Record<string, string>;
|
|
405
407
|
}
|
|
408
|
+
/** Fail-closed result of reading the hash marker from an on-disk skill file. */
|
|
409
|
+
export type MarkerReadResult = {
|
|
410
|
+
kind: 'absent';
|
|
411
|
+
} | {
|
|
412
|
+
kind: 'invalid';
|
|
413
|
+
} | {
|
|
414
|
+
kind: 'legacy';
|
|
415
|
+
} | {
|
|
416
|
+
kind: 'current';
|
|
417
|
+
hash: string;
|
|
418
|
+
lineIndex: number;
|
|
419
|
+
};
|
|
420
|
+
/** Per-file write decision made by generateWorkflowSkills for one skill definition. */
|
|
421
|
+
export type SkillFileDecision = {
|
|
422
|
+
action: 'write';
|
|
423
|
+
} | {
|
|
424
|
+
action: 'skip-unchanged';
|
|
425
|
+
} | {
|
|
426
|
+
action: 'skip-user-modified';
|
|
427
|
+
} | {
|
|
428
|
+
action: 'skip-error';
|
|
429
|
+
message: string;
|
|
430
|
+
};
|
|
406
431
|
//# sourceMappingURL=skill-registry.d.ts.map
|
|
@@ -435,6 +435,11 @@ export interface SyncDivergence {
|
|
|
435
435
|
yamlStatus: string;
|
|
436
436
|
dataStatus: string;
|
|
437
437
|
}
|
|
438
|
+
/** Options controlling how syncSpecState reconciles divergences. */
|
|
439
|
+
export interface SyncSpecStateOptions {
|
|
440
|
+
/** When false, non-terminal drift is reported read-only instead of applied via handleUpdateStatus. */
|
|
441
|
+
applyTransitions?: boolean;
|
|
442
|
+
}
|
|
438
443
|
/** Report produced by spec state synchronisation. */
|
|
439
444
|
export interface SyncReport {
|
|
440
445
|
synced: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SpecStatus, SpecType, SpecScope, SpecTarget, ToolResult } from '../common/index.js';
|
|
1
|
+
import type { ModelTierUsed, SpecStatus, SpecType, SpecScope, SpecTarget, ToolResult } from '../common/index.js';
|
|
2
2
|
import type { Actuals } from '../estimation.js';
|
|
3
3
|
import type { GlobalConfig } from '../project/config-metrics.js';
|
|
4
4
|
import type { ProjectKnowledge } from '../project.js';
|
|
@@ -58,7 +58,7 @@ export interface UpdateStatusInput {
|
|
|
58
58
|
* - implementation: lower/intermediate implementer tier
|
|
59
59
|
* - review: reviewer tier
|
|
60
60
|
*/
|
|
61
|
-
modelTierUsed?:
|
|
61
|
+
modelTierUsed?: ModelTierUsed;
|
|
62
62
|
/** SHA-256 hash of the persisted context package used for this transition. */
|
|
63
63
|
contextHash?: string;
|
|
64
64
|
/** Path to the persisted handoff artifact generated by package_handoff. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Spec } from './spec/core.js';
|
|
2
2
|
import type { Estimation } from './estimation.js';
|
|
3
|
-
import type { SpecStatus } from './common/index.js';
|
|
3
|
+
import type { ModelTierUsed, SpecStatus } from './common/index.js';
|
|
4
4
|
import type { CriterionGroundingRecord, TechnicalReferenceGroundingRecord } from './spec-grounding.js';
|
|
5
5
|
/** A criterion in the lean spec frontmatter. */
|
|
6
6
|
export interface LeanCriterion {
|
|
@@ -110,6 +110,15 @@ export interface LegacyMigrationDirective {
|
|
|
110
110
|
legacyFiles: LegacyArtifactHit[];
|
|
111
111
|
directive: 'migrate_legacy_spec';
|
|
112
112
|
}
|
|
113
|
+
export interface UpdateStatusBatchEvidence {
|
|
114
|
+
modelTierUsed?: ModelTierUsed;
|
|
115
|
+
modelId?: string;
|
|
116
|
+
contextHash?: string;
|
|
117
|
+
handoffPath?: string;
|
|
118
|
+
handoffArtifactId?: string;
|
|
119
|
+
reviewedBy?: string;
|
|
120
|
+
arbitratedBy?: string;
|
|
121
|
+
}
|
|
113
122
|
export interface UpdateStatusBatchInput {
|
|
114
123
|
specIds: string[];
|
|
115
124
|
status: Exclude<SpecStatus, 'done'>;
|
|
@@ -117,6 +126,7 @@ export interface UpdateStatusBatchInput {
|
|
|
117
126
|
projectPath?: string;
|
|
118
127
|
dryRun?: boolean;
|
|
119
128
|
reviewNotes?: string;
|
|
129
|
+
evidence?: Record<string, UpdateStatusBatchEvidence>;
|
|
120
130
|
}
|
|
121
131
|
/** Report of detected migration drift (SPEC-715). Read-only — no FS mutations. */
|
|
122
132
|
export interface MigrationDriftReport {
|
|
@@ -19,4 +19,16 @@ export interface GroundingGateResult {
|
|
|
19
19
|
issues: string[];
|
|
20
20
|
records: CriterionGroundingRecord[];
|
|
21
21
|
}
|
|
22
|
+
export interface RawGroundingFrontmatter {
|
|
23
|
+
grounding?: {
|
|
24
|
+
criteria?: unknown;
|
|
25
|
+
technicalReferences?: unknown;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export type FrontmatterYamlOutcome = {
|
|
29
|
+
parsed: true;
|
|
30
|
+
document: Record<string, unknown> | undefined;
|
|
31
|
+
} | {
|
|
32
|
+
parsed: false;
|
|
33
|
+
};
|
|
22
34
|
//# sourceMappingURL=spec-grounding.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Result of folding technical.md into spec.md ## Technical section. */
|
|
2
2
|
export interface FoldTechnicalResult {
|
|
3
3
|
ok: boolean;
|
|
4
|
-
reason: 'already_unified' | 'no_technical_md' | 'ok' | 'error';
|
|
4
|
+
reason: 'already_unified' | 'no_technical_md' | 'ok' | 'error' | 'folded_residual';
|
|
5
5
|
byteDelta?: number;
|
|
6
6
|
error?: string;
|
|
7
7
|
}
|
|
@@ -15,6 +15,16 @@ export interface ValidationArtifactDigests {
|
|
|
15
15
|
readonly traceability: string;
|
|
16
16
|
readonly contractValidation: string;
|
|
17
17
|
}
|
|
18
|
+
export interface ValidationArtifactProvenanceWriteResult {
|
|
19
|
+
readonly writtenPaths: readonly string[];
|
|
20
|
+
readonly absentArtifacts: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
export interface PerFileArtifactSentinel {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly digestValue: string;
|
|
25
|
+
readonly sentinel: string;
|
|
26
|
+
readonly payloadFile?: string;
|
|
27
|
+
}
|
|
18
28
|
export interface ValidationArtifactProvenance {
|
|
19
29
|
readonly receiptId: string;
|
|
20
30
|
/** Digest of canonical artifact content excluding this provenance envelope. */
|
|
@@ -28,6 +38,23 @@ export interface ValidationFreshnessLease {
|
|
|
28
38
|
readonly epoch: string;
|
|
29
39
|
readonly generation: number;
|
|
30
40
|
}
|
|
41
|
+
export type ValidationFreshnessBarrierReason = 'lease-superseded' | 'invalidation-drain-failed' | 'evidence-check-failed' | 'evidence-changed' | 'source-changed' | 'source-check-failed' | 'state-lost' | 'lease-expired' | 'bindings-mismatch';
|
|
42
|
+
export type ValidationFreshnessBarrierResult = {
|
|
43
|
+
readonly fresh: true;
|
|
44
|
+
} | {
|
|
45
|
+
readonly fresh: false;
|
|
46
|
+
readonly reason: ValidationFreshnessBarrierReason;
|
|
47
|
+
readonly changedInput?: string;
|
|
48
|
+
};
|
|
49
|
+
export type ValidationFreshnessRebaselineReason = 'lease-expired' | 'recompute-failed' | 'bindings-mismatch' | 'lease-unstable';
|
|
50
|
+
export type ValidationFreshnessRebaselineResult = {
|
|
51
|
+
readonly lease: ValidationFreshnessLease;
|
|
52
|
+
} | {
|
|
53
|
+
readonly rejection: {
|
|
54
|
+
readonly reason: ValidationFreshnessRebaselineReason;
|
|
55
|
+
readonly changedInput?: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
31
58
|
/**
|
|
32
59
|
* Classification of one raw filesystem watcher event feeding the freshness
|
|
33
60
|
* barrier: a direct relevant/ignored child path, a synthetic root event (the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.6",
|
|
4
4
|
"description": "Planu — MCP Server for Spec Driven Development. Cross-platform (Linux/macOS/Windows, x64/arm64).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"LICENSE"
|
|
21
21
|
],
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
23
|
+
"node": ">=22.13.0"
|
|
24
24
|
},
|
|
25
25
|
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
26
26
|
"scripts": {
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"test:watch": "vitest",
|
|
49
49
|
"test:coverage": "vitest run --coverage --testTimeout=60000 --maxWorkers=4",
|
|
50
50
|
"test:release-gate": "vitest run --exclude 'tests/integration/**'",
|
|
51
|
+
"test:pre-push-scripts": "PLANU_PRE_PUSH_SCRIPTS_LANE=1 vitest run tests/scripts --reporter=dot",
|
|
51
52
|
"test:integration": "vitest run tests/integration",
|
|
52
53
|
"test:website:unit": "vitest run tests/website tests/scripts/generate-website-proof.test.ts tests/scripts/website-tool-counts.test.ts",
|
|
53
54
|
"test:website:browser": "playwright test --config playwright.website.config.ts",
|