@gmickel/gno 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +18 -4
  2. package/assets/skill/SKILL.md +44 -1
  3. package/assets/skill/mcp-reference.md +21 -0
  4. package/package.json +3 -2
  5. package/spec/AGENTS.md +83 -0
  6. package/spec/CLAUDE.md +83 -0
  7. package/spec/bench-fixture.schema.json +137 -0
  8. package/spec/cli.md +2894 -0
  9. package/spec/db/schema.sql +442 -0
  10. package/spec/evals-agentic.md +510 -0
  11. package/spec/evals.md +1106 -0
  12. package/spec/mcp.md +2229 -0
  13. package/spec/output-schemas/activation-verification.schema.json +515 -0
  14. package/spec/output-schemas/ask.schema.json +366 -0
  15. package/spec/output-schemas/backlinks.schema.json +131 -0
  16. package/spec/output-schemas/bench-result.schema.json +120 -0
  17. package/spec/output-schemas/capture-receipt.schema.json +143 -0
  18. package/spec/output-schemas/collection-list.schema.json +45 -0
  19. package/spec/output-schemas/context-capsule-v1.schema.json +691 -0
  20. package/spec/output-schemas/context-capsule-verification.schema.json +1338 -0
  21. package/spec/output-schemas/context-list.schema.json +21 -0
  22. package/spec/output-schemas/doctor.schema.json +313 -0
  23. package/spec/output-schemas/error.schema.json +30 -0
  24. package/spec/output-schemas/expansion.schema.json +37 -0
  25. package/spec/output-schemas/get.schema.json +140 -0
  26. package/spec/output-schemas/graph-query.schema.json +99 -0
  27. package/spec/output-schemas/graph.schema.json +371 -0
  28. package/spec/output-schemas/links-list.schema.json +186 -0
  29. package/spec/output-schemas/mcp-add-collection-result.schema.json +23 -0
  30. package/spec/output-schemas/mcp-capture-result.schema.json +152 -0
  31. package/spec/output-schemas/mcp-http-error.schema.json +30 -0
  32. package/spec/output-schemas/mcp-job-list.schema.json +58 -0
  33. package/spec/output-schemas/mcp-job-status.schema.json +224 -0
  34. package/spec/output-schemas/mcp-remove-result.schema.json +39 -0
  35. package/spec/output-schemas/mcp-sync-result.schema.json +41 -0
  36. package/spec/output-schemas/mcp-tag-result.schema.json +33 -0
  37. package/spec/output-schemas/models-list.schema.json +93 -0
  38. package/spec/output-schemas/multi-get.schema.json +103 -0
  39. package/spec/output-schemas/process-status.schema.json +119 -0
  40. package/spec/output-schemas/query-diagnose.schema.json +123 -0
  41. package/spec/output-schemas/resident-status.schema.json +154 -0
  42. package/spec/output-schemas/retrieval-trace-common.schema.json +492 -0
  43. package/spec/output-schemas/retrieval-trace-delete.schema.json +16 -0
  44. package/spec/output-schemas/retrieval-trace-export.schema.json +61 -0
  45. package/spec/output-schemas/retrieval-trace-filters.schema.json +139 -0
  46. package/spec/output-schemas/retrieval-trace-judgment.schema.json +15 -0
  47. package/spec/output-schemas/retrieval-trace-list.schema.json +18 -0
  48. package/spec/output-schemas/retrieval-trace-payloads.schema.json +178 -0
  49. package/spec/output-schemas/retrieval-trace-purge.schema.json +31 -0
  50. package/spec/output-schemas/retrieval-trace-qrels.schema.json +303 -0
  51. package/spec/output-schemas/retrieval-trace-replay.schema.json +286 -0
  52. package/spec/output-schemas/retrieval-trace-show.schema.json +69 -0
  53. package/spec/output-schemas/retrieval-trace-summary.schema.json +65 -0
  54. package/spec/output-schemas/search-result.schema.json +154 -0
  55. package/spec/output-schemas/search-results.schema.json +338 -0
  56. package/spec/output-schemas/similar.schema.json +84 -0
  57. package/spec/output-schemas/status.schema.json +676 -0
  58. package/spec/output-schemas/tags-list.schema.json +48 -0
  59. package/src/app/context-runtime-types.ts +3 -0
  60. package/src/app/context-runtime.ts +15 -1
  61. package/src/cli/commands/ask.ts +106 -36
  62. package/src/cli/commands/context-build.ts +56 -9
  63. package/src/cli/commands/daemon.ts +69 -2
  64. package/src/cli/commands/get.ts +64 -3
  65. package/src/cli/commands/models/pull.ts +13 -3
  66. package/src/cli/commands/query.ts +62 -23
  67. package/src/cli/commands/replay.ts +140 -0
  68. package/src/cli/commands/search.ts +48 -3
  69. package/src/cli/commands/shared.ts +3 -1
  70. package/src/cli/commands/status.ts +2 -0
  71. package/src/cli/commands/trace.ts +200 -0
  72. package/src/cli/commands/vsearch.ts +75 -53
  73. package/src/cli/detach.ts +37 -20
  74. package/src/cli/program.ts +329 -27
  75. package/src/config/index.ts +12 -0
  76. package/src/config/retrieval-traces.ts +56 -0
  77. package/src/config/types.ts +41 -0
  78. package/src/core/context-compiler.ts +11 -4
  79. package/src/core/job-manager.ts +19 -0
  80. package/src/core/mutation-generations.ts +33 -0
  81. package/src/core/retrieval-qrels.ts +405 -0
  82. package/src/core/retrieval-replay-candidate.ts +368 -0
  83. package/src/core/retrieval-replay-types.ts +109 -0
  84. package/src/core/retrieval-replay-validation.ts +89 -0
  85. package/src/core/retrieval-replay.ts +441 -0
  86. package/src/core/retrieval-trace-evidence-origin.ts +175 -0
  87. package/src/core/retrieval-trace-export.ts +113 -0
  88. package/src/core/retrieval-trace-filter-normalization.ts +27 -0
  89. package/src/core/retrieval-trace-filters.ts +19 -0
  90. package/src/core/retrieval-trace-management-helpers.ts +247 -0
  91. package/src/core/retrieval-trace-management-types.ts +132 -0
  92. package/src/core/retrieval-trace-management.ts +422 -0
  93. package/src/core/retrieval-trace-request.ts +141 -0
  94. package/src/core/retrieval-trace-session.ts +494 -0
  95. package/src/core/retrieval-trace.ts +472 -0
  96. package/src/llm/cache.ts +13 -3
  97. package/src/llm/nodeLlamaCpp/adapter.ts +10 -1
  98. package/src/llm/nodeLlamaCpp/lifecycle.ts +71 -0
  99. package/src/mcp/context.ts +161 -0
  100. package/src/mcp/http-security.ts +477 -0
  101. package/src/mcp/http-session.ts +272 -0
  102. package/src/mcp/http-transport.ts +370 -0
  103. package/src/mcp/resources/index.ts +141 -134
  104. package/src/mcp/server.ts +19 -79
  105. package/src/mcp/tools/add-collection.ts +3 -1
  106. package/src/mcp/tools/capture.ts +3 -0
  107. package/src/mcp/tools/clear-collection-embeddings.ts +2 -0
  108. package/src/mcp/tools/context.ts +68 -16
  109. package/src/mcp/tools/embed.ts +62 -52
  110. package/src/mcp/tools/get.ts +35 -1
  111. package/src/mcp/tools/index-cmd.ts +88 -74
  112. package/src/mcp/tools/index.ts +96 -2
  113. package/src/mcp/tools/query.ts +95 -64
  114. package/src/mcp/tools/remove-collection.ts +2 -0
  115. package/src/mcp/tools/search.ts +36 -13
  116. package/src/mcp/tools/status.ts +11 -0
  117. package/src/mcp/tools/sync.ts +16 -14
  118. package/src/mcp/tools/trace.ts +143 -0
  119. package/src/mcp/tools/vsearch.ts +71 -38
  120. package/src/mcp/tools/workspace-write.ts +7 -3
  121. package/src/pipeline/answer.ts +167 -26
  122. package/src/pipeline/graph-retrieval.ts +15 -1
  123. package/src/pipeline/hybrid.ts +151 -43
  124. package/src/pipeline/search.ts +36 -3
  125. package/src/pipeline/trace-metadata.ts +47 -0
  126. package/src/pipeline/types.ts +43 -0
  127. package/src/pipeline/vsearch.ts +101 -38
  128. package/src/sdk/client.ts +380 -71
  129. package/src/sdk/documents.ts +48 -1
  130. package/src/sdk/index.ts +17 -0
  131. package/src/sdk/types.ts +28 -0
  132. package/src/serve/background-runtime.ts +12 -212
  133. package/src/serve/context-capsule.ts +67 -8
  134. package/src/serve/embed-scheduler.ts +74 -43
  135. package/src/serve/index.ts +9 -0
  136. package/src/serve/jobs.ts +78 -80
  137. package/src/serve/public/app.tsx +12 -1
  138. package/src/serve/public/components/HealthCenter.tsx +74 -1
  139. package/src/serve/public/globals.built.css +1 -1
  140. package/src/serve/public/lib/workspace-tabs.ts +2 -0
  141. package/src/serve/public/pages/Dashboard.tsx +11 -0
  142. package/src/serve/public/pages/TraceHistory.tsx +478 -0
  143. package/src/serve/public/pages/trace-history-detail.tsx +224 -0
  144. package/src/serve/resident-admission.ts +159 -0
  145. package/src/serve/resident-background-work.ts +39 -0
  146. package/src/serve/resident-request.ts +55 -0
  147. package/src/serve/resident-runtime.ts +490 -0
  148. package/src/serve/resident-status.ts +96 -0
  149. package/src/serve/retrieval-trace.ts +28 -0
  150. package/src/serve/routes/api.ts +629 -239
  151. package/src/serve/routes/mcp.ts +69 -0
  152. package/src/serve/routes/traces.ts +156 -0
  153. package/src/serve/server.ts +276 -37
  154. package/src/serve/status-model.ts +51 -0
  155. package/src/serve/status.ts +5 -0
  156. package/src/store/index.ts +31 -0
  157. package/src/store/migrations/014-retrieval-traces.ts +303 -0
  158. package/src/store/migrations/index.ts +2 -0
  159. package/src/store/retrieval-trace-codec.ts +384 -0
  160. package/src/store/sqlite/adapter.ts +179 -10
  161. package/src/store/sqlite/retrieval-trace-management-store.ts +341 -0
  162. package/src/store/sqlite/retrieval-trace-retention.ts +349 -0
  163. package/src/store/sqlite/retrieval-trace-rows.ts +267 -0
  164. package/src/store/sqlite/retrieval-trace-store.ts +515 -0
  165. package/src/store/types.ts +297 -0
  166. package/src/store/vector/sqlite-vec.ts +76 -1
  167. package/src/store/vector/types.ts +1 -1
@@ -5,8 +5,18 @@
5
5
  * @module src/cli/commands/vsearch
6
6
  */
7
7
 
8
+ import type {
9
+ RetrievalTraceSession,
10
+ RetrievalTraceSurfaceMetadata,
11
+ } from "../../core/retrieval-trace-session";
12
+ import type { EmbeddingPort } from "../../llm/types";
8
13
  import type { SearchOptions, SearchResults } from "../../pipeline/types";
9
14
 
15
+ import {
16
+ finishRetrievalTraceAfterError,
17
+ retrievalTraceFilters,
18
+ startRetrievalTraceRequest,
19
+ } from "../../core/retrieval-trace-request";
10
20
  import { LlmAdapter } from "../../llm/nodeLlamaCpp/adapter";
11
21
  import { resolveModelUri } from "../../llm/registry";
12
22
  import { formatQueryForEmbedding } from "../../pipeline/contextual";
@@ -47,7 +57,11 @@ export type VsearchCommandOptions = SearchOptions & {
47
57
  };
48
58
 
49
59
  export type VsearchResult =
50
- | { success: true; data: SearchResults }
60
+ | {
61
+ success: true;
62
+ data: SearchResults;
63
+ metadata?: RetrievalTraceSurfaceMetadata;
64
+ }
51
65
  | { success: false; error: string };
52
66
 
53
67
  // ─────────────────────────────────────────────────────────────────────────────
@@ -78,6 +92,8 @@ export async function vsearch(
78
92
  }
79
93
 
80
94
  const { store, config } = initResult;
95
+ let embedPort: EmbeddingPort | null = null;
96
+ let traceSession: RetrievalTraceSession | undefined;
81
97
 
82
98
  try {
83
99
  // Get model URI from preset
@@ -87,67 +103,74 @@ export async function vsearch(
87
103
  options.model,
88
104
  options.collection
89
105
  );
106
+ const traceStart = await startRetrievalTraceRequest({
107
+ store,
108
+ config,
109
+ query,
110
+ filters: retrievalTraceFilters({ ...options, limit }),
111
+ pipeline: "vector",
112
+ indexName: options.indexName,
113
+ modelUris: [modelUri],
114
+ });
115
+ if (!traceStart.ok) {
116
+ return { success: false, error: traceStart.error.message };
117
+ }
118
+ traceSession = traceStart.value ?? undefined;
90
119
 
91
120
  // Create LLM adapter for embeddings
92
121
  const llm = new LlmAdapter(config);
93
122
  const embedResult = await llm.createEmbeddingPort(modelUri);
94
123
  if (!embedResult.ok) {
124
+ await traceSession?.finish("failed");
95
125
  return { success: false, error: embedResult.error.message };
96
126
  }
97
127
 
98
- const embedPort = embedResult.value;
99
-
100
- try {
101
- // Embed query with contextual formatting (also determines dimensions)
102
- const queryEmbedResult = await embedPort.embed(
103
- formatQueryForEmbedding(query, embedPort.modelUri)
104
- );
105
- if (!queryEmbedResult.ok) {
106
- return { success: false, error: queryEmbedResult.error.message };
107
- }
108
- const queryEmbedding = new Float32Array(queryEmbedResult.value);
109
- const dimensions = queryEmbedding.length;
110
-
111
- // Create vector index port
112
- const db = store.getRawDb();
113
- const vectorResult = await createVectorIndexPort(db, {
114
- model: modelUri,
115
- dimensions,
116
- });
117
-
118
- if (!vectorResult.ok) {
119
- return { success: false, error: vectorResult.error.message };
120
- }
121
-
122
- const vectorIndex = vectorResult.value;
123
-
124
- const deps: VectorSearchDeps = {
125
- store,
126
- vectorIndex,
127
- embedPort,
128
- config,
129
- };
130
-
131
- // Pass pre-computed embedding to avoid double-embed
132
- const result = await searchVectorWithEmbedding(
133
- deps,
134
- query,
135
- queryEmbedding,
136
- { ...options, limit }
137
- );
138
-
139
- if (!result.ok) {
140
- return { success: false, error: result.error.message };
141
- }
142
-
143
- return {
144
- success: true,
145
- data: decorateSearchResultsForIndex(result.value, options.indexName),
146
- };
147
- } finally {
148
- await embedPort.dispose();
128
+ embedPort = embedResult.value;
129
+ const queryEmbedResult = await embedPort.embed(
130
+ formatQueryForEmbedding(query, embedPort.modelUri)
131
+ );
132
+ if (!queryEmbedResult.ok) {
133
+ await traceSession?.finish("failed");
134
+ return { success: false, error: queryEmbedResult.error.message };
149
135
  }
136
+ const queryEmbedding = new Float32Array(queryEmbedResult.value);
137
+ const vectorResult = await createVectorIndexPort(store.getRawDb(), {
138
+ model: modelUri,
139
+ dimensions: queryEmbedding.length,
140
+ });
141
+ if (!vectorResult.ok) {
142
+ await traceSession?.finish("failed");
143
+ return { success: false, error: vectorResult.error.message };
144
+ }
145
+ const deps: VectorSearchDeps = {
146
+ store,
147
+ vectorIndex: vectorResult.value,
148
+ embedPort,
149
+ config,
150
+ };
151
+ const result = await searchVectorWithEmbedding(
152
+ deps,
153
+ query,
154
+ queryEmbedding,
155
+ { ...options, limit, traceSession }
156
+ );
157
+ if (!result.ok) {
158
+ await traceSession?.finish("failed");
159
+ return { success: false, error: result.error.message };
160
+ }
161
+ return {
162
+ success: true,
163
+ data: decorateSearchResultsForIndex(result.value, options.indexName),
164
+ metadata: traceSession?.metadata(),
165
+ };
166
+ } catch (cause) {
167
+ await finishRetrievalTraceAfterError(traceSession, cause);
168
+ return {
169
+ success: false,
170
+ error: cause instanceof Error ? cause.message : "Vector search failed",
171
+ };
150
172
  } finally {
173
+ await embedPort?.dispose();
151
174
  await store.close();
152
175
  }
153
176
  }
@@ -194,7 +217,6 @@ export function formatVsearch(
194
217
  })
195
218
  : `Error: ${result.error}`;
196
219
  }
197
-
198
220
  const formatOpts: FormatOptions = {
199
221
  format: getFormatType(options),
200
222
  full: options.full,
package/src/cli/detach.ts CHANGED
@@ -20,9 +20,12 @@ import { mkdir, stat, unlink } from "node:fs/promises";
20
20
  // node:path — no Bun path utils.
21
21
  import { dirname, join } from "node:path";
22
22
 
23
+ import type { ResidentStatus } from "../serve/status-model";
24
+
23
25
  import { VERSION, resolveDirs } from "../app/constants";
24
26
  import { toAbsolutePath } from "../config/paths";
25
27
  import { atomicWrite } from "../core/file-ops";
28
+ import { isResidentStatus } from "../serve/resident-status";
26
29
  import { CliError } from "./errors";
27
30
 
28
31
  // ─────────────────────────────────────────────────────────────────────────────
@@ -63,6 +66,7 @@ export interface ProcessStatus {
63
66
  version: string | null;
64
67
  started_at: string | null;
65
68
  uptime_seconds: number | null;
69
+ resident: ResidentStatus | null;
66
70
  pid_file: string;
67
71
  log_file: string;
68
72
  log_size_bytes: number | null;
@@ -424,7 +428,7 @@ export interface SpawnDetachedOptions {
424
428
  * self-contained executable like a single `.mjs` file).
425
429
  */
426
430
  entryScript?: string | null;
427
- /** Optional port to embed in the pid-file payload (serve only). */
431
+ /** Optional resident HTTP port to embed in the pid-file payload. */
428
432
  port?: number | null;
429
433
  /** Working directory for the child. Defaults to `process.cwd()`. */
430
434
  cwd?: string;
@@ -736,6 +740,23 @@ export interface StatusOptions {
736
740
  logFile: string;
737
741
  /** Clock override for deterministic tests. Defaults to `Date.now`. */
738
742
  now?: () => number;
743
+ fetchResidentStatus?: (port: number) => Promise<ResidentStatus | null>;
744
+ }
745
+
746
+ async function fetchResidentStatus(
747
+ port: number
748
+ ): Promise<ResidentStatus | null> {
749
+ try {
750
+ const response = await fetch(
751
+ `http://127.0.0.1:${port}/api/resident/status`,
752
+ { signal: AbortSignal.timeout(500) }
753
+ );
754
+ if (!response.ok) return null;
755
+ const body: unknown = await response.json();
756
+ return isResidentStatus(body) ? body : null;
757
+ } catch {
758
+ return null;
759
+ }
739
760
  }
740
761
 
741
762
  /**
@@ -765,6 +786,7 @@ export async function statusProcess(
765
786
  version: null,
766
787
  started_at: null,
767
788
  uptime_seconds: null,
789
+ resident: null,
768
790
  pid_file: options.pidFile,
769
791
  log_file: options.logFile,
770
792
  log_size_bytes: logSize,
@@ -789,33 +811,28 @@ export async function statusProcess(
789
811
  ? Math.max(0, Math.floor((now() - Date.parse(payload.started_at)) / 1000))
790
812
  : null;
791
813
 
792
- // Schema invariant: a live serve must report a numeric port. If the pid-file
793
- // is missing one somehow, fall back to not-running rather than lying.
794
- const portForRunningServe =
795
- running && effectiveKind === "serve"
796
- ? typeof payload.port === "number"
797
- ? payload.port
798
- : null
799
- : running && effectiveKind === "daemon"
800
- ? null
801
- : (payload.port ?? null);
802
-
803
- const runningFinal =
804
- running && !(effectiveKind === "serve" && portForRunningServe === null);
814
+ // Both resident modes expose an HTTP listener. If a live pid-file is
815
+ // missing its port, fall back to not-running rather than claiming a gateway
816
+ // that clients cannot locate.
817
+ const portForRunningProcess =
818
+ running && typeof payload.port === "number" ? payload.port : null;
819
+ const runningFinal = running && portForRunningProcess !== null;
820
+ const resident =
821
+ runningFinal && portForRunningProcess !== null
822
+ ? await (options.fetchResidentStatus ?? fetchResidentStatus)(
823
+ portForRunningProcess
824
+ )
825
+ : null;
805
826
 
806
827
  return {
807
828
  running: runningFinal,
808
829
  pid: payload.pid,
809
- port:
810
- runningFinal && effectiveKind === "serve"
811
- ? portForRunningServe
812
- : effectiveKind === "daemon"
813
- ? null
814
- : (payload.port ?? null),
830
+ port: runningFinal ? portForRunningProcess : (payload.port ?? null),
815
831
  cmd: effectiveKind,
816
832
  version: payload.version,
817
833
  started_at: payload.started_at,
818
834
  uptime_seconds: runningFinal ? uptimeSeconds : null,
835
+ resident,
819
836
  pid_file: options.pidFile,
820
837
  log_file: options.logFile,
821
838
  log_size_bytes: logSize,