spidersan 0.20.2 → 0.22.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 (69) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +29 -73
  3. package/dist/bin/command-registry.js +3 -3
  4. package/dist/bin/command-registry.js.map +1 -1
  5. package/dist/commands/config.d.ts.map +1 -1
  6. package/dist/commands/config.js +5 -41
  7. package/dist/commands/config.js.map +1 -1
  8. package/dist/commands/conflicts.d.ts +6 -3
  9. package/dist/commands/conflicts.d.ts.map +1 -1
  10. package/dist/commands/conflicts.js +7 -9
  11. package/dist/commands/conflicts.js.map +1 -1
  12. package/dist/commands/cross-conflicts.d.ts +2 -2
  13. package/dist/commands/cross-conflicts.d.ts.map +1 -1
  14. package/dist/commands/cross-conflicts.js +17 -13
  15. package/dist/commands/cross-conflicts.js.map +1 -1
  16. package/dist/commands/git-watch.d.ts +9 -17
  17. package/dist/commands/git-watch.d.ts.map +1 -1
  18. package/dist/commands/git-watch.js +23 -76
  19. package/dist/commands/git-watch.js.map +1 -1
  20. package/dist/commands/github-sync.d.ts.map +1 -1
  21. package/dist/commands/github-sync.js +2 -26
  22. package/dist/commands/github-sync.js.map +1 -1
  23. package/dist/commands/merge-order.d.ts +2 -1
  24. package/dist/commands/merge-order.d.ts.map +1 -1
  25. package/dist/commands/merge-order.js +60 -2
  26. package/dist/commands/merge-order.js.map +1 -1
  27. package/dist/commands/registry-sync.d.ts +3 -2
  28. package/dist/commands/registry-sync.d.ts.map +1 -1
  29. package/dist/commands/registry-sync.js +13 -22
  30. package/dist/commands/registry-sync.js.map +1 -1
  31. package/dist/commands/watch.js +2 -2
  32. package/dist/commands/watch.js.map +1 -1
  33. package/dist/lib/ai/reasoner.js +1 -1
  34. package/dist/lib/config.d.ts +4 -0
  35. package/dist/lib/config.d.ts.map +1 -1
  36. package/dist/lib/config.js.map +1 -1
  37. package/dist/lib/git.d.ts +1 -1
  38. package/dist/lib/git.js +1 -1
  39. package/dist/lib/graph.d.ts +50 -1
  40. package/dist/lib/graph.d.ts.map +1 -1
  41. package/dist/lib/graph.js +148 -10
  42. package/dist/lib/graph.js.map +1 -1
  43. package/dist/lib/notify.d.ts +2 -2
  44. package/dist/lib/notify.js +2 -2
  45. package/dist/lib/push-registry.d.ts +1 -1
  46. package/dist/lib/push-registry.d.ts.map +1 -1
  47. package/dist/lib/push-registry.js +3 -2
  48. package/dist/lib/push-registry.js.map +1 -1
  49. package/dist/lib/supabase-credentials.d.ts +9 -27
  50. package/dist/lib/supabase-credentials.d.ts.map +1 -1
  51. package/dist/lib/supabase-credentials.js +9 -32
  52. package/dist/lib/supabase-credentials.js.map +1 -1
  53. package/dist/storage/factory.d.ts +4 -1
  54. package/dist/storage/factory.d.ts.map +1 -1
  55. package/dist/storage/factory.js +4 -7
  56. package/dist/storage/factory.js.map +1 -1
  57. package/dist/storage/index.d.ts +0 -1
  58. package/dist/storage/index.d.ts.map +1 -1
  59. package/dist/storage/index.js +0 -1
  60. package/dist/storage/index.js.map +1 -1
  61. package/dist/storage/registry-sync.d.ts +26 -0
  62. package/dist/storage/registry-sync.d.ts.map +1 -0
  63. package/dist/storage/registry-sync.js +66 -0
  64. package/dist/storage/registry-sync.js.map +1 -0
  65. package/dist/storage/supabase.d.ts +7 -5
  66. package/dist/storage/supabase.d.ts.map +1 -1
  67. package/dist/storage/supabase.js +15 -7
  68. package/dist/storage/supabase.js.map +1 -1
  69. package/package.json +1 -1
@@ -1,36 +1,18 @@
1
1
  /**
2
- * Single source of truth for resolving spidersan's Supabase credentials.
2
+ * Supabase environment credentials, for the activity log only.
3
3
  *
4
- * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_* → config.storage.*
4
+ * Cross-machine registry sync no longer uses these: it goes through a configured
5
+ * storage.syncModule (see src/storage/registry-sync.ts). This stays because
6
+ * src/lib/activity.ts still uploads the optional activity log with them, and
7
+ * `spidersan config` reports whether they are set.
5
8
  *
6
- * SPIDERSAN_SUPABASE_* MUST come first. envoak's vault-inject guard drops any
7
- * secret whose name carries a bare SUPABASE_ prefix, so vault-injected creds
8
- * only ever arrive under the scoped names. Resolvers checking just the bare
9
- * names silently no-op under `envoak vault inject` — the production hook path —
10
- * and report "Supabase not configured" while a valid grant is present (fc8cf22,
11
- * 29aa575, tb-efmm; tb-ly0b found 7 more copies with the same defect).
12
- *
13
- * This module exists so that stays fixed in ONE place. Do not re-derive these
14
- * env names inline; call resolveSupabaseCredentials()/resolveSupabaseEnv().
15
- *
16
- * COLONY_SUPABASE_* is deliberately absent from the chain: colony points at a
17
- * different Supabase project, so falling back to it would silently write
18
- * spider_registries into the wrong database (tb-ly0b).
19
- */
20
- export interface SupabaseCredentials {
21
- url: string;
22
- key: string;
23
- }
24
- /**
25
- * Env-only resolution. For callers with no config file in scope (subscribers,
26
- * activity logging) that need a synchronous answer.
9
+ * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_*. The scoped names come first
10
+ * because some secret injectors refuse to pass a bare SUPABASE_* name, and a
11
+ * resolver that checked only the bare names would silently report "not set".
27
12
  */
13
+ /** Env-only resolution; either field is undefined when unset. */
28
14
  export declare function resolveSupabaseEnv(): {
29
15
  url?: string;
30
16
  key?: string;
31
17
  };
32
- /**
33
- * Env → config.storage. The default for commands; null when unconfigured.
34
- */
35
- export declare function resolveSupabaseCredentials(basePath?: string): Promise<SupabaseCredentials | null>;
36
18
  //# sourceMappingURL=supabase-credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"supabase-credentials.d.ts","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,mBAAmB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAKnE;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC5C,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAQrC"}
1
+ {"version":3,"file":"supabase-credentials.d.ts","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iEAAiE;AACjE,wBAAgB,kBAAkB,IAAI;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAKnE"}
@@ -1,43 +1,20 @@
1
1
  /**
2
- * Single source of truth for resolving spidersan's Supabase credentials.
2
+ * Supabase environment credentials, for the activity log only.
3
3
  *
4
- * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_* → config.storage.*
4
+ * Cross-machine registry sync no longer uses these: it goes through a configured
5
+ * storage.syncModule (see src/storage/registry-sync.ts). This stays because
6
+ * src/lib/activity.ts still uploads the optional activity log with them, and
7
+ * `spidersan config` reports whether they are set.
5
8
  *
6
- * SPIDERSAN_SUPABASE_* MUST come first. envoak's vault-inject guard drops any
7
- * secret whose name carries a bare SUPABASE_ prefix, so vault-injected creds
8
- * only ever arrive under the scoped names. Resolvers checking just the bare
9
- * names silently no-op under `envoak vault inject` — the production hook path —
10
- * and report "Supabase not configured" while a valid grant is present (fc8cf22,
11
- * 29aa575, tb-efmm; tb-ly0b found 7 more copies with the same defect).
12
- *
13
- * This module exists so that stays fixed in ONE place. Do not re-derive these
14
- * env names inline; call resolveSupabaseCredentials()/resolveSupabaseEnv().
15
- *
16
- * COLONY_SUPABASE_* is deliberately absent from the chain: colony points at a
17
- * different Supabase project, so falling back to it would silently write
18
- * spider_registries into the wrong database (tb-ly0b).
19
- */
20
- import { loadConfig } from './config.js';
21
- /**
22
- * Env-only resolution. For callers with no config file in scope (subscribers,
23
- * activity logging) that need a synchronous answer.
9
+ * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_*. The scoped names come first
10
+ * because some secret injectors refuse to pass a bare SUPABASE_* name, and a
11
+ * resolver that checked only the bare names would silently report "not set".
24
12
  */
13
+ /** Env-only resolution; either field is undefined when unset. */
25
14
  export function resolveSupabaseEnv() {
26
15
  return {
27
16
  url: process.env.SPIDERSAN_SUPABASE_URL || process.env.SUPABASE_URL,
28
17
  key: process.env.SPIDERSAN_SUPABASE_KEY || process.env.SUPABASE_KEY,
29
18
  };
30
19
  }
31
- /**
32
- * Env → config.storage. The default for commands; null when unconfigured.
33
- */
34
- export async function resolveSupabaseCredentials(basePath) {
35
- const env = resolveSupabaseEnv();
36
- const config = await loadConfig(basePath);
37
- const url = env.url || config.storage.supabaseUrl;
38
- const key = env.key || config.storage.supabaseKey;
39
- if (!url || !key)
40
- return null;
41
- return { url, key };
42
- }
43
20
  //# sourceMappingURL=supabase-credentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"supabase-credentials.js","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAC9B,OAAO;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QACnE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;KACtE,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC5C,QAAiB;IAEjB,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAClD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAElD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"supabase-credentials.js","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iEAAiE;AACjE,MAAM,UAAU,kBAAkB;IAC9B,OAAO;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QACnE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;KACtE,CAAC;AACN,CAAC"}
@@ -1,5 +1,8 @@
1
1
  /**
2
- * Storage factory - selects the right storage backend
2
+ * Storage factory.
3
+ *
4
+ * The branch registry is always the local JSON store. Cross-machine sync is a
5
+ * separate concern, resolved by resolveRegistrySync() from storage.syncModule.
3
6
  */
4
7
  import type { StorageAdapter } from './adapter.js';
5
8
  export declare function getStorage(): Promise<StorageAdapter>;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAQ1D"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAE1D"}
@@ -1,14 +1,11 @@
1
1
  /**
2
- * Storage factory - selects the right storage backend
2
+ * Storage factory.
3
+ *
4
+ * The branch registry is always the local JSON store. Cross-machine sync is a
5
+ * separate concern, resolved by resolveRegistrySync() from storage.syncModule.
3
6
  */
4
7
  import { LocalStorage } from './local.js';
5
- import { SupabaseStorage } from './supabase.js';
6
- import { resolveSupabaseCredentials } from '../lib/supabase-credentials.js';
7
8
  export async function getStorage() {
8
- const supabaseConfig = await resolveSupabaseCredentials();
9
- if (supabaseConfig) {
10
- return new SupabaseStorage(supabaseConfig);
11
- }
12
9
  return new LocalStorage();
13
10
  }
14
11
  //# sourceMappingURL=factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,cAAc,GAAG,MAAM,0BAA0B,EAAE,CAAC;IAE1D,IAAI,cAAc,EAAE,CAAC;QACjB,OAAO,IAAI,eAAe,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,YAAY,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/storage/factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,OAAO,IAAI,YAAY,EAAE,CAAC;AAC9B,CAAC"}
@@ -5,6 +5,5 @@ export * from './json-branch-registry-store.js';
5
5
  export * from './memory-branch-registry-store.js';
6
6
  export * from './supabase.js';
7
7
  export * from './supabase-registry-sync-client.js';
8
- export * from './supabase-registry-sync-client-impl.js';
9
8
  export * from './factory.js';
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,cAAc,CAAC"}
@@ -6,6 +6,5 @@ export * from './json-branch-registry-store.js';
6
6
  export * from './memory-branch-registry-store.js';
7
7
  export * from './supabase.js';
8
8
  export * from './supabase-registry-sync-client.js';
9
- export * from './supabase-registry-sync-client-impl.js';
10
9
  export * from './factory.js';
11
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,YAAY,CAAC;AAC3B,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAC9B,cAAc,oCAAoC,CAAC;AACnD,cAAc,cAAc,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Which cross-machine registry backend to use.
3
+ *
4
+ * Cross-machine sync is pluggable only: a deployment supplies its own
5
+ * SupabaseRegistrySyncClient as an ES module that exports
6
+ * `createRegistrySyncClient()` (sync or async), named by SPIDERSAN_SYNC_MODULE or
7
+ * `storage.syncModule` in the USER's ~/.spidersanrc. A repo-local .spidersanrc is
8
+ * never consulted for this: it would let any cloned repo run code on
9
+ * `spidersan conflicts`.
10
+ *
11
+ * There is no built-in client any more. The hosted registry tables it talked to
12
+ * are being dropped, so without a module there is no cross-machine sync, and
13
+ * callers say so with syncModuleRequiredMessage() rather than reporting "no
14
+ * conflicts" or failing on a missing table.
15
+ */
16
+ import { SupabaseStorage } from './supabase.js';
17
+ export declare function syncModulePath(): Promise<string | undefined>;
18
+ /** The configured sync client, or null when no storage.syncModule is set. */
19
+ export declare function resolveRegistrySync(): Promise<SupabaseStorage | null>;
20
+ /**
21
+ * The one message for "cross-machine sync asked for, no module configured".
22
+ * Mentions the legacy credentials when they are still set: someone upgrading
23
+ * with SUPABASE_* in their environment would otherwise assume sync still works.
24
+ */
25
+ export declare function syncModuleRequiredMessage(): string[];
26
+ //# sourceMappingURL=registry-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-sync.d.ts","sourceRoot":"","sources":["../../src/storage/registry-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAWlE;AAED,6EAA6E;AAC7E,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQ3E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAYpD"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Which cross-machine registry backend to use.
3
+ *
4
+ * Cross-machine sync is pluggable only: a deployment supplies its own
5
+ * SupabaseRegistrySyncClient as an ES module that exports
6
+ * `createRegistrySyncClient()` (sync or async), named by SPIDERSAN_SYNC_MODULE or
7
+ * `storage.syncModule` in the USER's ~/.spidersanrc. A repo-local .spidersanrc is
8
+ * never consulted for this: it would let any cloned repo run code on
9
+ * `spidersan conflicts`.
10
+ *
11
+ * There is no built-in client any more. The hosted registry tables it talked to
12
+ * are being dropped, so without a module there is no cross-machine sync, and
13
+ * callers say so with syncModuleRequiredMessage() rather than reporting "no
14
+ * conflicts" or failing on a missing table.
15
+ */
16
+ import { homedir } from 'node:os';
17
+ import { isAbsolute, join } from 'node:path';
18
+ import { pathToFileURL } from 'node:url';
19
+ import { loadConfigWithSources } from '../lib/config.js';
20
+ import { resolveSupabaseEnv } from '../lib/supabase-credentials.js';
21
+ import { SupabaseStorage } from './supabase.js';
22
+ export async function syncModulePath() {
23
+ let p = process.env.SPIDERSAN_SYNC_MODULE;
24
+ if (!p) {
25
+ // home dir only: includeGlobal=false with basePath=home reads just ~/.spidersanrc*
26
+ const { config } = await loadConfigWithSources(homedir(), { includeGlobal: false });
27
+ p = config.storage.syncModule;
28
+ }
29
+ if (!p)
30
+ return undefined;
31
+ if (p.startsWith('~/'))
32
+ p = join(homedir(), p.slice(2));
33
+ if (!isAbsolute(p))
34
+ throw new Error(`storage.syncModule must be an absolute path (or ~/...), got ${p}`);
35
+ return p;
36
+ }
37
+ /** The configured sync client, or null when no storage.syncModule is set. */
38
+ export async function resolveRegistrySync() {
39
+ const mod = await syncModulePath();
40
+ if (!mod)
41
+ return null;
42
+ const m = await import(pathToFileURL(mod).href);
43
+ if (typeof m.createRegistrySyncClient !== 'function') {
44
+ throw new Error(`${mod} does not export createRegistrySyncClient()`);
45
+ }
46
+ return new SupabaseStorage(await m.createRegistrySyncClient());
47
+ }
48
+ /**
49
+ * The one message for "cross-machine sync asked for, no module configured".
50
+ * Mentions the legacy credentials when they are still set: someone upgrading
51
+ * with SUPABASE_* in their environment would otherwise assume sync still works.
52
+ */
53
+ export function syncModuleRequiredMessage() {
54
+ const lines = [
55
+ 'Cross-machine sync needs a sync module (storage.syncModule); none is configured.',
56
+ ' Set it in ~/.spidersanrc (absolute path or ~/...): { "storage": { "syncModule": "~/path/to/client.mjs" } }',
57
+ ' or export SPIDERSAN_SYNC_MODULE=/path/to/client.mjs',
58
+ ' The module must export createRegistrySyncClient().',
59
+ ];
60
+ const env = resolveSupabaseEnv();
61
+ if (env.url || env.key) {
62
+ lines.push(' Note: the built-in hosted sync client was removed; SPIDERSAN_SUPABASE_* / SUPABASE_* no longer enable sync.');
63
+ }
64
+ return lines;
65
+ }
66
+ //# sourceMappingURL=registry-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-sync.js","sourceRoot":"","sources":["../../src/storage/registry-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,CAAC,KAAK,UAAU,cAAc;IAChC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC1C,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,mFAAmF;QACnF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC,GAAI,MAAM,CAAC,OAAmC,CAAC,UAAU,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,EAAE,CAAC,CAAC;IACxG,OAAO,CAAC,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACrC,MAAM,GAAG,GAAG,MAAM,cAAc,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAA0G,CAAC;IACzJ,IAAI,OAAO,CAAC,CAAC,wBAAwB,KAAK,UAAU,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,6CAA6C,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,wBAAwB,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB;IACrC,MAAM,KAAK,GAAG;QACV,kFAAkF;QAClF,+GAA+G;QAC/G,uDAAuD;QACvD,sDAAsD;KACzD,CAAC;IACF,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,+GAA+G,CAAC,CAAC;IAChI,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -1,16 +1,18 @@
1
1
  /**
2
- * Supabase Storage Adapter
2
+ * Registry storage with cross-machine sync.
3
3
  *
4
- * Thin compatibility wrapper over a local JsonBranchRegistryStore plus
5
- * SupabaseRegistrySyncClientImpl for cross-machine sync.
4
+ * Thin compatibility wrapper over a local JsonBranchRegistryStore plus a
5
+ * SupabaseRegistrySyncClient supplied by a configured storage.syncModule (the
6
+ * interface keeps its historical name; any backend can implement it).
6
7
  */
7
8
  import type { StorageAdapter, Branch } from './adapter.js';
8
- import { type SupabaseRegistrySyncClientConfig } from './supabase-registry-sync-client-impl.js';
9
+ import type { SupabaseRegistrySyncClient } from './supabase-registry-sync-client.js';
9
10
  import type { CrossMachineConflict, MachineIdentity, MachineRegistryView, RegistryStatus, RegistrySyncResult } from '../types/cloud.js';
10
11
  export declare class SupabaseStorage implements StorageAdapter {
11
12
  private store;
12
13
  private syncClient;
13
- constructor(config: SupabaseRegistrySyncClientConfig, basePath?: string);
14
+ /** `syncClient` comes from storage.syncModule; there is no built-in client. */
15
+ constructor(syncClient: SupabaseRegistrySyncClient, basePath?: string);
14
16
  init(): Promise<void>;
15
17
  isInitialized(): Promise<boolean>;
16
18
  list(): Promise<Branch[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAEH,KAAK,gCAAgC,EACxC,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EACR,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,eAAgB,YAAW,cAAc;IAClD,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,UAAU,CAAiC;gBAEvC,MAAM,EAAE,gCAAgC,EAAE,QAAQ,GAAE,MAAsB;IAKhF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/C,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlE,YAAY,CACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAIxB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAIpI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAI/D,2BAA2B,CAC7B,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,oBAAoB,EAAE,CAAC;CAGrC"}
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAErF,OAAO,KAAK,EACR,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,eAAgB,YAAW,cAAc;IAClD,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,UAAU,CAA6B;IAE/C,+EAA+E;gBACnE,UAAU,EAAE,0BAA0B,EAAE,QAAQ,GAAE,MAAsB;IAK9E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/C,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlE,YAAY,CACd,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAIxB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAUpI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAI/D,2BAA2B,CAC7B,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,oBAAoB,EAAE,CAAC;CAGrC"}
@@ -1,17 +1,19 @@
1
1
  /**
2
- * Supabase Storage Adapter
2
+ * Registry storage with cross-machine sync.
3
3
  *
4
- * Thin compatibility wrapper over a local JsonBranchRegistryStore plus
5
- * SupabaseRegistrySyncClientImpl for cross-machine sync.
4
+ * Thin compatibility wrapper over a local JsonBranchRegistryStore plus a
5
+ * SupabaseRegistrySyncClient supplied by a configured storage.syncModule (the
6
+ * interface keeps its historical name; any backend can implement it).
6
7
  */
7
8
  import { JsonBranchRegistryStore } from './json-branch-registry-store.js';
8
- import { SupabaseRegistrySyncClientImpl, } from './supabase-registry-sync-client-impl.js';
9
+ import { dropShadowedPushRows } from '../lib/push-registry.js';
9
10
  export class SupabaseStorage {
10
11
  store;
11
12
  syncClient;
12
- constructor(config, basePath = process.cwd()) {
13
+ /** `syncClient` comes from storage.syncModule; there is no built-in client. */
14
+ constructor(syncClient, basePath = process.cwd()) {
13
15
  this.store = new JsonBranchRegistryStore(basePath);
14
- this.syncClient = new SupabaseRegistrySyncClientImpl(config);
16
+ this.syncClient = syncClient;
15
17
  }
16
18
  async init() {
17
19
  await this.store.init();
@@ -44,7 +46,13 @@ export class SupabaseStorage {
44
46
  return this.syncClient.push(machine, repoName, repoPath, branches);
45
47
  }
46
48
  async pullRegistries(repoName, excludeMachine, ownBranches) {
47
- return this.syncClient.pull(repoName, excludeMachine, ownBranches);
49
+ // De-duplicate BEFORE excluding the caller's machine, whatever the module does:
50
+ // the caller's own rows are what shadow a pushed-branch row for a branch it
51
+ // registered itself. dropShadowedPushRows only filters, so a module that
52
+ // already de-duplicates gets the same answer.
53
+ const own = ownBranches ? [...ownBranches] : [];
54
+ const views = await this.syncClient.pull(repoName, undefined, own);
55
+ return dropShadowedPushRows(views, own).filter((v) => v.machine_id !== excludeMachine);
48
56
  }
49
57
  async getRegistryStatus(repoName) {
50
58
  return this.syncClient.getStatus(repoName);
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EACH,8BAA8B,GAEjC,MAAM,yCAAyC,CAAC;AASjD,MAAM,OAAO,eAAe;IAChB,KAAK,CAA0B;IAC/B,UAAU,CAAiC;IAEnD,YAAY,MAAwC,EAAE,WAAmB,OAAO,CAAC,GAAG,EAAE;QAClF,IAAI,CAAC,KAAK,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,IAAI,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,IAAI;QACN,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,aAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAoC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,OAAwB;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAe;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAe,EAAE,aAAa,GAAG,KAAK;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,YAAY,CACd,OAAwB,EACxB,QAAgB,EAChB,QAAgB,EAChB,QAAkB;QAElB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAA2B,EAAE,cAAuB,EAAE,WAA8B;QACrG,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAiB;QACrC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,2BAA2B,CAC7B,QAAgB,EAChB,cAAuB;QAEvB,OAAO,IAAI,CAAC,UAAU,CAAC,2BAA2B,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACjF,CAAC;CACJ"}
1
+ {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAS/D,MAAM,OAAO,eAAe;IAChB,KAAK,CAA0B;IAC/B,UAAU,CAA6B;IAE/C,+EAA+E;IAC/E,YAAY,UAAsC,EAAE,WAAmB,OAAO,CAAC,GAAG,EAAE;QAChF,IAAI,CAAC,KAAK,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI;QACN,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,aAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAoC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,OAAwB;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAe;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAe,EAAE,aAAa,GAAG,KAAK;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,YAAY,CACd,OAAwB,EACxB,QAAgB,EAChB,QAAgB,EAChB,QAAkB;QAElB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAA2B,EAAE,cAAuB,EAAE,WAA8B;QACrG,gFAAgF;QAChF,4EAA4E;QAC5E,yEAAyE;QACzE,8CAA8C;QAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QACnE,OAAO,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,cAAc,CAAC,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAiB;QACrC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,2BAA2B,CAC7B,QAAgB,EAChB,cAAuB;QAEvB,OAAO,IAAI,CAAC,UAAU,CAAC,2BAA2B,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACjF,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spidersan",
3
- "version": "0.20.2",
3
+ "version": "0.22.0",
4
4
  "description": "Branch coordination for AI coding agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",