@stoneforge/quarry 1.12.0 → 1.14.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 (199) hide show
  1. package/README.md +2 -0
  2. package/dist/api/quarry-api.d.ts +9 -1
  3. package/dist/api/quarry-api.d.ts.map +1 -1
  4. package/dist/api/quarry-api.js +21 -2
  5. package/dist/api/quarry-api.js.map +1 -1
  6. package/dist/api/types.d.ts +8 -1
  7. package/dist/api/types.d.ts.map +1 -1
  8. package/dist/api/types.js.map +1 -1
  9. package/dist/cli/commands/auto-link-helper.d.ts +33 -0
  10. package/dist/cli/commands/auto-link-helper.d.ts.map +1 -0
  11. package/dist/cli/commands/auto-link-helper.js +74 -0
  12. package/dist/cli/commands/auto-link-helper.js.map +1 -0
  13. package/dist/cli/commands/crud.d.ts +3 -0
  14. package/dist/cli/commands/crud.d.ts.map +1 -1
  15. package/dist/cli/commands/crud.js +144 -15
  16. package/dist/cli/commands/crud.js.map +1 -1
  17. package/dist/cli/commands/docs.js +2 -2
  18. package/dist/cli/commands/docs.js.map +1 -1
  19. package/dist/cli/commands/document.js +1 -1
  20. package/dist/cli/commands/document.js.map +1 -1
  21. package/dist/cli/commands/entity.js +1 -1
  22. package/dist/cli/commands/entity.js.map +1 -1
  23. package/dist/cli/commands/external-sync.d.ts +18 -0
  24. package/dist/cli/commands/external-sync.d.ts.map +1 -0
  25. package/dist/cli/commands/external-sync.js +2499 -0
  26. package/dist/cli/commands/external-sync.js.map +1 -0
  27. package/dist/cli/commands/library.js +1 -1
  28. package/dist/cli/commands/library.js.map +1 -1
  29. package/dist/cli/commands/message.js +2 -2
  30. package/dist/cli/commands/message.js.map +1 -1
  31. package/dist/cli/commands/serve.d.ts.map +1 -1
  32. package/dist/cli/commands/serve.js +2 -0
  33. package/dist/cli/commands/serve.js.map +1 -1
  34. package/dist/cli/commands/task.d.ts.map +1 -1
  35. package/dist/cli/commands/task.js +7 -4
  36. package/dist/cli/commands/task.js.map +1 -1
  37. package/dist/cli/commands/team.js +1 -1
  38. package/dist/cli/commands/team.js.map +1 -1
  39. package/dist/cli/commands/workflow.js +1 -1
  40. package/dist/cli/commands/workflow.js.map +1 -1
  41. package/dist/cli/runner.d.ts.map +1 -1
  42. package/dist/cli/runner.js +3 -0
  43. package/dist/cli/runner.js.map +1 -1
  44. package/dist/cli/utils/progress.d.ts +30 -0
  45. package/dist/cli/utils/progress.d.ts.map +1 -0
  46. package/dist/cli/utils/progress.js +47 -0
  47. package/dist/cli/utils/progress.js.map +1 -0
  48. package/dist/config/config.d.ts.map +1 -1
  49. package/dist/config/config.js +34 -0
  50. package/dist/config/config.js.map +1 -1
  51. package/dist/config/defaults.d.ts +13 -1
  52. package/dist/config/defaults.d.ts.map +1 -1
  53. package/dist/config/defaults.js +22 -0
  54. package/dist/config/defaults.js.map +1 -1
  55. package/dist/config/file.d.ts.map +1 -1
  56. package/dist/config/file.js +71 -0
  57. package/dist/config/file.js.map +1 -1
  58. package/dist/config/index.d.ts +3 -3
  59. package/dist/config/index.d.ts.map +1 -1
  60. package/dist/config/index.js +2 -2
  61. package/dist/config/index.js.map +1 -1
  62. package/dist/config/merge.d.ts.map +1 -1
  63. package/dist/config/merge.js +52 -1
  64. package/dist/config/merge.js.map +1 -1
  65. package/dist/config/types.d.ts +68 -1
  66. package/dist/config/types.d.ts.map +1 -1
  67. package/dist/config/types.js +33 -0
  68. package/dist/config/types.js.map +1 -1
  69. package/dist/config/validation.d.ts.map +1 -1
  70. package/dist/config/validation.js +64 -1
  71. package/dist/config/validation.js.map +1 -1
  72. package/dist/external-sync/adapters/document-sync-adapter.d.ts +150 -0
  73. package/dist/external-sync/adapters/document-sync-adapter.d.ts.map +1 -0
  74. package/dist/external-sync/adapters/document-sync-adapter.js +325 -0
  75. package/dist/external-sync/adapters/document-sync-adapter.js.map +1 -0
  76. package/dist/external-sync/adapters/task-sync-adapter.d.ts +177 -0
  77. package/dist/external-sync/adapters/task-sync-adapter.d.ts.map +1 -0
  78. package/dist/external-sync/adapters/task-sync-adapter.js +353 -0
  79. package/dist/external-sync/adapters/task-sync-adapter.js.map +1 -0
  80. package/dist/external-sync/auto-link.d.ts +66 -0
  81. package/dist/external-sync/auto-link.d.ts.map +1 -0
  82. package/dist/external-sync/auto-link.js +98 -0
  83. package/dist/external-sync/auto-link.js.map +1 -0
  84. package/dist/external-sync/conflict-resolver.d.ts +170 -0
  85. package/dist/external-sync/conflict-resolver.d.ts.map +1 -0
  86. package/dist/external-sync/conflict-resolver.js +580 -0
  87. package/dist/external-sync/conflict-resolver.js.map +1 -0
  88. package/dist/external-sync/index.d.ts +23 -0
  89. package/dist/external-sync/index.d.ts.map +1 -0
  90. package/dist/external-sync/index.js +24 -0
  91. package/dist/external-sync/index.js.map +1 -0
  92. package/dist/external-sync/provider-registry.d.ts +113 -0
  93. package/dist/external-sync/provider-registry.d.ts.map +1 -0
  94. package/dist/external-sync/provider-registry.js +205 -0
  95. package/dist/external-sync/provider-registry.js.map +1 -0
  96. package/dist/external-sync/providers/folder/folder-document-adapter.d.ts +97 -0
  97. package/dist/external-sync/providers/folder/folder-document-adapter.d.ts.map +1 -0
  98. package/dist/external-sync/providers/folder/folder-document-adapter.js +261 -0
  99. package/dist/external-sync/providers/folder/folder-document-adapter.js.map +1 -0
  100. package/dist/external-sync/providers/folder/folder-fs.d.ts +146 -0
  101. package/dist/external-sync/providers/folder/folder-fs.d.ts.map +1 -0
  102. package/dist/external-sync/providers/folder/folder-fs.js +300 -0
  103. package/dist/external-sync/providers/folder/folder-fs.js.map +1 -0
  104. package/dist/external-sync/providers/folder/folder-provider.d.ts +28 -0
  105. package/dist/external-sync/providers/folder/folder-provider.d.ts.map +1 -0
  106. package/dist/external-sync/providers/folder/folder-provider.js +87 -0
  107. package/dist/external-sync/providers/folder/folder-provider.js.map +1 -0
  108. package/dist/external-sync/providers/folder/index.d.ts +11 -0
  109. package/dist/external-sync/providers/folder/index.d.ts.map +1 -0
  110. package/dist/external-sync/providers/folder/index.js +13 -0
  111. package/dist/external-sync/providers/folder/index.js.map +1 -0
  112. package/dist/external-sync/providers/github/github-api.d.ts +271 -0
  113. package/dist/external-sync/providers/github/github-api.d.ts.map +1 -0
  114. package/dist/external-sync/providers/github/github-api.js +366 -0
  115. package/dist/external-sync/providers/github/github-api.js.map +1 -0
  116. package/dist/external-sync/providers/github/github-field-map.d.ts +76 -0
  117. package/dist/external-sync/providers/github/github-field-map.d.ts.map +1 -0
  118. package/dist/external-sync/providers/github/github-field-map.js +157 -0
  119. package/dist/external-sync/providers/github/github-field-map.js.map +1 -0
  120. package/dist/external-sync/providers/github/github-provider.d.ts +36 -0
  121. package/dist/external-sync/providers/github/github-provider.d.ts.map +1 -0
  122. package/dist/external-sync/providers/github/github-provider.js +212 -0
  123. package/dist/external-sync/providers/github/github-provider.js.map +1 -0
  124. package/dist/external-sync/providers/github/github-task-adapter.d.ts +135 -0
  125. package/dist/external-sync/providers/github/github-task-adapter.d.ts.map +1 -0
  126. package/dist/external-sync/providers/github/github-task-adapter.js +374 -0
  127. package/dist/external-sync/providers/github/github-task-adapter.js.map +1 -0
  128. package/dist/external-sync/providers/github/index.d.ts +12 -0
  129. package/dist/external-sync/providers/github/index.d.ts.map +1 -0
  130. package/dist/external-sync/providers/github/index.js +15 -0
  131. package/dist/external-sync/providers/github/index.js.map +1 -0
  132. package/dist/external-sync/providers/index.d.ts +13 -0
  133. package/dist/external-sync/providers/index.d.ts.map +1 -0
  134. package/dist/external-sync/providers/index.js +15 -0
  135. package/dist/external-sync/providers/index.js.map +1 -0
  136. package/dist/external-sync/providers/linear/index.d.ts +19 -0
  137. package/dist/external-sync/providers/linear/index.d.ts.map +1 -0
  138. package/dist/external-sync/providers/linear/index.js +19 -0
  139. package/dist/external-sync/providers/linear/index.js.map +1 -0
  140. package/dist/external-sync/providers/linear/linear-api.d.ts +252 -0
  141. package/dist/external-sync/providers/linear/linear-api.d.ts.map +1 -0
  142. package/dist/external-sync/providers/linear/linear-api.js +522 -0
  143. package/dist/external-sync/providers/linear/linear-api.js.map +1 -0
  144. package/dist/external-sync/providers/linear/linear-field-map.d.ts +135 -0
  145. package/dist/external-sync/providers/linear/linear-field-map.d.ts.map +1 -0
  146. package/dist/external-sync/providers/linear/linear-field-map.js +338 -0
  147. package/dist/external-sync/providers/linear/linear-field-map.js.map +1 -0
  148. package/dist/external-sync/providers/linear/linear-provider.d.ts +52 -0
  149. package/dist/external-sync/providers/linear/linear-provider.d.ts.map +1 -0
  150. package/dist/external-sync/providers/linear/linear-provider.js +169 -0
  151. package/dist/external-sync/providers/linear/linear-provider.js.map +1 -0
  152. package/dist/external-sync/providers/linear/linear-task-adapter.d.ts +190 -0
  153. package/dist/external-sync/providers/linear/linear-task-adapter.d.ts.map +1 -0
  154. package/dist/external-sync/providers/linear/linear-task-adapter.js +521 -0
  155. package/dist/external-sync/providers/linear/linear-task-adapter.js.map +1 -0
  156. package/dist/external-sync/providers/linear/linear-types.d.ts +114 -0
  157. package/dist/external-sync/providers/linear/linear-types.d.ts.map +1 -0
  158. package/dist/external-sync/providers/linear/linear-types.js +10 -0
  159. package/dist/external-sync/providers/linear/linear-types.js.map +1 -0
  160. package/dist/external-sync/providers/notion/index.d.ts +19 -0
  161. package/dist/external-sync/providers/notion/index.d.ts.map +1 -0
  162. package/dist/external-sync/providers/notion/index.js +20 -0
  163. package/dist/external-sync/providers/notion/index.js.map +1 -0
  164. package/dist/external-sync/providers/notion/notion-api.d.ts +253 -0
  165. package/dist/external-sync/providers/notion/notion-api.d.ts.map +1 -0
  166. package/dist/external-sync/providers/notion/notion-api.js +492 -0
  167. package/dist/external-sync/providers/notion/notion-api.js.map +1 -0
  168. package/dist/external-sync/providers/notion/notion-blocks.d.ts +93 -0
  169. package/dist/external-sync/providers/notion/notion-blocks.d.ts.map +1 -0
  170. package/dist/external-sync/providers/notion/notion-blocks.js +773 -0
  171. package/dist/external-sync/providers/notion/notion-blocks.js.map +1 -0
  172. package/dist/external-sync/providers/notion/notion-document-adapter.d.ts +176 -0
  173. package/dist/external-sync/providers/notion/notion-document-adapter.d.ts.map +1 -0
  174. package/dist/external-sync/providers/notion/notion-document-adapter.js +413 -0
  175. package/dist/external-sync/providers/notion/notion-document-adapter.js.map +1 -0
  176. package/dist/external-sync/providers/notion/notion-provider.d.ts +57 -0
  177. package/dist/external-sync/providers/notion/notion-provider.d.ts.map +1 -0
  178. package/dist/external-sync/providers/notion/notion-provider.js +159 -0
  179. package/dist/external-sync/providers/notion/notion-provider.js.map +1 -0
  180. package/dist/external-sync/providers/notion/notion-types.d.ts +388 -0
  181. package/dist/external-sync/providers/notion/notion-types.d.ts.map +1 -0
  182. package/dist/external-sync/providers/notion/notion-types.js +47 -0
  183. package/dist/external-sync/providers/notion/notion-types.js.map +1 -0
  184. package/dist/external-sync/sync-engine.d.ts +364 -0
  185. package/dist/external-sync/sync-engine.d.ts.map +1 -0
  186. package/dist/external-sync/sync-engine.js +1154 -0
  187. package/dist/external-sync/sync-engine.js.map +1 -0
  188. package/dist/index.d.ts +1 -0
  189. package/dist/index.d.ts.map +1 -1
  190. package/dist/index.js +2 -0
  191. package/dist/index.js.map +1 -1
  192. package/dist/server/index.js +8 -8
  193. package/dist/server/index.js.map +1 -1
  194. package/dist/services/inbox.js +1 -1
  195. package/dist/sync/hash.d.ts +5 -0
  196. package/dist/sync/hash.d.ts.map +1 -1
  197. package/dist/sync/hash.js +21 -2
  198. package/dist/sync/hash.js.map +1 -1
  199. package/package.json +10 -12
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Provider Registry — manages ExternalProvider registrations
3
+ *
4
+ * Provides a central registry for external sync providers (GitHub, Linear, etc.).
5
+ * Supports registration, lookup by name, listing all providers, and querying
6
+ * providers by adapter type.
7
+ *
8
+ * Usage:
9
+ * ```typescript
10
+ * import { createProviderRegistry } from '@stoneforge/quarry';
11
+ *
12
+ * const registry = createProviderRegistry();
13
+ * registry.register(myProvider);
14
+ * const github = registry.get('github');
15
+ * const taskProviders = registry.getAdaptersOfType('task');
16
+ * ```
17
+ */
18
+ import type { ExternalProvider, ProviderConfig, SyncAdapterType, TaskSyncAdapter, DocumentSyncAdapter, MessageSyncAdapter } from '@stoneforge/core';
19
+ /**
20
+ * Result from getAdaptersOfType — a provider and its adapter for the requested type
21
+ */
22
+ export interface ProviderAdapterEntry {
23
+ readonly provider: ExternalProvider;
24
+ readonly adapter: TaskSyncAdapter | DocumentSyncAdapter | MessageSyncAdapter;
25
+ }
26
+ /**
27
+ * Registry for external sync providers.
28
+ *
29
+ * Manages registration and lookup of ExternalProvider instances.
30
+ * Providers are keyed by their `name` property (e.g., 'github', 'linear').
31
+ */
32
+ export declare class ProviderRegistry {
33
+ private readonly providers;
34
+ /**
35
+ * Register a provider.
36
+ *
37
+ * @param provider - The provider to register
38
+ * @throws Error if a provider with the same name is already registered
39
+ */
40
+ register(provider: ExternalProvider): void;
41
+ /**
42
+ * Look up a provider by name.
43
+ *
44
+ * @param name - The provider name (e.g., 'github')
45
+ * @returns The provider, or undefined if not found
46
+ */
47
+ get(name: string): ExternalProvider | undefined;
48
+ /**
49
+ * List all registered providers.
50
+ *
51
+ * @returns Array of all registered providers
52
+ */
53
+ list(): ExternalProvider[];
54
+ /**
55
+ * Find all providers that support a given adapter type, and return
56
+ * the provider paired with its adapter for that type.
57
+ *
58
+ * @param type - The adapter type to filter by ('task', 'document', 'message')
59
+ * @returns Array of { provider, adapter } for all matching providers
60
+ */
61
+ getAdaptersOfType(type: SyncAdapterType): ProviderAdapterEntry[];
62
+ /**
63
+ * Check if a provider is registered.
64
+ *
65
+ * @param name - The provider name
66
+ * @returns true if the provider is registered
67
+ */
68
+ has(name: string): boolean;
69
+ /**
70
+ * Unregister a provider by name.
71
+ *
72
+ * @param name - The provider name to remove
73
+ * @returns true if the provider was removed, false if not found
74
+ */
75
+ unregister(name: string): boolean;
76
+ /**
77
+ * Remove all registered providers.
78
+ */
79
+ clear(): void;
80
+ }
81
+ /**
82
+ * Create a new ProviderRegistry instance.
83
+ *
84
+ * @returns A new, empty ProviderRegistry
85
+ */
86
+ export declare function createProviderRegistry(): ProviderRegistry;
87
+ /**
88
+ * Create a ProviderRegistry with default providers registered.
89
+ *
90
+ * Registers placeholder providers for GitHub, Linear, and Notion by default,
91
+ * plus the Folder provider (which needs no authentication and is always ready).
92
+ * The actual provider implementations replace placeholders when configured with API keys.
93
+ *
94
+ * @returns A ProviderRegistry with default providers
95
+ */
96
+ export declare function createDefaultProviderRegistry(): ProviderRegistry;
97
+ /**
98
+ * Create a ProviderRegistry with real configured providers.
99
+ *
100
+ * Starts with placeholder providers for all known providers (GitHub, Linear, Notion, Folder),
101
+ * then replaces placeholders with real configured providers for any configs
102
+ * that have a token set. This ensures providers without tokens remain as
103
+ * placeholders (which throw descriptive errors), while configured providers
104
+ * are ready for actual sync operations.
105
+ *
106
+ * Note: The Folder provider is always ready (no token needed), so it is
107
+ * never replaced — it remains as-is from the default registry.
108
+ *
109
+ * @param providerConfigs - Array of provider configurations (from settings)
110
+ * @returns A ProviderRegistry with configured providers replacing placeholders
111
+ */
112
+ export declare function createConfiguredProviderRegistry(providerConfigs: readonly ProviderConfig[]): ProviderRegistry;
113
+ //# sourceMappingURL=provider-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../../src/external-sync/provider-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAU1B;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;CAC9E;AAMD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAEjE;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAU1C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAI/C;;;;OAIG;IACH,IAAI,IAAI,gBAAgB,EAAE;IAI1B;;;;;;OAMG;IACH,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,oBAAoB,EAAE;IAiBhE;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AA6BD;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,IAAI,gBAAgB,CAOhE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAC9C,eAAe,EAAE,SAAS,cAAc,EAAE,GACzC,gBAAgB,CA8ClB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Provider Registry — manages ExternalProvider registrations
3
+ *
4
+ * Provides a central registry for external sync providers (GitHub, Linear, etc.).
5
+ * Supports registration, lookup by name, listing all providers, and querying
6
+ * providers by adapter type.
7
+ *
8
+ * Usage:
9
+ * ```typescript
10
+ * import { createProviderRegistry } from '@stoneforge/quarry';
11
+ *
12
+ * const registry = createProviderRegistry();
13
+ * registry.register(myProvider);
14
+ * const github = registry.get('github');
15
+ * const taskProviders = registry.getAdaptersOfType('task');
16
+ * ```
17
+ */
18
+ import { createGitHubProvider, createGitHubPlaceholderProvider } from './providers/github/index.js';
19
+ import { createLinearProvider, createLinearPlaceholderProvider } from './providers/linear/index.js';
20
+ import { createNotionProvider, createNotionPlaceholderProvider } from './providers/notion/index.js';
21
+ import { createFolderProvider } from './providers/folder/index.js';
22
+ // ============================================================================
23
+ // ProviderRegistry
24
+ // ============================================================================
25
+ /**
26
+ * Registry for external sync providers.
27
+ *
28
+ * Manages registration and lookup of ExternalProvider instances.
29
+ * Providers are keyed by their `name` property (e.g., 'github', 'linear').
30
+ */
31
+ export class ProviderRegistry {
32
+ providers = new Map();
33
+ /**
34
+ * Register a provider.
35
+ *
36
+ * @param provider - The provider to register
37
+ * @throws Error if a provider with the same name is already registered
38
+ */
39
+ register(provider) {
40
+ if (this.providers.has(provider.name)) {
41
+ throw new Error(`Provider '${provider.name}' is already registered. ` +
42
+ `Unregister it first or use a different name.`);
43
+ }
44
+ this.providers.set(provider.name, provider);
45
+ }
46
+ /**
47
+ * Look up a provider by name.
48
+ *
49
+ * @param name - The provider name (e.g., 'github')
50
+ * @returns The provider, or undefined if not found
51
+ */
52
+ get(name) {
53
+ return this.providers.get(name);
54
+ }
55
+ /**
56
+ * List all registered providers.
57
+ *
58
+ * @returns Array of all registered providers
59
+ */
60
+ list() {
61
+ return Array.from(this.providers.values());
62
+ }
63
+ /**
64
+ * Find all providers that support a given adapter type, and return
65
+ * the provider paired with its adapter for that type.
66
+ *
67
+ * @param type - The adapter type to filter by ('task', 'document', 'message')
68
+ * @returns Array of { provider, adapter } for all matching providers
69
+ */
70
+ getAdaptersOfType(type) {
71
+ const results = [];
72
+ for (const provider of this.providers.values()) {
73
+ if (!provider.supportedAdapters.includes(type)) {
74
+ continue;
75
+ }
76
+ const adapter = getAdapterByType(provider, type);
77
+ if (adapter) {
78
+ results.push({ provider, adapter });
79
+ }
80
+ }
81
+ return results;
82
+ }
83
+ /**
84
+ * Check if a provider is registered.
85
+ *
86
+ * @param name - The provider name
87
+ * @returns true if the provider is registered
88
+ */
89
+ has(name) {
90
+ return this.providers.has(name);
91
+ }
92
+ /**
93
+ * Unregister a provider by name.
94
+ *
95
+ * @param name - The provider name to remove
96
+ * @returns true if the provider was removed, false if not found
97
+ */
98
+ unregister(name) {
99
+ return this.providers.delete(name);
100
+ }
101
+ /**
102
+ * Remove all registered providers.
103
+ */
104
+ clear() {
105
+ this.providers.clear();
106
+ }
107
+ }
108
+ // ============================================================================
109
+ // Helper Functions
110
+ // ============================================================================
111
+ /**
112
+ * Get the adapter from a provider for a given adapter type.
113
+ */
114
+ function getAdapterByType(provider, type) {
115
+ switch (type) {
116
+ case 'task':
117
+ return provider.getTaskAdapter?.();
118
+ case 'document':
119
+ return provider.getDocumentAdapter?.();
120
+ case 'message':
121
+ return provider.getMessageAdapter?.();
122
+ default:
123
+ return undefined;
124
+ }
125
+ }
126
+ // ============================================================================
127
+ // Factory
128
+ // ============================================================================
129
+ /**
130
+ * Create a new ProviderRegistry instance.
131
+ *
132
+ * @returns A new, empty ProviderRegistry
133
+ */
134
+ export function createProviderRegistry() {
135
+ return new ProviderRegistry();
136
+ }
137
+ /**
138
+ * Create a ProviderRegistry with default providers registered.
139
+ *
140
+ * Registers placeholder providers for GitHub, Linear, and Notion by default,
141
+ * plus the Folder provider (which needs no authentication and is always ready).
142
+ * The actual provider implementations replace placeholders when configured with API keys.
143
+ *
144
+ * @returns A ProviderRegistry with default providers
145
+ */
146
+ export function createDefaultProviderRegistry() {
147
+ const registry = new ProviderRegistry();
148
+ registry.register(createGitHubPlaceholderProvider());
149
+ registry.register(createLinearPlaceholderProvider());
150
+ registry.register(createNotionPlaceholderProvider());
151
+ registry.register(createFolderProvider());
152
+ return registry;
153
+ }
154
+ /**
155
+ * Create a ProviderRegistry with real configured providers.
156
+ *
157
+ * Starts with placeholder providers for all known providers (GitHub, Linear, Notion, Folder),
158
+ * then replaces placeholders with real configured providers for any configs
159
+ * that have a token set. This ensures providers without tokens remain as
160
+ * placeholders (which throw descriptive errors), while configured providers
161
+ * are ready for actual sync operations.
162
+ *
163
+ * Note: The Folder provider is always ready (no token needed), so it is
164
+ * never replaced — it remains as-is from the default registry.
165
+ *
166
+ * @param providerConfigs - Array of provider configurations (from settings)
167
+ * @returns A ProviderRegistry with configured providers replacing placeholders
168
+ */
169
+ export function createConfiguredProviderRegistry(providerConfigs) {
170
+ const registry = createDefaultProviderRegistry();
171
+ for (const config of providerConfigs) {
172
+ // Folder provider doesn't need a token — it's always ready
173
+ if (config.provider === 'folder') {
174
+ continue;
175
+ }
176
+ if (!config.token) {
177
+ continue;
178
+ }
179
+ // Replace the placeholder with a real configured provider
180
+ registry.unregister(config.provider);
181
+ switch (config.provider) {
182
+ case 'github':
183
+ registry.register(createGitHubProvider({
184
+ provider: 'github',
185
+ token: config.token,
186
+ apiBaseUrl: config.apiBaseUrl,
187
+ defaultProject: config.defaultProject,
188
+ }));
189
+ break;
190
+ case 'linear':
191
+ registry.register(createLinearProvider({
192
+ apiKey: config.token,
193
+ }));
194
+ break;
195
+ case 'notion':
196
+ registry.register(createNotionProvider({
197
+ token: config.token,
198
+ }));
199
+ break;
200
+ // Unknown providers are silently skipped — their placeholders remain
201
+ }
202
+ }
203
+ return registry;
204
+ }
205
+ //# sourceMappingURL=provider-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../../src/external-sync/provider-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Folder Document Sync Adapter
3
+ *
4
+ * Implements the DocumentSyncAdapter interface for local folder-based
5
+ * document synchronization. Maps between Stoneforge documents and
6
+ * markdown files with YAML frontmatter in a local directory tree.
7
+ *
8
+ * Uses folder-fs.ts for all filesystem operations (read, write, list).
9
+ *
10
+ * Conventions:
11
+ * - project = absolute folder path (base directory)
12
+ * - externalId = relative file path within the folder (e.g., 'notes/meeting.md')
13
+ * - URL format: file:///absolute/path/to/file.md
14
+ * - Filenames are generated from titles using slugification
15
+ */
16
+ import type { DocumentSyncAdapter, ExternalDocument, ExternalDocumentInput, Timestamp } from '@stoneforge/core';
17
+ /**
18
+ * Converts a title string into a filename-safe slug.
19
+ *
20
+ * - Lowercases the string
21
+ * - Replaces non-alphanumeric characters (except hyphens) with hyphens
22
+ * - Collapses consecutive hyphens
23
+ * - Trims leading/trailing hyphens
24
+ * - Falls back to 'untitled' for empty results
25
+ *
26
+ * @param title - The document title to slugify
27
+ * @returns A filename-safe slug string (without extension)
28
+ */
29
+ export declare function slugify(title: string): string;
30
+ /**
31
+ * DocumentSyncAdapter implementation for local folder-based sync.
32
+ *
33
+ * Maps between Stoneforge ExternalDocument and markdown files with YAML
34
+ * frontmatter on the local filesystem.
35
+ *
36
+ * Usage:
37
+ * ```typescript
38
+ * const adapter = new FolderDocumentAdapter();
39
+ * const doc = await adapter.getPage('/path/to/docs', 'notes/meeting.md');
40
+ * ```
41
+ */
42
+ export declare class FolderDocumentAdapter implements DocumentSyncAdapter {
43
+ /**
44
+ * Fetch a single document by its relative file path.
45
+ *
46
+ * @param project - Absolute path to the base directory
47
+ * @param externalId - Relative file path (e.g., 'notes/meeting.md')
48
+ * @returns The document as an ExternalDocument, or null if not found
49
+ */
50
+ getPage(project: string, externalId: string): Promise<ExternalDocument | null>;
51
+ /**
52
+ * List documents modified since a given timestamp.
53
+ *
54
+ * Reads each file to extract title and content, returning full
55
+ * ExternalDocument objects.
56
+ *
57
+ * @param project - Absolute path to the base directory
58
+ * @param since - ISO 8601 timestamp; only files modified after this are returned
59
+ * @returns Array of ExternalDocument objects for modified files
60
+ */
61
+ listPagesSince(project: string, since: Timestamp): Promise<ExternalDocument[]>;
62
+ /**
63
+ * Create a new document file in the folder.
64
+ *
65
+ * Generates a filename from the title using slugification, writes
66
+ * the content with frontmatter, and returns the created document.
67
+ *
68
+ * If the page has a `libraryPath`, the file is placed in the
69
+ * corresponding subdirectory. For example, a libraryPath of
70
+ * 'documentation/api' results in the file being created at
71
+ * 'documentation/api/my-doc.md'.
72
+ *
73
+ * @param project - Absolute path to the base directory
74
+ * @param page - Document input with title, content, and optional contentType
75
+ * @returns The created ExternalDocument
76
+ */
77
+ createPage(project: string, page: ExternalDocumentInput): Promise<ExternalDocument>;
78
+ /**
79
+ * Update an existing document file in the folder.
80
+ *
81
+ * Reads the existing file, merges the updates (preserving existing
82
+ * frontmatter), and writes back. Returns the updated document.
83
+ *
84
+ * @param project - Absolute path to the base directory
85
+ * @param externalId - Relative file path of the existing document
86
+ * @param updates - Partial document input with fields to update
87
+ * @returns The updated ExternalDocument
88
+ */
89
+ updatePage(project: string, externalId: string, updates: Partial<ExternalDocumentInput>): Promise<ExternalDocument>;
90
+ }
91
+ /**
92
+ * Creates a new FolderDocumentAdapter instance.
93
+ *
94
+ * @returns A configured FolderDocumentAdapter
95
+ */
96
+ export declare function createFolderDocumentAdapter(): FolderDocumentAdapter;
97
+ //# sourceMappingURL=folder-document-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-document-adapter.d.ts","sourceRoot":"","sources":["../../../../src/external-sync/providers/folder/folder-document-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,SAAS,EACV,MAAM,kBAAkB,CAAC;AAe1B;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ7C;AAsBD;;;;;;;;;;;GAWG;AACH,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D;;;;;;OAMG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA8BnC;;;;;;;;;OASG;IACG,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAuB9B;;;;;;;;;;;;;;OAcG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IAqC5B;;;;;;;;;;OAUG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACtC,OAAO,CAAC,gBAAgB,CAAC;CAsC7B;AA6CD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CAEnE"}