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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ievgen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,433 @@
1
+ # Argustack
2
+
3
+ **RAG engine for project intelligence — ask AI about your Jira, Git, and databases**
4
+
5
+ [RAG](https://en.wikipedia.org/wiki/Retrieval-augmented_generation) (Retrieval-Augmented Generation) — an architecture where AI answers questions based on **your** data, not its training set:
6
+
7
+ 1. **Retrieval** — pull and index your project data locally (PostgreSQL + pgvector)
8
+ 2. **Augmentation** — inject relevant context into the AI prompt
9
+ 3. **Generation** — LLM generates answers grounded in your actual Jira tickets, code, and databases
10
+
11
+ Argustack builds this knowledge base from your project's sources of truth:
12
+
13
+ ```
14
+ YOUR SOURCES YOUR MACHINE
15
+ ┌──────────────────────┐ ┌─────────────────────────────────────┐
16
+ │ Jira Cloud / Server │ │ │
17
+ │ (issues, comments, │ pull │ PostgreSQL (Docker, localhost) │
18
+ │ changelogs, etc.) │ ──────►│ ├── issues (all fields) │
19
+ └──────────────────────┘ │ ├── issue_comments (discussions) │
20
+ │ ├── issue_changelogs (history) │
21
+ ┌──────────────────────┐ │ ├── issue_worklogs (time logs) │
22
+ │ Git repository │ pull │ ├── issue_links (relations) │
23
+ │ (commits, files, │ ──────►│ ├── commits (history) │
24
+ │ diffs, authors) │ │ ├── commit_files (per-file Δ) │
25
+ └──────────────────────┘ │ ├── commit_issue_refs (cross-ref)│
26
+ │ │ │
27
+ ┌──────────────────────┐ │ │ GitHub (optional, via token) │
28
+ │ GitHub API │ pull │ ├── pull_requests (PRs + meta) │
29
+ │ (PRs, reviews, │ ──────►│ ├── pr_reviews (approvals) │
30
+ │ releases) │ │ ├── pr_comments (discussions) │
31
+ └──────────────────────┘ │ ├── pr_issue_refs (PR↔Jira) │
32
+ │ └── releases (tags) │
33
+ ┌──────────────────────┐ │ │
34
+ │ Database (planned) │ │ MCP Server (localhost, stdio) │
35
+ └──────────────────────┘ │ └── queries DB ──► Claude / LLM │
36
+ │ │
37
+ │ .env (credentials — never leaves) │
38
+ └─────────────────────────────────────┘
39
+ ```
40
+
41
+ > *Is this bug still relevant or already fixed in code?*
42
+ > *Was the feature implemented as described in the ticket?*
43
+ > *Who worked on this module and what changed last month?*
44
+ > *Which commits and PRs reference ticket PAP-123?*
45
+ > *Who approved the PR and what was the review feedback?*
46
+
47
+ ## How it works
48
+
49
+ **Retrieval** — pulls all data from Jira, Git, and GitHub into local PostgreSQL with pgvector. Every field, every comment, every changelog entry, every commit with per-file diffs, every PR with reviews and approvals. Raw JSON preserved as-is. Nothing is filtered or lost.
50
+
51
+ **Augmentation** — MCP server gives Claude Desktop / Claude Code direct access to your local database. Full-text search, semantic search (pgvector embeddings), filters, raw SQL, aggregate statistics, cross-source timeline, cross-reference between Jira issues, Git commits, and GitHub PRs — all without leaving your machine.
52
+
53
+ **Generation** — ask questions in natural language. Claude queries your local data and answers with full project context.
54
+
55
+ ## Quick Start
56
+
57
+ ### Prerequisites
58
+
59
+ - [Node.js](https://nodejs.org/) >= 20
60
+ - [Docker](https://www.docker.com/) (or [OrbStack](https://orbstack.dev/) / Podman)
61
+
62
+ ### Install & setup
63
+
64
+ ```bash
65
+ npm i -g argustack
66
+ argustack init
67
+ ```
68
+
69
+ Argustack supports **two modes** of initialization:
70
+
71
+ #### Interactive mode (default)
72
+
73
+ Run `argustack init` and follow the prompts:
74
+
75
+ ```
76
+ ? Workspace directory: ~/projects/my-team
77
+ ? Sources: ✔ Jira — issues, comments, changelogs
78
+ ✔ Git — commits, diffs, authors
79
+ ✔ GitHub — PRs, reviews, releases
80
+ ? Jira URL: https://your-team.atlassian.net
81
+ ? Email: you@company.com
82
+ ? API Token: ****
83
+
84
+ Testing connection... Connected! Found 3 projects: MKT, BRAND, WEB
85
+
86
+ ? Projects to pull: ✔ MKT ✔ BRAND
87
+ ? Where is your Git repository?
88
+ ● Clone from GitHub — select repos using your token
89
+ ? GitHub token (PAT): ****
90
+
91
+ Fetching repositories... Found 12 repos.
92
+
93
+ ? Repositories to clone: ✔ your-org/frontend ✔ your-org/backend
94
+ ? GitHub source: Auto-configured from clone step
95
+
96
+ ? Start database and sync now? Yes
97
+
98
+ ✔ Database running!
99
+ ✔ Jira sync complete!
100
+ MKT: 506 issues (150/506 ████░░░░ 30% → 506/506 done)
101
+ ✔ Git sync complete!
102
+ your-org/frontend: 735 commits (400/735 ██████░░ 54% → 735/735 done)
103
+ ✔ GitHub sync complete!
104
+ 66 PRs (30/66 ██████░░ 45% → 66/66 done), 124 reviews, 3 releases
105
+ ```
106
+
107
+ The interactive setup will:
108
+
109
+ 1. Ask which sources you have (Jira, Git, GitHub, Database)
110
+ 2. Collect credentials and test connections
111
+ 3. For Git — choose local path, clone from GitHub (multi-select repos), or clone from URL
112
+ 4. For GitHub — auto-configured if you cloned from GitHub in the previous step, or enter a Personal Access Token (see [GitHub token setup](#github-token-setup))
113
+ 5. Create a workspace with Docker config
114
+ 6. Start PostgreSQL + pgweb automatically
115
+ 7. Pull all your data
116
+
117
+ #### Non-interactive mode (for AI agents and CI/CD)
118
+
119
+ Pass `--no-interactive` with all values as CLI flags — no prompts, no terminal needed:
120
+
121
+ ```bash
122
+ argustack init \
123
+ --no-interactive \
124
+ --dir ~/projects/my-team \
125
+ --source jira,git,github \
126
+ --jira-url "https://your-team.atlassian.net" \
127
+ --jira-email "you@company.com" \
128
+ --jira-token "ATATT3x..." \
129
+ --jira-projects PAP,MKT \
130
+ --git-repo /path/to/repo1,/path/to/repo2 \
131
+ --github-token "github_pat_..." \
132
+ --github-owner your-org \
133
+ --github-repo your-repo
134
+ ```
135
+
136
+ Then start the database and sync:
137
+
138
+ ```bash
139
+ cd ~/projects/my-team
140
+ docker compose up -d
141
+ argustack sync
142
+ ```
143
+
144
+ All available flags:
145
+
146
+ | Flag | Description |
147
+ |------|-------------|
148
+ | `--no-interactive` | Run without prompts — all values from flags |
149
+ | `-d, --dir <path>` | Workspace directory (default: current) |
150
+ | `-s, --source <list>` | Comma-separated: `jira,git,github,csv,db` |
151
+ | `--jira-url <url>` | Jira instance URL |
152
+ | `--jira-email <email>` | Jira user email |
153
+ | `--jira-token <token>` | Jira API token |
154
+ | `--jira-projects <keys>` | Comma-separated project keys, or `all` |
155
+ | `--git-repo <paths>` | Git repo paths, comma-separated |
156
+ | `--github-token <token>` | GitHub Personal Access Token |
157
+ | `--github-owner <owner>` | GitHub repo owner |
158
+ | `--github-repo <repo>` | GitHub repo name |
159
+ | `--csv-file <path>` | Path to Jira CSV export file |
160
+ | `--db-port <port>` | Argustack PostgreSQL port (default: `5434`) |
161
+ | `--pgweb-port <port>` | pgweb UI port (default: `8086`) |
162
+
163
+ This mode is ideal for:
164
+ - **AI agents** — a project manager tells their AI agent "set up argustack" and it runs everything autonomously
165
+ - **CI/CD pipelines** — automated workspace provisioning
166
+ - **Scripted setups** — reproducible environment creation
167
+
168
+ Browse your data at [localhost:8086](http://localhost:8086) — pgweb UI for running SQL queries and exploring tables in your browser.
169
+
170
+ ### Connect to Claude
171
+
172
+ ```bash
173
+ argustack mcp install
174
+ ```
175
+
176
+ Adds Argustack as an MCP server to Claude Desktop. Now you can ask Claude questions about your project data directly.
177
+
178
+ ## Commands
179
+
180
+ ```bash
181
+ argustack init # create workspace (interactive prompts)
182
+ argustack init --no-interactive ... # create workspace from CLI flags (no prompts)
183
+ argustack sync # pull data from all configured sources
184
+ argustack sync jira # pull Jira only
185
+ argustack sync git # pull Git commits only
186
+ argustack sync github # pull GitHub PRs, reviews, releases
187
+ argustack sync csv # import from Jira CSV export
188
+ argustack sync csv -f /path/to.csv # import specific CSV file
189
+ argustack sync -p PROJ # pull specific Jira project
190
+ argustack sync --since 2025-01-01 # incremental pull (only new/updated)
191
+ argustack sources # list configured sources
192
+ argustack status # workspace info
193
+ argustack embed # generate embeddings for semantic search
194
+ argustack mcp install # connect to Claude Desktop
195
+ ```
196
+
197
+ ## What gets stored
198
+
199
+ All data goes into local PostgreSQL in Docker on your machine (nothing leaves `localhost`):
200
+
201
+ ### Jira tables
202
+
203
+ | Table | Content |
204
+ |-------|---------|
205
+ | `issues` | All issues — typed columns + `custom_fields` JSONB + full `raw_json` |
206
+ | `issue_comments` | Comments with authors and timestamps |
207
+ | `issue_changelogs` | Every field change in history |
208
+ | `issue_worklogs` | Time tracking entries |
209
+ | `issue_links` | Issue-to-issue relationships |
210
+
211
+ Every custom field is preserved exactly as Jira returns it. 500 custom fields? All stored. Zero filtering, zero data loss.
212
+
213
+ ### Git tables
214
+
215
+ | Table | Content |
216
+ |-------|---------|
217
+ | `commits` | Commit hash, message, author, email, date, full-text search |
218
+ | `commit_files` | Per-file changes — path, status, additions, deletions |
219
+ | `commit_issue_refs` | Cross-reference: commit ↔ Jira issue (extracted from commit messages) |
220
+
221
+ Commit messages mentioning issue keys like `PAP-123` or `PROJ-45` are automatically linked to Jira issues.
222
+
223
+ ### GitHub tables
224
+
225
+ Select "GitHub" during `argustack init` or add later with `argustack source add github`:
226
+
227
+ | Table | Content |
228
+ |-------|---------|
229
+ | `pull_requests` | PRs — state, author, reviewers, additions/deletions, merge info, full-text search |
230
+ | `pr_reviews` | Review approvals and change requests |
231
+ | `pr_comments` | Inline review comments with file paths and line numbers |
232
+ | `pr_files` | Per-file changes in each PR |
233
+ | `pr_issue_refs` | Cross-reference: PR ↔ Jira issue (extracted from PR title and body) |
234
+ | `releases` | GitHub releases with tags, notes, and full-text search |
235
+
236
+ PR titles and bodies mentioning issue keys like `PAP-123` are automatically linked to Jira issues — just like commits.
237
+
238
+ ## MCP Tools
239
+
240
+ When connected to Claude, these tools are available:
241
+
242
+ ### Jira tools
243
+
244
+ | Tool | What it does |
245
+ |------|-------------|
246
+ | `query_issues` | Search issues — full-text, filters, or raw SQL |
247
+ | `get_issue` | Full issue details with comments, changelogs, custom fields |
248
+ | `issue_stats` | Aggregate stats — by status, type, assignee, project |
249
+ | `pull_jira` | Sync latest data from Jira |
250
+ | `list_projects` | List available Jira projects |
251
+
252
+ ### Git tools
253
+
254
+ | Tool | What it does |
255
+ |------|-------------|
256
+ | `query_commits` | Search commits by text, author, date, file path, or raw SQL. Optional `repo_path` filter for multi-repo workspaces |
257
+ | `issue_commits` | Cross-reference: find all commits mentioning a Jira issue key. Optional `repo_path` filter |
258
+ | `commit_stats` | Aggregate stats — top authors, most changed files, linked issues. Optional `repo_path` filter |
259
+
260
+ ### GitHub tools
261
+
262
+ | Tool | What it does |
263
+ |------|-------------|
264
+ | `query_prs` | Search PRs — full-text, state, author, base branch, or raw SQL |
265
+ | `issue_prs` | Cross-reference: find all PRs mentioning a Jira issue key with reviews |
266
+ | `query_releases` | List releases with full-text search |
267
+
268
+ ### Cross-source tools
269
+
270
+ | Tool | What it does |
271
+ |------|-------------|
272
+ | `issue_timeline` | Chronological timeline — changelogs + commits + PRs for one issue |
273
+ | `semantic_search` | Find similar issues by meaning (pgvector embeddings) |
274
+ | `estimate` | Predict effort for new tasks — finds similar completed tasks, analyzes developer profiles, cycle/coding time, bug rate |
275
+
276
+ ### System tools
277
+
278
+ | Tool | What it does |
279
+ |------|-------------|
280
+ | `workspace_info` | Current workspace configuration |
281
+
282
+ ## Embeddings & Semantic Search
283
+
284
+ **Embeddings** turn issue text into numerical vectors that capture meaning. Two issues about "login not working" and "SSO authentication fails" will have similar vectors — even though they share zero keywords.
285
+
286
+ How it works:
287
+
288
+ 1. `argustack embed` sends each issue's `summary + description` to OpenAI API (`text-embedding-3-small` model)
289
+ 2. Returns a 1536-dimensional vector per issue, stored in PostgreSQL via pgvector
290
+ 3. `semantic_search` MCP tool embeds your question, then finds issues with the closest vectors using cosine similarity
291
+
292
+ ```bash
293
+ # Generate embeddings for all issues (requires OPENAI_API_KEY in .env)
294
+ argustack embed
295
+ ```
296
+
297
+ After embedding, ask Claude: *"Find issues similar to payment timeout errors"* — it will search by meaning, not keywords.
298
+
299
+ **Costs:** text-embedding-3-small costs ~$0.02 per 1M tokens. 10,000 issues ≈ $0.05-0.10.
300
+
301
+ **Optional:** Embeddings require an OpenAI API key. All other features work without it.
302
+
303
+ ## GitHub token setup
304
+
305
+ Argustack only reads data from GitHub — it never writes anything. You need a **fine-grained Personal Access Token** with read-only permissions.
306
+
307
+ 1. Go to [github.com/settings/personal-access-tokens/new](https://github.com/settings/personal-access-tokens/new)
308
+ 2. **Token name** — anything (e.g. `argustack`)
309
+ 3. **Description** — optional, can leave empty
310
+ 4. **Resource owner** — your account, or the organization that owns the repo
311
+ 5. **Expiration** — "No expiration" recommended. Token is read-only and stays in your local `.env`
312
+ 6. **Repository access** — pick one:
313
+ - **Only select repositories** (recommended) — pick specific repos, max 50
314
+ - **All repositories** — all your current and future repos
315
+ - **Public repositories** — read-only access to public repos only
316
+ 5. **Permissions** → Repository permissions (3 total):
317
+
318
+ | Permission | Access | Why |
319
+ |---|---|---|
320
+ | **Contents** | Read-only | Releases, downloads, tags |
321
+ | **Metadata** | Read-only | Repository info (auto-selected, required) |
322
+ | **Pull requests** | Read-only | PRs, reviews, comments, files |
323
+
324
+ 7. Click "Generate token" and copy it
325
+
326
+ During `argustack init`, select "GitHub" as a source and paste the token when asked. Or add to `.env` manually:
327
+
328
+ ```bash
329
+ GITHUB_TOKEN=github_pat_...
330
+ GITHUB_OWNER=your-org
331
+ GITHUB_REPO=your-repo
332
+ ```
333
+
334
+ Then run `argustack source add github` and `argustack sync github`.
335
+
336
+ ## Multiple workspaces
337
+
338
+ Each data source = separate workspace (like git repos):
339
+
340
+ ```
341
+ ~/projects/
342
+ ├── client-alpha/ # argustack init → Alpha's Jira + Git
343
+ │ ├── .argustack/
344
+ │ ├── .env # Alpha credentials
345
+ │ └── docker-compose.yml
346
+
347
+ ├── client-beta/ # argustack init → Beta's Jira + Git
348
+ │ ├── .argustack/
349
+ │ ├── .env # Beta credentials
350
+ │ └── docker-compose.yml
351
+ ```
352
+
353
+ ## Security & Credentials
354
+
355
+ **Argustack is a CLI tool. It has no backend, no cloud, no accounts.** Everything runs on your machine.
356
+
357
+ When you run `argustack init`, it creates a `.env` file in your workspace with your credentials:
358
+
359
+ ```bash
360
+ # .env — YOUR file, on YOUR machine, never uploaded anywhere
361
+
362
+ # === Jira ===
363
+ JIRA_URL=https://your-team.atlassian.net
364
+ JIRA_EMAIL=you@company.com
365
+ JIRA_API_TOKEN=your-api-token-here
366
+ JIRA_PROJECTS=PROJ,OTHER
367
+
368
+ # === Git ===
369
+ GIT_REPO_PATHS=/path/to/repo1,/path/to/repo2
370
+
371
+ # === GitHub ===
372
+ GITHUB_TOKEN=github_pat_...
373
+ GITHUB_OWNER=your-org
374
+ GITHUB_REPO=your-repo
375
+
376
+ # === Argustack internal PostgreSQL (match docker-compose.yml) ===
377
+ DB_HOST=localhost
378
+ DB_PORT=5434
379
+ DB_USER=argustack
380
+ DB_PASSWORD=argustack_local
381
+ DB_NAME=argustack
382
+
383
+ # === OpenAI embeddings (optional, for semantic search) ===
384
+ # OPENAI_API_KEY=sk-...
385
+ ```
386
+
387
+ **Where credentials go:**
388
+
389
+ | What | Where | Who can see |
390
+ |------|-------|-------------|
391
+ | Jira token | `.env` on your disk | Only you |
392
+ | GitHub token | `.env` on your disk | Only you |
393
+ | Jira data | PostgreSQL in Docker on `localhost:5434` | Only you |
394
+ | Git + GitHub data | PostgreSQL in Docker on `localhost:5434` | Only you |
395
+ | Database password | `.env` on your disk | Only you |
396
+ | Source code (this repo) | GitHub | Everyone — **no secrets here** |
397
+
398
+ **What Argustack does NOT do:**
399
+ - Does not send your data to any external server
400
+ - Does not have analytics, telemetry, or tracking
401
+ - Does not store credentials anywhere except your local `.env`
402
+ - Does not require registration or accounts
403
+
404
+ **`.env` is in `.gitignore`** — if you accidentally run `git add .`, your credentials won't be committed.
405
+
406
+ ## Tech Stack
407
+
408
+ - TypeScript / Node.js
409
+ - Commander.js — CLI
410
+ - jira.js — Jira REST API
411
+ - Octokit — GitHub REST API (PRs, reviews, releases)
412
+ - es-git — native Git bindings (N-API, powered by libgit2)
413
+ - PostgreSQL 16 + pgvector — storage + vector search
414
+ - MCP SDK — Claude integration
415
+ - Docker — database infrastructure
416
+
417
+ ## Roadmap
418
+
419
+ - [x] Jira pull (all fields, comments, changelogs, worklogs, links)
420
+ - [x] Git pull (commits, per-file diffs, issue cross-references)
421
+ - [x] GitHub pull (PRs, reviews, comments, files, releases, Jira cross-references)
422
+ - [x] MCP server for Claude Desktop / Claude Code (15 tools)
423
+ - [x] Embeddings + semantic search (OpenAI text-embedding-3-small, pgvector)
424
+ - [x] Cross-source timeline (issue_timeline: changelogs + commits + PRs)
425
+ - [x] Multi-repo Git support (multiple repos per workspace, `GIT_REPO_PATHS`)
426
+ - [x] Progress indicators during sync (e.g. `150/506 issues (30%)`)
427
+ - [ ] Database adapter (schema, sample data)
428
+ - [ ] Cross-source analysis (Jira ticket vs actual code vs DB state)
429
+ - [x] CSV import (Jira export without API token)
430
+
431
+ ## License
432
+
433
+ MIT
@@ -0,0 +1,4 @@
1
+ export { CsvProvider } from './provider.js';
2
+ export { mapCsvRow, type CsvRowResult } from './mapper.js';
3
+ export { detectSchema, parseJiraDate, type CsvSchema } from './parser.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/csv/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { CsvProvider } from './provider.js';
2
+ export { mapCsvRow } from './mapper.js';
3
+ export { detectSchema, parseJiraDate } from './parser.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/csv/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Issue, IssueComment, IssueWorklog, IssueLink } from '../../core/types/index.js';
2
+ import type { CsvSchema } from './parser.js';
3
+ export interface CsvRowResult {
4
+ issue: Issue;
5
+ comments: IssueComment[];
6
+ worklogs: IssueWorklog[];
7
+ links: IssueLink[];
8
+ }
9
+ export declare function mapCsvRow(row: string[], schema: CsvSchema): CsvRowResult;
10
+ //# sourceMappingURL=mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../../src/adapters/csv/mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAcD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,GAAG,YAAY,CAsCxE"}
@@ -0,0 +1,179 @@
1
+ import { parseJiraDate } from './parser.js';
2
+ function cell(row, index) {
3
+ if (index === undefined) {
4
+ return null;
5
+ }
6
+ const value = row[index]?.trim() ?? '';
7
+ return value === '' ? null : value;
8
+ }
9
+ function cellStr(row, index) {
10
+ return cell(row, index) ?? '';
11
+ }
12
+ export function mapCsvRow(row, schema) {
13
+ const sf = schema.standardFields;
14
+ const issueKey = cellStr(row, sf.get('Issue key'));
15
+ const projectKey = issueKey.split('-')[0] ?? '';
16
+ const issue = {
17
+ key: issueKey,
18
+ id: cellStr(row, sf.get('Issue id')),
19
+ projectKey,
20
+ summary: cellStr(row, sf.get('Summary')),
21
+ description: cell(row, sf.get('Description')),
22
+ issueType: cell(row, sf.get('Issue Type')),
23
+ status: cell(row, sf.get('Status')),
24
+ statusCategory: cell(row, sf.get('Status Category')),
25
+ priority: cell(row, sf.get('Priority')),
26
+ resolution: cell(row, sf.get('Resolution')),
27
+ assignee: cell(row, sf.get('Assignee')),
28
+ reporter: cell(row, sf.get('Reporter')),
29
+ created: parseJiraDate(cell(row, sf.get('Created'))),
30
+ updated: parseJiraDate(cell(row, sf.get('Updated'))),
31
+ resolved: parseJiraDate(cell(row, sf.get('Resolved'))),
32
+ dueDate: cell(row, sf.get('Due date')),
33
+ labels: extractRepeated(row, schema, 'Labels'),
34
+ components: extractRepeated(row, schema, 'Components'),
35
+ fixVersions: extractRepeated(row, schema, 'Fix versions'),
36
+ parentKey: cell(row, sf.get('Parent key')),
37
+ sprint: null,
38
+ storyPoints: parseFloat(cell(row, sf.get('Original estimate')) ?? '') || null,
39
+ customFields: extractCustomFields(row, schema),
40
+ rawJson: buildRawJson(row, schema),
41
+ };
42
+ const comments = extractComments(issueKey, row, schema);
43
+ const worklogs = extractWorklogs(issueKey, row, schema);
44
+ const links = extractLinks(issueKey, row, schema);
45
+ return { issue, comments, worklogs, links };
46
+ }
47
+ function extractRepeated(row, schema, name) {
48
+ const group = schema.repeatedGroups.get(name);
49
+ if (!group) {
50
+ return [];
51
+ }
52
+ const result = [];
53
+ for (let i = group.startIndex; i < group.startIndex + group.count; i++) {
54
+ const value = row[i]?.trim();
55
+ if (value) {
56
+ result.push(value);
57
+ }
58
+ }
59
+ return result;
60
+ }
61
+ function extractCustomFields(row, schema) {
62
+ const result = {};
63
+ for (const cf of schema.customFields) {
64
+ const value = cell(row, cf.columnIndex);
65
+ if (value !== null) {
66
+ result[cf.name] = value;
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+ function buildRawJson(row, schema) {
72
+ const raw = {};
73
+ for (const [name, index] of schema.standardFields) {
74
+ raw[name] = cell(row, index);
75
+ }
76
+ for (const cf of schema.customFields) {
77
+ raw[`Custom field (${cf.name})`] = cell(row, cf.columnIndex);
78
+ }
79
+ return raw;
80
+ }
81
+ /**
82
+ * Jira CSV comment format: `timestamp;user_id;comment_text`
83
+ * Split on first 2 semicolons — comment body may contain semicolons.
84
+ */
85
+ function extractComments(issueKey, row, schema) {
86
+ const group = schema.repeatedGroups.get('Comment');
87
+ if (!group) {
88
+ return [];
89
+ }
90
+ const result = [];
91
+ for (let i = group.startIndex; i < group.startIndex + group.count; i++) {
92
+ const raw = row[i]?.trim();
93
+ if (!raw) {
94
+ continue;
95
+ }
96
+ const firstSemi = raw.indexOf(';');
97
+ if (firstSemi === -1) {
98
+ continue;
99
+ }
100
+ const secondSemi = raw.indexOf(';', firstSemi + 1);
101
+ if (secondSemi === -1) {
102
+ continue;
103
+ }
104
+ const timestamp = raw.slice(0, firstSemi);
105
+ const author = raw.slice(firstSemi + 1, secondSemi);
106
+ const body = raw.slice(secondSemi + 1);
107
+ result.push({
108
+ issueKey,
109
+ commentId: `csv-${issueKey}-comment-${i}`,
110
+ author: author || null,
111
+ body: body || null,
112
+ created: parseJiraDate(timestamp),
113
+ updated: null,
114
+ });
115
+ }
116
+ return result;
117
+ }
118
+ /**
119
+ * Jira CSV worklog format: `description;timestamp;user;minutes`
120
+ * Minutes × 60 = seconds.
121
+ */
122
+ function extractWorklogs(issueKey, row, schema) {
123
+ const group = schema.repeatedGroups.get('Log Work');
124
+ if (!group) {
125
+ return [];
126
+ }
127
+ const result = [];
128
+ for (let i = group.startIndex; i < group.startIndex + group.count; i++) {
129
+ const raw = row[i]?.trim();
130
+ if (!raw) {
131
+ continue;
132
+ }
133
+ const parts = raw.split(';');
134
+ if (parts.length < 4) {
135
+ continue;
136
+ }
137
+ const description = parts[0] ?? '';
138
+ const timestamp = parts[1] ?? '';
139
+ const author = parts[2] ?? '';
140
+ const minutesStr = parts[parts.length - 1] ?? '0';
141
+ const minutes = parseInt(minutesStr, 10);
142
+ result.push({
143
+ issueKey,
144
+ author: author || null,
145
+ timeSpent: isNaN(minutes) ? null : `${minutes}m`,
146
+ timeSpentSeconds: isNaN(minutes) ? null : minutes * 60,
147
+ comment: description || null,
148
+ started: parseJiraDate(timestamp),
149
+ });
150
+ }
151
+ return result;
152
+ }
153
+ function extractLinks(issueKey, row, schema) {
154
+ const result = [];
155
+ for (const link of schema.issueLinks) {
156
+ const targetKey = row[link.columnIndex]?.trim();
157
+ if (!targetKey) {
158
+ continue;
159
+ }
160
+ if (link.direction === 'outward') {
161
+ result.push({
162
+ sourceKey: issueKey,
163
+ targetKey,
164
+ linkType: link.linkType,
165
+ direction: 'outward',
166
+ });
167
+ }
168
+ else {
169
+ result.push({
170
+ sourceKey: targetKey,
171
+ targetKey: issueKey,
172
+ linkType: link.linkType,
173
+ direction: 'inward',
174
+ });
175
+ }
176
+ }
177
+ return result;
178
+ }
179
+ //# sourceMappingURL=mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../../src/adapters/csv/mapper.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAS5C,SAAS,IAAI,CAAC,GAAa,EAAE,KAAyB;IACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACvC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC;AAED,SAAS,OAAO,CAAC,GAAa,EAAE,KAAyB;IACvD,OAAO,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAa,EAAE,MAAiB;IACxD,MAAM,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;IAEjC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEhD,MAAM,KAAK,GAAU;QACnB,GAAG,EAAE,QAAQ;QACb,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpC,UAAU;QACV,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACpD,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC3C,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QACpD,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QACpD,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QACtD,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC;QAC9C,UAAU,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC;QACtD,WAAW,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC;QACzD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;QAC7E,YAAY,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC;QAC9C,OAAO,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC;KACnC,CAAC;IAEF,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAElD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,eAAe,CAAC,GAAa,EAAE,MAAiB,EAAE,IAAY;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC7B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAa,EAAE,MAAiB;IAC3D,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,GAAa,EAAE,MAAiB;IACpD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAClD,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACrC,GAAG,CAAC,iBAAiB,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,GAAa,EAAE,MAAiB;IACzE,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACvE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAEvC,MAAM,CAAC,IAAI,CAAC;YACV,QAAQ;YACR,SAAS,EAAE,OAAO,QAAQ,YAAY,CAAC,EAAE;YACzC,MAAM,EAAE,MAAM,IAAI,IAAI;YACtB,IAAI,EAAE,IAAI,IAAI,IAAI;YAClB,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC;YACjC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,GAAa,EAAE,MAAiB;IACzE,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACvE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAEzC,MAAM,CAAC,IAAI,CAAC;YACV,QAAQ;YACR,MAAM,EAAE,MAAM,IAAI,IAAI;YACtB,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG;YAChD,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE;YACtD,OAAO,EAAE,WAAW,IAAI,IAAI;YAC5B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB,EAAE,GAAa,EAAE,MAAiB;IACtE,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,QAAQ;gBACnB,SAAS;gBACT,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,SAAS;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,QAAQ;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}