@gmickel/gno 1.25.1 → 1.26.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 (56) hide show
  1. package/README.md +10 -4
  2. package/assets/skill/SKILL.md +29 -17
  3. package/browser-extension/artifacts/{gno-browser-clipper-v1.25.1.zip → gno-browser-clipper-v1.26.0.zip} +0 -0
  4. package/browser-extension/artifacts/gno-browser-clipper-v1.26.0.zip.sha256 +1 -0
  5. package/browser-extension/dist/manifest.json +1 -1
  6. package/package.json +1 -1
  7. package/spec/cli.md +146 -4
  8. package/spec/db/schema.sql +1 -1
  9. package/spec/output-schemas/project-profile-apply.schema.json +209 -0
  10. package/spec/output-schemas/project-profile-command.schema.json +160 -0
  11. package/spec/output-schemas/query-diagnose.schema.json +7 -1
  12. package/spec/output-schemas/setup-profile-result.schema.json +87 -0
  13. package/spec/project-profile.schema.json +301 -0
  14. package/src/cli/commands/collection/add.ts +39 -45
  15. package/src/cli/commands/collection/remove.ts +28 -28
  16. package/src/cli/commands/collection/rename.ts +55 -73
  17. package/src/cli/commands/context/add.ts +37 -26
  18. package/src/cli/commands/context/rm.ts +47 -20
  19. package/src/cli/commands/init.ts +55 -125
  20. package/src/cli/commands/models/use.ts +43 -38
  21. package/src/cli/commands/profile-apply.ts +334 -0
  22. package/src/cli/commands/profile.ts +409 -0
  23. package/src/cli/commands/setup-activation.ts +205 -54
  24. package/src/cli/commands/setup-profile.ts +223 -0
  25. package/src/cli/commands/setup.ts +3 -0
  26. package/src/cli/program.ts +110 -9
  27. package/src/config/index.ts +3 -0
  28. package/src/config/project-profile.ts +367 -0
  29. package/src/config/saver.ts +16 -7
  30. package/src/config/types.ts +42 -0
  31. package/src/core/config-mutation.ts +138 -76
  32. package/src/core/config-write-lock.ts +89 -0
  33. package/src/core/context-identity.ts +16 -0
  34. package/src/core/context-resolver.ts +2 -12
  35. package/src/core/folder-setup-planning.ts +6 -21
  36. package/src/core/folder-setup.ts +30 -2
  37. package/src/core/path-rules.ts +53 -0
  38. package/src/core/project-affinity-surface.ts +102 -7
  39. package/src/core/project-profile-apply-state.ts +268 -0
  40. package/src/core/project-profile-apply-validation.ts +95 -0
  41. package/src/core/project-profile-apply.ts +408 -0
  42. package/src/core/project-profile-canonical.ts +71 -0
  43. package/src/core/project-profile-diff.ts +302 -0
  44. package/src/core/project-profile-discovery.ts +519 -0
  45. package/src/core/project-profile-file.ts +37 -0
  46. package/src/core/project-profile-parser.ts +98 -0
  47. package/src/core/project-profile.ts +490 -0
  48. package/src/ingestion/walker.ts +85 -44
  49. package/src/llm/cache.ts +21 -0
  50. package/src/serve/config-sync.ts +2 -2
  51. package/src/serve/resident-runtime.ts +1 -0
  52. package/src/serve/routes/api.ts +1 -0
  53. package/src/store/migrations/021-multi-context-identity.ts +37 -0
  54. package/src/store/migrations/index.ts +2 -0
  55. package/src/store/sqlite/adapter.ts +83 -0
  56. package/browser-extension/artifacts/gno-browser-clipper-v1.25.1.zip.sha256 +0 -1
@@ -240,6 +240,7 @@ export async function startResidentRuntime(
240
240
  const ctxHolder: ContextHolder = {
241
241
  current: ctx,
242
242
  config: initialConfig,
243
+ actualConfigPath,
243
244
  scheduler: null,
244
245
  eventBus: options.eventBus ?? null,
245
246
  watchService: null,
@@ -168,6 +168,7 @@ import { handleChanges, handleDiff, handleImpact } from "./changes";
168
168
  export interface ContextHolder {
169
169
  current: ServerContext;
170
170
  config: Config;
171
+ actualConfigPath?: string;
171
172
  scheduler: EmbedScheduler | null;
172
173
  eventBus: DocumentEventBus | null;
173
174
  watchService: CollectionWatchService | null;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Migration: allow multiple distinct context records at one logical scope.
3
+ *
4
+ * Context resolution already treats text as part of deterministic identity.
5
+ * The original two-column key accidentally limited each scope to one record.
6
+ *
7
+ * @module src/store/migrations/021-multi-context-identity
8
+ */
9
+
10
+ import type { Database } from "bun:sqlite";
11
+
12
+ import type { Migration } from "./runner";
13
+
14
+ export const migration: Migration = {
15
+ version: 21,
16
+ name: "multi_context_identity",
17
+
18
+ up(db: Database): void {
19
+ db.exec(`
20
+ CREATE TABLE contexts_v21 (
21
+ scope_type TEXT NOT NULL
22
+ CHECK (scope_type IN ('global', 'collection', 'prefix')),
23
+ scope_key TEXT NOT NULL,
24
+ text TEXT NOT NULL,
25
+ synced_at TEXT NOT NULL DEFAULT (datetime('now')),
26
+ PRIMARY KEY (scope_type, scope_key, text)
27
+ );
28
+
29
+ INSERT INTO contexts_v21 (scope_type, scope_key, text, synced_at)
30
+ SELECT scope_type, scope_key, text, synced_at
31
+ FROM contexts;
32
+
33
+ DROP TABLE contexts;
34
+ ALTER TABLE contexts_v21 RENAME TO contexts;
35
+ `);
36
+ },
37
+ };
@@ -34,6 +34,7 @@ import { migration as m017 } from "./017-document-change-retention-counters";
34
34
  import { migration as m018 } from "./018-saved-capsule-registration-epoch";
35
35
  import { migration as m019 } from "./019-saved-capsule-registration-generation";
36
36
  import { migration as m020 } from "./020-browser-clipper-security";
37
+ import { migration as m021 } from "./021-multi-context-identity";
37
38
 
38
39
  /** All migrations in order */
39
40
  export const migrations = [
@@ -57,4 +58,5 @@ export const migrations = [
57
58
  m018,
58
59
  m019,
59
60
  m020,
61
+ m021,
60
62
  ];
@@ -625,6 +625,57 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
625
625
  }
626
626
  }
627
627
 
628
+ async upsertCollections(
629
+ collections: Collection[]
630
+ ): Promise<StoreResult<void>> {
631
+ try {
632
+ const db = this.ensureOpen();
633
+ const stmt = db.prepare(`
634
+ INSERT INTO collections (name, path, pattern, include, exclude, update_cmd, language_hint, synced_at)
635
+ VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))
636
+ ON CONFLICT(name) DO UPDATE SET
637
+ path = excluded.path,
638
+ pattern = excluded.pattern,
639
+ include = excluded.include,
640
+ exclude = excluded.exclude,
641
+ update_cmd = excluded.update_cmd,
642
+ language_hint = excluded.language_hint,
643
+ synced_at = datetime('now')
644
+ WHERE collections.path IS NOT excluded.path
645
+ OR collections.pattern IS NOT excluded.pattern
646
+ OR collections.include IS NOT excluded.include
647
+ OR collections.exclude IS NOT excluded.exclude
648
+ OR collections.update_cmd IS NOT excluded.update_cmd
649
+ OR collections.language_hint IS NOT excluded.language_hint
650
+ `);
651
+ const transaction = db.transaction(() => {
652
+ for (const collection of collections) {
653
+ stmt.run(
654
+ collection.name,
655
+ collection.path,
656
+ collection.pattern,
657
+ collection.include.length > 0
658
+ ? JSON.stringify(collection.include)
659
+ : null,
660
+ collection.exclude.length > 0
661
+ ? JSON.stringify(collection.exclude)
662
+ : null,
663
+ collection.updateCmd ?? null,
664
+ collection.languageHint ?? null
665
+ );
666
+ }
667
+ });
668
+ transaction();
669
+ return ok(undefined);
670
+ } catch (cause) {
671
+ return err(
672
+ "QUERY_FAILED",
673
+ cause instanceof Error ? cause.message : "Failed to upsert collections",
674
+ cause
675
+ );
676
+ }
677
+ }
678
+
628
679
  async syncContexts(contexts: Context[]): Promise<StoreResult<void>> {
629
680
  try {
630
681
  const db = this.ensureOpen();
@@ -636,6 +687,8 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
636
687
  const stmt = db.prepare(`
637
688
  INSERT INTO contexts (scope_type, scope_key, text, synced_at)
638
689
  VALUES (?, ?, ?, datetime('now'))
690
+ ON CONFLICT(scope_type, scope_key, text) DO UPDATE SET
691
+ synced_at = excluded.synced_at
639
692
  `);
640
693
 
641
694
  for (const c of contexts) {
@@ -655,6 +708,36 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
655
708
  }
656
709
  }
657
710
 
711
+ async upsertContexts(contexts: Context[]): Promise<StoreResult<void>> {
712
+ try {
713
+ const db = this.ensureOpen();
714
+ const stmt = db.prepare(`
715
+ INSERT INTO contexts (scope_type, scope_key, text, synced_at)
716
+ VALUES (?, ?, ?, datetime('now'))
717
+ ON CONFLICT(scope_type, scope_key, text) DO NOTHING
718
+ `);
719
+ let inserted = 0;
720
+ const transaction = db.transaction(() => {
721
+ for (const context of contexts) {
722
+ inserted += stmt.run(
723
+ context.scopeType,
724
+ context.scopeKey,
725
+ context.text
726
+ ).changes;
727
+ }
728
+ });
729
+ transaction();
730
+ if (inserted > 0) this.contextGeneration += 1;
731
+ return ok(undefined);
732
+ } catch (cause) {
733
+ return err(
734
+ "QUERY_FAILED",
735
+ cause instanceof Error ? cause.message : "Failed to upsert contexts",
736
+ cause
737
+ );
738
+ }
739
+ }
740
+
658
741
  async getCollections(): Promise<StoreResult<CollectionRow[]>> {
659
742
  try {
660
743
  const db = this.ensureOpen();
@@ -1 +0,0 @@
1
- 454ebbfbe59a6821c471fbc22630dfd804c297a8dc7a4ce3880a032accb76382 gno-browser-clipper-v1.25.1.zip