@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
|
@@ -9,7 +9,6 @@ import { registerDesignStackTools } from './register-platform-tools/design-stack
|
|
|
9
9
|
import { registerQualityComplianceGroupTools } from './tool-registry/group-quality-compliance.js';
|
|
10
10
|
import { registerInfraGroupTools } from './tool-registry/group-infra.js';
|
|
11
11
|
import { safe } from './safe-handler.js';
|
|
12
|
-
import { handleCreateRule } from './create-rule.js';
|
|
13
12
|
import { handleCreateSkill } from './create-skill.js';
|
|
14
13
|
import { handleReconcileUniversalRules } from './reconcile-universal-rules.js';
|
|
15
14
|
import { registerBumpSpecVersionTool } from './bump-spec-version.js';
|
|
@@ -43,28 +42,6 @@ function registerOnly(server, names, register) {
|
|
|
43
42
|
register(scopedServer);
|
|
44
43
|
}
|
|
45
44
|
function registerUniversalRulesTools(s) {
|
|
46
|
-
s.registerTool('create_rule', {
|
|
47
|
-
description: 'Create a host-aware rule file for a Planu project. For Claude Code, writes to `.claude/rules/{name}.md`. For Codex, inserts a delimited block in `AGENTS.md`. For Gemini, inserts a delimited block in `.gemini/conventions.md`. Use host: "auto" to detect the current host automatically.',
|
|
48
|
-
inputSchema: {
|
|
49
|
-
projectPath: z
|
|
50
|
-
.string()
|
|
51
|
-
.describe('Absolute path to the project root where the rule will be written'),
|
|
52
|
-
name: z
|
|
53
|
-
.string()
|
|
54
|
-
.min(1)
|
|
55
|
-
.describe('Rule identifier — kebab-case, no extension (e.g. "team-style").'),
|
|
56
|
-
content: z.string().min(1).describe('Markdown body of the rule (no frontmatter required)'),
|
|
57
|
-
host: z
|
|
58
|
-
.enum(['claude-code', 'codex', 'gemini', 'auto'])
|
|
59
|
-
.default('auto')
|
|
60
|
-
.describe('Target host or auto-detection.'),
|
|
61
|
-
overwriteExisting: z
|
|
62
|
-
.boolean()
|
|
63
|
-
.optional()
|
|
64
|
-
.describe('When true, overwrite an existing file with different content.'),
|
|
65
|
-
},
|
|
66
|
-
annotations: { readOnlyHint: false, destructiveHint: false, title: 'Create Rule' },
|
|
67
|
-
}, safe((args) => handleCreateRule(args)));
|
|
68
45
|
s.registerTool('create_skill', {
|
|
69
46
|
description: 'Create a host-aware skill for a Planu project. For Claude Code, writes to `.claude/skills/{name}/SKILL.md`. For Codex, inserts a skill block in `AGENTS.md`. For Gemini, writes to `.gemini/skills/{name}.md`. Use host: "auto" to detect the current host automatically.',
|
|
70
47
|
inputSchema: {
|
|
@@ -7,7 +7,6 @@ import { handleSetLocale } from '../set-locale.js';
|
|
|
7
7
|
import { handleInitProject } from '../init-project.js';
|
|
8
8
|
import { handleSetWorkMode } from '../set-work-mode-handler.js';
|
|
9
9
|
import { handleInitConstitution } from '../init-constitution.js';
|
|
10
|
-
import { handleClarifyRequirements } from '../clarify-requirements.js';
|
|
11
10
|
import { handleCreateSpec } from '../create-spec.js';
|
|
12
11
|
import { handleListSpecs } from '../list-specs.js';
|
|
13
12
|
import { handleUpdateStatus } from '../update-status.js';
|
|
@@ -159,32 +158,6 @@ export function registerCoreSpecTools(server) {
|
|
|
159
158
|
.describe('Manual principles to include'),
|
|
160
159
|
},
|
|
161
160
|
}, safeTracked('init_constitution', async (args) => handleInitConstitution(args)));
|
|
162
|
-
// 4. clarify_requirements
|
|
163
|
-
server.registerTool('clarify_requirements', {
|
|
164
|
-
description: t('tools.clarify_requirements.description'),
|
|
165
|
-
inputSchema: {
|
|
166
|
-
projectId: z.string().max(500).describe('Project ID'),
|
|
167
|
-
topic: z.string().max(500).describe('The topic or feature to clarify'),
|
|
168
|
-
context: z
|
|
169
|
-
.string()
|
|
170
|
-
.max(10_000)
|
|
171
|
-
.optional()
|
|
172
|
-
.describe('Additional context about the requirement'),
|
|
173
|
-
maxQuestions: z
|
|
174
|
-
.number()
|
|
175
|
-
.optional()
|
|
176
|
-
.describe('Maximum number of questions to generate (default: 5)'),
|
|
177
|
-
sessionId: z
|
|
178
|
-
.string()
|
|
179
|
-
.max(500)
|
|
180
|
-
.optional()
|
|
181
|
-
.describe('Existing clarification session to resume with user-confirmed answers.'),
|
|
182
|
-
answers: z
|
|
183
|
-
.record(z.string(), z.string())
|
|
184
|
-
.optional()
|
|
185
|
-
.describe('Explicit user-confirmed answers keyed by clarification question ID.'),
|
|
186
|
-
},
|
|
187
|
-
}, safeTracked('clarify_requirements', async (args) => handleClarifyRequirements(args, server)));
|
|
188
161
|
// 5. create_spec
|
|
189
162
|
server.registerTool('create_spec', {
|
|
190
163
|
description: t('tools.create_spec.description'),
|
|
@@ -432,6 +405,24 @@ export function registerCoreSpecTools(server) {
|
|
|
432
405
|
.max(10_000)
|
|
433
406
|
.optional()
|
|
434
407
|
.describe('Optional notes for each transition.'),
|
|
408
|
+
evidence: z
|
|
409
|
+
.record(z.string(), z.object({
|
|
410
|
+
modelTierUsed: z
|
|
411
|
+
.enum(['max', 'implementation', 'review'])
|
|
412
|
+
.optional()
|
|
413
|
+
.describe('Model tier used for this spec.'),
|
|
414
|
+
modelId: z.string().optional().describe('Model ID used for this spec.'),
|
|
415
|
+
contextHash: z.string().optional().describe('Context hash for this spec.'),
|
|
416
|
+
handoffPath: z.string().optional().describe('Handoff artifact path for this spec.'),
|
|
417
|
+
handoffArtifactId: z
|
|
418
|
+
.string()
|
|
419
|
+
.optional()
|
|
420
|
+
.describe('Handoff artifact ID for this spec.'),
|
|
421
|
+
reviewedBy: z.string().optional().describe('Reviewer identity for this spec.'),
|
|
422
|
+
arbitratedBy: z.string().optional().describe('Arbitrator identity for this spec.'),
|
|
423
|
+
}))
|
|
424
|
+
.optional()
|
|
425
|
+
.describe('Per-spec model-routing evidence keyed by spec ID. Required for status approved or implementing: each entry supplies modelTierUsed, modelId, contextHash and handoffPath for that spec.'),
|
|
435
426
|
},
|
|
436
427
|
}, safeTracked('update_status_batch', async (args) => handleUpdateStatusBatch(args)));
|
|
437
428
|
// 8. estimate
|
|
@@ -16,7 +16,7 @@ export { TokenIntelligencePeriodEnum, TokenIntelligenceGroupByEnum, TokenIntelli
|
|
|
16
16
|
export { ProjectGraphActionEnum, ProjectGraphQueryKindEnum } from './project-graph.js';
|
|
17
17
|
export { ConfigureLLMProvidersActionEnum, LoadBalancingStrategyEnum, } from './llm-provider-schemas.js';
|
|
18
18
|
export { PluginActionEnum } from './plugins-schemas.js';
|
|
19
|
-
export { ListSpecsOutputSchema, EstimateOutputSchema, ValidateOutputSchema, CheckReadinessOutputSchema, } from './output-schemas.js';
|
|
19
|
+
export { ListSpecsOutputSchema, EstimateOutputSchema, ValidateOutputSchema, CheckReadinessOutputSchema, PackageHandoffOutputSchema, } from './output-schemas.js';
|
|
20
20
|
export { CreatePRFromSpecSchema, PRStatusSchema, ReviewPRSchema, CreateReleaseSchema, GenerateChangelogSchema, } from './github.js';
|
|
21
21
|
export { SkillSearchInputSchema, SkillInstallInputSchema } from './skill-registry-schemas.js';
|
|
22
22
|
export { EcosystemStatusInputSchema } from './ecosystem-schemas.js';
|
|
@@ -17,7 +17,7 @@ export { TokenIntelligencePeriodEnum, TokenIntelligenceGroupByEnum, TokenIntelli
|
|
|
17
17
|
export { ProjectGraphActionEnum, ProjectGraphQueryKindEnum } from './project-graph.js';
|
|
18
18
|
export { ConfigureLLMProvidersActionEnum, LoadBalancingStrategyEnum, } from './llm-provider-schemas.js';
|
|
19
19
|
export { PluginActionEnum } from './plugins-schemas.js';
|
|
20
|
-
export { ListSpecsOutputSchema, EstimateOutputSchema, ValidateOutputSchema, CheckReadinessOutputSchema, } from './output-schemas.js';
|
|
20
|
+
export { ListSpecsOutputSchema, EstimateOutputSchema, ValidateOutputSchema, CheckReadinessOutputSchema, PackageHandoffOutputSchema, } from './output-schemas.js';
|
|
21
21
|
export { CreatePRFromSpecSchema, PRStatusSchema, ReviewPRSchema, CreateReleaseSchema, GenerateChangelogSchema, } from './github.js';
|
|
22
22
|
export { SkillSearchInputSchema, SkillInstallInputSchema } from './skill-registry-schemas.js';
|
|
23
23
|
export { EcosystemStatusInputSchema } from './ecosystem-schemas.js';
|
|
@@ -33,16 +33,7 @@ export declare const ListSpecsOutputSchema: {
|
|
|
33
33
|
totalReviewHours: z.ZodNumber;
|
|
34
34
|
totalCostUsd: z.ZodNumber;
|
|
35
35
|
}, z.core.$strip>;
|
|
36
|
-
teamSuggestion: z.ZodNullable<z.ZodObject<{
|
|
37
|
-
recommended: z.ZodBoolean;
|
|
38
|
-
reason: z.ZodString;
|
|
39
|
-
templateId: z.ZodString;
|
|
40
|
-
teamSize: z.ZodNumber;
|
|
41
|
-
specs: z.ZodArray<z.ZodString>;
|
|
42
|
-
toolCalls: z.ZodArray<z.ZodString>;
|
|
43
|
-
}, z.core.$strip>>;
|
|
44
36
|
message: z.ZodString;
|
|
45
|
-
teamDistributionHint: z.ZodOptional<z.ZodString>;
|
|
46
37
|
humanSummary: z.ZodOptional<z.ZodString>;
|
|
47
38
|
branchInfo: z.ZodOptional<z.ZodObject<{
|
|
48
39
|
current: z.ZodString;
|
|
@@ -126,16 +117,7 @@ export declare const ListSpecsOutputObjectSchema: z.ZodObject<{
|
|
|
126
117
|
totalReviewHours: z.ZodNumber;
|
|
127
118
|
totalCostUsd: z.ZodNumber;
|
|
128
119
|
}, z.core.$strip>;
|
|
129
|
-
teamSuggestion: z.ZodNullable<z.ZodObject<{
|
|
130
|
-
recommended: z.ZodBoolean;
|
|
131
|
-
reason: z.ZodString;
|
|
132
|
-
templateId: z.ZodString;
|
|
133
|
-
teamSize: z.ZodNumber;
|
|
134
|
-
specs: z.ZodArray<z.ZodString>;
|
|
135
|
-
toolCalls: z.ZodArray<z.ZodString>;
|
|
136
|
-
}, z.core.$strip>>;
|
|
137
120
|
message: z.ZodString;
|
|
138
|
-
teamDistributionHint: z.ZodOptional<z.ZodString>;
|
|
139
121
|
humanSummary: z.ZodOptional<z.ZodString>;
|
|
140
122
|
branchInfo: z.ZodOptional<z.ZodObject<{
|
|
141
123
|
current: z.ZodString;
|
|
@@ -217,6 +199,7 @@ export declare const EstimateOutputSchema: {
|
|
|
217
199
|
calibrationApplied: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
218
200
|
};
|
|
219
201
|
export { ValidateCompletionOutputSchema, ValidateOutputSchema } from './validate-output-schema.js';
|
|
202
|
+
export { PackageHandoffOutputSchema } from './package-handoff-output-schema.js';
|
|
220
203
|
export declare const CheckReadinessOutputSchema: {
|
|
221
204
|
specId: z.ZodString;
|
|
222
205
|
score: z.ZodNumber;
|
|
@@ -39,18 +39,7 @@ export const ListSpecsOutputSchema = {
|
|
|
39
39
|
totalReviewHours: z.number(),
|
|
40
40
|
totalCostUsd: z.number(),
|
|
41
41
|
}),
|
|
42
|
-
teamSuggestion: z
|
|
43
|
-
.object({
|
|
44
|
-
recommended: z.boolean(),
|
|
45
|
-
reason: z.string(),
|
|
46
|
-
templateId: z.string(),
|
|
47
|
-
teamSize: z.number(),
|
|
48
|
-
specs: z.array(z.string()),
|
|
49
|
-
toolCalls: z.array(z.string()),
|
|
50
|
-
})
|
|
51
|
-
.nullable(),
|
|
52
42
|
message: z.string(),
|
|
53
|
-
teamDistributionHint: z.string().optional(),
|
|
54
43
|
humanSummary: z.string().optional(),
|
|
55
44
|
branchInfo: z
|
|
56
45
|
.object({
|
|
@@ -142,6 +131,7 @@ export const EstimateOutputSchema = {
|
|
|
142
131
|
};
|
|
143
132
|
// ── validate ────────────────────────────────────────────────────────────────
|
|
144
133
|
export { ValidateCompletionOutputSchema, ValidateOutputSchema } from './validate-output-schema.js';
|
|
134
|
+
export { PackageHandoffOutputSchema } from './package-handoff-output-schema.js';
|
|
145
135
|
// ── check_readiness ─────────────────────────────────────────────────────────
|
|
146
136
|
export const CheckReadinessOutputSchema = {
|
|
147
137
|
specId: z.string(),
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Exact public structured-output contract for the package_handoff MCP tool submission ack. */
|
|
3
|
+
export declare const PackageHandoffOutputSchema: {
|
|
4
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
5
|
+
operationId: z.ZodString;
|
|
6
|
+
projectId: z.ZodString;
|
|
7
|
+
workspaceId: z.ZodString;
|
|
8
|
+
state: z.ZodEnum<{
|
|
9
|
+
accepted: "accepted";
|
|
10
|
+
cancelled: "cancelled";
|
|
11
|
+
checkpointed: "checkpointed";
|
|
12
|
+
completed: "completed";
|
|
13
|
+
"dead-letter": "dead-letter";
|
|
14
|
+
failed: "failed";
|
|
15
|
+
running: "running";
|
|
16
|
+
}>;
|
|
17
|
+
submittedAt: z.ZodISODateTime;
|
|
18
|
+
attachedAt: z.ZodISODateTime;
|
|
19
|
+
reused: z.ZodBoolean;
|
|
20
|
+
cursor: z.ZodString;
|
|
21
|
+
queue: z.ZodObject<{
|
|
22
|
+
status: z.ZodEnum<{
|
|
23
|
+
active: "active";
|
|
24
|
+
queued: "queued";
|
|
25
|
+
terminal: "terminal";
|
|
26
|
+
}>;
|
|
27
|
+
position: z.ZodNullable<z.ZodNumber>;
|
|
28
|
+
aheadCount: z.ZodNumber;
|
|
29
|
+
capacity: z.ZodNumber;
|
|
30
|
+
remainingBudgetMs: z.ZodNumber;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
terminalStates: z.ZodTuple<[z.ZodLiteral<"completed">, z.ZodLiteral<"failed">, z.ZodLiteral<"cancelled">, z.ZodLiteral<"dead-letter">], null>;
|
|
33
|
+
resultSchema: z.ZodLiteral<"package-handoff-completion/v1">;
|
|
34
|
+
observation: z.ZodObject<{
|
|
35
|
+
get: z.ZodLiteral<"get_job">;
|
|
36
|
+
restart: z.ZodLiteral<"restart_job">;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
recoveryAction: z.ZodOptional<z.ZodLiteral<"restart_job">>;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=package-handoff-output-schema.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Exact public structured-output contract for the package_handoff MCP tool submission ack. */
|
|
3
|
+
export const PackageHandoffOutputSchema = {
|
|
4
|
+
schemaVersion: z.literal(1).describe('Ack schema version.'),
|
|
5
|
+
operationId: z
|
|
6
|
+
.string()
|
|
7
|
+
.min(1)
|
|
8
|
+
.max(128)
|
|
9
|
+
.describe('Deterministic durable job id, form handoff-<sha256 hex>.'),
|
|
10
|
+
projectId: z.string().min(1).max(128).describe('Canonical project identity.'),
|
|
11
|
+
workspaceId: z.string().min(1).max(128).describe('Durable job workspace scope.'),
|
|
12
|
+
state: z
|
|
13
|
+
.enum([
|
|
14
|
+
'accepted',
|
|
15
|
+
'running',
|
|
16
|
+
'checkpointed',
|
|
17
|
+
'completed',
|
|
18
|
+
'failed',
|
|
19
|
+
'cancelled',
|
|
20
|
+
'dead-letter',
|
|
21
|
+
])
|
|
22
|
+
.describe('Current durable job state at submission or reuse time.'),
|
|
23
|
+
submittedAt: z.iso.datetime().describe('When this job was first accepted.'),
|
|
24
|
+
attachedAt: z.iso.datetime().describe('When this request attached to the job.'),
|
|
25
|
+
reused: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.describe('True when this request attached to an existing job instead of inserting a new one.'),
|
|
28
|
+
cursor: z
|
|
29
|
+
.string()
|
|
30
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
31
|
+
.describe('Content-derived observation cursor.'),
|
|
32
|
+
queue: z.object({
|
|
33
|
+
status: z.enum(['active', 'queued', 'terminal']).describe('Queue lifecycle bucket.'),
|
|
34
|
+
position: z
|
|
35
|
+
.number()
|
|
36
|
+
.int()
|
|
37
|
+
.positive()
|
|
38
|
+
.nullable()
|
|
39
|
+
.describe('1-based queue position, null once terminal.'),
|
|
40
|
+
aheadCount: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.nonnegative()
|
|
44
|
+
.describe('Jobs ahead of this one in the same scope.'),
|
|
45
|
+
capacity: z.number().int().positive().describe('Worker concurrency capacity for this scope.'),
|
|
46
|
+
remainingBudgetMs: z.number().int().nonnegative().describe('Remaining execution budget in ms.'),
|
|
47
|
+
}),
|
|
48
|
+
terminalStates: z
|
|
49
|
+
.tuple([
|
|
50
|
+
z.literal('completed'),
|
|
51
|
+
z.literal('failed'),
|
|
52
|
+
z.literal('cancelled'),
|
|
53
|
+
z.literal('dead-letter'),
|
|
54
|
+
])
|
|
55
|
+
.describe('The states get_job should treat as terminal.'),
|
|
56
|
+
resultSchema: z
|
|
57
|
+
.literal('package-handoff-completion/v1')
|
|
58
|
+
.describe('Result payload schema id once completed.'),
|
|
59
|
+
observation: z.object({
|
|
60
|
+
get: z.literal('get_job').describe('Tool to poll for job progress and result.'),
|
|
61
|
+
restart: z.literal('restart_job').describe('Tool to reactivate a terminal-failed job.'),
|
|
62
|
+
}),
|
|
63
|
+
recoveryAction: z
|
|
64
|
+
.literal('restart_job')
|
|
65
|
+
.optional()
|
|
66
|
+
.describe('Present when the reused job ended terminal-failed/cancelled/dead-letter and needs restart_job.'),
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=package-handoff-output-schema.js.map
|
|
@@ -252,6 +252,7 @@ export declare const ValidateOutputSchema: {
|
|
|
252
252
|
}>;
|
|
253
253
|
submittedAt: z.ZodISODateTime;
|
|
254
254
|
attachedAt: z.ZodISODateTime;
|
|
255
|
+
reused: z.ZodBoolean;
|
|
255
256
|
cursor: z.ZodString;
|
|
256
257
|
queue: z.ZodObject<{
|
|
257
258
|
status: z.ZodEnum<{
|
|
@@ -268,8 +269,6 @@ export declare const ValidateOutputSchema: {
|
|
|
268
269
|
resultSchema: z.ZodLiteral<"validate-completion/v1">;
|
|
269
270
|
observation: z.ZodObject<{
|
|
270
271
|
get: z.ZodLiteral<"get_job">;
|
|
271
|
-
watch: z.ZodLiteral<"watch_job">;
|
|
272
|
-
cancel: z.ZodLiteral<"cancel_job">;
|
|
273
272
|
restart: z.ZodLiteral<"restart_job">;
|
|
274
273
|
}, z.core.$strip>;
|
|
275
274
|
};
|
|
@@ -197,6 +197,9 @@ export const ValidateOutputSchema = {
|
|
|
197
197
|
state: z.enum(['accepted', 'running', 'checkpointed']),
|
|
198
198
|
submittedAt: z.iso.datetime(),
|
|
199
199
|
attachedAt: z.iso.datetime(),
|
|
200
|
+
reused: z
|
|
201
|
+
.boolean()
|
|
202
|
+
.describe('True when this request attached to an already-running validation job instead of dispatching new work.'),
|
|
200
203
|
cursor: z.string().regex(/^[a-f0-9]{64}$/),
|
|
201
204
|
queue: z.object({
|
|
202
205
|
status: z.enum(['active', 'queued', 'terminal']),
|
|
@@ -214,8 +217,6 @@ export const ValidateOutputSchema = {
|
|
|
214
217
|
resultSchema: z.literal('validate-completion/v1'),
|
|
215
218
|
observation: z.object({
|
|
216
219
|
get: z.literal('get_job'),
|
|
217
|
-
watch: z.literal('watch_job'),
|
|
218
|
-
cancel: z.literal('cancel_job'),
|
|
219
220
|
restart: z.literal('restart_job'),
|
|
220
221
|
}),
|
|
221
222
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// tools/session-checkpoint.ts — Manual trigger for session checkpoint (SPEC-563).
|
|
2
|
-
import {
|
|
2
|
+
import { getSessionTracker } from '../engine/session/session-tracker.js';
|
|
3
3
|
import { writeCheckpoint } from '../engine/session/checkpoint-writer.js';
|
|
4
4
|
import { compactResult } from './output-formatter.js';
|
|
5
5
|
/**
|
|
@@ -7,7 +7,7 @@ import { compactResult } from './output-formatter.js';
|
|
|
7
7
|
* Writes a checkpoint immediately regardless of the call-count threshold.
|
|
8
8
|
*/
|
|
9
9
|
export async function handleSessionCheckpoint(args) {
|
|
10
|
-
const snapshot =
|
|
10
|
+
const snapshot = getSessionTracker(args.projectPath).getSnapshot();
|
|
11
11
|
await writeCheckpoint(args.projectPath, snapshot);
|
|
12
12
|
return compactResult(`Session checkpoint written to ${args.projectPath}/planu/.runtime/session-context.md\n` +
|
|
13
13
|
`Calls recorded: ${String(snapshot.callCount)}, ` +
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type { SyncReport } from '../types/index.js';
|
|
2
|
+
import type { SyncReport, SyncSpecStateOptions } from '../types/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Sync spec state for a single project.
|
|
5
5
|
* Reads YAML frontmatter from spec.md files and reconciles divergences into the store.
|
|
6
6
|
*/
|
|
7
|
-
export declare function syncSpecState(projectPath: string, projectId: string): Promise<SyncReport>;
|
|
7
|
+
export declare function syncSpecState(projectPath: string, projectId: string, options?: SyncSpecStateOptions): Promise<SyncReport>;
|
|
8
8
|
/**
|
|
9
9
|
* Startup sync: iterates all registered projects and calls syncSpecState for each.
|
|
10
10
|
* Non-blocking — errors are logged but not propagated.
|
|
@@ -20,7 +20,8 @@ import { readFile, stat } from 'node:fs/promises';
|
|
|
20
20
|
* Sync spec state for a single project.
|
|
21
21
|
* Reads YAML frontmatter from spec.md files and reconciles divergences into the store.
|
|
22
22
|
*/
|
|
23
|
-
export async function syncSpecState(projectPath, projectId) {
|
|
23
|
+
export async function syncSpecState(projectPath, projectId, options = {}) {
|
|
24
|
+
const { applyTransitions = true } = options;
|
|
24
25
|
let dataEntries;
|
|
25
26
|
try {
|
|
26
27
|
const specs = await listSpecs(projectId);
|
|
@@ -109,6 +110,14 @@ export async function syncSpecState(projectPath, projectId) {
|
|
|
109
110
|
report.synced += 1;
|
|
110
111
|
continue;
|
|
111
112
|
}
|
|
113
|
+
if (!applyTransitions) {
|
|
114
|
+
report.rejected.push({ specId, reason: refusalReason });
|
|
115
|
+
const idx = report.divergences.findIndex((d) => d.specId === specId);
|
|
116
|
+
if (idx !== -1) {
|
|
117
|
+
report.divergences.splice(idx, 1);
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
112
121
|
try {
|
|
113
122
|
const result = await handleUpdateStatus({
|
|
114
123
|
specId,
|
|
@@ -205,13 +214,24 @@ export async function startupSync() {
|
|
|
205
214
|
}
|
|
206
215
|
await Promise.all(projects.map(async (project) => {
|
|
207
216
|
try {
|
|
208
|
-
await syncSpecState(project.path, project.hash
|
|
217
|
+
const report = await syncSpecState(project.path, project.hash, {
|
|
218
|
+
applyTransitions: false,
|
|
219
|
+
});
|
|
220
|
+
if (report.rejected.length > 0) {
|
|
221
|
+
console.error(`[Planu] startupSync: ${project.path} has ${report.rejected.length} spec status divergence(s) reported read-only:`, report.rejected);
|
|
222
|
+
}
|
|
209
223
|
}
|
|
210
224
|
catch (err) {
|
|
211
225
|
console.error(`[Planu] startupSync: failed to sync project ${project.path}:`, err);
|
|
212
226
|
}
|
|
213
227
|
try {
|
|
214
|
-
await cleanEphemeralArtifacts({
|
|
228
|
+
const cleanupResult = await cleanEphemeralArtifacts({
|
|
229
|
+
projectPath: project.path,
|
|
230
|
+
dryRun: true,
|
|
231
|
+
});
|
|
232
|
+
if (cleanupResult.wouldDelete.length > 0) {
|
|
233
|
+
console.error(`[Planu] startupSync: ${project.path} has ${cleanupResult.wouldDelete.length} ephemeral artifact(s) that would be deleted (run housekeeping-sweep to apply):`, cleanupResult.wouldDelete);
|
|
234
|
+
}
|
|
215
235
|
}
|
|
216
236
|
catch (err) {
|
|
217
237
|
console.error(`[Planu] startupSync: failed to clean spec artifacts ${project.path}:`, err);
|
|
@@ -38,14 +38,13 @@ import { handleIdeConfig } from '../ide-config-handler.js';
|
|
|
38
38
|
import { IdeTargetEnum, IdeConfigScopeEnum } from '../schemas/ide-config.js';
|
|
39
39
|
import { handleReconcileSpecLiving } from '../reconcile-spec-living-handler.js';
|
|
40
40
|
import { handleSecurityReport } from '../security-report-handler.js';
|
|
41
|
-
import { handleFeedbackStatus, handleResolveFeedback, handleSubmitFeedback, handleSyncFeedback, handleTriageFeedback, } from '../feedback-handler.js';
|
|
42
41
|
import { handleDogfoodWatch } from '../dogfood-watch.js';
|
|
43
42
|
import { SecurityReportTimeRangeEnum, SecurityReportFormatEnum, } from '../schemas/runtime-security.js';
|
|
44
43
|
import { RenderSpecForProviderInputSchema, handleRenderSpecForProvider, } from '../render-spec-for-provider.js';
|
|
45
44
|
import { handleTriageRequest, TriageRequestInputSchema } from '../triage-request.js';
|
|
46
45
|
import { handleStoragePaths } from '../storage-paths-handler.js';
|
|
47
46
|
import { handleStorageExport, handleStorageImport } from '../storage-bundle-handler.js';
|
|
48
|
-
import {
|
|
47
|
+
import { handleGetJob, handleRestartJob } from '../jobs/handlers.js';
|
|
49
48
|
// ── Registry ─────────────────────────────────────────────────────────────────
|
|
50
49
|
const coreToolsRegistry = [
|
|
51
50
|
{
|
|
@@ -81,48 +80,6 @@ const coreToolsRegistry = [
|
|
|
81
80
|
wrap: 'safe',
|
|
82
81
|
group: 'infrastructure',
|
|
83
82
|
},
|
|
84
|
-
{
|
|
85
|
-
name: 'watch_job',
|
|
86
|
-
description: 'Wait up to 30 seconds for a durable Planu job to change or reach a terminal state.',
|
|
87
|
-
schema: {
|
|
88
|
-
operationId: z.string().trim().min(1).max(128),
|
|
89
|
-
projectId: z.string().trim().min(1).max(128),
|
|
90
|
-
workspaceId: z.string().trim().min(1).max(128).optional(),
|
|
91
|
-
afterCursor: z
|
|
92
|
-
.string()
|
|
93
|
-
.regex(/^[a-f0-9]{64}$/)
|
|
94
|
-
.optional(),
|
|
95
|
-
timeoutMs: z.number().int().min(0).max(30_000).optional(),
|
|
96
|
-
},
|
|
97
|
-
handler: handleWatchJob,
|
|
98
|
-
annotations: {
|
|
99
|
-
title: 'Watch Durable Job',
|
|
100
|
-
readOnlyHint: true,
|
|
101
|
-
destructiveHint: false,
|
|
102
|
-
openWorldHint: false,
|
|
103
|
-
},
|
|
104
|
-
wrap: 'safe',
|
|
105
|
-
group: 'infrastructure',
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
name: 'cancel_job',
|
|
109
|
-
description: 'Durably cancel a Planu job and fence any worker that still holds its former lease.',
|
|
110
|
-
schema: {
|
|
111
|
-
operationId: z.string().trim().min(1).max(128),
|
|
112
|
-
projectId: z.string().trim().min(1).max(128),
|
|
113
|
-
workspaceId: z.string().trim().min(1).max(128).optional(),
|
|
114
|
-
},
|
|
115
|
-
handler: handleCancelJob,
|
|
116
|
-
annotations: {
|
|
117
|
-
title: 'Cancel Durable Job',
|
|
118
|
-
readOnlyHint: false,
|
|
119
|
-
destructiveHint: true,
|
|
120
|
-
idempotentHint: true,
|
|
121
|
-
openWorldHint: false,
|
|
122
|
-
},
|
|
123
|
-
wrap: 'safe',
|
|
124
|
-
group: 'infrastructure',
|
|
125
|
-
},
|
|
126
83
|
{
|
|
127
84
|
name: 'restart_job',
|
|
128
85
|
description: 'Restart a cancelled or failed durable job and schedule its typed executor.',
|
|
@@ -899,102 +856,6 @@ const coreToolsRegistry = [
|
|
|
899
856
|
wrap: 'tracked',
|
|
900
857
|
group: 'core',
|
|
901
858
|
},
|
|
902
|
-
// ── feedback hub (SPEC-188, SPEC-1100) ───────────────────────────────────
|
|
903
|
-
{
|
|
904
|
-
name: 'submit_feedback',
|
|
905
|
-
description: 'Submit user feedback or a bug report to Planu Feedback Hub. Always persists locally first, then attempts privacy-bounded remote registration with the central feedback intake.',
|
|
906
|
-
schema: {
|
|
907
|
-
type: z
|
|
908
|
-
.enum(['bug', 'feature', 'suggestion', 'dx'])
|
|
909
|
-
.describe('Feedback type: bug | feature | suggestion | dx'),
|
|
910
|
-
title: z.string().min(1).max(200).describe('Short feedback title'),
|
|
911
|
-
description: z.string().min(1).max(5000).describe('Detailed feedback description'),
|
|
912
|
-
context: z
|
|
913
|
-
.object({
|
|
914
|
-
projectPath: z.string().max(4096).optional(),
|
|
915
|
-
currentFile: z.string().max(4096).optional(),
|
|
916
|
-
errorMessage: z.string().max(2000).optional(),
|
|
917
|
-
stack: z.string().max(8000).optional(),
|
|
918
|
-
})
|
|
919
|
-
.optional()
|
|
920
|
-
.describe('Optional local-only context; sensitive path fields are not sent remotely.'),
|
|
921
|
-
},
|
|
922
|
-
handler: async (args) => handleSubmitFeedback(args),
|
|
923
|
-
annotations: {
|
|
924
|
-
title: 'Submit Feedback',
|
|
925
|
-
readOnlyHint: false,
|
|
926
|
-
destructiveHint: false,
|
|
927
|
-
openWorldHint: true,
|
|
928
|
-
},
|
|
929
|
-
wrap: 'tracked',
|
|
930
|
-
group: 'feedback',
|
|
931
|
-
},
|
|
932
|
-
{
|
|
933
|
-
name: 'triage_feedback',
|
|
934
|
-
description: 'Group pending local feedback by similarity so maintainers can decide whether to create specs, merge duplicates, or dismiss items.',
|
|
935
|
-
schema: {
|
|
936
|
-
filter: z
|
|
937
|
-
.enum(['bug', 'feature', 'suggestion', 'dx'])
|
|
938
|
-
.optional()
|
|
939
|
-
.describe('Optional feedback type filter'),
|
|
940
|
-
},
|
|
941
|
-
handler: async (args) => Promise.resolve(handleTriageFeedback(args)),
|
|
942
|
-
annotations: { title: 'Triage Feedback', readOnlyHint: true },
|
|
943
|
-
wrap: 'tracked',
|
|
944
|
-
group: 'feedback',
|
|
945
|
-
},
|
|
946
|
-
{
|
|
947
|
-
name: 'resolve_feedback',
|
|
948
|
-
description: 'Mark a local feedback item as resolved and optionally link it to a Planu spec, PR URL, and resolution notes.',
|
|
949
|
-
schema: {
|
|
950
|
-
feedbackId: z.string().min(1).max(50).describe('Local feedback ID, e.g. FB-001'),
|
|
951
|
-
specId: z.string().max(50).optional().describe('Optional linked Planu spec ID'),
|
|
952
|
-
prUrl: z.url().optional().describe('Optional pull request URL'),
|
|
953
|
-
notes: z.string().max(2000).optional().describe('Optional resolution notes'),
|
|
954
|
-
},
|
|
955
|
-
handler: async (args) => handleResolveFeedback(args),
|
|
956
|
-
annotations: { title: 'Resolve Feedback', readOnlyHint: false, destructiveHint: false },
|
|
957
|
-
wrap: 'tracked',
|
|
958
|
-
group: 'feedback',
|
|
959
|
-
},
|
|
960
|
-
{
|
|
961
|
-
name: 'sync_feedback',
|
|
962
|
-
description: 'Retry remote Supabase registration for local feedback entries whose delivery is pending or failed. Does not accept remote row IDs or perform direct SQL/Data API writes.',
|
|
963
|
-
schema: {
|
|
964
|
-
projectPath: z.string().max(4096).optional().describe('Absolute path to project root'),
|
|
965
|
-
includeSynced: z
|
|
966
|
-
.boolean()
|
|
967
|
-
.optional()
|
|
968
|
-
.describe('When true, also reprocess entries already marked synced. Default false.'),
|
|
969
|
-
limit: z
|
|
970
|
-
.number()
|
|
971
|
-
.int()
|
|
972
|
-
.positive()
|
|
973
|
-
.max(500)
|
|
974
|
-
.optional()
|
|
975
|
-
.describe('Maximum number of local entries to process.'),
|
|
976
|
-
},
|
|
977
|
-
handler: async (args) => handleSyncFeedback(args),
|
|
978
|
-
annotations: {
|
|
979
|
-
title: 'Sync Feedback',
|
|
980
|
-
readOnlyHint: false,
|
|
981
|
-
destructiveHint: false,
|
|
982
|
-
openWorldHint: true,
|
|
983
|
-
},
|
|
984
|
-
wrap: 'tracked',
|
|
985
|
-
group: 'feedback',
|
|
986
|
-
},
|
|
987
|
-
{
|
|
988
|
-
name: 'feedback_status',
|
|
989
|
-
description: 'Show aggregate local feedback totals and remote delivery health without exposing descriptions, file paths, user identifiers, or secrets.',
|
|
990
|
-
schema: {
|
|
991
|
-
projectPath: z.string().max(4096).optional().describe('Absolute path to project root'),
|
|
992
|
-
},
|
|
993
|
-
handler: async (args) => Promise.resolve(handleFeedbackStatus(args)),
|
|
994
|
-
annotations: { title: 'Feedback Status', readOnlyHint: true },
|
|
995
|
-
wrap: 'tracked',
|
|
996
|
-
group: 'feedback',
|
|
997
|
-
},
|
|
998
859
|
{
|
|
999
860
|
name: 'dogfood_watch',
|
|
1000
861
|
description: 'Analyze recent local Planu runtime evidence and surface actionable dogfooding gaps such as repeated tool failures, persisted version drift, guard fallback leakage, and stale local compatibility mirrors.',
|