agentstatedeveloper_mcp/mcp_params.rs
1//! MCP tool parameter types (Plan M t-002, 1.0.92).
2//!
3//! Extracted from `mcp_server.rs` to make the handler file scannable.
4//! Each struct is a typed shape for one MCP tool's arguments —
5//! `Deserialize` so rmcp can parse the incoming JSON, `JsonSchema` so
6//! rmcp can serve the tool's parameter schema to the agent.
7//!
8//! Naming-convention notes preserved at the bottom of this file
9//! (was at the same position in mcp_server.rs).
10//!
11//! No behavior change in this extraction; pure relocation.
12
13use schemars::JsonSchema;
14use serde::Deserialize;
15
16#[derive(Deserialize, JsonSchema)]
17pub struct CodeQueryParams {
18 /// Substring match on qualified name.
19 pub name_contains: Option<String>,
20 /// Filter by symbol kind: module, function, method, class, variable.
21 pub kind: Option<String>,
22 /// Filter by language (e.g. "python").
23 pub language: Option<String>,
24 /// Max results to return (default: 50).
25 #[serde(default = "default_limit")]
26 pub limit: u32,
27}
28
29#[derive(Deserialize, JsonSchema)]
30pub struct CodeSearchParams {
31 /// Concept or keyword(s) to search for. BM25-ranked via FTS5.
32 /// Supports inline exclusion syntax: "drift playhead -sample -waveform".
33 pub query: String,
34 /// Filter by symbol kind: module, function, method, class, variable.
35 pub kind: Option<String>,
36 /// Filter by language (e.g. "swift", "python", "typescript", "rust").
37 pub language: Option<String>,
38 /// Max results to return (default: 20).
39 #[serde(default = "default_search_limit")]
40 pub limit: u32,
41 /// Include test-file symbols in results (default: false — tests excluded so
42 /// production entry points rank first).
43 #[serde(default)]
44 pub include_tests: bool,
45 /// Restrict to test symbols only. Overrides include_tests when true.
46 /// Use when classifying test coverage or auditing test layout.
47 #[serde(default)]
48 pub tests_only: bool,
49 /// Comma-separated terms to exclude (e.g. "sample editor,waveform").
50 pub exclude: Option<String>,
51 /// Comma-separated glob patterns to restrict to specific paths (e.g. "App/**/DriftPad*").
52 pub paths: Option<String>,
53 /// Named scope alias from .asd/scopes.toml (e.g. "drift-pad").
54 pub scope: Option<String>,
55}
56
57fn default_search_limit() -> u32 {
58 20
59}
60
61#[derive(Deserialize, JsonSchema)]
62pub struct ReferencesParams {
63 /// Symbol name to find references for. Pass a qname (e.g. `pkg.mod.Type`)
64 /// for exact definition lookup, or a bare identifier (e.g. `MasterBusParams`)
65 /// to match any symbol whose qname ends with `.<name>` plus all literal
66 /// text occurrences in the worktree.
67 pub name: String,
68 /// Project root for the rg scan. Defaults to the current directory.
69 pub path: Option<String>,
70 /// Cap the number of occurrences returned (default: 500, 0 = unlimited).
71 #[serde(default = "default_references_limit")]
72 pub limit: u32,
73 /// Optional rg `--glob` filter, e.g. "**/*.swift". Comma-separated for multiple.
74 pub globs: Option<String>,
75}
76
77fn default_references_limit() -> u32 {
78 500
79}
80
81#[derive(Deserialize, JsonSchema)]
82pub struct ConclusionsListParams {
83 /// Restrict to one conclusion class: decisions | classifications |
84 /// mappings | hazards | recipes | followups. Omit to list all six.
85 pub class: Option<String>,
86 /// Restrict to one symbol qname. Omit to list across all symbols.
87 pub symbol: Option<String>,
88}
89
90#[derive(Deserialize, JsonSchema)]
91pub struct ConclusionsExportParams {
92 /// Output directory for the JSONL files. Defaults to `.asd/conclusions/`
93 /// relative to the database parent directory.
94 pub out: Option<String>,
95}
96
97#[derive(Deserialize, JsonSchema)]
98pub struct ConclusionsImportParams {
99 /// Input directory containing `*.jsonl` files. Defaults to
100 /// `.asd/conclusions/` relative to the database parent directory.
101 #[serde(rename = "in")]
102 pub in_dir: Option<String>,
103}
104
105#[derive(Deserialize, JsonSchema)]
106pub struct RecipeClassifyTestMigrationParams {
107 /// Search query — finds candidate test symbols.
108 pub query: String,
109 /// Max candidates to classify (default: 50).
110 #[serde(default = "default_recipe_limit")]
111 pub limit: u32,
112}
113
114fn default_recipe_limit() -> u32 {
115 50
116}
117
118// -- Plan G t-003: agent-thinking write surface ------------------------------
119
120#[derive(Deserialize, JsonSchema)]
121pub struct ThinkSpeculateParams {
122 pub qname: String,
123 /// Confidence in [0.0, 1.0]. Below 0.3 is excluded from prior_thinking
124 /// auto-surface by default.
125 pub confidence: f64,
126 pub summary: String,
127 pub body: Option<String>,
128}
129
130#[derive(Deserialize, JsonSchema)]
131pub struct ThinkModelParams {
132 pub name: String,
133 /// Comma-separated qnames the model spans (first is anchor).
134 pub symbols: String,
135 pub summary: String,
136}
137
138#[derive(Deserialize, JsonSchema)]
139pub struct ThinkFailedParams {
140 pub qname: String,
141 pub tried: String,
142 pub because: String,
143}
144
145#[derive(Deserialize, JsonSchema)]
146pub struct ThinkQuestionParams {
147 pub qname: String,
148 pub question: String,
149}
150
151#[derive(Deserialize, JsonSchema)]
152pub struct ThinkListParams {
153 /// Filter to one thinking kind: hypothesis | mental_model |
154 /// failed_attempt | open_question.
155 pub kind: Option<String>,
156 pub symbol: Option<String>,
157}
158
159#[derive(Deserialize, JsonSchema)]
160pub struct InvestigateParams {
161 /// Natural-language or keyword query.
162 /// Supports inline exclusion syntax: "drift playhead -sample -waveform".
163 pub query: String,
164 /// Number of top entry-point symbols to fully expand (default: 5).
165 #[serde(default = "default_investigate_depth")]
166 pub depth: u32,
167 /// Filter by symbol kind: module, function, method, class, variable.
168 pub kind: Option<String>,
169 /// Filter by language (e.g. "swift", "python", "typescript", "rust").
170 pub language: Option<String>,
171 /// Include test-file symbols as entry-point candidates (default: false).
172 #[serde(default)]
173 pub include_tests: bool,
174 /// Adjust output ordering and guidance for a specific intent.
175 /// Values: bugfix, feature, refactor, test, architecture, ui.
176 pub intent: Option<String>,
177 /// Comma-separated terms to exclude (e.g. "sample editor,waveform").
178 pub exclude: Option<String>,
179 /// Comma-separated glob patterns to restrict to specific paths.
180 pub paths: Option<String>,
181 /// Named scope alias from .asd/scopes.toml.
182 pub scope: Option<String>,
183}
184
185fn default_investigate_depth() -> u32 {
186 10
187}
188fn default_impact_depth() -> u32 {
189 3
190}
191fn default_git_depth() -> u32 {
192 20
193}
194fn default_checklist_depth() -> u32 {
195 10
196}
197fn default_test_depth() -> u32 {
198 2
199}
200fn default_prepare_depth() -> u32 {
201 10
202}
203fn default_prepare_git_depth() -> u32 {
204 10
205}
206
207#[derive(Deserialize, JsonSchema)]
208pub struct PrepareChangeParams {
209 /// Free-form description of the intended change (treated as a search query).
210 /// Supports inline exclusion syntax: "drift playhead -sample -waveform".
211 pub description: String,
212 /// Number of top entry-point symbols to expand (default: 7).
213 #[serde(default = "default_prepare_depth")]
214 pub depth: u32,
215 /// Filter by symbol kind.
216 pub kind: Option<String>,
217 /// Filter by language.
218 pub language: Option<String>,
219 /// Include test-file symbols as entry-point candidates (default: false).
220 #[serde(default)]
221 pub include_tests: bool,
222 /// Adjust output for a specific intent.
223 /// Values: bugfix, feature, refactor, test, architecture, ui.
224 pub intent: Option<String>,
225 /// BFS depth for finding affected tests from the top entry point (default: 2).
226 #[serde(default = "default_test_depth")]
227 pub test_depth: u32,
228 /// Number of recent git commits to scan per file (default: 10).
229 #[serde(default = "default_prepare_git_depth")]
230 pub git_depth: u32,
231 /// Comma-separated terms to exclude (e.g. "sample editor,waveform").
232 pub exclude: Option<String>,
233 /// Comma-separated glob patterns to restrict to specific paths.
234 pub paths: Option<String>,
235 /// Named scope alias from .asd/scopes.toml.
236 pub scope: Option<String>,
237 /// Active task context to enrich the query (e.g. a CTX task description).
238 /// Tokens are appended to the description before candidate scoring so the
239 /// result set is biased toward symbols relevant to the current task.
240 pub task_context: Option<String>,
241}
242
243#[derive(Deserialize, JsonSchema)]
244pub struct ChecklistParams {
245 /// Natural-language or keyword query.
246 /// Supports inline exclusion syntax: "drift playhead -sample -waveform".
247 pub query: String,
248 /// Number of top entry-point symbols to analyse (default: 5).
249 #[serde(default = "default_checklist_depth")]
250 pub depth: u32,
251 /// Filter by symbol kind.
252 pub kind: Option<String>,
253 /// Filter by language.
254 pub language: Option<String>,
255 /// Include test-file symbols as entry-point candidates (default: false).
256 #[serde(default)]
257 pub include_tests: bool,
258 /// Adjust checklist framing for a specific intent.
259 /// Values: bugfix, feature, refactor, test, architecture, ui.
260 pub intent: Option<String>,
261 /// Caller BFS depth for finding affected tests (default: 2).
262 #[serde(default = "default_test_depth")]
263 pub test_depth: u32,
264 /// Comma-separated terms to exclude (e.g. "sample editor,waveform").
265 pub exclude: Option<String>,
266 /// Comma-separated glob patterns to restrict to specific paths.
267 pub paths: Option<String>,
268 /// Named scope alias from .asd/scopes.toml.
269 pub scope: Option<String>,
270}
271
272#[derive(Deserialize, JsonSchema)]
273pub struct ImpactParams {
274 /// Fully-qualified symbol name to analyse.
275 pub qname: String,
276 /// Caller-graph traversal depth (default: 3).
277 #[serde(default = "default_impact_depth")]
278 pub depth: u32,
279 /// Number of recent git commits to look back per touched file (default: 20).
280 #[serde(default = "default_git_depth")]
281 pub git_depth: u32,
282}
283
284#[derive(Deserialize, JsonSchema)]
285pub struct HelpParams {
286 /// Feature name (e.g. "impact") or a phrase (e.g. "blast radius") to
287 /// fuzzy-match. Omit to get the full grouped catalog of every feature.
288 #[serde(default)]
289 pub topic: Option<String>,
290}
291
292#[derive(Deserialize, JsonSchema)]
293pub struct ArchitectureParams {
294 /// How many packages, hotspots, and clusters to list (default: 12).
295 #[serde(default = "default_arch_top")]
296 pub top: usize,
297}
298
299fn default_arch_top() -> usize {
300 12
301}
302
303#[derive(Deserialize, JsonSchema)]
304pub struct DeadCodeParams {
305 /// Max candidates to list; the total count is always reported (default: 50).
306 #[serde(default = "default_dead_limit")]
307 pub limit: usize,
308 /// Include test functions (excluded by default).
309 #[serde(default)]
310 pub include_tests: bool,
311}
312
313fn default_dead_limit() -> usize {
314 50
315}
316
317#[derive(Deserialize, JsonSchema)]
318pub struct SinceParams {
319 /// Base commit SHA (or branch/tag) to diff against HEAD.
320 pub sha: String,
321 /// Caller-graph BFS depth for blast radius (default: 3).
322 #[serde(default = "default_impact_depth")]
323 pub depth: u32,
324 /// Number of recent git commits to scan per changed file (default: 10).
325 #[serde(default = "default_since_git_depth")]
326 pub git_depth: u32,
327}
328
329fn default_since_git_depth() -> u32 {
330 10
331}
332
333#[derive(Deserialize, JsonSchema)]
334pub struct InvariantAddParams {
335 /// Fully-qualified symbol name.
336 pub qname: String,
337 /// One-line invariant summary.
338 pub summary: String,
339 /// Author identifier (default: "asd-mcp-agent").
340 #[serde(default = "default_author_id")]
341 pub author_id: String,
342}
343
344#[derive(Deserialize, JsonSchema)]
345pub struct InvariantListParams {
346 /// Filter to a single symbol's invariants. Omit to list all.
347 pub qname: Option<String>,
348}
349
350#[derive(Deserialize, JsonSchema)]
351pub struct FeedbackMarkParams {
352 /// The search query that produced this result.
353 pub query: String,
354 /// Fully-qualified symbol name being rated.
355 pub qname: String,
356 /// Verdict: "useful", "noisy", "missing", "wrong_layer",
357 /// "already_covered" (Plan C t-005), or "diagnostic_only" (Plan C t-005).
358 pub verdict: String,
359 /// Optional free-text note explaining the verdict.
360 pub note: Option<String>,
361 /// Agent/author identifier (default: "asd-mcp-agent").
362 #[serde(default = "default_author_id")]
363 pub author_id: String,
364 /// Plan E t-009: when verdict is "already_covered", the qname of
365 /// the symbol whose behavior covers this one. Auto-writes a paired
366 /// Mapping ledger entry alongside the FeedbackEntry.
367 pub covered_by: Option<String>,
368 /// Plan J t-014: optional expiry in days from now. After `now + N
369 /// days` the entry no longer influences ranking. Useful for
370 /// false-positive marks that should auto-decay.
371 pub ttl_days: Option<i64>,
372}
373
374#[derive(Deserialize, JsonSchema)]
375pub struct FeedbackListParams {
376 /// Filter to feedback for a specific symbol qname. Omit to list all.
377 pub qname: Option<String>,
378}
379
380#[derive(Deserialize, JsonSchema)]
381pub struct FeedbackWithdrawParams {
382 /// Entry id to retract, from `feedback_list`.
383 pub entry_id: String,
384 /// Who is retracting it. Recorded on the entry.
385 pub by: Option<String>,
386 /// Why. Free text, stored with the withdrawal.
387 pub reason: Option<String>,
388}
389
390#[derive(Deserialize, JsonSchema)]
391pub struct FeedbackPromoteParams {
392 /// Fully-qualified symbol name to promote.
393 pub qname: String,
394 /// The domain concept this symbol is the source-of-truth for (e.g. "Drift Pad playhead").
395 pub concept: String,
396 /// Agent/author identifier (default: "asd-mcp-agent").
397 #[serde(default = "default_author_id")]
398 pub author_id: String,
399}
400
401#[derive(Deserialize, JsonSchema)]
402pub struct CodeReadParams {
403 /// Fully-qualified symbol name.
404 pub qname: String,
405}
406
407#[derive(Deserialize, JsonSchema)]
408pub struct EffectsOfParams {
409 /// Fully-qualified symbol name.
410 pub qname: String,
411}
412
413#[derive(Deserialize, JsonSchema)]
414pub struct CallersOfParams {
415 /// Fully-qualified symbol name.
416 pub qname: String,
417}
418
419#[derive(Deserialize, JsonSchema)]
420pub struct CalleesOfParams {
421 /// Fully-qualified symbol name.
422 pub qname: String,
423}
424
425#[derive(Deserialize, JsonSchema)]
426pub struct LedgerGetParams {
427 /// Fully-qualified symbol name.
428 pub qname: String,
429 /// Include entries that have been superseded (default: false).
430 #[serde(default)]
431 pub include_superseded: bool,
432}
433
434#[derive(Deserialize, JsonSchema)]
435pub struct LedgerFindParams {
436 /// Filter by ledger kind (decision, assumption, constraint, rationale, hazard, tradeoff).
437 pub kind: Option<String>,
438 /// Filter by tag (must be present on entry).
439 pub tag: Option<String>,
440 /// Filter by author id.
441 pub author_id: Option<String>,
442 /// Max results to return (default: 50).
443 #[serde(default = "default_limit")]
444 pub limit: u32,
445}
446
447#[derive(Deserialize, JsonSchema)]
448pub struct LedgerAppendParams {
449 /// Fully-qualified symbol name this entry attaches to.
450 pub qname: String,
451 /// Ledger entry kind.
452 pub kind: String,
453 /// One-line summary.
454 pub summary: String,
455 /// Optional free-form body (markdown ok).
456 pub body: Option<String>,
457 /// Optional tags.
458 pub tags: Option<Vec<String>>,
459 /// Author kind: "agent" or "human" (default: "agent").
460 #[serde(default = "default_author_kind")]
461 pub author_kind: String,
462 /// Author id (default: "asd-mcp").
463 #[serde(default = "default_author_id")]
464 pub author_id: String,
465 /// Plan B t-002: optional classification role/intent tag
466 /// (e.g. "diagnostic-test", "fast-test", "fixture-path").
467 pub role: Option<String>,
468 /// Plan B t-002: optional canonical reproduction or validation command
469 /// (e.g. "swift test --filter SongPlayersTests").
470 pub command: Option<String>,
471}
472
473#[derive(Deserialize, JsonSchema)]
474pub struct LedgerApproveParams {
475 /// Entry id (returned by a prior `ledger_append` call).
476 pub entry_id: String,
477 /// Approver identifier — recorded on the entry as `approved-by:<id>`.
478 pub approver: String,
479 /// Approver kind. Must match an `approver:*` tag on the original
480 /// entry (e.g., "human", "senior_agent") unless `approver` itself
481 /// matches directly.
482 #[serde(default = "default_approver_kind_mcp")]
483 pub approver_kind: String,
484 /// Optional approver rationale — appended to the entry body as an
485 /// "Approver note" section.
486 #[serde(default)]
487 pub message: Option<String>,
488}
489
490#[derive(Deserialize, JsonSchema)]
491pub struct LedgerRejectParams {
492 /// Entry id to reject.
493 pub entry_id: String,
494 /// Reviewer id — recorded as `rejected-by:<id>`.
495 pub reviewer: String,
496 /// Reviewer kind. Same approver-match rule as approve.
497 #[serde(default = "default_approver_kind_mcp")]
498 pub reviewer_kind: String,
499 /// Rejection reason (required). Appended to the entry body.
500 pub reason: String,
501}
502
503#[derive(Deserialize, JsonSchema)]
504pub struct LedgerWithdrawParams {
505 /// Entry id to withdraw.
506 pub entry_id: String,
507 /// Author id — must match the original `entry.author.id`.
508 pub author_id: String,
509}
510
511#[derive(Deserialize, JsonSchema)]
512pub struct LedgerSupersedeParams {
513 /// Qname the new entry attaches to.
514 pub qname: String,
515 /// Entry ids superseded by the new entry.
516 pub supersedes: Vec<String>,
517 /// Ledger kind for the new entry (decision, rationale, hazard, …).
518 pub kind: String,
519 /// One-line summary.
520 pub summary: String,
521 /// Optional body.
522 #[serde(default)]
523 pub body: Option<String>,
524 /// Author kind (default: "agent").
525 #[serde(default = "default_author_kind")]
526 pub author_kind: String,
527 /// Author id (default: "asd-mcp").
528 #[serde(default = "default_author_id")]
529 pub author_id: String,
530}
531
532fn default_approver_kind_mcp() -> String {
533 "human".to_string()
534}
535
536#[derive(Deserialize, JsonSchema)]
537pub struct TracesOfParams {
538 /// Fully-qualified symbol name.
539 pub qname: String,
540 /// Maximum number of trace records to return (default 20).
541 #[serde(default)]
542 pub limit: Option<usize>,
543}
544
545#[derive(Deserialize, JsonSchema)]
546pub struct ReindexParams {
547 /// Absolute or relative path to a source file or directory to reindex.
548 /// Relative paths are resolved from the process working directory.
549 pub path: String,
550}
551
552#[derive(Deserialize, JsonSchema)]
553pub struct SyncParams {
554 /// Project root to sync into (`.asd/v1/` is appended). Defaults to the
555 /// directory of the active db.
556 #[serde(default)]
557 pub dir: Option<String>,
558 /// Also remove orphaned sidecar files for symbols that no longer exist.
559 #[serde(default)]
560 pub prune: bool,
561}
562
563#[derive(Deserialize, JsonSchema)]
564pub struct TestSummaryParams {
565 /// Raw test-runner output to summarize (cargo/pytest auto-detected; others
566 /// via a generic scan).
567 pub output: String,
568}
569
570#[derive(Deserialize, JsonSchema)]
571pub struct MapParams {
572 /// Return the summary without writing any Ownership ledger entries.
573 #[serde(default)]
574 pub dry_run: bool,
575}
576
577#[derive(Deserialize, JsonSchema)]
578pub struct LedgerRebindParams {
579 /// symbol_id of the old symbol whose ledger entries should be re-parented.
580 pub from_symbol_id: String,
581 /// Fully-qualified name of the new symbol to resolve and bind to.
582 pub to_qname: String,
583 /// Agent or user performing the rebind.
584 #[serde(default = "default_author_id")]
585 pub agent_id: String,
586}
587
588#[derive(Deserialize, JsonSchema)]
589pub struct AuditTailParams {
590 /// Substring match on event_type (e.g., `ledger.approve`,
591 /// `ledger.` for all ledger events).
592 #[serde(default)]
593 pub event_type: Option<String>,
594 /// Return only events AFTER this `event_id` (exclusive). Use for
595 /// incremental polling.
596 #[serde(default)]
597 pub since: Option<String>,
598 /// Exact match on actor_id.
599 #[serde(default)]
600 pub actor: Option<String>,
601 /// Exact match on outcome.
602 #[serde(default)]
603 pub outcome: Option<String>,
604 /// Max events to return (default 200, max 1000).
605 #[serde(default)]
606 pub limit: Option<u32>,
607}
608
609#[derive(Deserialize, JsonSchema)]
610pub struct EffectDeclareParams {
611 /// Fully-qualified symbol name.
612 pub qname: String,
613 /// List of declared effects. Each element is a JSON object matching the
614 /// `Effect` schema: `{ "effect": "<category>", "qualifiers": ..., "note": ... }`.
615 pub declared: Vec<serde_json::Value>,
616 /// Author id (default: "asd-mcp"). Surfaced to the policy gate so rules
617 /// can scope by agent identity.
618 #[serde(default = "default_author_id")]
619 pub author_id: String,
620}
621
622fn default_limit() -> u32 {
623 50
624}
625fn default_author_kind() -> String {
626 "agent".to_string()
627}
628fn default_author_id() -> String {
629 "asd-mcp".to_string()
630}
631
632// -- Scratch parameter types ------------------------------------------------
633
634#[derive(Deserialize, JsonSchema)]
635pub struct ScratchWriteParams {
636 /// Working notes content (markdown OK).
637 pub content: String,
638 /// Optional: qualified name of the symbol to attach this note to.
639 /// In planning mode, the symbol does not need to exist yet.
640 #[serde(default)]
641 pub symbol: Option<String>,
642 /// Optional: named investigation context (e.g. "tracing-sync-bug").
643 #[serde(default)]
644 pub workflow: Option<String>,
645 /// Optional: time-to-live in hours. When not set, no expiry.
646 #[serde(default)]
647 pub ttl_hours: Option<i64>,
648 /// Optional: freeform tags.
649 #[serde(default)]
650 pub tags: Option<Vec<String>>,
651 /// When true, marks this entry as pre-implementation planning notes.
652 /// Adds the "planning" tag automatically. Unresolved symbol names are
653 /// stored as-is rather than causing an error — useful for naming planned
654 /// symbols that do not exist in the index yet.
655 #[serde(default)]
656 pub planning: Option<bool>,
657}
658
659#[derive(Deserialize, JsonSchema)]
660pub struct ScratchListParams {
661 /// Filter by symbol qualified name.
662 #[serde(default)]
663 pub symbol: Option<String>,
664 /// Filter by workflow name.
665 #[serde(default)]
666 pub workflow: Option<String>,
667 /// Filter by session/agent_id.
668 #[serde(default)]
669 pub session: Option<String>,
670 /// Filter by status: "draft", "promoted", "discarded". Defaults to "draft".
671 #[serde(default)]
672 pub status: Option<String>,
673 /// Max results to return (default: 50).
674 #[serde(default = "default_limit")]
675 pub limit: u32,
676}
677
678#[derive(Deserialize, JsonSchema)]
679pub struct ScratchReadParams {
680 /// Scratch entry ID (`scr_…`).
681 pub scratch_id: String,
682}
683
684#[derive(Deserialize, JsonSchema)]
685pub struct ScratchUpdateParams {
686 /// Scratch entry ID to update.
687 pub scratch_id: String,
688 /// Replacement content (replaces previous content entirely).
689 pub content: String,
690}
691
692#[derive(Deserialize, JsonSchema)]
693pub struct ScratchDiscardParams {
694 /// Scratch entry ID to discard.
695 pub scratch_id: String,
696}
697
698#[derive(Deserialize, JsonSchema)]
699pub struct ScratchPromoteParams {
700 /// Scratch entry ID to promote.
701 pub scratch_id: String,
702 /// Ledger kind: decision, assumption, constraint, rationale, hazard, tradeoff, invariant, ownership, proof, validation_scenario, known_bug, concept.
703 pub kind: String,
704 /// Symbol qualified name. Required if the scratch entry has no symbol attached.
705 #[serde(default)]
706 pub qname: Option<String>,
707 /// One-line summary. Defaults to the first non-empty line of the scratch content.
708 #[serde(default)]
709 pub summary: Option<String>,
710}
711
712#[derive(Deserialize, JsonSchema)]
713pub struct ScratchCleanParams {
714 /// Delete entries older than this many hours. Required.
715 pub older_than_hours: u32,
716 /// Comma-separated statuses to clean: "discarded,promoted" (default).
717 #[serde(default = "default_scratch_clean_statuses")]
718 pub statuses: String,
719 /// When true, report what would be deleted without removing anything.
720 #[serde(default)]
721 pub dry_run: bool,
722}
723
724fn default_scratch_clean_statuses() -> String {
725 "discarded,promoted".to_string()
726}
727
728// -- New tool parameter types -----------------------------------------------
729
730#[derive(Deserialize, JsonSchema)]
731pub struct SearchParams {
732 /// Concept or keyword(s) to search for.
733 pub query: String,
734 /// Filter by symbol kind.
735 pub kind: Option<String>,
736 /// Filter by language.
737 pub language: Option<String>,
738 /// Max results (default: 20).
739 #[serde(default = "default_search_limit")]
740 pub limit: u32,
741 /// Include test-file symbols (default: false).
742 #[serde(default)]
743 pub include_tests: bool,
744 /// Adjust guidance for a specific intent (bugfix, feature, refactor, test, architecture, ui).
745 pub intent: Option<String>,
746 /// Named scope alias from .asd/scopes.toml.
747 pub scope: Option<String>,
748 /// Comma-separated glob patterns to restrict to specific paths.
749 pub paths: Option<String>,
750 /// Comma-separated exclusion terms.
751 pub exclude: Option<String>,
752 /// Skip document index; return symbol hits only (default: false).
753 #[serde(default)]
754 pub symbols_only: bool,
755 /// Agent token budget (default: 8000).
756 #[serde(default = "default_agent_budget")]
757 pub agent_budget: u32,
758}
759
760fn default_agent_budget() -> u32 {
761 8000
762}
763
764#[derive(Deserialize, JsonSchema)]
765pub struct ContextForParams {
766 /// Comma-separated fully-qualified symbol names.
767 pub qnames: String,
768 /// Token budget for the output.
769 pub budget_tokens: Option<u32>,
770 /// Include full source body (default: false).
771 #[serde(default)]
772 pub include_body: bool,
773}
774
775#[derive(Deserialize, JsonSchema)]
776pub struct TaskCloseParams {
777 /// Free-text proof of completion (default: "task completed").
778 pub proof: Option<String>,
779 /// Comma-separated qnames to annotate. If omitted, resolved from git HEAD changed files.
780 pub symbols: Option<String>,
781 /// Mark the task as validated.
782 #[serde(default)]
783 pub validated: bool,
784 /// Validation note (used when validated = true).
785 pub validation_note: Option<String>,
786 /// Reference to validation evidence (file, URL, or test name).
787 pub evidence: Option<String>,
788 /// CTX plan ID.
789 pub plan: Option<String>,
790 /// CTX task ID.
791 pub task: Option<String>,
792 /// Author id (default: "asd-task-close").
793 #[serde(default = "default_task_close_author")]
794 pub author: String,
795}
796
797fn default_task_close_author() -> String {
798 "asd-task-close".to_string()
799}
800
801#[derive(Deserialize, JsonSchema)]
802pub struct VerifyEffectsParams {
803 /// Fully-qualified symbol name.
804 pub qname: String,
805 /// Write verification result back to the store (default: false).
806 #[serde(default)]
807 pub write: bool,
808}
809
810#[derive(Deserialize, JsonSchema)]
811pub struct StatusParams {
812 /// Show source files modified since last commit (default: false).
813 #[serde(default)]
814 pub show_dirty: bool,
815}
816
817#[derive(Deserialize, JsonSchema)]
818pub struct ScorecardParams {
819 /// Named scope alias.
820 pub scope: Option<String>,
821 /// Comma-separated glob patterns.
822 pub paths: Option<String>,
823 /// Drill-down dimension: "truth", "feedback", "change", "uncertainty", "workflow".
824 pub drill_down: Option<String>,
825 /// Max symbols shown in drill-down (default: 10).
826 #[serde(default = "default_scorecard_limit")]
827 pub limit: u32,
828}
829
830fn default_scorecard_limit() -> u32 {
831 10
832}
833
834#[derive(Deserialize, JsonSchema)]
835pub struct AnnotateCommitParams {
836 /// Git commit SHA (default: "HEAD").
837 pub sha: Option<String>,
838 /// Actually write entries (default: false — dry-run).
839 #[serde(default)]
840 pub write: bool,
841 /// Author id (defaults to git user.name).
842 pub author: Option<String>,
843 /// Additional task context appended to commit body for annotation extraction.
844 pub task_description: Option<String>,
845 /// CTX task ID — written as ctx:task:<id> provenance tag.
846 pub ctx_task: Option<String>,
847 /// CTX plan ID — written as ctx:plan:<id> provenance tag.
848 pub ctx_plan: Option<String>,
849}
850
851// -- Tool implementations ---------------------------------------------------
852//
853// MCP tool naming conventions (see CLI parity audit):
854// - Tools that mirror a CLI verb 1:1 use the same name (search, callers, callees,
855// impact, since, investigate, prepare_change, ...).
856// - `code_*` prefix is used for tools whose bare CLI name would collide in the
857// flat MCP namespace shared with other servers: `code_search`, `code_read`,
858// `code_query` — CLI equivalents are `asd search` and `asd read`.
859// - Subcommand-style CLI verbs are flattened with an underscore in MCP because
860// MCP has no nested-command concept: MCP `ledger_append` = CLI `asd ledger append`,
861// MCP `scratch_write` = CLI `asd scratch write`, and so on for feedback_*,
862// invariant_*, audit_*.
863// - No `_of` suffix: use bare names (callers, callees, effects, traces).