@deimoscloud/coreai 0.1.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 (216) hide show
  1. package/.prettierrc +9 -0
  2. package/AGENT_SPEC.md +347 -0
  3. package/ARCHITECTURE.md +547 -0
  4. package/DRAFT_PRD.md +1440 -0
  5. package/IMPLEMENTATION_PLAN.md +256 -0
  6. package/PRODUCT.md +473 -0
  7. package/README.md +303 -0
  8. package/WORKFLOWS.md +295 -0
  9. package/agents/_templates/ic-engineer.md +185 -0
  10. package/agents/_templates/reviewer.md +182 -0
  11. package/agents/backend-engineer.yaml +72 -0
  12. package/agents/devops-engineer.yaml +72 -0
  13. package/agents/engineering-manager.yaml +70 -0
  14. package/agents/examples/android-engineer.md +302 -0
  15. package/agents/examples/backend-engineer.md +320 -0
  16. package/agents/examples/devops-engineer.md +742 -0
  17. package/agents/examples/engineering-manager.md +469 -0
  18. package/agents/examples/frontend-engineer.md +58 -0
  19. package/agents/examples/product-manager.md +315 -0
  20. package/agents/examples/qa-engineer.md +371 -0
  21. package/agents/examples/security-engineer.md +525 -0
  22. package/agents/examples/solutions-architect.md +351 -0
  23. package/agents/examples/wearos-engineer.md +359 -0
  24. package/agents/frontend-engineer.yaml +72 -0
  25. package/commands/core/check-inbox.md +34 -0
  26. package/commands/core/delegate.md +30 -0
  27. package/commands/core/git-commit.md +144 -0
  28. package/commands/core/pr-create.md +193 -0
  29. package/commands/core/review.md +56 -0
  30. package/commands/core/sprint-status.md +65 -0
  31. package/commands/optional/docs-update.md +200 -0
  32. package/commands/optional/jira-create.md +200 -0
  33. package/commands/optional/jira-transition.md +184 -0
  34. package/commands/optional/worktree-cleanup.md +167 -0
  35. package/commands/optional/worktree-setup.md +110 -0
  36. package/dist/cli/index.js +4037 -0
  37. package/dist/cli/index.js.map +1 -0
  38. package/dist/index.d.ts +2978 -0
  39. package/dist/index.js +3867 -0
  40. package/dist/index.js.map +1 -0
  41. package/eslint.config.js +29 -0
  42. package/jest.config.js +22 -0
  43. package/knowledge-library/README.md +118 -0
  44. package/knowledge-library/android-engineer/context/current.txt +42 -0
  45. package/knowledge-library/android-engineer/control/decisions.txt +9 -0
  46. package/knowledge-library/android-engineer/control/dependencies.txt +19 -0
  47. package/knowledge-library/android-engineer/control/objectives.txt +26 -0
  48. package/knowledge-library/android-engineer/history/.gitkeep +0 -0
  49. package/knowledge-library/android-engineer/inbox/processed/.gitkeep +0 -0
  50. package/knowledge-library/android-engineer/outbox/.gitkeep +0 -0
  51. package/knowledge-library/android-engineer/tech/.gitkeep +0 -0
  52. package/knowledge-library/architecture.txt +61 -0
  53. package/knowledge-library/backend-engineer/context/current.txt +42 -0
  54. package/knowledge-library/backend-engineer/control/decisions.txt +9 -0
  55. package/knowledge-library/backend-engineer/control/dependencies.txt +19 -0
  56. package/knowledge-library/backend-engineer/control/objectives.txt +26 -0
  57. package/knowledge-library/backend-engineer/history/.gitkeep +0 -0
  58. package/knowledge-library/backend-engineer/inbox/processed/.gitkeep +0 -0
  59. package/knowledge-library/backend-engineer/outbox/.gitkeep +0 -0
  60. package/knowledge-library/backend-engineer/tech/.gitkeep +0 -0
  61. package/knowledge-library/context.txt +52 -0
  62. package/knowledge-library/devops-engineer/context/current.txt +42 -0
  63. package/knowledge-library/devops-engineer/control/decisions.txt +9 -0
  64. package/knowledge-library/devops-engineer/control/dependencies.txt +19 -0
  65. package/knowledge-library/devops-engineer/control/objectives.txt +26 -0
  66. package/knowledge-library/devops-engineer/history/.gitkeep +0 -0
  67. package/knowledge-library/devops-engineer/inbox/processed/.gitkeep +0 -0
  68. package/knowledge-library/devops-engineer/outbox/.gitkeep +0 -0
  69. package/knowledge-library/devops-engineer/tech/.gitkeep +0 -0
  70. package/knowledge-library/engineering-manager/context/current.txt +40 -0
  71. package/knowledge-library/engineering-manager/control/decisions.txt +9 -0
  72. package/knowledge-library/engineering-manager/control/objectives.txt +27 -0
  73. package/knowledge-library/engineering-manager/history/.gitkeep +0 -0
  74. package/knowledge-library/engineering-manager/inbox/processed/.gitkeep +0 -0
  75. package/knowledge-library/engineering-manager/outbox/.gitkeep +0 -0
  76. package/knowledge-library/engineering-manager/tech/.gitkeep +0 -0
  77. package/knowledge-library/prd.txt +81 -0
  78. package/knowledge-library/product-manager/context/current.txt +42 -0
  79. package/knowledge-library/product-manager/control/decisions.txt +9 -0
  80. package/knowledge-library/product-manager/control/dependencies.txt +19 -0
  81. package/knowledge-library/product-manager/control/objectives.txt +26 -0
  82. package/knowledge-library/product-manager/history/.gitkeep +0 -0
  83. package/knowledge-library/product-manager/inbox/processed/.gitkeep +0 -0
  84. package/knowledge-library/product-manager/outbox/.gitkeep +0 -0
  85. package/knowledge-library/product-manager/tech/.gitkeep +0 -0
  86. package/knowledge-library/qa-engineer/context/current.txt +42 -0
  87. package/knowledge-library/qa-engineer/control/decisions.txt +9 -0
  88. package/knowledge-library/qa-engineer/control/dependencies.txt +19 -0
  89. package/knowledge-library/qa-engineer/control/objectives.txt +26 -0
  90. package/knowledge-library/qa-engineer/history/.gitkeep +0 -0
  91. package/knowledge-library/qa-engineer/inbox/processed/.gitkeep +0 -0
  92. package/knowledge-library/qa-engineer/outbox/.gitkeep +0 -0
  93. package/knowledge-library/qa-engineer/tech/.gitkeep +0 -0
  94. package/knowledge-library/security-engineer/context/current.txt +42 -0
  95. package/knowledge-library/security-engineer/control/decisions.txt +9 -0
  96. package/knowledge-library/security-engineer/control/dependencies.txt +19 -0
  97. package/knowledge-library/security-engineer/control/objectives.txt +26 -0
  98. package/knowledge-library/security-engineer/history/.gitkeep +0 -0
  99. package/knowledge-library/security-engineer/inbox/processed/.gitkeep +0 -0
  100. package/knowledge-library/security-engineer/outbox/.gitkeep +0 -0
  101. package/knowledge-library/security-engineer/tech/.gitkeep +0 -0
  102. package/knowledge-library/solutions-architect/context/current.txt +42 -0
  103. package/knowledge-library/solutions-architect/control/decisions.txt +9 -0
  104. package/knowledge-library/solutions-architect/control/dependencies.txt +19 -0
  105. package/knowledge-library/solutions-architect/control/objectives.txt +26 -0
  106. package/knowledge-library/solutions-architect/history/.gitkeep +0 -0
  107. package/knowledge-library/solutions-architect/inbox/processed/.gitkeep +0 -0
  108. package/knowledge-library/solutions-architect/outbox/.gitkeep +0 -0
  109. package/knowledge-library/solutions-architect/tech/.gitkeep +0 -0
  110. package/knowledge-library/wearos-engineer/context/current.txt +42 -0
  111. package/knowledge-library/wearos-engineer/control/decisions.txt +9 -0
  112. package/knowledge-library/wearos-engineer/control/dependencies.txt +19 -0
  113. package/knowledge-library/wearos-engineer/control/objectives.txt +26 -0
  114. package/knowledge-library/wearos-engineer/history/.gitkeep +0 -0
  115. package/knowledge-library/wearos-engineer/inbox/processed/.gitkeep +0 -0
  116. package/knowledge-library/wearos-engineer/outbox/.gitkeep +0 -0
  117. package/knowledge-library/wearos-engineer/tech/.gitkeep +0 -0
  118. package/package.json +66 -0
  119. package/schemas/agent.schema.json +171 -0
  120. package/schemas/coreai.config.schema.json +257 -0
  121. package/scripts/add-agent.sh +323 -0
  122. package/scripts/install.sh +354 -0
  123. package/src/adapters/factory.test.ts +386 -0
  124. package/src/adapters/factory.ts +305 -0
  125. package/src/adapters/index.ts +113 -0
  126. package/src/adapters/interfaces.ts +268 -0
  127. package/src/adapters/mcp/client.test.ts +130 -0
  128. package/src/adapters/mcp/client.ts +451 -0
  129. package/src/adapters/mcp/discovery.test.ts +315 -0
  130. package/src/adapters/mcp/discovery.ts +340 -0
  131. package/src/adapters/mcp/index.ts +66 -0
  132. package/src/adapters/mcp/mapper.test.ts +218 -0
  133. package/src/adapters/mcp/mapper.ts +536 -0
  134. package/src/adapters/mcp/registry.test.ts +433 -0
  135. package/src/adapters/mcp/registry.ts +550 -0
  136. package/src/adapters/mcp/types.ts +258 -0
  137. package/src/adapters/native/filesystem.test.ts +350 -0
  138. package/src/adapters/native/filesystem.ts +393 -0
  139. package/src/adapters/native/github.test.ts +173 -0
  140. package/src/adapters/native/github.ts +627 -0
  141. package/src/adapters/native/index.ts +22 -0
  142. package/src/adapters/native/selector.test.ts +224 -0
  143. package/src/adapters/native/selector.ts +150 -0
  144. package/src/adapters/types.ts +270 -0
  145. package/src/agents/compiler.test.ts +399 -0
  146. package/src/agents/compiler.ts +359 -0
  147. package/src/agents/index.ts +36 -0
  148. package/src/agents/loader.test.ts +319 -0
  149. package/src/agents/loader.ts +143 -0
  150. package/src/agents/resolver.test.ts +282 -0
  151. package/src/agents/resolver.ts +262 -0
  152. package/src/agents/types.ts +87 -0
  153. package/src/cache/index.ts +38 -0
  154. package/src/cache/interfaces.ts +283 -0
  155. package/src/cache/manager.test.ts +266 -0
  156. package/src/cache/manager.ts +388 -0
  157. package/src/cache/provider.test.ts +485 -0
  158. package/src/cache/provider.ts +745 -0
  159. package/src/cache/types.test.ts +192 -0
  160. package/src/cache/types.ts +313 -0
  161. package/src/cli/commands/build.test.ts +248 -0
  162. package/src/cli/commands/build.ts +244 -0
  163. package/src/cli/commands/cache.test.ts +221 -0
  164. package/src/cli/commands/cache.ts +229 -0
  165. package/src/cli/commands/index.ts +63 -0
  166. package/src/cli/commands/init.test.ts +173 -0
  167. package/src/cli/commands/init.ts +296 -0
  168. package/src/cli/commands/skills.test.ts +272 -0
  169. package/src/cli/commands/skills.ts +348 -0
  170. package/src/cli/commands/status.test.ts +392 -0
  171. package/src/cli/commands/status.ts +332 -0
  172. package/src/cli/commands/sync.test.ts +213 -0
  173. package/src/cli/commands/sync.ts +251 -0
  174. package/src/cli/commands/validate.test.ts +216 -0
  175. package/src/cli/commands/validate.ts +340 -0
  176. package/src/cli/index.test.ts +190 -0
  177. package/src/cli/index.ts +493 -0
  178. package/src/commands/context.test.ts +163 -0
  179. package/src/commands/context.ts +111 -0
  180. package/src/commands/index.ts +56 -0
  181. package/src/commands/loader.test.ts +273 -0
  182. package/src/commands/loader.ts +355 -0
  183. package/src/commands/registry.test.ts +384 -0
  184. package/src/commands/registry.ts +248 -0
  185. package/src/commands/runner.test.ts +297 -0
  186. package/src/commands/runner.ts +222 -0
  187. package/src/commands/types.ts +361 -0
  188. package/src/config/index.ts +19 -0
  189. package/src/config/loader.test.ts +262 -0
  190. package/src/config/loader.ts +188 -0
  191. package/src/config/types.ts +154 -0
  192. package/src/context/index.ts +14 -0
  193. package/src/context/loader.test.ts +334 -0
  194. package/src/context/loader.ts +357 -0
  195. package/src/index.test.ts +13 -0
  196. package/src/index.ts +244 -0
  197. package/src/knowledge-library/index.ts +44 -0
  198. package/src/knowledge-library/manager.test.ts +536 -0
  199. package/src/knowledge-library/manager.ts +804 -0
  200. package/src/knowledge-library/types.ts +432 -0
  201. package/src/skills/generator.test.ts +602 -0
  202. package/src/skills/generator.ts +491 -0
  203. package/src/skills/index.ts +27 -0
  204. package/src/skills/templates.ts +520 -0
  205. package/src/skills/types.ts +251 -0
  206. package/templates/completion-report.md +72 -0
  207. package/templates/feedback.md +56 -0
  208. package/templates/project-files/CLAUDE.md.template +109 -0
  209. package/templates/project-files/coreai.json.example +47 -0
  210. package/templates/project-files/mcp.json.template +20 -0
  211. package/templates/review-complete.md +64 -0
  212. package/templates/review-request.md +67 -0
  213. package/templates/task-assignment.md +51 -0
  214. package/tsconfig.build.json +4 -0
  215. package/tsconfig.json +26 -0
  216. package/tsup.config.ts +23 -0
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Native Adapter Selector Tests
3
+ */
4
+
5
+ import type { CoreAIConfig } from '../../config/types.js';
6
+ import { AdapterFactory } from '../factory.js';
7
+ import { FilesystemAdapter } from './filesystem.js';
8
+ import {
9
+ registerNativeAdapters,
10
+ checkNativeAdapterAvailability,
11
+ parseGitHubRemote,
12
+ } from './selector.js';
13
+
14
+ describe('registerNativeAdapters', () => {
15
+ it('should register state adapter creator', async () => {
16
+ const config: CoreAIConfig = {
17
+ project: { root: '/tmp/test' },
18
+ };
19
+ const factory = new AdapterFactory(config);
20
+
21
+ registerNativeAdapters(factory, { statePath: '/tmp/test' });
22
+
23
+ // Verify the creator was registered by trying to get the adapter
24
+ // We can't directly access the creators, but we can test the factory behavior
25
+ expect(factory).toBeDefined();
26
+ });
27
+
28
+ it('should register git adapter creator', () => {
29
+ const config: CoreAIConfig = {
30
+ project: { root: '/tmp/test' },
31
+ integrations: {
32
+ git: {
33
+ provider: 'github',
34
+ owner: 'test-owner',
35
+ repo: 'test-repo',
36
+ },
37
+ },
38
+ };
39
+ const factory = new AdapterFactory(config);
40
+
41
+ registerNativeAdapters(factory, { githubRepository: 'owner/repo' });
42
+
43
+ expect(factory).toBeDefined();
44
+ });
45
+
46
+ it('should use options for state path', () => {
47
+ const config: CoreAIConfig = {
48
+ project: { root: '/original' },
49
+ };
50
+ const factory = new AdapterFactory(config);
51
+
52
+ registerNativeAdapters(factory, {
53
+ statePath: '/custom/path',
54
+ });
55
+
56
+ expect(factory).toBeDefined();
57
+ });
58
+
59
+ it('should use options for github repository', () => {
60
+ const config: CoreAIConfig = {};
61
+ const factory = new AdapterFactory(config);
62
+
63
+ registerNativeAdapters(factory, {
64
+ githubRepository: 'custom/repo',
65
+ });
66
+
67
+ expect(factory).toBeDefined();
68
+ });
69
+ });
70
+
71
+ describe('checkNativeAdapterAvailability', () => {
72
+ it('should return state as available with valid config', () => {
73
+ const config: CoreAIConfig = {
74
+ project: { root: '/tmp/test' },
75
+ };
76
+
77
+ const availability = checkNativeAdapterAvailability(config);
78
+
79
+ expect(availability.state).toBe(true);
80
+ expect(availability.stateReason).toBeUndefined();
81
+ });
82
+
83
+ it('should return git as available when configured', () => {
84
+ const config: CoreAIConfig = {
85
+ integrations: {
86
+ git: {
87
+ provider: 'github',
88
+ config: {
89
+ owner: 'test-owner',
90
+ repo: 'test-repo',
91
+ },
92
+ },
93
+ },
94
+ };
95
+
96
+ const availability = checkNativeAdapterAvailability(config);
97
+
98
+ expect(availability.git).toBe(true);
99
+ expect(availability.gitReason).toBeUndefined();
100
+ });
101
+
102
+ it('should return git as unavailable without configuration', () => {
103
+ const config: CoreAIConfig = {};
104
+
105
+ const availability = checkNativeAdapterAvailability(config);
106
+
107
+ expect(availability.git).toBe(false);
108
+ expect(availability.gitReason).toBe('GitHub repository not configured');
109
+ });
110
+
111
+ it('should use options to override config for git', () => {
112
+ const config: CoreAIConfig = {};
113
+ const options = { githubRepository: 'owner/repo' };
114
+
115
+ const availability = checkNativeAdapterAvailability(config, options);
116
+
117
+ expect(availability.git).toBe(true);
118
+ });
119
+
120
+ it('should use options to override config for state', () => {
121
+ const config: CoreAIConfig = {};
122
+ const options = { statePath: '/custom/path' };
123
+
124
+ const availability = checkNativeAdapterAvailability(config, options);
125
+
126
+ expect(availability.state).toBe(true);
127
+ });
128
+
129
+ it('should check git provider is github', () => {
130
+ const config: CoreAIConfig = {
131
+ integrations: {
132
+ git: {
133
+ provider: 'gitlab', // Not github
134
+ owner: 'test-owner',
135
+ repo: 'test-repo',
136
+ },
137
+ },
138
+ };
139
+
140
+ const availability = checkNativeAdapterAvailability(config);
141
+
142
+ expect(availability.git).toBe(false);
143
+ });
144
+ });
145
+
146
+ describe('parseGitHubRemote', () => {
147
+ it('should parse HTTPS URL', () => {
148
+ const url = 'https://github.com/owner/repo.git';
149
+ const result = parseGitHubRemote(url);
150
+ expect(result).toBe('owner/repo');
151
+ });
152
+
153
+ it('should parse HTTPS URL without .git suffix', () => {
154
+ const url = 'https://github.com/owner/repo';
155
+ const result = parseGitHubRemote(url);
156
+ expect(result).toBe('owner/repo');
157
+ });
158
+
159
+ it('should parse SSH URL', () => {
160
+ const url = 'git@github.com:owner/repo.git';
161
+ const result = parseGitHubRemote(url);
162
+ expect(result).toBe('owner/repo');
163
+ });
164
+
165
+ it('should parse SSH URL without .git suffix', () => {
166
+ const url = 'git@github.com:owner/repo';
167
+ const result = parseGitHubRemote(url);
168
+ expect(result).toBe('owner/repo');
169
+ });
170
+
171
+ it('should return null for non-GitHub URL', () => {
172
+ const url = 'https://gitlab.com/owner/repo.git';
173
+ const result = parseGitHubRemote(url);
174
+ expect(result).toBeNull();
175
+ });
176
+
177
+ it('should return null for invalid URL', () => {
178
+ const url = 'not-a-url';
179
+ const result = parseGitHubRemote(url);
180
+ expect(result).toBeNull();
181
+ });
182
+
183
+ it('should handle complex repo names', () => {
184
+ const url = 'https://github.com/my-org/my-cool-repo.git';
185
+ const result = parseGitHubRemote(url);
186
+ expect(result).toBe('my-org/my-cool-repo');
187
+ });
188
+
189
+ it('should handle underscores in names', () => {
190
+ const url = 'git@github.com:my_org/my_repo.git';
191
+ const result = parseGitHubRemote(url);
192
+ expect(result).toBe('my_org/my_repo');
193
+ });
194
+ });
195
+
196
+ describe('Integration tests', () => {
197
+ it('should create filesystem adapter through factory', async () => {
198
+ const config: CoreAIConfig = {
199
+ project: { root: '/tmp/test' },
200
+ };
201
+ const factory = new AdapterFactory(config);
202
+
203
+ registerNativeAdapters(factory, { statePath: '/tmp' });
204
+
205
+ // The factory will try to create and connect, which may fail
206
+ // but we can test that the creator is properly registered
207
+ try {
208
+ const adapter = await factory.getStateProvider({ strategy: 'native' });
209
+ expect(adapter).toBeInstanceOf(FilesystemAdapter);
210
+ await adapter.disconnect();
211
+ } catch {
212
+ // Connect may fail in test environment, that's ok
213
+ }
214
+ });
215
+
216
+ it('should throw when getting git adapter without config', async () => {
217
+ const config: CoreAIConfig = {};
218
+ const factory = new AdapterFactory(config);
219
+
220
+ registerNativeAdapters(factory);
221
+
222
+ await expect(factory.getGitProvider({ strategy: 'native' })).rejects.toThrow();
223
+ });
224
+ });
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Native Adapter Selector
3
+ *
4
+ * Registers native adapters with the adapter factory and provides
5
+ * helper functions for adapter selection.
6
+ */
7
+
8
+ import type { CoreAIConfig } from '../../config/types.js';
9
+ import type { AdapterFactory } from '../factory.js';
10
+ import { FilesystemAdapter } from './filesystem.js';
11
+ import { GitHubAdapter } from './github.js';
12
+
13
+ /**
14
+ * Options for the native adapter selector
15
+ */
16
+ export interface NativeAdapterSelectorOptions {
17
+ /**
18
+ * Base path for filesystem adapter (defaults to .coreai in project root)
19
+ */
20
+ statePath?: string;
21
+
22
+ /**
23
+ * GitHub repository in owner/repo format (auto-detected if not provided)
24
+ */
25
+ githubRepository?: string;
26
+
27
+ /**
28
+ * Path to gh CLI (defaults to 'gh')
29
+ */
30
+ ghPath?: string;
31
+ }
32
+
33
+ /**
34
+ * Register native adapters with a factory
35
+ *
36
+ * This function registers the native adapters (filesystem, github) with the
37
+ * adapter factory. The factory will use these as fallbacks when MCP adapters
38
+ * are not available.
39
+ */
40
+ export function registerNativeAdapters(
41
+ factory: AdapterFactory,
42
+ options?: NativeAdapterSelectorOptions
43
+ ): void {
44
+ // Register state provider (filesystem)
45
+ factory.registerCreator('state', 'native', async (config: CoreAIConfig) => {
46
+ const basePath = options?.statePath ?? config.project?.root ?? process.cwd();
47
+ const adapter = new FilesystemAdapter({
48
+ basePath,
49
+ defaultEncoding: 'utf-8',
50
+ });
51
+ return adapter;
52
+ });
53
+
54
+ // Register git provider (github)
55
+ factory.registerCreator('git', 'native', async (config: CoreAIConfig) => {
56
+ // Try to get repository from options or config
57
+ let repository = options?.githubRepository;
58
+
59
+ if (!repository) {
60
+ // Try to get from git integration config
61
+ const gitConfig = config.integrations?.git;
62
+ if (gitConfig?.provider === 'github' && gitConfig.config?.owner && gitConfig.config?.repo) {
63
+ repository = `${gitConfig.config.owner}/${gitConfig.config.repo}`;
64
+ }
65
+ }
66
+
67
+ if (!repository) {
68
+ throw new Error(
69
+ 'GitHub repository not configured. Set integrations.git.owner and integrations.git.repo in config.'
70
+ );
71
+ }
72
+
73
+ const adapterOptions: { repository: string; ghPath?: string } = { repository };
74
+ if (options?.ghPath) {
75
+ adapterOptions.ghPath = options.ghPath;
76
+ }
77
+ const adapter = new GitHubAdapter(adapterOptions);
78
+ return adapter;
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Check if native adapters are available for the current environment
84
+ */
85
+ export interface NativeAdapterAvailability {
86
+ state: boolean;
87
+ git: boolean;
88
+ stateReason?: string;
89
+ gitReason?: string;
90
+ }
91
+
92
+ /**
93
+ * Check which native adapters are available
94
+ */
95
+ export function checkNativeAdapterAvailability(
96
+ config: CoreAIConfig,
97
+ options?: NativeAdapterSelectorOptions
98
+ ): NativeAdapterAvailability {
99
+ const result: NativeAdapterAvailability = {
100
+ state: true,
101
+ git: false,
102
+ };
103
+
104
+ // State adapter is always available (filesystem)
105
+ // Just needs a valid base path
106
+ const basePath = options?.statePath ?? config.project?.root ?? process.cwd();
107
+ if (!basePath) {
108
+ result.state = false;
109
+ result.stateReason = 'No base path configured';
110
+ }
111
+
112
+ // Git adapter needs repository configuration
113
+ let repository = options?.githubRepository;
114
+ if (!repository) {
115
+ const gitConfig = config.integrations?.git;
116
+ if (gitConfig?.provider === 'github' && gitConfig.config?.owner && gitConfig.config?.repo) {
117
+ repository = `${gitConfig.config.owner}/${gitConfig.config.repo}`;
118
+ }
119
+ }
120
+
121
+ if (repository) {
122
+ result.git = true;
123
+ } else {
124
+ result.gitReason = 'GitHub repository not configured';
125
+ }
126
+
127
+ return result;
128
+ }
129
+
130
+ /**
131
+ * Auto-detect GitHub repository from git remote
132
+ *
133
+ * Parses the git remote URL to extract owner/repo.
134
+ * Supports both HTTPS and SSH URL formats.
135
+ */
136
+ export function parseGitHubRemote(remoteUrl: string): string | null {
137
+ // HTTPS format: https://github.com/owner/repo.git
138
+ const httpsMatch = remoteUrl.match(/https:\/\/github\.com\/([^/]+)\/([^/.]+)/);
139
+ if (httpsMatch) {
140
+ return `${httpsMatch[1]}/${httpsMatch[2]}`;
141
+ }
142
+
143
+ // SSH format: git@github.com:owner/repo.git
144
+ const sshMatch = remoteUrl.match(/git@github\.com:([^/]+)\/([^/.]+)/);
145
+ if (sshMatch) {
146
+ return `${sshMatch[1]}/${sshMatch[2]}`;
147
+ }
148
+
149
+ return null;
150
+ }
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Adapter Types
3
+ *
4
+ * Common types used across all adapters.
5
+ */
6
+
7
+ /**
8
+ * The type of adapter
9
+ */
10
+ export type AdapterType = 'issue_tracker' | 'git' | 'documentation' | 'state';
11
+
12
+ /**
13
+ * How the adapter connects to the service
14
+ */
15
+ export type AdapterImplementation = 'mcp' | 'native' | 'mock';
16
+
17
+ /**
18
+ * Base metadata for all adapters
19
+ */
20
+ export interface AdapterInfo {
21
+ /**
22
+ * Type of adapter
23
+ */
24
+ type: AdapterType;
25
+
26
+ /**
27
+ * Provider name (e.g., 'github', 'jira', 'confluence')
28
+ */
29
+ provider: string;
30
+
31
+ /**
32
+ * How this adapter is implemented
33
+ */
34
+ implementation: AdapterImplementation;
35
+
36
+ /**
37
+ * Whether the adapter is currently connected/available
38
+ */
39
+ connected: boolean;
40
+ }
41
+
42
+ /**
43
+ * Common issue status values
44
+ */
45
+ export type IssueStatus =
46
+ | 'backlog'
47
+ | 'todo'
48
+ | 'in_progress'
49
+ | 'in_review'
50
+ | 'done'
51
+ | 'closed'
52
+ | string;
53
+
54
+ /**
55
+ * Common pull request status values
56
+ */
57
+ export type PullRequestStatus = 'open' | 'merged' | 'closed' | 'draft';
58
+
59
+ /**
60
+ * Common review decision values
61
+ */
62
+ export type ReviewDecision = 'approve' | 'request_changes' | 'comment';
63
+
64
+ /**
65
+ * Issue data structure
66
+ */
67
+ export interface Issue {
68
+ id: string;
69
+ key: string;
70
+ title: string;
71
+ description?: string;
72
+ status: IssueStatus;
73
+ assignee?: string;
74
+ reporter?: string;
75
+ labels?: string[];
76
+ priority?: string;
77
+ created_at?: string;
78
+ updated_at?: string;
79
+ url?: string;
80
+ }
81
+
82
+ /**
83
+ * Data for creating an issue
84
+ */
85
+ export interface CreateIssueData {
86
+ title: string;
87
+ description?: string;
88
+ assignee?: string;
89
+ labels?: string[];
90
+ priority?: string;
91
+ type?: string;
92
+ }
93
+
94
+ /**
95
+ * Data for updating an issue
96
+ */
97
+ export interface UpdateIssueData {
98
+ title?: string;
99
+ description?: string;
100
+ assignee?: string;
101
+ labels?: string[];
102
+ priority?: string;
103
+ status?: IssueStatus;
104
+ }
105
+
106
+ /**
107
+ * Query parameters for listing issues
108
+ */
109
+ export interface IssueQuery {
110
+ assignee?: string;
111
+ status?: IssueStatus | IssueStatus[];
112
+ labels?: string[];
113
+ limit?: number;
114
+ offset?: number;
115
+ }
116
+
117
+ /**
118
+ * Pull request data structure
119
+ */
120
+ export interface PullRequest {
121
+ id: string;
122
+ number: number;
123
+ title: string;
124
+ description?: string;
125
+ status: PullRequestStatus;
126
+ author?: string;
127
+ source_branch: string;
128
+ target_branch: string;
129
+ created_at?: string;
130
+ updated_at?: string;
131
+ merged_at?: string;
132
+ url?: string;
133
+ reviewers?: string[];
134
+ }
135
+
136
+ /**
137
+ * Data for creating a pull request
138
+ */
139
+ export interface CreatePullRequestData {
140
+ title: string;
141
+ description?: string;
142
+ source_branch: string;
143
+ target_branch: string;
144
+ draft?: boolean;
145
+ reviewers?: string[];
146
+ }
147
+
148
+ /**
149
+ * Query parameters for listing pull requests
150
+ */
151
+ export interface PullRequestQuery {
152
+ status?: PullRequestStatus | PullRequestStatus[];
153
+ author?: string;
154
+ limit?: number;
155
+ offset?: number;
156
+ }
157
+
158
+ /**
159
+ * Review data for a pull request
160
+ */
161
+ export interface Review {
162
+ id: string;
163
+ pull_request_id: string;
164
+ author: string;
165
+ decision: ReviewDecision;
166
+ body?: string;
167
+ created_at?: string;
168
+ }
169
+
170
+ /**
171
+ * Data for creating a review
172
+ */
173
+ export interface CreateReviewData {
174
+ decision: ReviewDecision;
175
+ body?: string;
176
+ comments?: ReviewComment[];
177
+ }
178
+
179
+ /**
180
+ * Comment on a specific line in a review
181
+ */
182
+ export interface ReviewComment {
183
+ path: string;
184
+ line: number;
185
+ body: string;
186
+ }
187
+
188
+ /**
189
+ * Documentation page data structure
190
+ */
191
+ export interface DocumentationPage {
192
+ id: string;
193
+ title: string;
194
+ content?: string;
195
+ path?: string;
196
+ url?: string;
197
+ parent_id?: string;
198
+ created_at?: string;
199
+ updated_at?: string;
200
+ }
201
+
202
+ /**
203
+ * Query parameters for searching documentation
204
+ */
205
+ export interface DocumentationQuery {
206
+ query: string;
207
+ space?: string;
208
+ limit?: number;
209
+ }
210
+
211
+ /**
212
+ * File/directory entry for state provider
213
+ */
214
+ export interface StateEntry {
215
+ path: string;
216
+ name: string;
217
+ type: 'file' | 'directory';
218
+ size?: number;
219
+ modified_at?: string;
220
+ }
221
+
222
+ /**
223
+ * Options for state operations
224
+ */
225
+ export interface StateOptions {
226
+ /**
227
+ * Create parent directories if they don't exist
228
+ */
229
+ recursive?: boolean;
230
+
231
+ /**
232
+ * Encoding for text content
233
+ */
234
+ encoding?: BufferEncoding;
235
+ }
236
+
237
+ /**
238
+ * Adapter error with context
239
+ */
240
+ export class AdapterError extends Error {
241
+ public readonly code: AdapterErrorCode;
242
+ public readonly adapter?: AdapterInfo;
243
+
244
+ constructor(message: string, code: AdapterErrorCode, adapter?: AdapterInfo, cause?: Error) {
245
+ super(message, { cause });
246
+ this.name = 'AdapterError';
247
+ this.code = code;
248
+ if (adapter) {
249
+ this.adapter = adapter;
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Error codes for adapter operations
256
+ */
257
+ export type AdapterErrorCode =
258
+ | 'not_found'
259
+ | 'unauthorized'
260
+ | 'forbidden'
261
+ | 'rate_limited'
262
+ | 'network_error'
263
+ | 'invalid_request'
264
+ | 'not_implemented'
265
+ | 'connection_failed'
266
+ | 'provider_error'
267
+ | 'operation_failed'
268
+ | 'invalid_operation'
269
+ | 'not_connected'
270
+ | 'invalid_config';