@mrc2204/agent-smart-memo 5.1.0 → 5.1.2

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.
Files changed (69) hide show
  1. package/README.md +209 -375
  2. package/bin/asm.mjs +365 -0
  3. package/bin/opencode-mcp-server.mjs +320 -0
  4. package/dist/core/contracts/adapter-contracts.d.ts +1 -1
  5. package/dist/core/contracts/adapter-contracts.d.ts.map +1 -1
  6. package/dist/core/contracts/change-overlay-contracts.d.ts +69 -0
  7. package/dist/core/contracts/change-overlay-contracts.d.ts.map +1 -0
  8. package/dist/core/contracts/change-overlay-contracts.js +2 -0
  9. package/dist/core/contracts/change-overlay-contracts.js.map +1 -0
  10. package/dist/core/contracts/feature-pack-contracts.d.ts +37 -0
  11. package/dist/core/contracts/feature-pack-contracts.d.ts.map +1 -0
  12. package/dist/core/contracts/feature-pack-contracts.js +8 -0
  13. package/dist/core/contracts/feature-pack-contracts.js.map +1 -0
  14. package/dist/core/contracts/project-query-contracts.d.ts +84 -0
  15. package/dist/core/contracts/project-query-contracts.d.ts.map +1 -0
  16. package/dist/core/contracts/project-query-contracts.js +2 -0
  17. package/dist/core/contracts/project-query-contracts.js.map +1 -0
  18. package/dist/core/graph/code-graph-model.d.ts +9 -0
  19. package/dist/core/graph/code-graph-model.d.ts.map +1 -0
  20. package/dist/core/graph/code-graph-model.js +70 -0
  21. package/dist/core/graph/code-graph-model.js.map +1 -0
  22. package/dist/core/graph/code-graph-populator.d.ts +20 -0
  23. package/dist/core/graph/code-graph-populator.d.ts.map +1 -0
  24. package/dist/core/graph/code-graph-populator.js +760 -0
  25. package/dist/core/graph/code-graph-populator.js.map +1 -0
  26. package/dist/core/graph/contracts.d.ts +29 -0
  27. package/dist/core/graph/contracts.d.ts.map +1 -0
  28. package/dist/core/graph/contracts.js +47 -0
  29. package/dist/core/graph/contracts.js.map +1 -0
  30. package/dist/core/ingest/contracts.d.ts +1 -1
  31. package/dist/core/ingest/contracts.d.ts.map +1 -1
  32. package/dist/core/ingest/ingest-pipeline.js +1 -1
  33. package/dist/core/ingest/ingest-pipeline.js.map +1 -1
  34. package/dist/core/ingest/semantic-block-extractor.d.ts.map +1 -1
  35. package/dist/core/ingest/semantic-block-extractor.js +36 -0
  36. package/dist/core/ingest/semantic-block-extractor.js.map +1 -1
  37. package/dist/core/usecases/default-memory-usecase-port.d.ts +35 -0
  38. package/dist/core/usecases/default-memory-usecase-port.d.ts.map +1 -1
  39. package/dist/core/usecases/default-memory-usecase-port.js +1578 -19
  40. package/dist/core/usecases/default-memory-usecase-port.js.map +1 -1
  41. package/dist/db/graph-db.d.ts +24 -0
  42. package/dist/db/graph-db.d.ts.map +1 -1
  43. package/dist/db/graph-db.js +81 -2
  44. package/dist/db/graph-db.js.map +1 -1
  45. package/dist/db/slot-db.d.ts +227 -1
  46. package/dist/db/slot-db.d.ts.map +1 -1
  47. package/dist/db/slot-db.js +700 -13
  48. package/dist/db/slot-db.js.map +1 -1
  49. package/dist/index.d.ts +7 -247
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +32 -119
  52. package/dist/index.js.map +1 -1
  53. package/dist/shared/asm-config.d.ts +82 -0
  54. package/dist/shared/asm-config.d.ts.map +1 -0
  55. package/dist/shared/asm-config.js +254 -0
  56. package/dist/shared/asm-config.js.map +1 -0
  57. package/dist/shared/slotdb-path.d.ts +4 -3
  58. package/dist/shared/slotdb-path.d.ts.map +1 -1
  59. package/dist/shared/slotdb-path.js +15 -6
  60. package/dist/shared/slotdb-path.js.map +1 -1
  61. package/dist/tools/graph-tools.d.ts.map +1 -1
  62. package/dist/tools/graph-tools.js +131 -0
  63. package/dist/tools/graph-tools.js.map +1 -1
  64. package/dist/tools/project-tools.d.ts.map +1 -1
  65. package/dist/tools/project-tools.js +476 -1
  66. package/dist/tools/project-tools.js.map +1 -1
  67. package/openclaw.plugin.json +5 -164
  68. package/package.json +61 -26
  69. package/scripts/init-openclaw.mjs +727 -0
@@ -106,6 +106,41 @@ export function registerProjectTools(api, options) {
106
106
  }
107
107
  },
108
108
  });
109
+ api.registerTool({
110
+ name: "project_binding_preview",
111
+ label: "Project Binding Preview",
112
+ description: "Read-only OpenCode-style project binding preview. Resolves active project by project_id/project_alias/repo_root/session alias, blocks ambiguous multi-project binding unless cross-project is explicit.",
113
+ parameters: {
114
+ type: "object",
115
+ properties: {
116
+ project_id: { type: "string" },
117
+ project_alias: { type: "string" },
118
+ repo_root: { type: "string" },
119
+ session_project_alias: { type: "string" },
120
+ allow_cross_project: { type: "boolean" },
121
+ },
122
+ },
123
+ async execute(_id, params, ctx) {
124
+ try {
125
+ const sessionKey = getSessionKey(ctx);
126
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
127
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
128
+ const data = await useCasePort.run("project.binding_preview", {
129
+ context: { userId, agentId },
130
+ payload: params,
131
+ meta: {
132
+ source: "openclaw",
133
+ toolName: "project_binding_preview",
134
+ requestId: _id,
135
+ },
136
+ });
137
+ return createResult(JSON.stringify(data, null, 2));
138
+ }
139
+ catch (error) {
140
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
141
+ }
142
+ },
143
+ });
109
144
  api.registerTool({
110
145
  name: "project_registration_state_set",
111
146
  label: "Project Registration State Set",
@@ -332,6 +367,7 @@ export function registerProjectTools(api, options) {
332
367
  checksum: { type: "string" },
333
368
  module: { type: "string" },
334
369
  language: { type: "string" },
370
+ content: { type: "string" },
335
371
  },
336
372
  required: ["relative_path"],
337
373
  },
@@ -360,6 +396,197 @@ export function registerProjectTools(api, options) {
360
396
  }
361
397
  },
362
398
  });
399
+ api.registerTool({
400
+ name: "project_deindex",
401
+ label: "Project Deindex",
402
+ description: "Mark a project as deindexed (non-destructive): keep registry identity but tombstone indexed artifacts so retrieval/search no longer returns them.",
403
+ parameters: {
404
+ type: "object",
405
+ properties: {
406
+ project_id: { type: "string" },
407
+ reason: { type: "string" },
408
+ },
409
+ required: ["project_id"],
410
+ },
411
+ async execute(_id, params, ctx) {
412
+ try {
413
+ const sessionKey = getSessionKey(ctx);
414
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
415
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
416
+ const data = await useCasePort.run("project.deindex", {
417
+ context: { userId, agentId },
418
+ payload: params,
419
+ meta: {
420
+ source: "openclaw",
421
+ toolName: "project_deindex",
422
+ requestId: _id,
423
+ },
424
+ });
425
+ return createResult(JSON.stringify(data, null, 2));
426
+ }
427
+ catch (error) {
428
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
429
+ }
430
+ },
431
+ });
432
+ api.registerTool({
433
+ name: "project_detach",
434
+ label: "Project Detach",
435
+ description: "Detach a project from active bindings (aliases/repo/tracker) after deindex safety step. Non-purge and reversible via re-register.",
436
+ parameters: {
437
+ type: "object",
438
+ properties: {
439
+ project_ref: {
440
+ type: "object",
441
+ properties: {
442
+ project_id: { type: "string" },
443
+ project_alias: { type: "string" },
444
+ },
445
+ },
446
+ reason: { type: "string" },
447
+ },
448
+ required: ["project_ref"],
449
+ },
450
+ async execute(_id, params, ctx) {
451
+ try {
452
+ const sessionKey = getSessionKey(ctx);
453
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
454
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
455
+ const data = await useCasePort.run("project.detach", {
456
+ context: { userId, agentId },
457
+ payload: params,
458
+ meta: {
459
+ source: "openclaw",
460
+ toolName: "project_detach",
461
+ requestId: _id,
462
+ },
463
+ });
464
+ return createResult(JSON.stringify(data, null, 2));
465
+ }
466
+ catch (error) {
467
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
468
+ }
469
+ },
470
+ });
471
+ api.registerTool({
472
+ name: "project_unregister",
473
+ label: "Project Unregister",
474
+ description: "Safe unregister lifecycle step: requires explicit confirm=true, deindexes first, then disables project and detaches active bindings without destructive purge.",
475
+ parameters: {
476
+ type: "object",
477
+ properties: {
478
+ project_ref: {
479
+ type: "object",
480
+ properties: {
481
+ project_id: { type: "string" },
482
+ project_alias: { type: "string" },
483
+ },
484
+ },
485
+ confirm: { type: "boolean" },
486
+ mode: { type: "string", enum: ["safe"] },
487
+ reason: { type: "string" },
488
+ },
489
+ required: ["project_ref", "confirm"],
490
+ },
491
+ async execute(_id, params, ctx) {
492
+ try {
493
+ const sessionKey = getSessionKey(ctx);
494
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
495
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
496
+ const data = await useCasePort.run("project.unregister", {
497
+ context: { userId, agentId },
498
+ payload: params,
499
+ meta: {
500
+ source: "openclaw",
501
+ toolName: "project_unregister",
502
+ requestId: _id,
503
+ },
504
+ });
505
+ return createResult(JSON.stringify(data, null, 2));
506
+ }
507
+ catch (error) {
508
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
509
+ }
510
+ },
511
+ });
512
+ api.registerTool({
513
+ name: "project_purge_preview",
514
+ label: "Project Purge Preview",
515
+ description: "Preview destructive purge impact with guardrails. Purge is only allowed when lifecycle_status=disabled and still requires explicit confirm in the purge call.",
516
+ parameters: {
517
+ type: "object",
518
+ properties: {
519
+ project_ref: {
520
+ type: "object",
521
+ properties: {
522
+ project_id: { type: "string" },
523
+ project_alias: { type: "string" },
524
+ },
525
+ },
526
+ },
527
+ required: ["project_ref"],
528
+ },
529
+ async execute(_id, params, ctx) {
530
+ try {
531
+ const sessionKey = getSessionKey(ctx);
532
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
533
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
534
+ const data = await useCasePort.run("project.purge_preview", {
535
+ context: { userId, agentId },
536
+ payload: params,
537
+ meta: {
538
+ source: "openclaw",
539
+ toolName: "project_purge_preview",
540
+ requestId: _id,
541
+ },
542
+ });
543
+ return createResult(JSON.stringify(data, null, 2));
544
+ }
545
+ catch (error) {
546
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
547
+ }
548
+ },
549
+ });
550
+ api.registerTool({
551
+ name: "project_purge",
552
+ label: "Project Purge",
553
+ description: "Destructive lifecycle endpoint. Requires project to be disabled first and explicit confirm=true. Use project_purge_preview before execution.",
554
+ parameters: {
555
+ type: "object",
556
+ properties: {
557
+ project_ref: {
558
+ type: "object",
559
+ properties: {
560
+ project_id: { type: "string" },
561
+ project_alias: { type: "string" },
562
+ },
563
+ },
564
+ confirm: { type: "boolean" },
565
+ reason: { type: "string" },
566
+ },
567
+ required: ["project_ref", "confirm"],
568
+ },
569
+ async execute(_id, params, ctx) {
570
+ try {
571
+ const sessionKey = getSessionKey(ctx);
572
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
573
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
574
+ const data = await useCasePort.run("project.purge", {
575
+ context: { userId, agentId },
576
+ payload: params,
577
+ meta: {
578
+ source: "openclaw",
579
+ toolName: "project_purge",
580
+ requestId: _id,
581
+ },
582
+ });
583
+ return createResult(JSON.stringify(data, null, 2));
584
+ }
585
+ catch (error) {
586
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
587
+ }
588
+ },
589
+ });
363
590
  api.registerTool({
364
591
  name: "project_telegram_onboarding",
365
592
  label: "Project Telegram Onboarding",
@@ -420,6 +647,7 @@ export function registerProjectTools(api, options) {
420
647
  checksum: { type: "string" },
421
648
  module: { type: "string" },
422
649
  language: { type: "string" },
650
+ content: { type: "string" },
423
651
  },
424
652
  required: ["relative_path"],
425
653
  },
@@ -456,10 +684,13 @@ export function registerProjectTools(api, options) {
456
684
  type: "object",
457
685
  properties: {
458
686
  project_id: { type: "string" },
687
+ repo_root: { type: "string" },
459
688
  source_rev: { type: "string" },
460
- event_type: { type: "string", enum: ["post_commit", "post_merge", "manual"] },
689
+ event_type: { type: "string", enum: ["post_commit", "post_merge", "post_rewrite", "manual"] },
461
690
  changed_files: { type: "array", items: { type: "string" } },
462
691
  deleted_files: { type: "array", items: { type: "string" } },
692
+ trusted_sync: { type: "boolean" },
693
+ full_snapshot: { type: "boolean" },
463
694
  },
464
695
  required: ["project_id"],
465
696
  },
@@ -664,6 +895,249 @@ export function registerProjectTools(api, options) {
664
895
  }
665
896
  },
666
897
  });
898
+ api.registerTool({
899
+ name: "project_change_overlay_query",
900
+ label: "Project Change Overlay Query",
901
+ description: "Query ASM-94 change-aware overlay with explicit selector (task/tracker) and optional feature filter.",
902
+ parameters: {
903
+ type: "object",
904
+ properties: {
905
+ project_id: { type: "string" },
906
+ task_id: { type: "string" },
907
+ tracker_issue_key: { type: "string" },
908
+ task_title: { type: "string" },
909
+ feature_key: {
910
+ type: "string",
911
+ enum: [
912
+ "project_onboarding_registration_indexing",
913
+ "code_aware_retrieval",
914
+ "heartbeat_health_runtime_integrity",
915
+ "change_aware_impact",
916
+ "post_entry_review_decision_support",
917
+ ],
918
+ },
919
+ feature_name: { type: "string" },
920
+ include_related: { type: "boolean" },
921
+ include_parent_chain: { type: "boolean" },
922
+ },
923
+ required: ["project_id"],
924
+ },
925
+ async execute(_id, params, ctx) {
926
+ try {
927
+ const sessionKey = getSessionKey(ctx);
928
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
929
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
930
+ const data = await useCasePort.run("project.change_overlay.query", {
931
+ context: { userId, agentId },
932
+ payload: params,
933
+ meta: {
934
+ source: "openclaw",
935
+ toolName: "project_change_overlay_query",
936
+ requestId: _id,
937
+ },
938
+ });
939
+ return createResult(JSON.stringify(data, null, 2));
940
+ }
941
+ catch (error) {
942
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
943
+ }
944
+ },
945
+ });
946
+ api.registerTool({
947
+ name: "project_feature_pack_generate",
948
+ label: "Project Feature Pack Generate",
949
+ description: "Generate a minimal feature/capability pack for a registered project flow. ASM-93 Slice 2 supports multiple priority feature packs.",
950
+ parameters: {
951
+ type: "object",
952
+ properties: {
953
+ project_id: { type: "string" },
954
+ project_alias: { type: "string" },
955
+ feature_key: {
956
+ type: "string",
957
+ enum: [
958
+ "project_onboarding_registration_indexing",
959
+ "code_aware_retrieval",
960
+ "heartbeat_health_runtime_integrity",
961
+ "change_aware_impact",
962
+ "post_entry_review_decision_support",
963
+ ],
964
+ },
965
+ },
966
+ },
967
+ async execute(_id, params, ctx) {
968
+ try {
969
+ const sessionKey = getSessionKey(ctx);
970
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
971
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
972
+ const data = await useCasePort.run("project.feature_pack.generate", {
973
+ context: { userId, agentId },
974
+ payload: params,
975
+ meta: {
976
+ source: "openclaw",
977
+ toolName: "project_feature_pack_generate",
978
+ requestId: _id,
979
+ },
980
+ });
981
+ return createResult(JSON.stringify(data, null, 2));
982
+ }
983
+ catch (error) {
984
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
985
+ }
986
+ },
987
+ });
988
+ api.registerTool({
989
+ name: "project_feature_pack_query",
990
+ label: "Project Feature Pack Query",
991
+ description: "Query feature pack by feature_key or feature name (human-friendly) for a registered project.",
992
+ parameters: {
993
+ type: "object",
994
+ properties: {
995
+ project_id: { type: "string" },
996
+ project_alias: { type: "string" },
997
+ feature_key: {
998
+ type: "string",
999
+ enum: [
1000
+ "project_onboarding_registration_indexing",
1001
+ "code_aware_retrieval",
1002
+ "heartbeat_health_runtime_integrity",
1003
+ "change_aware_impact",
1004
+ "post_entry_review_decision_support",
1005
+ ],
1006
+ },
1007
+ feature_name: { type: "string" },
1008
+ },
1009
+ },
1010
+ async execute(_id, params, ctx) {
1011
+ try {
1012
+ const sessionKey = getSessionKey(ctx);
1013
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
1014
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
1015
+ const data = await useCasePort.run("project.feature_pack.query", {
1016
+ context: { userId, agentId },
1017
+ payload: params,
1018
+ meta: {
1019
+ source: "openclaw",
1020
+ toolName: "project_feature_pack_query",
1021
+ requestId: _id,
1022
+ },
1023
+ });
1024
+ return createResult(JSON.stringify(data, null, 2));
1025
+ }
1026
+ catch (error) {
1027
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
1028
+ }
1029
+ },
1030
+ });
1031
+ api.registerTool({
1032
+ name: "project_opencode_search",
1033
+ label: "Project OpenCode Search",
1034
+ description: "Read-only OpenCode retrieval surface. Resolves project binding first, then runs project-scoped developer query. Cross-project behavior requires explicit opt-in.",
1035
+ parameters: {
1036
+ type: "object",
1037
+ properties: {
1038
+ query: { type: "string" },
1039
+ limit: { type: "number" },
1040
+ project_id: { type: "string" },
1041
+ project_alias: { type: "string" },
1042
+ repo_root: { type: "string" },
1043
+ session_project_alias: { type: "string" },
1044
+ explicit_project_id: { type: "string" },
1045
+ explicit_project_alias: { type: "string" },
1046
+ explicit_cross_project: { type: "boolean" },
1047
+ },
1048
+ required: ["query"],
1049
+ },
1050
+ async execute(_id, params, ctx) {
1051
+ try {
1052
+ const sessionKey = getSessionKey(ctx);
1053
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
1054
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
1055
+ const data = await useCasePort.run("project.opencode_search", {
1056
+ context: { userId, agentId },
1057
+ payload: params,
1058
+ meta: {
1059
+ source: "openclaw",
1060
+ toolName: "project_opencode_search",
1061
+ requestId: _id,
1062
+ },
1063
+ });
1064
+ return createResult(JSON.stringify(data, null, 2));
1065
+ }
1066
+ catch (error) {
1067
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
1068
+ }
1069
+ },
1070
+ });
1071
+ api.registerTool({
1072
+ name: "project_developer_query",
1073
+ label: "Project Developer Query",
1074
+ description: "ASM-112 typed developer query parser surface with deterministic intent/selector normalization over existing hybrid_search/feature_pack/change_overlay capabilities.",
1075
+ parameters: {
1076
+ type: "object",
1077
+ properties: {
1078
+ project_id: { type: "string" },
1079
+ project_alias: { type: "string" },
1080
+ query: { type: "string" },
1081
+ intent: {
1082
+ type: "string",
1083
+ enum: [
1084
+ "locate_symbol",
1085
+ "locate_file",
1086
+ "feature_lookup",
1087
+ "change_lookup",
1088
+ "locate",
1089
+ "trace_flow",
1090
+ "impact",
1091
+ "impact_analysis",
1092
+ "change_aware_lookup",
1093
+ "feature_understanding",
1094
+ ],
1095
+ },
1096
+ limit: { type: "number" },
1097
+ symbol_name: { type: "string" },
1098
+ relative_path: { type: "string" },
1099
+ route_path: { type: "string" },
1100
+ tracker_issue_key: { type: "string" },
1101
+ task_id: { type: "string" },
1102
+ task_title: { type: "string" },
1103
+ tracker_issue_keys: { type: "array", items: { type: "string" } },
1104
+ task_ids: { type: "array", items: { type: "string" } },
1105
+ route_paths: { type: "array", items: { type: "string" } },
1106
+ feature_key: {
1107
+ type: "string",
1108
+ enum: [
1109
+ "project_onboarding_registration_indexing",
1110
+ "code_aware_retrieval",
1111
+ "heartbeat_health_runtime_integrity",
1112
+ "change_aware_impact",
1113
+ "post_entry_review_decision_support",
1114
+ ],
1115
+ },
1116
+ feature_name: { type: "string" },
1117
+ },
1118
+ required: [],
1119
+ },
1120
+ async execute(_id, params, ctx) {
1121
+ try {
1122
+ const sessionKey = getSessionKey(ctx);
1123
+ const { userId, agentId } = parseOpenClawSessionIdentity(sessionKey);
1124
+ const useCasePort = getMemoryUseCasePortForContext(ctx);
1125
+ const data = await useCasePort.run("project.developer_query", {
1126
+ context: { userId, agentId },
1127
+ payload: params,
1128
+ meta: {
1129
+ source: "openclaw",
1130
+ toolName: "project_developer_query",
1131
+ requestId: _id,
1132
+ },
1133
+ });
1134
+ return createResult(JSON.stringify(data, null, 2));
1135
+ }
1136
+ catch (error) {
1137
+ return createResult(`Error: ${error instanceof Error ? error.message : String(error)}`, true);
1138
+ }
1139
+ },
1140
+ });
667
1141
  api.registerTool({
668
1142
  name: "project_hybrid_search",
669
1143
  label: "Project Hybrid Search",
@@ -674,6 +1148,7 @@ export function registerProjectTools(api, options) {
674
1148
  project_id: { type: "string" },
675
1149
  query: { type: "string" },
676
1150
  limit: { type: "number" },
1151
+ debug: { type: "boolean", description: "Return candidate-generation and ranking debug info for conformance/debugging." },
677
1152
  path_prefix: { type: "array", items: { type: "string" } },
678
1153
  module: { type: "array", items: { type: "string" } },
679
1154
  language: { type: "array", items: { type: "string" } },