@gmickel/gno 1.17.0 → 1.18.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 (51) hide show
  1. package/README.md +14 -2
  2. package/assets/skill/SKILL.md +17 -1
  3. package/assets/skill/mcp-reference.md +21 -0
  4. package/package.json +2 -2
  5. package/src/cli/commands/daemon.ts +69 -2
  6. package/src/cli/commands/models/pull.ts +13 -3
  7. package/src/cli/commands/status.ts +2 -0
  8. package/src/cli/detach.ts +37 -20
  9. package/src/cli/program.ts +74 -27
  10. package/src/config/index.ts +3 -0
  11. package/src/config/types.ts +37 -0
  12. package/src/core/job-manager.ts +19 -0
  13. package/src/core/mutation-generations.ts +33 -0
  14. package/src/llm/cache.ts +13 -3
  15. package/src/llm/nodeLlamaCpp/adapter.ts +10 -1
  16. package/src/llm/nodeLlamaCpp/lifecycle.ts +71 -0
  17. package/src/mcp/context.ts +161 -0
  18. package/src/mcp/http-security.ts +477 -0
  19. package/src/mcp/http-session.ts +272 -0
  20. package/src/mcp/http-transport.ts +370 -0
  21. package/src/mcp/resources/index.ts +141 -134
  22. package/src/mcp/server.ts +19 -79
  23. package/src/mcp/tools/add-collection.ts +3 -1
  24. package/src/mcp/tools/capture.ts +3 -0
  25. package/src/mcp/tools/clear-collection-embeddings.ts +2 -0
  26. package/src/mcp/tools/context.ts +9 -8
  27. package/src/mcp/tools/embed.ts +62 -52
  28. package/src/mcp/tools/index-cmd.ts +88 -74
  29. package/src/mcp/tools/index.ts +22 -2
  30. package/src/mcp/tools/remove-collection.ts +2 -0
  31. package/src/mcp/tools/status.ts +11 -0
  32. package/src/mcp/tools/sync.ts +16 -14
  33. package/src/mcp/tools/workspace-write.ts +7 -3
  34. package/src/serve/background-runtime.ts +12 -212
  35. package/src/serve/embed-scheduler.ts +74 -43
  36. package/src/serve/index.ts +9 -0
  37. package/src/serve/jobs.ts +78 -80
  38. package/src/serve/public/components/HealthCenter.tsx +74 -1
  39. package/src/serve/public/globals.built.css +1 -1
  40. package/src/serve/public/pages/Dashboard.tsx +1 -0
  41. package/src/serve/resident-admission.ts +159 -0
  42. package/src/serve/resident-background-work.ts +39 -0
  43. package/src/serve/resident-request.ts +55 -0
  44. package/src/serve/resident-runtime.ts +490 -0
  45. package/src/serve/resident-status.ts +96 -0
  46. package/src/serve/routes/api.ts +263 -167
  47. package/src/serve/routes/mcp.ts +69 -0
  48. package/src/serve/server.ts +191 -37
  49. package/src/serve/status-model.ts +51 -0
  50. package/src/serve/status.ts +5 -0
  51. package/src/store/sqlite/adapter.ts +26 -9
@@ -10,6 +10,8 @@
10
10
  // CRITICAL: Import setup FIRST to configure custom SQLite before any Database use
11
11
  import "./setup";
12
12
  import { Database } from "bun:sqlite";
13
+ // node:async_hooks binds nested transactions to one async request; Bun has no separate native equivalent.
14
+ import { AsyncLocalStorage } from "node:async_hooks";
13
15
  // node:path basename: no Bun path utilities.
14
16
  import { basename } from "node:path";
15
17
 
@@ -312,8 +314,9 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
312
314
  private dbPath = "";
313
315
  private ftsTokenizer: FtsTokenizer = "unicode61";
314
316
  private configPath = ""; // Set by CLI layer for status output
315
- private txDepth = 0; // Transaction nesting depth
316
317
  private txCounter = 0; // Savepoint counter for unique names
318
+ private readonly txContext = new AsyncLocalStorage<{ depth: number }>();
319
+ private txTail: Promise<void> = Promise.resolve();
317
320
  private contextGeneration = 0;
318
321
 
319
322
  // ─────────────────────────────────────────────────────────────────────────
@@ -407,9 +410,12 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
407
410
  */
408
411
  async withTransaction<T>(fn: () => Promise<T>): Promise<StoreResult<T>> {
409
412
  const db = this.ensureOpen();
410
-
411
- const isOuter = this.txDepth === 0;
413
+ const parent = this.txContext.getStore();
414
+ const isOuter = parent === undefined;
412
415
  const savepoint = `sp_${++this.txCounter}`;
416
+ const releaseWriter = isOuter
417
+ ? await this.acquireTransactionWriter()
418
+ : null;
413
419
 
414
420
  try {
415
421
  if (isOuter) {
@@ -419,9 +425,10 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
419
425
  db.exec(`SAVEPOINT ${savepoint}`);
420
426
  }
421
427
 
422
- this.txDepth += 1;
423
- const value = await fn();
424
- this.txDepth -= 1;
428
+ const value = await this.txContext.run(
429
+ { depth: (parent?.depth ?? 0) + 1 },
430
+ fn
431
+ );
425
432
 
426
433
  if (isOuter) {
427
434
  db.exec("COMMIT");
@@ -431,8 +438,6 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
431
438
 
432
439
  return ok(value);
433
440
  } catch (cause) {
434
- this.txDepth = Math.max(0, this.txDepth - 1);
435
-
436
441
  try {
437
442
  if (isOuter) {
438
443
  db.exec("ROLLBACK");
@@ -447,9 +452,21 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
447
452
  const message =
448
453
  cause instanceof Error ? cause.message : "Transaction failed";
449
454
  return err("TRANSACTION_FAILED", message, cause);
455
+ } finally {
456
+ releaseWriter?.();
450
457
  }
451
458
  }
452
459
 
460
+ private async acquireTransactionWriter(): Promise<() => void> {
461
+ const previous = this.txTail;
462
+ let release!: () => void;
463
+ this.txTail = new Promise<void>((resolve) => {
464
+ release = resolve;
465
+ });
466
+ await previous;
467
+ return release;
468
+ }
469
+
453
470
  /**
454
471
  * Set config path for status output (called by CLI layer).
455
472
  */
@@ -4232,7 +4249,7 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
4232
4249
  // Last updated (max updated_at from documents)
4233
4250
  const lastUpdatedRow = db
4234
4251
  .query<{ last_updated: string | null }, []>(
4235
- "SELECT MAX(updated_at) as last_updated FROM documents"
4252
+ "SELECT strftime('%Y-%m-%dT%H:%M:%fZ', MAX(updated_at)) as last_updated FROM documents"
4236
4253
  )
4237
4254
  .get();
4238
4255