argustack 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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +433 -0
  3. package/dist/adapters/csv/index.d.ts +4 -0
  4. package/dist/adapters/csv/index.d.ts.map +1 -0
  5. package/dist/adapters/csv/index.js +4 -0
  6. package/dist/adapters/csv/index.js.map +1 -0
  7. package/dist/adapters/csv/mapper.d.ts +10 -0
  8. package/dist/adapters/csv/mapper.d.ts.map +1 -0
  9. package/dist/adapters/csv/mapper.js +179 -0
  10. package/dist/adapters/csv/mapper.js.map +1 -0
  11. package/dist/adapters/csv/parser.d.ts +22 -0
  12. package/dist/adapters/csv/parser.d.ts.map +1 -0
  13. package/dist/adapters/csv/parser.js +96 -0
  14. package/dist/adapters/csv/parser.js.map +1 -0
  15. package/dist/adapters/csv/provider.d.ts +11 -0
  16. package/dist/adapters/csv/provider.d.ts.map +1 -0
  17. package/dist/adapters/csv/provider.js +98 -0
  18. package/dist/adapters/csv/provider.js.map +1 -0
  19. package/dist/adapters/git/index.d.ts +3 -0
  20. package/dist/adapters/git/index.d.ts.map +1 -0
  21. package/dist/adapters/git/index.js +3 -0
  22. package/dist/adapters/git/index.js.map +1 -0
  23. package/dist/adapters/git/mapper.d.ts +11 -0
  24. package/dist/adapters/git/mapper.d.ts.map +1 -0
  25. package/dist/adapters/git/mapper.js +47 -0
  26. package/dist/adapters/git/mapper.js.map +1 -0
  27. package/dist/adapters/git/provider.d.ts +12 -0
  28. package/dist/adapters/git/provider.d.ts.map +1 -0
  29. package/dist/adapters/git/provider.js +115 -0
  30. package/dist/adapters/git/provider.js.map +1 -0
  31. package/dist/adapters/github/client.d.ts +8 -0
  32. package/dist/adapters/github/client.d.ts.map +1 -0
  33. package/dist/adapters/github/client.js +5 -0
  34. package/dist/adapters/github/client.js.map +1 -0
  35. package/dist/adapters/github/index.d.ts +4 -0
  36. package/dist/adapters/github/index.d.ts.map +1 -0
  37. package/dist/adapters/github/index.js +4 -0
  38. package/dist/adapters/github/index.js.map +1 -0
  39. package/dist/adapters/github/mapper.d.ts +12 -0
  40. package/dist/adapters/github/mapper.d.ts.map +1 -0
  41. package/dist/adapters/github/mapper.js +117 -0
  42. package/dist/adapters/github/mapper.js.map +1 -0
  43. package/dist/adapters/github/provider.d.ts +18 -0
  44. package/dist/adapters/github/provider.d.ts.map +1 -0
  45. package/dist/adapters/github/provider.js +95 -0
  46. package/dist/adapters/github/provider.js.map +1 -0
  47. package/dist/adapters/jira/client.d.ts +11 -0
  48. package/dist/adapters/jira/client.d.ts.map +1 -0
  49. package/dist/adapters/jira/client.js +16 -0
  50. package/dist/adapters/jira/client.js.map +1 -0
  51. package/dist/adapters/jira/index.d.ts +3 -0
  52. package/dist/adapters/jira/index.d.ts.map +1 -0
  53. package/dist/adapters/jira/index.js +3 -0
  54. package/dist/adapters/jira/index.js.map +1 -0
  55. package/dist/adapters/jira/mapper.d.ts +14 -0
  56. package/dist/adapters/jira/mapper.d.ts.map +1 -0
  57. package/dist/adapters/jira/mapper.js +169 -0
  58. package/dist/adapters/jira/mapper.js.map +1 -0
  59. package/dist/adapters/jira/provider.d.ts +21 -0
  60. package/dist/adapters/jira/provider.d.ts.map +1 -0
  61. package/dist/adapters/jira/provider.js +79 -0
  62. package/dist/adapters/jira/provider.js.map +1 -0
  63. package/dist/adapters/openai/embedding-provider.d.ts +16 -0
  64. package/dist/adapters/openai/embedding-provider.d.ts.map +1 -0
  65. package/dist/adapters/openai/embedding-provider.js +34 -0
  66. package/dist/adapters/openai/embedding-provider.js.map +1 -0
  67. package/dist/adapters/openai/index.d.ts +2 -0
  68. package/dist/adapters/openai/index.d.ts.map +1 -0
  69. package/dist/adapters/openai/index.js +2 -0
  70. package/dist/adapters/openai/index.js.map +1 -0
  71. package/dist/adapters/postgres/connection.d.ts +13 -0
  72. package/dist/adapters/postgres/connection.d.ts.map +1 -0
  73. package/dist/adapters/postgres/connection.js +16 -0
  74. package/dist/adapters/postgres/connection.js.map +1 -0
  75. package/dist/adapters/postgres/index.d.ts +3 -0
  76. package/dist/adapters/postgres/index.d.ts.map +1 -0
  77. package/dist/adapters/postgres/index.js +3 -0
  78. package/dist/adapters/postgres/index.js.map +1 -0
  79. package/dist/adapters/postgres/schema.d.ts +6 -0
  80. package/dist/adapters/postgres/schema.d.ts.map +1 -0
  81. package/dist/adapters/postgres/schema.js +246 -0
  82. package/dist/adapters/postgres/schema.js.map +1 -0
  83. package/dist/adapters/postgres/storage.d.ts +32 -0
  84. package/dist/adapters/postgres/storage.d.ts.map +1 -0
  85. package/dist/adapters/postgres/storage.js +322 -0
  86. package/dist/adapters/postgres/storage.js.map +1 -0
  87. package/dist/cli/embed.d.ts +3 -0
  88. package/dist/cli/embed.d.ts.map +1 -0
  89. package/dist/cli/embed.js +52 -0
  90. package/dist/cli/embed.js.map +1 -0
  91. package/dist/cli/index.d.ts +3 -0
  92. package/dist/cli/index.d.ts.map +1 -0
  93. package/dist/cli/index.js +64 -0
  94. package/dist/cli/index.js.map +1 -0
  95. package/dist/cli/init.d.ts +24 -0
  96. package/dist/cli/init.d.ts.map +1 -0
  97. package/dist/cli/init.js +966 -0
  98. package/dist/cli/init.js.map +1 -0
  99. package/dist/cli/jira.d.ts +3 -0
  100. package/dist/cli/jira.d.ts.map +1 -0
  101. package/dist/cli/jira.js +78 -0
  102. package/dist/cli/jira.js.map +1 -0
  103. package/dist/cli/mcp-install.d.ts +10 -0
  104. package/dist/cli/mcp-install.d.ts.map +1 -0
  105. package/dist/cli/mcp-install.js +207 -0
  106. package/dist/cli/mcp-install.js.map +1 -0
  107. package/dist/cli/sources.d.ts +10 -0
  108. package/dist/cli/sources.d.ts.map +1 -0
  109. package/dist/cli/sources.js +132 -0
  110. package/dist/cli/sources.js.map +1 -0
  111. package/dist/cli/status.d.ts +6 -0
  112. package/dist/cli/status.d.ts.map +1 -0
  113. package/dist/cli/status.js +93 -0
  114. package/dist/cli/status.js.map +1 -0
  115. package/dist/cli/sync.d.ts +21 -0
  116. package/dist/cli/sync.d.ts.map +1 -0
  117. package/dist/cli/sync.js +321 -0
  118. package/dist/cli/sync.js.map +1 -0
  119. package/dist/core/ports/embedding-provider.d.ts +15 -0
  120. package/dist/core/ports/embedding-provider.d.ts.map +1 -0
  121. package/dist/core/ports/embedding-provider.js +2 -0
  122. package/dist/core/ports/embedding-provider.js.map +1 -0
  123. package/dist/core/ports/git-provider.d.ts +30 -0
  124. package/dist/core/ports/git-provider.d.ts.map +1 -0
  125. package/dist/core/ports/git-provider.js +2 -0
  126. package/dist/core/ports/git-provider.js.map +1 -0
  127. package/dist/core/ports/github-provider.d.ts +30 -0
  128. package/dist/core/ports/github-provider.d.ts.map +1 -0
  129. package/dist/core/ports/github-provider.js +2 -0
  130. package/dist/core/ports/github-provider.js.map +1 -0
  131. package/dist/core/ports/index.d.ts +6 -0
  132. package/dist/core/ports/index.d.ts.map +1 -0
  133. package/dist/core/ports/index.js +2 -0
  134. package/dist/core/ports/index.js.map +1 -0
  135. package/dist/core/ports/source-provider.d.ts +27 -0
  136. package/dist/core/ports/source-provider.d.ts.map +1 -0
  137. package/dist/core/ports/source-provider.js +2 -0
  138. package/dist/core/ports/source-provider.js.map +1 -0
  139. package/dist/core/ports/storage.d.ts +47 -0
  140. package/dist/core/ports/storage.d.ts.map +1 -0
  141. package/dist/core/ports/storage.js +2 -0
  142. package/dist/core/ports/storage.js.map +1 -0
  143. package/dist/core/types/config.d.ts +26 -0
  144. package/dist/core/types/config.d.ts.map +1 -0
  145. package/dist/core/types/config.js +41 -0
  146. package/dist/core/types/config.js.map +1 -0
  147. package/dist/core/types/git.d.ts +35 -0
  148. package/dist/core/types/git.d.ts.map +1 -0
  149. package/dist/core/types/git.js +6 -0
  150. package/dist/core/types/git.js.map +1 -0
  151. package/dist/core/types/github.d.ts +75 -0
  152. package/dist/core/types/github.d.ts.map +1 -0
  153. package/dist/core/types/github.js +2 -0
  154. package/dist/core/types/github.js.map +1 -0
  155. package/dist/core/types/index.d.ts +7 -0
  156. package/dist/core/types/index.d.ts.map +1 -0
  157. package/dist/core/types/index.js +2 -0
  158. package/dist/core/types/index.js.map +1 -0
  159. package/dist/core/types/issue.d.ts +74 -0
  160. package/dist/core/types/issue.d.ts.map +1 -0
  161. package/dist/core/types/issue.js +7 -0
  162. package/dist/core/types/issue.js.map +1 -0
  163. package/dist/core/types/project.d.ts +9 -0
  164. package/dist/core/types/project.d.ts.map +1 -0
  165. package/dist/core/types/project.js +5 -0
  166. package/dist/core/types/project.js.map +1 -0
  167. package/dist/db/connection.d.ts +2 -0
  168. package/dist/db/connection.d.ts.map +1 -0
  169. package/dist/db/connection.js +4 -0
  170. package/dist/db/connection.js.map +1 -0
  171. package/dist/db/import.d.ts +2 -0
  172. package/dist/db/import.d.ts.map +1 -0
  173. package/dist/db/import.js +4 -0
  174. package/dist/db/import.js.map +1 -0
  175. package/dist/db/schema.d.ts +2 -0
  176. package/dist/db/schema.d.ts.map +1 -0
  177. package/dist/db/schema.js +4 -0
  178. package/dist/db/schema.js.map +1 -0
  179. package/dist/jira/client.d.ts +2 -0
  180. package/dist/jira/client.d.ts.map +1 -0
  181. package/dist/jira/client.js +4 -0
  182. package/dist/jira/client.js.map +1 -0
  183. package/dist/jira/pull.d.ts +2 -0
  184. package/dist/jira/pull.d.ts.map +1 -0
  185. package/dist/jira/pull.js +5 -0
  186. package/dist/jira/pull.js.map +1 -0
  187. package/dist/mcp/server.d.ts +16 -0
  188. package/dist/mcp/server.d.ts.map +1 -0
  189. package/dist/mcp/server.js +1463 -0
  190. package/dist/mcp/server.js.map +1 -0
  191. package/dist/use-cases/embed.d.ts +23 -0
  192. package/dist/use-cases/embed.d.ts.map +1 -0
  193. package/dist/use-cases/embed.js +63 -0
  194. package/dist/use-cases/embed.js.map +1 -0
  195. package/dist/use-cases/pull-git.d.ts +25 -0
  196. package/dist/use-cases/pull-git.d.ts.map +1 -0
  197. package/dist/use-cases/pull-git.js +59 -0
  198. package/dist/use-cases/pull-git.js.map +1 -0
  199. package/dist/use-cases/pull-github.d.ts +28 -0
  200. package/dist/use-cases/pull-github.d.ts.map +1 -0
  201. package/dist/use-cases/pull-github.js +67 -0
  202. package/dist/use-cases/pull-github.js.map +1 -0
  203. package/dist/use-cases/pull.d.ts +32 -0
  204. package/dist/use-cases/pull.d.ts.map +1 -0
  205. package/dist/use-cases/pull.js +82 -0
  206. package/dist/use-cases/pull.js.map +1 -0
  207. package/dist/workspace/config.d.ts +36 -0
  208. package/dist/workspace/config.d.ts.map +1 -0
  209. package/dist/workspace/config.js +91 -0
  210. package/dist/workspace/config.js.map +1 -0
  211. package/dist/workspace/resolver.d.ts +19 -0
  212. package/dist/workspace/resolver.d.ts.map +1 -0
  213. package/dist/workspace/resolver.js +47 -0
  214. package/dist/workspace/resolver.js.map +1 -0
  215. package/package.json +71 -0
  216. package/templates/docker-compose.yml +26 -0
  217. package/templates/env.example +14 -0
  218. package/templates/gitignore +6 -0
  219. package/templates/init.sql +236 -0
@@ -0,0 +1,34 @@
1
+ export class OpenAIEmbeddingProvider {
2
+ name = 'OpenAI';
3
+ dimensions;
4
+ apiKey;
5
+ model;
6
+ constructor(config) {
7
+ this.apiKey = config.apiKey;
8
+ this.model = config.model ?? 'text-embedding-3-small';
9
+ this.dimensions = config.dimensions ?? 1536;
10
+ }
11
+ async embed(texts) {
12
+ const response = await fetch('https://api.openai.com/v1/embeddings', {
13
+ method: 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ 'Authorization': `Bearer ${this.apiKey}`,
17
+ },
18
+ body: JSON.stringify({
19
+ model: this.model,
20
+ input: texts,
21
+ dimensions: this.dimensions,
22
+ }),
23
+ });
24
+ if (!response.ok) {
25
+ const body = await response.text();
26
+ throw new Error(`OpenAI API error ${String(response.status)}: ${body}`);
27
+ }
28
+ const json = await response.json();
29
+ return json.data
30
+ .sort((a, b) => a.index - b.index)
31
+ .map((d) => d.embedding);
32
+ }
33
+ }
34
+ //# sourceMappingURL=embedding-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-provider.js","sourceRoot":"","sources":["../../../src/adapters/openai/embedding-provider.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,uBAAuB;IACzB,IAAI,GAAG,QAAQ,CAAC;IAChB,UAAU,CAAS;IACX,MAAM,CAAS;IACf,KAAK,CAAS;IAE/B,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,wBAAwB,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAe;QACzB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,sCAAsC,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;QAE9D,OAAO,IAAI,CAAC,IAAI;aACb,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export { OpenAIEmbeddingProvider } from './embedding-provider.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { OpenAIEmbeddingProvider } from './embedding-provider.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/openai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import pg from 'pg';
2
+ export interface DbConfig {
3
+ host: string;
4
+ port: number;
5
+ user: string;
6
+ password: string;
7
+ database: string;
8
+ }
9
+ /**
10
+ * Create a PostgreSQL connection pool.
11
+ */
12
+ export declare function createPool(config: DbConfig): pg.Pool;
13
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/adapters/postgres/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,EAAE,CAAC,IAAI,CASpD"}
@@ -0,0 +1,16 @@
1
+ import pg from 'pg';
2
+ const { Pool } = pg;
3
+ /**
4
+ * Create a PostgreSQL connection pool.
5
+ */
6
+ export function createPool(config) {
7
+ return new Pool({
8
+ host: config.host,
9
+ port: config.port,
10
+ user: config.user,
11
+ password: config.password,
12
+ database: config.database,
13
+ max: 5,
14
+ });
15
+ }
16
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/adapters/postgres/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAUpB;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAgB;IACzC,OAAO,IAAI,IAAI,CAAC;QACd,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,CAAC;KACP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { PostgresStorage } from './storage.js';
2
+ export { createPool, type DbConfig } from './connection.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { PostgresStorage } from './storage.js';
2
+ export { createPool } from './connection.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAiB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type pg from 'pg';
2
+ /**
3
+ * Ensure all tables exist. Idempotent — safe to call every time.
4
+ */
5
+ export declare function ensureSchema(pool: pg.Pool): Promise<void>;
6
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/adapters/postgres/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAoQ/D"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Ensure all tables exist. Idempotent — safe to call every time.
3
+ */
4
+ export async function ensureSchema(pool) {
5
+ await pool.query(`CREATE EXTENSION IF NOT EXISTS vector`);
6
+ await pool.query(`
7
+ CREATE TABLE IF NOT EXISTS issues (
8
+ id SERIAL PRIMARY KEY,
9
+ issue_key TEXT UNIQUE NOT NULL,
10
+ issue_id TEXT,
11
+ project_key TEXT,
12
+ summary TEXT NOT NULL,
13
+ description TEXT,
14
+ issue_type VARCHAR(50),
15
+ status VARCHAR(50),
16
+ status_category VARCHAR(50),
17
+ priority TEXT,
18
+ resolution VARCHAR(50),
19
+ assignee VARCHAR(100),
20
+ reporter VARCHAR(100),
21
+ created TIMESTAMP,
22
+ updated TIMESTAMP,
23
+ resolved TIMESTAMP,
24
+ due_date DATE,
25
+ labels TEXT[],
26
+ components TEXT[],
27
+ fix_versions TEXT[],
28
+ parent_key TEXT,
29
+ sprint VARCHAR(200),
30
+ story_points NUMERIC,
31
+ custom_fields JSONB,
32
+ raw_json JSONB,
33
+ embedding vector(1536),
34
+ search_vector tsvector,
35
+ pulled_at TIMESTAMP DEFAULT NOW()
36
+ )
37
+ `);
38
+ await pool.query(`
39
+ CREATE TABLE IF NOT EXISTS issue_comments (
40
+ id SERIAL PRIMARY KEY,
41
+ issue_key TEXT NOT NULL,
42
+ comment_id TEXT,
43
+ author VARCHAR(100),
44
+ body TEXT,
45
+ created TIMESTAMP,
46
+ updated TIMESTAMP
47
+ )
48
+ `);
49
+ await pool.query(`
50
+ CREATE TABLE IF NOT EXISTS issue_changelogs (
51
+ id SERIAL PRIMARY KEY,
52
+ issue_key TEXT NOT NULL,
53
+ author VARCHAR(100),
54
+ field VARCHAR(100),
55
+ from_value TEXT,
56
+ to_value TEXT,
57
+ changed_at TIMESTAMP
58
+ )
59
+ `);
60
+ await pool.query(`
61
+ CREATE TABLE IF NOT EXISTS issue_worklogs (
62
+ id SERIAL PRIMARY KEY,
63
+ issue_key TEXT NOT NULL,
64
+ author VARCHAR(100),
65
+ time_spent TEXT,
66
+ time_spent_seconds INTEGER,
67
+ comment TEXT,
68
+ started TIMESTAMP
69
+ )
70
+ `);
71
+ await pool.query(`
72
+ CREATE TABLE IF NOT EXISTS issue_links (
73
+ id SERIAL PRIMARY KEY,
74
+ source_key TEXT NOT NULL,
75
+ target_key TEXT NOT NULL,
76
+ link_type VARCHAR(50),
77
+ direction VARCHAR(10)
78
+ )
79
+ `);
80
+ // ─── Git tables ───────────────────────────────────────────────────────
81
+ await pool.query(`
82
+ CREATE TABLE IF NOT EXISTS commits (
83
+ hash VARCHAR(40) PRIMARY KEY,
84
+ message TEXT,
85
+ author VARCHAR(200),
86
+ email VARCHAR(200),
87
+ committed_at TIMESTAMPTZ,
88
+ parents TEXT[],
89
+ repo_path TEXT,
90
+ search_vector tsvector,
91
+ pulled_at TIMESTAMP DEFAULT NOW()
92
+ )
93
+ `);
94
+ await pool.query(`
95
+ CREATE TABLE IF NOT EXISTS commit_files (
96
+ id SERIAL PRIMARY KEY,
97
+ commit_hash VARCHAR(40) NOT NULL REFERENCES commits(hash),
98
+ file_path TEXT NOT NULL,
99
+ status TEXT,
100
+ additions INTEGER DEFAULT 0,
101
+ deletions INTEGER DEFAULT 0
102
+ )
103
+ `);
104
+ await pool.query(`
105
+ CREATE TABLE IF NOT EXISTS commit_issue_refs (
106
+ commit_hash VARCHAR(40) NOT NULL REFERENCES commits(hash),
107
+ issue_key TEXT NOT NULL,
108
+ PRIMARY KEY (commit_hash, issue_key)
109
+ )
110
+ `);
111
+ // ─── GitHub tables ──────────────────────────────────────────────────────
112
+ await pool.query(`
113
+ CREATE TABLE IF NOT EXISTS pull_requests (
114
+ number INTEGER NOT NULL,
115
+ repo_full_name VARCHAR(200) NOT NULL,
116
+ title TEXT,
117
+ body TEXT,
118
+ state VARCHAR(10),
119
+ author VARCHAR(200),
120
+ created_at TIMESTAMPTZ,
121
+ updated_at TIMESTAMPTZ,
122
+ merged_at TIMESTAMPTZ,
123
+ closed_at TIMESTAMPTZ,
124
+ merge_commit_sha VARCHAR(40),
125
+ head_ref VARCHAR(200),
126
+ base_ref VARCHAR(200),
127
+ labels TEXT[],
128
+ reviewers TEXT[],
129
+ additions INTEGER DEFAULT 0,
130
+ deletions INTEGER DEFAULT 0,
131
+ changed_files INTEGER DEFAULT 0,
132
+ raw_json JSONB,
133
+ search_vector tsvector,
134
+ pulled_at TIMESTAMP DEFAULT NOW(),
135
+ PRIMARY KEY (repo_full_name, number)
136
+ )
137
+ `);
138
+ await pool.query(`
139
+ CREATE TABLE IF NOT EXISTS pr_reviews (
140
+ id SERIAL PRIMARY KEY,
141
+ pr_number INTEGER NOT NULL,
142
+ repo_full_name VARCHAR(200) NOT NULL,
143
+ review_id INTEGER NOT NULL,
144
+ reviewer VARCHAR(200),
145
+ state VARCHAR(30),
146
+ body TEXT,
147
+ submitted_at TIMESTAMPTZ
148
+ )
149
+ `);
150
+ await pool.query(`
151
+ CREATE TABLE IF NOT EXISTS pr_comments (
152
+ id SERIAL PRIMARY KEY,
153
+ pr_number INTEGER NOT NULL,
154
+ repo_full_name VARCHAR(200) NOT NULL,
155
+ comment_id BIGINT NOT NULL,
156
+ author VARCHAR(200),
157
+ body TEXT,
158
+ path TEXT,
159
+ line INTEGER,
160
+ created_at TIMESTAMPTZ,
161
+ updated_at TIMESTAMPTZ
162
+ )
163
+ `);
164
+ await pool.query(`
165
+ CREATE TABLE IF NOT EXISTS pr_files (
166
+ id SERIAL PRIMARY KEY,
167
+ pr_number INTEGER NOT NULL,
168
+ repo_full_name VARCHAR(200) NOT NULL,
169
+ file_path TEXT NOT NULL,
170
+ status TEXT,
171
+ additions INTEGER DEFAULT 0,
172
+ deletions INTEGER DEFAULT 0
173
+ )
174
+ `);
175
+ await pool.query(`
176
+ CREATE TABLE IF NOT EXISTS pr_issue_refs (
177
+ pr_number INTEGER NOT NULL,
178
+ repo_full_name VARCHAR(200) NOT NULL,
179
+ issue_key TEXT NOT NULL,
180
+ PRIMARY KEY (repo_full_name, pr_number, issue_key)
181
+ )
182
+ `);
183
+ await pool.query(`
184
+ CREATE TABLE IF NOT EXISTS releases (
185
+ id INTEGER NOT NULL,
186
+ repo_full_name VARCHAR(200) NOT NULL,
187
+ tag_name VARCHAR(200),
188
+ name TEXT,
189
+ body TEXT,
190
+ author VARCHAR(200),
191
+ draft BOOLEAN DEFAULT FALSE,
192
+ prerelease BOOLEAN DEFAULT FALSE,
193
+ created_at TIMESTAMPTZ,
194
+ published_at TIMESTAMPTZ,
195
+ raw_json JSONB,
196
+ search_vector tsvector,
197
+ pulled_at TIMESTAMP DEFAULT NOW(),
198
+ PRIMARY KEY (repo_full_name, id)
199
+ )
200
+ `);
201
+ // ─── Indexes ──────────────────────────────────────────────────────────
202
+ const indexes = [
203
+ 'CREATE INDEX IF NOT EXISTS idx_issues_project ON issues(project_key)',
204
+ 'CREATE INDEX IF NOT EXISTS idx_issues_status ON issues(status)',
205
+ 'CREATE INDEX IF NOT EXISTS idx_issues_type ON issues(issue_type)',
206
+ 'CREATE INDEX IF NOT EXISTS idx_issues_assignee ON issues(assignee)',
207
+ 'CREATE INDEX IF NOT EXISTS idx_issues_created ON issues(created)',
208
+ 'CREATE INDEX IF NOT EXISTS idx_issues_updated ON issues(updated)',
209
+ 'CREATE INDEX IF NOT EXISTS idx_issues_search ON issues USING GIN(search_vector)',
210
+ 'CREATE INDEX IF NOT EXISTS idx_issues_custom ON issues USING GIN(custom_fields)',
211
+ 'CREATE INDEX IF NOT EXISTS idx_issues_raw ON issues USING GIN(raw_json)',
212
+ 'CREATE INDEX IF NOT EXISTS idx_comments_key ON issue_comments(issue_key)',
213
+ 'CREATE INDEX IF NOT EXISTS idx_changelogs_key ON issue_changelogs(issue_key)',
214
+ 'CREATE INDEX IF NOT EXISTS idx_worklogs_key ON issue_worklogs(issue_key)',
215
+ 'CREATE INDEX IF NOT EXISTS idx_links_source ON issue_links(source_key)',
216
+ 'CREATE INDEX IF NOT EXISTS idx_links_target ON issue_links(target_key)',
217
+ // Git indexes
218
+ 'CREATE INDEX IF NOT EXISTS idx_commits_author ON commits(author)',
219
+ 'CREATE INDEX IF NOT EXISTS idx_commits_date ON commits(committed_at)',
220
+ 'CREATE INDEX IF NOT EXISTS idx_commits_repo ON commits(repo_path)',
221
+ 'CREATE INDEX IF NOT EXISTS idx_commits_search ON commits USING GIN(search_vector)',
222
+ 'CREATE INDEX IF NOT EXISTS idx_commit_files_hash ON commit_files(commit_hash)',
223
+ 'CREATE INDEX IF NOT EXISTS idx_commit_files_path ON commit_files(file_path)',
224
+ 'CREATE INDEX IF NOT EXISTS idx_commit_refs_issue ON commit_issue_refs(issue_key)',
225
+ // GitHub indexes
226
+ 'CREATE INDEX IF NOT EXISTS idx_prs_repo ON pull_requests(repo_full_name)',
227
+ 'CREATE INDEX IF NOT EXISTS idx_prs_state ON pull_requests(state)',
228
+ 'CREATE INDEX IF NOT EXISTS idx_prs_author ON pull_requests(author)',
229
+ 'CREATE INDEX IF NOT EXISTS idx_prs_merged ON pull_requests(merged_at)',
230
+ 'CREATE INDEX IF NOT EXISTS idx_prs_updated ON pull_requests(updated_at)',
231
+ 'CREATE INDEX IF NOT EXISTS idx_prs_merge_sha ON pull_requests(merge_commit_sha)',
232
+ 'CREATE INDEX IF NOT EXISTS idx_prs_search ON pull_requests USING GIN(search_vector)',
233
+ 'CREATE INDEX IF NOT EXISTS idx_pr_reviews_pr ON pr_reviews(repo_full_name, pr_number)',
234
+ 'CREATE INDEX IF NOT EXISTS idx_pr_comments_pr ON pr_comments(repo_full_name, pr_number)',
235
+ 'CREATE INDEX IF NOT EXISTS idx_pr_files_pr ON pr_files(repo_full_name, pr_number)',
236
+ 'CREATE INDEX IF NOT EXISTS idx_pr_files_path ON pr_files(file_path)',
237
+ 'CREATE INDEX IF NOT EXISTS idx_pr_refs_issue ON pr_issue_refs(issue_key)',
238
+ 'CREATE INDEX IF NOT EXISTS idx_releases_repo ON releases(repo_full_name)',
239
+ 'CREATE INDEX IF NOT EXISTS idx_releases_tag ON releases(tag_name)',
240
+ 'CREATE INDEX IF NOT EXISTS idx_releases_search ON releases USING GIN(search_vector)',
241
+ ];
242
+ for (const idx of indexes) {
243
+ await pool.query(idx);
244
+ }
245
+ }
246
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/adapters/postgres/schema.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAa;IAC9C,MAAM,IAAI,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAE1D,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;GAUhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;GAUhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;GAUhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;GAQhB,CAAC,CAAC;IAEH,yEAAyE;IAEzE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;GAYhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;GAShB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;GAMhB,CAAC,CAAC;IAEH,2EAA2E;IAE3E,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;GAWhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;GAahB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;GAUhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;GAOhB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;GAiBhB,CAAC,CAAC;IAEH,yEAAyE;IAEzE,MAAM,OAAO,GAAG;QACd,sEAAsE;QACtE,gEAAgE;QAChE,kEAAkE;QAClE,oEAAoE;QACpE,kEAAkE;QAClE,kEAAkE;QAClE,iFAAiF;QACjF,iFAAiF;QACjF,yEAAyE;QACzE,0EAA0E;QAC1E,8EAA8E;QAC9E,0EAA0E;QAC1E,wEAAwE;QACxE,wEAAwE;QACxE,cAAc;QACd,kEAAkE;QAClE,sEAAsE;QACtE,mEAAmE;QACnE,mFAAmF;QACnF,+EAA+E;QAC/E,6EAA6E;QAC7E,kFAAkF;QAClF,iBAAiB;QACjB,0EAA0E;QAC1E,kEAAkE;QAClE,oEAAoE;QACpE,uEAAuE;QACvE,yEAAyE;QACzE,iFAAiF;QACjF,qFAAqF;QACrF,uFAAuF;QACvF,yFAAyF;QACzF,mFAAmF;QACnF,qEAAqE;QACrE,0EAA0E;QAC1E,0EAA0E;QAC1E,mEAAmE;QACnE,qFAAqF;KACtF,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { IStorage, QueryResult } from '../../core/ports/storage.js';
2
+ import type { IssueBatch } from '../../core/types/index.js';
3
+ import type { CommitBatch } from '../../core/types/git.js';
4
+ import type { GitHubBatch, Release } from '../../core/types/github.js';
5
+ import { type DbConfig } from './connection.js';
6
+ /**
7
+ * PostgreSQL adapter — implements IStorage.
8
+ *
9
+ * Uses UPSERT (ON CONFLICT) so re-pulling is safe and idempotent.
10
+ */
11
+ export declare class PostgresStorage implements IStorage {
12
+ readonly name = "PostgreSQL";
13
+ private readonly pool;
14
+ constructor(config: DbConfig);
15
+ initialize(): Promise<void>;
16
+ saveBatch(batch: IssueBatch): Promise<void>;
17
+ saveCommitBatch(batch: CommitBatch): Promise<void>;
18
+ getLastCommitDate(repoPath: string): Promise<Date | null>;
19
+ getLastUpdated(projectKey: string): Promise<string | null>;
20
+ saveGitHubBatch(batch: GitHubBatch): Promise<void>;
21
+ saveReleases(releases: Release[]): Promise<void>;
22
+ getLastPrUpdated(repoFullName: string): Promise<Date | null>;
23
+ getUnembeddedIssueKeys(limit: number): Promise<string[]>;
24
+ saveEmbedding(issueKey: string, vector: number[]): Promise<void>;
25
+ semanticSearch(vector: number[], limit: number, threshold?: number): Promise<{
26
+ issueKey: string;
27
+ similarity: number;
28
+ }[]>;
29
+ query(sql: string, params: unknown[]): Promise<QueryResult>;
30
+ close(): Promise<void>;
31
+ }
32
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/adapters/postgres/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG5D;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;gBAEnB,MAAM,EAAE,QAAQ;IAItB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAoH3C,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDlD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAWzD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAW1D,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAmHlD,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8ChD,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAa5D,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWxD,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE,cAAc,CAClB,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAyBhD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAK3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}