@gmickel/gno 2.4.0 → 2.6.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 (136) hide show
  1. package/README.md +69 -6
  2. package/assets/skill/README.md +5 -1
  3. package/assets/skill/SKILL.md +98 -1
  4. package/assets/skill/cli-reference.md +140 -0
  5. package/assets/skill/examples.md +45 -0
  6. package/assets/skill/mcp-reference.md +62 -0
  7. package/assets/skill/recipes/capture-and-file.md +6 -0
  8. package/assets/skill/recipes/memory-file-decision.md +6 -0
  9. package/assets/skill/recipes/memory-supersede-fact.md +5 -0
  10. package/assets/skill/recipes/session-evidence-lookup.md +98 -0
  11. package/assets/spa-production.json.gz +0 -0
  12. package/browser-extension/artifacts/{gno-browser-clipper-v2.4.0.zip → gno-browser-clipper-v2.6.0.zip} +0 -0
  13. package/browser-extension/artifacts/gno-browser-clipper-v2.6.0.zip.sha256 +1 -0
  14. package/browser-extension/dist/manifest.json +1 -1
  15. package/package.json +2 -1
  16. package/spec/cli.md +358 -24
  17. package/spec/compiled-context.md +68 -0
  18. package/spec/mcp.md +223 -2
  19. package/spec/output-schemas/capture-receipt.schema.json +3 -0
  20. package/spec/output-schemas/compiled-context-check.schema.json +44 -0
  21. package/spec/output-schemas/compiled-context-file.schema.json +165 -0
  22. package/spec/output-schemas/compiled-context-preview.schema.json +142 -0
  23. package/spec/output-schemas/mcp-capture-result.schema.json +3 -0
  24. package/spec/output-schemas/memory-remember.schema.json +8 -2
  25. package/spec/output-schemas/request-status.schema.json +113 -0
  26. package/spec/output-schemas/sessions-automation-run.schema.json +46 -0
  27. package/spec/output-schemas/sessions-discovery.schema.json +38 -0
  28. package/spec/output-schemas/sessions-import-receipt.schema.json +156 -0
  29. package/spec/output-schemas/sessions-status.schema.json +432 -0
  30. package/src/app/compiled-context-files.ts +361 -0
  31. package/src/app/compiled-context.ts +240 -0
  32. package/src/app/context-surface.ts +7 -2
  33. package/src/cli/commands/ask.ts +14 -2
  34. package/src/cli/commands/audit.ts +4 -0
  35. package/src/cli/commands/capture.ts +55 -96
  36. package/src/cli/commands/context-compiled.ts +136 -0
  37. package/src/cli/commands/daemon.ts +41 -0
  38. package/src/cli/commands/ls.ts +3 -0
  39. package/src/cli/commands/memory.ts +12 -3
  40. package/src/cli/commands/request-status.ts +59 -0
  41. package/src/cli/commands/reset.ts +39 -5
  42. package/src/cli/commands/sessions.ts +713 -0
  43. package/src/cli/commands/shared.ts +14 -1
  44. package/src/cli/errors.ts +10 -3
  45. package/src/cli/program.ts +458 -1
  46. package/src/cli/session-binding.ts +49 -0
  47. package/src/config/types.ts +8 -0
  48. package/src/core/capture-publish.ts +239 -0
  49. package/src/core/capture-sync.ts +3 -0
  50. package/src/core/compiled-context.ts +254 -0
  51. package/src/core/context-budget.ts +2 -10
  52. package/src/core/file-lock.ts +22 -5
  53. package/src/core/folder-setup-planning.ts +2 -1
  54. package/src/core/memory-remember.ts +233 -122
  55. package/src/core/memory-types.ts +11 -0
  56. package/src/core/network-boundary-inventory.ts +16 -0
  57. package/src/core/request-receipts.ts +671 -0
  58. package/src/core/setup-receipt.ts +27 -20
  59. package/src/core/typed-metadata.ts +4 -0
  60. package/src/core/validation.ts +9 -2
  61. package/src/core/windows-private-path.ts +96 -0
  62. package/src/index.ts +11 -2
  63. package/src/ingestion/compiled-context.ts +15 -0
  64. package/src/ingestion/sync.ts +40 -8
  65. package/src/ingestion/walker.ts +5 -4
  66. package/src/llm/nodeLlamaCpp/simulator-install.ts +6 -2
  67. package/src/mcp/context.ts +8 -0
  68. package/src/mcp/http-egress.ts +15 -3
  69. package/src/mcp/http-transport.ts +2 -0
  70. package/src/mcp/retrieval-warnings.ts +24 -0
  71. package/src/mcp/tools/ask.ts +14 -1
  72. package/src/mcp/tools/capture.ts +87 -83
  73. package/src/mcp/tools/context.ts +46 -2
  74. package/src/mcp/tools/index.ts +119 -7
  75. package/src/mcp/tools/memory-remember.ts +7 -0
  76. package/src/mcp/tools/memory-shared.ts +7 -1
  77. package/src/mcp/tools/query.ts +3 -1
  78. package/src/mcp/tools/request-status.ts +73 -0
  79. package/src/mcp/tools/search.ts +3 -1
  80. package/src/mcp/tools/sessions.ts +208 -0
  81. package/src/mcp/tools/vsearch.ts +3 -1
  82. package/src/sdk/client.ts +252 -89
  83. package/src/sdk/index.ts +13 -0
  84. package/src/sdk/types.ts +82 -3
  85. package/src/serve/capture-service.ts +98 -32
  86. package/src/serve/compiled-context.ts +84 -0
  87. package/src/serve/config-sync.ts +3 -2
  88. package/src/serve/public/app.tsx +15 -1
  89. package/src/serve/public/components/CaptureModal.tsx +26 -8
  90. package/src/serve/public/components/sessions/AutomationPanel.tsx +800 -0
  91. package/src/serve/public/components/sessions/ImportReceipt.tsx +238 -0
  92. package/src/serve/public/components/sessions/SessionSearch.tsx +286 -0
  93. package/src/serve/public/components/sessions/SourcesPanel.tsx +541 -0
  94. package/src/serve/public/components/sessions/api.ts +40 -0
  95. package/src/serve/public/components/sessions/snippet.tsx +53 -0
  96. package/src/serve/public/globals.built.css +1 -1
  97. package/src/serve/public/hooks/use-api.ts +10 -2
  98. package/src/serve/public/lib/request-intent.ts +69 -0
  99. package/src/serve/public/lib/workspace-actions.ts +12 -1
  100. package/src/serve/public/lib/workspace-tabs.ts +4 -0
  101. package/src/serve/public/pages/CompiledContext.tsx +364 -0
  102. package/src/serve/public/pages/Dashboard.tsx +17 -0
  103. package/src/serve/public/pages/DocView.tsx +15 -1
  104. package/src/serve/public/pages/DocumentEditor.tsx +139 -96
  105. package/src/serve/public/pages/Sessions.tsx +350 -0
  106. package/src/serve/resident-runtime.ts +43 -3
  107. package/src/serve/routes/api.ts +476 -147
  108. package/src/serve/routes/sessions.ts +766 -0
  109. package/src/serve/security.ts +9 -0
  110. package/src/serve/server.ts +248 -3
  111. package/src/serve/session-automation.ts +146 -0
  112. package/src/serve/spa-production-build.ts +6 -5
  113. package/src/sessions/archive.ts +348 -0
  114. package/src/sessions/automation-state.ts +444 -0
  115. package/src/sessions/automation-status.ts +239 -0
  116. package/src/sessions/automation.ts +1169 -0
  117. package/src/sessions/binding.ts +105 -0
  118. package/src/sessions/claude-hook.ts +240 -0
  119. package/src/sessions/config.ts +176 -0
  120. package/src/sessions/format.ts +191 -0
  121. package/src/sessions/import-child-env.ts +8 -0
  122. package/src/sessions/import-child.ts +152 -0
  123. package/src/sessions/parsers/claude-code.ts +259 -0
  124. package/src/sessions/parsers/codex.ts +303 -0
  125. package/src/sessions/parsers/hermes.ts +248 -0
  126. package/src/sessions/parsers/openclaw.ts +496 -0
  127. package/src/sessions/parsers/shared.ts +184 -0
  128. package/src/sessions/sanitize.ts +222 -0
  129. package/src/sessions/service.ts +1533 -0
  130. package/src/sessions/setup.ts +477 -0
  131. package/src/sessions/sources.ts +518 -0
  132. package/src/sessions/state.ts +118 -0
  133. package/src/sessions/types.ts +457 -0
  134. package/src/store/sqlite/adapter.ts +68 -16
  135. package/src/store/sqlite/scoped-index.ts +9 -0
  136. package/browser-extension/artifacts/gno-browser-clipper-v2.4.0.zip.sha256 +0 -1
package/src/sdk/client.ts CHANGED
@@ -1,13 +1,16 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+
4
+ import type { Config } from "../config/types";
1
5
  /**
2
6
  * GNO SDK client.
3
7
  *
4
8
  * @module src/sdk/client
5
9
  */
6
-
7
- import { mkdir } from "node:fs/promises";
8
- import { dirname } from "node:path";
9
-
10
- import type { Config } from "../config/types";
10
+ import type {
11
+ CompiledContextPreviewInput,
12
+ CompiledContextCheckInput,
13
+ } from "../core/compiled-context";
11
14
  import type { DownloadPolicy } from "../llm/policy";
12
15
  import type { EmbeddingPort, GenerationPort, RerankPort } from "../llm/types";
13
16
  import type { AskResult, SearchResults } from "../pipeline/types";
@@ -18,6 +21,7 @@ import type {
18
21
  GnoCaptureOptions,
19
22
  GnoCaptureResult,
20
23
  GnoClient,
24
+ GnoRequestStatusResult,
21
25
  GnoCreateFolderOptions,
22
26
  GnoCreateFolderResult,
23
27
  GnoCreateNoteOptions,
@@ -46,6 +50,11 @@ import type {
46
50
  GnoRenameNoteApplyOptions,
47
51
  GnoRenameNoteOptions,
48
52
  GnoSearchOptions,
53
+ GnoSessionsAutomationRunResult,
54
+ GnoSessionsDiscovery,
55
+ GnoSessionsImportInput,
56
+ GnoSessionsImportReceipt,
57
+ GnoSessionsStatus,
49
58
  GnoUpdateOptions,
50
59
  GnoVectorSearchOptions,
51
60
  KnowledgeChangesResult,
@@ -59,6 +68,15 @@ import type {
59
68
  SectionTargetV1,
60
69
  } from "./types";
61
70
 
71
+ import {
72
+ previewCompiledContext,
73
+ checkCompiledContext,
74
+ } from "../app/compiled-context";
75
+ import {
76
+ compileContextFile,
77
+ checkContextFile,
78
+ refreshContextFile,
79
+ } from "../app/compiled-context-files";
62
80
  import {
63
81
  decorateUriForIndex,
64
82
  DEFAULT_INDEX_NAME,
@@ -78,17 +96,17 @@ import { buildVerifiedAsk } from "../app/verified-ask";
78
96
  import {
79
97
  buildContentTypeBoostStatus,
80
98
  ConfigSchema,
99
+ getConfigPaths,
81
100
  loadConfig,
82
101
  normalizeConfigContentTypes,
83
102
  normalizeContentTypes,
84
103
  } from "../config";
85
104
  import {
86
- buildCaptureReceipt,
87
- type CapturePlan,
105
+ CaptureSyncError,
88
106
  listCaptureDiskRelPaths,
89
107
  planCapture,
90
108
  } from "../core/capture";
91
- import { writeCapturePlanFile } from "../core/capture-write";
109
+ import { publishCapture } from "../core/capture-publish";
92
110
  import { projectCollectionEgressPolicy } from "../core/collection-egress-policy-projection";
93
111
  import { CollectionEgressPolicyService } from "../core/collection-egress-policy-service";
94
112
  import { applyConfigChange } from "../core/config-mutation";
@@ -128,6 +146,12 @@ import {
128
146
  ProjectAffinityInputError,
129
147
  resolveRemoteProjectAffinity,
130
148
  } from "../core/project-affinity-surface";
149
+ import {
150
+ localRequestLedger,
151
+ readRequestStatus,
152
+ RequestReceiptError,
153
+ type RequestReceiptErrorCode,
154
+ } from "../core/request-receipts";
131
155
  import { RetrievalTraceManagementService } from "../core/retrieval-trace-management";
132
156
  import {
133
157
  finishRetrievalTraceAfterError,
@@ -157,7 +181,6 @@ import {
157
181
  normalizeMetadataPredicate,
158
182
  type MetadataPredicate,
159
183
  } from "../core/typed-metadata";
160
- import { writeLeasePath } from "../core/write-lease";
161
184
  import {
162
185
  defaultSyncService,
163
186
  type SyncResult,
@@ -181,6 +204,10 @@ import { searchHybrid } from "../pipeline/hybrid";
181
204
  import { RequestHydration } from "../pipeline/hydration";
182
205
  import { searchBm25 } from "../pipeline/search";
183
206
  import { searchVectorWithEmbedding } from "../pipeline/vsearch";
207
+ import { runAutomationProfile } from "../sessions/automation";
208
+ import { assertSessionBinding } from "../sessions/binding";
209
+ import { SessionsService } from "../sessions/service";
210
+ import { SESSIONS_VALIDATION_CODES, SessionsError } from "../sessions/types";
184
211
  import { SqliteAdapter } from "../store/sqlite/adapter";
185
212
  import { openScopedIndexStore } from "../store/sqlite/scoped-index";
186
213
  import { createVectorIndexPort } from "../store/vector";
@@ -302,6 +329,19 @@ async function resolveClientState(
302
329
  options.indexName ?? DEFAULT_INDEX_NAME
303
330
  );
304
331
  const dbPath = options.dbPath ?? getIndexDbPath(indexName);
332
+ try {
333
+ await assertSessionBinding({
334
+ config,
335
+ configPath:
336
+ configSource === "inline"
337
+ ? "<inline-config>"
338
+ : (options.configPath ?? getConfigPaths().configFile),
339
+ indexName,
340
+ dbPath,
341
+ });
342
+ } catch (cause) {
343
+ throw toSessionsSdkError(cause);
344
+ }
305
345
  await mkdir(dirname(dbPath), { recursive: true });
306
346
 
307
347
  const store = new SqliteAdapter();
@@ -325,6 +365,16 @@ async function resolveClientState(
325
365
  };
326
366
  }
327
367
 
368
+ /** Map a sessions error onto the SDK family; the sessions code survives in `details.code`. */
369
+ function toSessionsSdkError(cause: unknown): unknown {
370
+ if (!(cause instanceof SessionsError)) return cause;
371
+ return sdkError(
372
+ SESSIONS_VALIDATION_CODES.has(cause.code) ? "VALIDATION" : "RUNTIME",
373
+ cause.message,
374
+ { cause, details: { code: cause.code } }
375
+ );
376
+ }
377
+
328
378
  /** SDK error family per memory code; exhaustive so a new code fails to compile. */
329
379
  const MEMORY_ERROR_TO_SDK: Readonly<Record<MemoryErrorCode, GnoSdkErrorCode>> =
330
380
  {
@@ -351,9 +401,28 @@ const MEMORY_ERROR_TO_SDK: Readonly<Record<MemoryErrorCode, GnoSdkErrorCode>> =
351
401
  MEMORY_QUERY_FAILED: "RUNTIME",
352
402
  };
353
403
 
404
+ const REQUEST_ERROR_TO_SDK: Record<RequestReceiptErrorCode, GnoSdkErrorCode> = {
405
+ REQUEST_ID_INVALID: "VALIDATION",
406
+ REQUEST_ID_CONFLICT: "VALIDATION",
407
+ REQUEST_EXPIRED: "VALIDATION",
408
+ REQUEST_PENDING: "RUNTIME",
409
+ REQUEST_RECOVERY_CONFLICT: "RUNTIME",
410
+ REQUEST_CAPACITY_EXHAUSTED: "RUNTIME",
411
+ REQUEST_LEDGER_UNAVAILABLE: "RUNTIME",
412
+ };
413
+
414
+ /** Request receipt errors carry their stable code in `details.code`. */
415
+ function toRequestSdkError(cause: unknown): unknown {
416
+ if (!(cause instanceof RequestReceiptError)) return cause;
417
+ return sdkError(REQUEST_ERROR_TO_SDK[cause.code], cause.message, {
418
+ cause,
419
+ details: { code: cause.code },
420
+ });
421
+ }
422
+
354
423
  /** Map a core MemoryError onto the SDK error family; the memory code survives in `details.code`. */
355
424
  function toMemorySdkError(cause: unknown): unknown {
356
- if (!(cause instanceof MemoryError)) return cause;
425
+ if (!(cause instanceof MemoryError)) return toRequestSdkError(cause);
357
426
  return sdkError(MEMORY_ERROR_TO_SDK[cause.code], cause.message, {
358
427
  cause,
359
428
  details: { code: cause.code },
@@ -1255,6 +1324,61 @@ class GnoClientImpl implements GnoClient {
1255
1324
  }
1256
1325
  }
1257
1326
 
1327
+ compiledContextPreview(
1328
+ input: CompiledContextPreviewInput
1329
+ ): ReturnType<typeof previewCompiledContext> {
1330
+ this.assertOpen();
1331
+ return previewCompiledContext(input, {
1332
+ store: this.store,
1333
+ config: this.config,
1334
+ indexName: this.indexName,
1335
+ });
1336
+ }
1337
+
1338
+ compiledContextCheck(
1339
+ input: CompiledContextCheckInput
1340
+ ): ReturnType<typeof checkCompiledContext> {
1341
+ this.assertOpen();
1342
+ return checkCompiledContext(input, {
1343
+ store: this.store,
1344
+ config: this.config,
1345
+ indexName: this.indexName,
1346
+ });
1347
+ }
1348
+
1349
+ compileContextFile(
1350
+ input: Parameters<typeof compileContextFile>[0]
1351
+ ): ReturnType<typeof compileContextFile> {
1352
+ this.assertOpen();
1353
+ return compileContextFile(input, {
1354
+ store: this.store,
1355
+ config: this.config,
1356
+ indexName: this.indexName,
1357
+ });
1358
+ }
1359
+
1360
+ checkContextFile(
1361
+ input: Parameters<typeof checkContextFile>[0]
1362
+ ): ReturnType<typeof checkContextFile> {
1363
+ this.assertOpen();
1364
+ return checkContextFile(input, {
1365
+ store: this.store,
1366
+ config: this.config,
1367
+ indexName: this.indexName,
1368
+ });
1369
+ }
1370
+
1371
+ refreshContextFile(
1372
+ input: Parameters<typeof refreshContextFile>[0]
1373
+ ): ReturnType<typeof refreshContextFile> {
1374
+ this.assertOpen();
1375
+ return refreshContextFile(
1376
+ input,
1377
+ { store: this.store, config: this.config, indexName: this.indexName },
1378
+ (request) => this.context(request)
1379
+ );
1380
+ }
1381
+
1258
1382
  async verifyContext(
1259
1383
  capsule: GnoContextResult
1260
1384
  ): Promise<GnoContextVerificationResult> {
@@ -1278,6 +1402,8 @@ class GnoClientImpl implements GnoClient {
1278
1402
  requestedIndexName: resolution.value.indexName,
1279
1403
  config: this.config,
1280
1404
  configPath: this.configPath,
1405
+ }).catch((cause: unknown) => {
1406
+ throw toSessionsSdkError(cause);
1281
1407
  });
1282
1408
  try {
1283
1409
  const result = await getDocumentByRef(
@@ -1317,6 +1443,8 @@ class GnoClientImpl implements GnoClient {
1317
1443
  requestedIndexName: resolution.value.indexName,
1318
1444
  config: this.config,
1319
1445
  configPath: this.configPath,
1446
+ }).catch((cause: unknown) => {
1447
+ throw toSessionsSdkError(cause);
1320
1448
  });
1321
1449
  try {
1322
1450
  const result = await multiGetDocuments(
@@ -1723,7 +1851,8 @@ class GnoClientImpl implements GnoClient {
1723
1851
  store: this.store,
1724
1852
  config: this.config,
1725
1853
  collections: this.config.collections,
1726
- lockPath: writeLeasePath(this.dbPath),
1854
+ lockPath: this.requestLedger().lockPath,
1855
+ requests: this.requestLedger(),
1727
1856
  embedPort: ports.embedPort,
1728
1857
  vectorIndex: ports.vectorIndex,
1729
1858
  })
@@ -1735,6 +1864,62 @@ class GnoClientImpl implements GnoClient {
1735
1864
  }
1736
1865
  }
1737
1866
 
1867
+ private sessionsService(): SessionsService {
1868
+ this.assertOpen();
1869
+ return new SessionsService({
1870
+ config: this.config,
1871
+ configPath: this.configPath ?? getConfigPaths().configFile,
1872
+ indexName: this.indexName,
1873
+ store: this.store,
1874
+ });
1875
+ }
1876
+
1877
+ async sessionsStatus(): Promise<GnoSessionsStatus> {
1878
+ try {
1879
+ return await this.sessionsService().status();
1880
+ } catch (cause) {
1881
+ throw toSessionsSdkError(cause);
1882
+ }
1883
+ }
1884
+
1885
+ async discoverSessions(): Promise<GnoSessionsDiscovery> {
1886
+ try {
1887
+ return await this.sessionsService().discover();
1888
+ } catch (cause) {
1889
+ throw toSessionsSdkError(cause);
1890
+ }
1891
+ }
1892
+
1893
+ async importSessions(
1894
+ input: GnoSessionsImportInput
1895
+ ): Promise<GnoSessionsImportReceipt> {
1896
+ try {
1897
+ // The SDK runs in the owner's process, so explicit paths are allowed.
1898
+ return await this.sessionsService().import(input, { allowPaths: true });
1899
+ } catch (cause) {
1900
+ throw toSessionsSdkError(cause);
1901
+ }
1902
+ }
1903
+
1904
+ async runSessionsAutomation(input: {
1905
+ profileId: string;
1906
+ }): Promise<GnoSessionsAutomationRunResult> {
1907
+ this.assertOpen();
1908
+ try {
1909
+ return await runAutomationProfile(
1910
+ {
1911
+ configPath: this.configPath ?? getConfigPaths().configFile,
1912
+ indexName: this.indexName,
1913
+ store: this.store,
1914
+ },
1915
+ input.profileId,
1916
+ { trigger: "manual" }
1917
+ );
1918
+ } catch (cause) {
1919
+ throw toSessionsSdkError(cause);
1920
+ }
1921
+ }
1922
+
1738
1923
  async remember(input: GnoRememberInput): Promise<GnoRememberResult> {
1739
1924
  return this.withMemoryService(input?.collection, (service) =>
1740
1925
  service.remember(input)
@@ -1756,98 +1941,76 @@ class GnoClientImpl implements GnoClient {
1756
1941
  `Collection not found: ${options.collection}`
1757
1942
  );
1758
1943
  }
1759
-
1760
- const existingList = await this.store.listDocuments(collection.name);
1761
- if (!existingList.ok) {
1762
- throw sdkError("STORE", existingList.error.message, {
1763
- cause: existingList.error.cause,
1764
- });
1765
- }
1766
- const { overwrite: _unsupportedOverwrite, ...captureOptions } =
1767
- options as GnoCaptureOptions & { overwrite?: unknown };
1944
+ const {
1945
+ overwrite: _unsupportedOverwrite,
1946
+ requestId,
1947
+ ...captureOptions
1948
+ } = options as GnoCaptureOptions & { overwrite?: unknown };
1768
1949
  if (_unsupportedOverwrite !== undefined) {
1769
1950
  throw sdkError(
1770
1951
  "VALIDATION",
1771
1952
  "overwrite is not supported by client.capture(); use collisionPolicy instead"
1772
1953
  );
1773
1954
  }
1955
+ const input = { ...captureOptions, collection: collection.name };
1774
1956
 
1775
- let plan: CapturePlan;
1776
1957
  try {
1777
- plan = planCapture({
1778
- input: {
1779
- ...captureOptions,
1780
- collection: collection.name,
1958
+ const published = await publishCapture({
1959
+ collection,
1960
+ store: this.store,
1961
+ lockPath: this.requestLedger().lockPath,
1962
+ reportSyncFailure: true,
1963
+ config: this.config,
1964
+ plan: async () => {
1965
+ const existingList = await this.store.listDocuments(collection.name);
1966
+ if (!existingList.ok) {
1967
+ throw sdkError("STORE", existingList.error.message, {
1968
+ cause: existingList.error.cause,
1969
+ });
1970
+ }
1971
+ try {
1972
+ return planCapture({
1973
+ input,
1974
+ existingRelPaths: existingList.value.map((doc) => doc.relPath),
1975
+ diskRelPaths: await listCaptureDiskRelPaths(collection.path),
1976
+ });
1977
+ } catch (error) {
1978
+ throw sdkError(
1979
+ "VALIDATION",
1980
+ error instanceof Error ? error.message : String(error)
1981
+ );
1982
+ }
1781
1983
  },
1782
- existingRelPaths: existingList.value.map((doc) => doc.relPath),
1783
- diskRelPaths: await listCaptureDiskRelPaths(collection.path),
1984
+ request:
1985
+ requestId === undefined
1986
+ ? undefined
1987
+ : { ...this.requestLedger(), requestId, input },
1784
1988
  });
1785
- } catch (error) {
1786
- throw sdkError(
1787
- "VALIDATION",
1788
- error instanceof Error ? error.message : String(error)
1789
- );
1790
- }
1791
-
1792
- const fullPath = `${collection.path}/${plan.relPath}`;
1793
- if (plan.openedExisting) {
1794
- const existingDoc = await this.store.getDocument(
1795
- collection.name,
1796
- plan.relPath
1797
- );
1798
- if (!existingDoc.ok) {
1799
- throw sdkError("STORE", existingDoc.error.message, {
1800
- cause: existingDoc.error.cause,
1989
+ return published.request
1990
+ ? { ...published.receipt, request: published.request }
1991
+ : published.receipt;
1992
+ } catch (cause) {
1993
+ if (cause instanceof CaptureSyncError) {
1994
+ throw sdkError("RUNTIME", cause.message, {
1995
+ cause,
1996
+ details: { code: cause.code, absPath: cause.absPath },
1801
1997
  });
1802
1998
  }
1803
- return buildCaptureReceipt({
1804
- plan,
1805
- absPath: fullPath,
1806
- docid: existingDoc.value?.docid,
1807
- sync: existingDoc.value
1808
- ? { status: "completed" }
1809
- : {
1810
- status: "skipped",
1811
- reason: "Existing file is not indexed yet.",
1812
- },
1813
- });
1999
+ throw toRequestSdkError(cause);
1814
2000
  }
2001
+ }
1815
2002
 
1816
- await mkdir(dirname(fullPath), { recursive: true });
1817
- await writeCapturePlanFile(plan, fullPath);
1818
- const syncResults = await defaultSyncService.syncFiles(
1819
- collection,
1820
- this.store,
1821
- [plan.relPath],
1822
- withContentTypeRules(
1823
- {
1824
- runUpdateCmd: false,
1825
- gitPull: false,
1826
- },
1827
- this.config
1828
- )
1829
- );
1830
- const syncResult = syncResults[0];
1831
- const docResult = await this.store.getDocument(
1832
- collection.name,
1833
- plan.relPath
1834
- );
1835
- const docid = docResult.ok ? docResult.value?.docid : undefined;
1836
- return buildCaptureReceipt({
1837
- plan,
1838
- absPath: fullPath,
1839
- docid: syncResult?.docid ?? docid,
1840
- sync:
1841
- syncResult?.status === "error"
1842
- ? {
1843
- status: "failed",
1844
- error:
1845
- syncResult.errorMessage ??
1846
- syncResult.errorCode ??
1847
- "Unknown sync error",
1848
- }
1849
- : { status: "completed" },
1850
- });
2003
+ private requestLedger() {
2004
+ return localRequestLedger(this.dbPath);
2005
+ }
2006
+
2007
+ async requestStatus(requestId: string): Promise<GnoRequestStatusResult> {
2008
+ this.assertOpen();
2009
+ try {
2010
+ return await readRequestStatus({ ...this.requestLedger(), requestId });
2011
+ } catch (cause) {
2012
+ throw toRequestSdkError(cause);
2013
+ }
1851
2014
  }
1852
2015
 
1853
2016
  async createFolder(
package/src/sdk/index.ts CHANGED
@@ -62,10 +62,16 @@ export type {
62
62
  GnoRecallResult,
63
63
  GnoRememberInput,
64
64
  GnoRememberResult,
65
+ GnoRequestStatusResult,
65
66
  GnoRenameNoteApplyOptions,
66
67
  GnoRenameNoteOptions,
67
68
  GnoProjectHintOptions,
68
69
  GnoSearchOptions,
70
+ GnoSessionsDiscovery,
71
+ GnoSessionsImportInput,
72
+ GnoSessionsImportReceipt,
73
+ GnoSessionsAutomationRunResult,
74
+ GnoSessionsStatus,
69
75
  GnoSkippedDocument,
70
76
  GnoUpdateOptions,
71
77
  GnoVectorSearchOptions,
@@ -128,3 +134,10 @@ export type {
128
134
  RetrievalTracePurgeResult,
129
135
  RetrievalTraceSummary,
130
136
  } from "../core/retrieval-trace-management";
137
+
138
+ export type {
139
+ CompiledContextPreviewInput,
140
+ CompiledContextCheckInput,
141
+ CompiledContextPreview,
142
+ CompiledContextCheck,
143
+ } from "../core/compiled-context";
package/src/sdk/types.ts CHANGED
@@ -1,9 +1,17 @@
1
+ import type {
2
+ previewCompiledContext,
3
+ checkCompiledContext,
4
+ } from "../app/compiled-context";
5
+ import type {
6
+ compileContextFile,
7
+ checkContextFile,
8
+ refreshContextFile,
9
+ } from "../app/compiled-context-files";
1
10
  /**
2
11
  * Public SDK types.
3
12
  *
4
13
  * @module src/sdk/types
5
14
  */
6
-
7
15
  import type {
8
16
  ContextCapsuleBuildInput,
9
17
  ContextRuntimeErrorCode,
@@ -18,6 +26,10 @@ import type {
18
26
  CollectionEgressPolicyState,
19
27
  EgressRelaxationConfirmation,
20
28
  } from "../core/collection-egress-policy-service";
29
+ import type {
30
+ CompiledContextPreviewInput,
31
+ CompiledContextCheckInput,
32
+ } from "../core/compiled-context";
21
33
  import type {
22
34
  ContextCapsuleErrorCode,
23
35
  ContextCapsuleV1,
@@ -55,6 +67,10 @@ import type {
55
67
  } from "../core/memory";
56
68
  import type { NoteCollisionPolicy } from "../core/note-creation";
57
69
  import type { NotePresetId } from "../core/note-presets";
70
+ import type {
71
+ RequestReceiptInfo,
72
+ RequestStatusResult,
73
+ } from "../core/request-receipts";
58
74
  import type {
59
75
  RetrievalTraceDeleteResult,
60
76
  RetrievalTraceDetail,
@@ -82,6 +98,13 @@ import type {
82
98
  SearchOptions,
83
99
  SearchResults,
84
100
  } from "../pipeline/types";
101
+ import type { SessionImportInput } from "../sessions/service";
102
+ import type {
103
+ SessionAutomationRunResult,
104
+ SessionImportReceipt,
105
+ SessionsDiscovery,
106
+ SessionsStatus,
107
+ } from "../sessions/types";
85
108
  import type { IndexStatus } from "../store/types";
86
109
 
87
110
  export type {
@@ -251,11 +274,25 @@ export interface GnoCreateNoteResult {
251
274
  createdWithSuffix?: boolean;
252
275
  }
253
276
 
254
- export interface GnoCaptureOptions extends Omit<CaptureInput, "overwrite"> {}
277
+ export interface GnoCaptureOptions extends Omit<CaptureInput, "overwrite"> {
278
+ /** Opt-in retry identity; reuse it only to retry this same capture. */
279
+ requestId?: string;
280
+ }
281
+
282
+ export type GnoCaptureResult = CaptureReceipt & {
283
+ /** Present when the call carried a requestId. */
284
+ request?: RequestReceiptInfo;
285
+ };
255
286
 
256
- export type GnoCaptureResult = CaptureReceipt;
287
+ /** Lookup of a capture/remember request ID in the local-owner namespace. */
288
+ export type GnoRequestStatusResult = RequestStatusResult;
257
289
 
258
290
  /** Shared memory contract (identical on CLI, MCP, REST, and SDK). */
291
+ export type GnoSessionsStatus = SessionsStatus;
292
+ export type GnoSessionsDiscovery = SessionsDiscovery;
293
+ export type GnoSessionsImportReceipt = SessionImportReceipt;
294
+ export type GnoSessionsImportInput = SessionImportInput;
295
+ export type GnoSessionsAutomationRunResult = SessionAutomationRunResult;
259
296
  export type GnoRememberInput = RememberInput;
260
297
  export type GnoRememberResult = RememberResult;
261
298
  export type GnoRecallInput = RecallInput;
@@ -328,6 +365,21 @@ export interface GnoClient {
328
365
  query(query: string, options?: GnoQueryOptions): Promise<SearchResults>;
329
366
  ask(query: string, options?: GnoAskOptions): Promise<AskResult>;
330
367
  context(input: GnoContextInput): Promise<GnoContextResult>;
368
+ compiledContextPreview(
369
+ input: CompiledContextPreviewInput
370
+ ): ReturnType<typeof previewCompiledContext>;
371
+ compiledContextCheck(
372
+ input: CompiledContextCheckInput
373
+ ): ReturnType<typeof checkCompiledContext>;
374
+ compileContextFile(
375
+ input: Parameters<typeof compileContextFile>[0]
376
+ ): ReturnType<typeof compileContextFile>;
377
+ checkContextFile(
378
+ input: Parameters<typeof checkContextFile>[0]
379
+ ): ReturnType<typeof checkContextFile>;
380
+ refreshContextFile(
381
+ input: Parameters<typeof refreshContextFile>[0]
382
+ ): ReturnType<typeof refreshContextFile>;
331
383
  verifyContext(
332
384
  capsule: ContextCapsuleV1
333
385
  ): Promise<GnoContextVerificationResult>;
@@ -387,6 +439,11 @@ export interface GnoClient {
387
439
  embed(options?: GnoEmbedOptions): Promise<GnoEmbedResult>;
388
440
  index(options?: GnoIndexOptions): Promise<GnoIndexResult>;
389
441
  capture(options: GnoCaptureOptions): Promise<GnoCaptureResult>;
442
+ /**
443
+ * Look up a capture/remember `requestId` before retrying it: pending,
444
+ * committed (with a content-free result pointer), expired, or not_found.
445
+ */
446
+ requestStatus(requestId: string): Promise<GnoRequestStatusResult>;
390
447
  /**
391
448
  * Store one fact in a memory-managed collection, or propose candidates when
392
449
  * `decision` is omitted. Requires caller + session identity and explicit
@@ -398,6 +455,28 @@ export interface GnoClient {
398
455
  * The result carries a content-free fencing receipt.
399
456
  */
400
457
  recall(input: GnoRecallInput): Promise<GnoRecallResult>;
458
+ /**
459
+ * Session-archive status for a client opened on the dedicated archive
460
+ * config/index pair. Throws VALIDATION (`details.code`
461
+ * SESSIONS_NOT_CONFIGURED) on any other config.
462
+ */
463
+ sessionsStatus(): Promise<GnoSessionsStatus>;
464
+ /** Preview supported local session sources on this host. Never imports. */
465
+ discoverSessions(): Promise<GnoSessionsDiscovery>;
466
+ /**
467
+ * Manually import a registered source (`sourceId`) or explicit local paths
468
+ * (`paths` + `collection`) into the archive. Returns the shared receipt.
469
+ */
470
+ importSessions(
471
+ input: GnoSessionsImportInput
472
+ ): Promise<GnoSessionsImportReceipt>;
473
+ /**
474
+ * Run one configured automation profile now through the manual importer.
475
+ * Hooks and schedules are enabled only from the CLI or a same-host browser.
476
+ */
477
+ runSessionsAutomation(input: {
478
+ profileId: string;
479
+ }): Promise<GnoSessionsAutomationRunResult>;
401
480
  createNote(options: GnoCreateNoteOptions): Promise<GnoCreateNoteResult>;
402
481
  createFolder(options: GnoCreateFolderOptions): Promise<GnoCreateFolderResult>;
403
482
  previewRenameNote(