@2amtech/hai 0.0.1

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 (239) hide show
  1. package/README.md +212 -0
  2. package/dist/ai/agent-info.d.ts +1 -0
  3. package/dist/ai/agent-info.js +42 -0
  4. package/dist/ai/agent-info.js.map +1 -0
  5. package/dist/ai/agents/architect.d.ts +3 -0
  6. package/dist/ai/agents/architect.js +107 -0
  7. package/dist/ai/agents/architect.js.map +1 -0
  8. package/dist/ai/agents/backend-dev.d.ts +3 -0
  9. package/dist/ai/agents/backend-dev.js +33 -0
  10. package/dist/ai/agents/backend-dev.js.map +1 -0
  11. package/dist/ai/agents/frontend-dev.d.ts +3 -0
  12. package/dist/ai/agents/frontend-dev.js +31 -0
  13. package/dist/ai/agents/frontend-dev.js.map +1 -0
  14. package/dist/ai/agents/index.d.ts +3 -0
  15. package/dist/ai/agents/index.js +17 -0
  16. package/dist/ai/agents/index.js.map +1 -0
  17. package/dist/ai/agents/refactorer.d.ts +3 -0
  18. package/dist/ai/agents/refactorer.js +38 -0
  19. package/dist/ai/agents/refactorer.js.map +1 -0
  20. package/dist/ai/agents/researcher.d.ts +3 -0
  21. package/dist/ai/agents/researcher.js +28 -0
  22. package/dist/ai/agents/researcher.js.map +1 -0
  23. package/dist/ai/agents/security-reviewer.d.ts +3 -0
  24. package/dist/ai/agents/security-reviewer.js +99 -0
  25. package/dist/ai/agents/security-reviewer.js.map +1 -0
  26. package/dist/ai/agents/types.d.ts +6 -0
  27. package/dist/ai/agents/types.js +2 -0
  28. package/dist/ai/agents/types.js.map +1 -0
  29. package/dist/ai/agents/verifier.d.ts +3 -0
  30. package/dist/ai/agents/verifier.js +28 -0
  31. package/dist/ai/agents/verifier.js.map +1 -0
  32. package/dist/ai/prompts/document.d.ts +3 -0
  33. package/dist/ai/prompts/document.js +57 -0
  34. package/dist/ai/prompts/document.js.map +1 -0
  35. package/dist/ai/prompts/implement.d.ts +3 -0
  36. package/dist/ai/prompts/implement.js +128 -0
  37. package/dist/ai/prompts/implement.js.map +1 -0
  38. package/dist/ai/prompts/index.d.ts +3 -0
  39. package/dist/ai/prompts/index.js +17 -0
  40. package/dist/ai/prompts/index.js.map +1 -0
  41. package/dist/ai/prompts/optimize-ai.d.ts +3 -0
  42. package/dist/ai/prompts/optimize-ai.js +104 -0
  43. package/dist/ai/prompts/optimize-ai.js.map +1 -0
  44. package/dist/ai/prompts/pull-specs.d.ts +3 -0
  45. package/dist/ai/prompts/pull-specs.js +10 -0
  46. package/dist/ai/prompts/pull-specs.js.map +1 -0
  47. package/dist/ai/prompts/pull-tickets.d.ts +3 -0
  48. package/dist/ai/prompts/pull-tickets.js +11 -0
  49. package/dist/ai/prompts/pull-tickets.js.map +1 -0
  50. package/dist/ai/prompts/pull.d.ts +3 -0
  51. package/dist/ai/prompts/pull.js +9 -0
  52. package/dist/ai/prompts/pull.js.map +1 -0
  53. package/dist/ai/prompts/review-changes.d.ts +3 -0
  54. package/dist/ai/prompts/review-changes.js +88 -0
  55. package/dist/ai/prompts/review-changes.js.map +1 -0
  56. package/dist/ai/prompts/types.d.ts +6 -0
  57. package/dist/ai/prompts/types.js +2 -0
  58. package/dist/ai/prompts/types.js.map +1 -0
  59. package/dist/app.d.ts +14 -0
  60. package/dist/app.js +40 -0
  61. package/dist/app.js.map +1 -0
  62. package/dist/cli.d.ts +2 -0
  63. package/dist/cli.js +79 -0
  64. package/dist/cli.js.map +1 -0
  65. package/dist/commands/get.d.ts +8 -0
  66. package/dist/commands/get.js +73 -0
  67. package/dist/commands/get.js.map +1 -0
  68. package/dist/commands/init.d.ts +3 -0
  69. package/dist/commands/init.js +113 -0
  70. package/dist/commands/init.js.map +1 -0
  71. package/dist/commands/mcp/helpers.d.ts +15 -0
  72. package/dist/commands/mcp/helpers.js +21 -0
  73. package/dist/commands/mcp/helpers.js.map +1 -0
  74. package/dist/commands/mcp/pull.d.ts +3 -0
  75. package/dist/commands/mcp/pull.js +85 -0
  76. package/dist/commands/mcp/pull.js.map +1 -0
  77. package/dist/commands/mcp/server.d.ts +2 -0
  78. package/dist/commands/mcp/server.js +80 -0
  79. package/dist/commands/mcp/server.js.map +1 -0
  80. package/dist/commands/mcp/specs.d.ts +2 -0
  81. package/dist/commands/mcp/specs.js +325 -0
  82. package/dist/commands/mcp/specs.js.map +1 -0
  83. package/dist/commands/mcp/tickets.d.ts +3 -0
  84. package/dist/commands/mcp/tickets.js +77 -0
  85. package/dist/commands/mcp/tickets.js.map +1 -0
  86. package/dist/commands/pull.d.ts +10 -0
  87. package/dist/commands/pull.js +61 -0
  88. package/dist/commands/pull.js.map +1 -0
  89. package/dist/commands/status.d.ts +2 -0
  90. package/dist/commands/status.js +102 -0
  91. package/dist/commands/status.js.map +1 -0
  92. package/dist/components/ticket-renderer.d.ts +5 -0
  93. package/dist/components/ticket-renderer.js +89 -0
  94. package/dist/components/ticket-renderer.js.map +1 -0
  95. package/dist/contexts/config-context.d.ts +17 -0
  96. package/dist/contexts/config-context.js +77 -0
  97. package/dist/contexts/config-context.js.map +1 -0
  98. package/dist/contexts/error-context.d.ts +12 -0
  99. package/dist/contexts/error-context.js +28 -0
  100. package/dist/contexts/error-context.js.map +1 -0
  101. package/dist/helpers/config.d.ts +4 -0
  102. package/dist/helpers/config.js +29 -0
  103. package/dist/helpers/config.js.map +1 -0
  104. package/dist/helpers/fs.d.ts +8 -0
  105. package/dist/helpers/fs.js +83 -0
  106. package/dist/helpers/fs.js.map +1 -0
  107. package/dist/helpers/init.d.ts +2 -0
  108. package/dist/helpers/init.js +18 -0
  109. package/dist/helpers/init.js.map +1 -0
  110. package/dist/helpers/preflight.d.ts +8 -0
  111. package/dist/helpers/preflight.js +77 -0
  112. package/dist/helpers/preflight.js.map +1 -0
  113. package/dist/helpers/pull.d.ts +9 -0
  114. package/dist/helpers/pull.js +79 -0
  115. package/dist/helpers/pull.js.map +1 -0
  116. package/dist/helpers/symlink.d.ts +9 -0
  117. package/dist/helpers/symlink.js +104 -0
  118. package/dist/helpers/symlink.js.map +1 -0
  119. package/dist/helpers/tickets.d.ts +4 -0
  120. package/dist/helpers/tickets.js +56 -0
  121. package/dist/helpers/tickets.js.map +1 -0
  122. package/dist/hooks/use-async.d.ts +6 -0
  123. package/dist/hooks/use-async.js +37 -0
  124. package/dist/hooks/use-async.js.map +1 -0
  125. package/dist/plugins/atlassian/adf-to-markdown.d.ts +11 -0
  126. package/dist/plugins/atlassian/adf-to-markdown.js +121 -0
  127. package/dist/plugins/atlassian/adf-to-markdown.js.map +1 -0
  128. package/dist/plugins/atlassian/auth-step.d.ts +10 -0
  129. package/dist/plugins/atlassian/auth-step.js +59 -0
  130. package/dist/plugins/atlassian/auth-step.js.map +1 -0
  131. package/dist/plugins/atlassian/confluence-client.d.ts +24 -0
  132. package/dist/plugins/atlassian/confluence-client.js +250 -0
  133. package/dist/plugins/atlassian/confluence-client.js.map +1 -0
  134. package/dist/plugins/atlassian/data.d.ts +18 -0
  135. package/dist/plugins/atlassian/data.js +12 -0
  136. package/dist/plugins/atlassian/data.js.map +1 -0
  137. package/dist/plugins/atlassian/index.d.ts +2 -0
  138. package/dist/plugins/atlassian/index.js +57 -0
  139. package/dist/plugins/atlassian/index.js.map +1 -0
  140. package/dist/plugins/atlassian/init-step.d.ts +11 -0
  141. package/dist/plugins/atlassian/init-step.js +54 -0
  142. package/dist/plugins/atlassian/init-step.js.map +1 -0
  143. package/dist/plugins/atlassian/jira-client.d.ts +38 -0
  144. package/dist/plugins/atlassian/jira-client.js +308 -0
  145. package/dist/plugins/atlassian/jira-client.js.map +1 -0
  146. package/dist/plugins/atlassian/specs-step.d.ts +13 -0
  147. package/dist/plugins/atlassian/specs-step.js +71 -0
  148. package/dist/plugins/atlassian/specs-step.js.map +1 -0
  149. package/dist/plugins/atlassian/tickets-step.d.ts +8 -0
  150. package/dist/plugins/atlassian/tickets-step.js +45 -0
  151. package/dist/plugins/atlassian/tickets-step.js.map +1 -0
  152. package/dist/plugins/claude-code/agents.d.ts +4 -0
  153. package/dist/plugins/claude-code/agents.js +56 -0
  154. package/dist/plugins/claude-code/agents.js.map +1 -0
  155. package/dist/plugins/claude-code/commands.d.ts +4 -0
  156. package/dist/plugins/claude-code/commands.js +54 -0
  157. package/dist/plugins/claude-code/commands.js.map +1 -0
  158. package/dist/plugins/claude-code/index.d.ts +2 -0
  159. package/dist/plugins/claude-code/index.js +57 -0
  160. package/dist/plugins/claude-code/index.js.map +1 -0
  161. package/dist/plugins/cursor/index.d.ts +2 -0
  162. package/dist/plugins/cursor/index.js +60 -0
  163. package/dist/plugins/cursor/index.js.map +1 -0
  164. package/dist/plugins/index.d.ts +1 -0
  165. package/dist/plugins/index.js +16 -0
  166. package/dist/plugins/index.js.map +1 -0
  167. package/dist/plugins/local/index.d.ts +2 -0
  168. package/dist/plugins/local/index.js +53 -0
  169. package/dist/plugins/local/index.js.map +1 -0
  170. package/dist/plugins/local/init-step.d.ts +9 -0
  171. package/dist/plugins/local/init-step.js +24 -0
  172. package/dist/plugins/local/init-step.js.map +1 -0
  173. package/dist/plugins/local/local-spec-provider.d.ts +9 -0
  174. package/dist/plugins/local/local-spec-provider.js +66 -0
  175. package/dist/plugins/local/local-spec-provider.js.map +1 -0
  176. package/dist/plugins/local/local-ticket-provider.d.ts +24 -0
  177. package/dist/plugins/local/local-ticket-provider.js +89 -0
  178. package/dist/plugins/local/local-ticket-provider.js.map +1 -0
  179. package/dist/plugins/none/index.d.ts +2 -0
  180. package/dist/plugins/none/index.js +78 -0
  181. package/dist/plugins/none/index.js.map +1 -0
  182. package/dist/plugins/other-ai/index.d.ts +2 -0
  183. package/dist/plugins/other-ai/index.js +48 -0
  184. package/dist/plugins/other-ai/index.js.map +1 -0
  185. package/dist/plugins/registry.d.ts +4 -0
  186. package/dist/plugins/registry.js +18 -0
  187. package/dist/plugins/registry.js.map +1 -0
  188. package/dist/plugins/resolve.d.ts +8 -0
  189. package/dist/plugins/resolve.js +23 -0
  190. package/dist/plugins/resolve.js.map +1 -0
  191. package/dist/plugins/types.d.ts +36 -0
  192. package/dist/plugins/types.js +2 -0
  193. package/dist/plugins/types.js.map +1 -0
  194. package/dist/plugins/vscode-copilot/agents.d.ts +4 -0
  195. package/dist/plugins/vscode-copilot/agents.js +51 -0
  196. package/dist/plugins/vscode-copilot/agents.js.map +1 -0
  197. package/dist/plugins/vscode-copilot/index.d.ts +2 -0
  198. package/dist/plugins/vscode-copilot/index.js +59 -0
  199. package/dist/plugins/vscode-copilot/index.js.map +1 -0
  200. package/dist/plugins/vscode-copilot/prompts.d.ts +4 -0
  201. package/dist/plugins/vscode-copilot/prompts.js +60 -0
  202. package/dist/plugins/vscode-copilot/prompts.js.map +1 -0
  203. package/dist/schemas/config.d.ts +24 -0
  204. package/dist/schemas/config.js +38 -0
  205. package/dist/schemas/config.js.map +1 -0
  206. package/dist/types.d.ts +84 -0
  207. package/dist/types.js +2 -0
  208. package/dist/types.js.map +1 -0
  209. package/dist/ui/confirm.d.ts +7 -0
  210. package/dist/ui/confirm.js +19 -0
  211. package/dist/ui/confirm.js.map +1 -0
  212. package/dist/ui/error-display.d.ts +6 -0
  213. package/dist/ui/error-display.js +23 -0
  214. package/dist/ui/error-display.js.map +1 -0
  215. package/dist/ui/masked-input.d.ts +9 -0
  216. package/dist/ui/masked-input.js +25 -0
  217. package/dist/ui/masked-input.js.map +1 -0
  218. package/dist/ui/multi-select.d.ts +13 -0
  219. package/dist/ui/multi-select.js +127 -0
  220. package/dist/ui/multi-select.js.map +1 -0
  221. package/dist/ui/select-input.d.ts +12 -0
  222. package/dist/ui/select-input.js +81 -0
  223. package/dist/ui/select-input.js.map +1 -0
  224. package/dist/ui/spinner.d.ts +6 -0
  225. package/dist/ui/spinner.js +18 -0
  226. package/dist/ui/spinner.js.map +1 -0
  227. package/dist/ui/text-input.d.ts +9 -0
  228. package/dist/ui/text-input.js +23 -0
  229. package/dist/ui/text-input.js.map +1 -0
  230. package/dist/wizard/passthrough-step.d.ts +6 -0
  231. package/dist/wizard/passthrough-step.js +8 -0
  232. package/dist/wizard/passthrough-step.js.map +1 -0
  233. package/dist/wizard/plugin-select-step.d.ts +10 -0
  234. package/dist/wizard/plugin-select-step.js +31 -0
  235. package/dist/wizard/plugin-select-step.js.map +1 -0
  236. package/dist/wizard/summary-step.d.ts +2 -0
  237. package/dist/wizard/summary-step.js +97 -0
  238. package/dist/wizard/summary-step.js.map +1 -0
  239. package/package.json +79 -0
@@ -0,0 +1,88 @@
1
+ const reviewChanges = {
2
+ name: 'review-changes',
3
+ description: 'Review uncommitted changes against project guidelines and suggest improvements.',
4
+ shortDescription: 'Review uncommitted code changes',
5
+ body: `Review all uncommitted changes in the current working tree and provide actionable improvement suggestions.
6
+
7
+ ## Instructions
8
+
9
+ 1. **Gather the diff.** Run \`git diff HEAD\` to capture all uncommitted changes (both staged and unstaged) against the latest commit. If there are no changes, inform the user and stop.
10
+
11
+ 2. **Discover project guidelines.** Before reviewing, read all available project context:
12
+ - All \`AGENTS.md\` files in the project tree (root and domain-scoped) — these contain coding conventions, architectural rules, tech stack details, and style guides.
13
+ - Specification files in \`.ai/specs/\` if available (check \`.ai/specification-index.md\` for lookup) — these describe intended architecture and design.
14
+ - Any linter, formatter, or editor configuration files (e.g. \`.eslintrc\`, \`.prettierrc\`, \`biome.json\`, \`.editorconfig\`, \`tsconfig.json\`, \`pyproject.toml\`, \`.rubocop.yml\`, etc.) to understand enforced code style.
15
+ - The project's \`README.md\` or contributing guide if present, for high-level conventions.
16
+ - Collect all discovered rules, conventions, and architectural patterns into a checklist to review against.
17
+
18
+ 3. **Identify the tech stack.** From the project files (package.json, Cargo.toml, go.mod, pyproject.toml, Gemfile, etc.) and the \`AGENTS.md\` files, determine the languages, frameworks, and key libraries in use. Tailor your review to the idioms and best practices of the identified stack.
19
+
20
+ 4. **Review the diff.** For each changed file, evaluate the changes across the following dimensions:
21
+
22
+ **Code Cleanliness**
23
+ - Dead code, unused imports, or unreachable branches introduced by the changes
24
+ - Duplicated logic that could use existing helpers or utilities already in the codebase
25
+ - Overly complex expressions that could be simplified
26
+ - Magic numbers or strings that should be named constants
27
+ - Inconsistent or unclear naming (variables, functions, types)
28
+
29
+ **Code Style & Conventions**
30
+ - Violations of project-specific style rules discovered in step 2
31
+ - Inconsistencies with patterns established in surrounding code
32
+ - Formatting issues not caught by automated tooling
33
+ - Naming convention violations (casing, prefixes, suffixes) based on project norms
34
+
35
+ **Architecture & Design**
36
+ - Violations of architectural rules or boundaries defined in \`AGENTS.md\` or specs
37
+ - Misplaced logic (e.g. business logic in controllers, data access in UI components)
38
+ - Missing or incorrect use of established patterns (dependency injection, repository pattern, service layers, etc.)
39
+ - API design issues (inconsistent endpoints, missing validation, wrong HTTP methods)
40
+ - Changes that break separation of concerns or introduce tight coupling
41
+
42
+ **Security**
43
+ - Injection vulnerabilities (SQL, command, XSS, template)
44
+ - Hardcoded credentials, API keys, or secrets
45
+ - Missing input validation or sanitization at system boundaries
46
+ - Sensitive data exposure (PII in logs, tokens in error messages)
47
+ - Missing authentication or authorization checks
48
+ - Insecure configurations introduced by the changes
49
+
50
+ **Readability & Maintainability**
51
+ - Functions or methods that are too long or do too many things
52
+ - Missing or misleading comments on non-obvious logic
53
+ - Unclear control flow or deeply nested conditionals
54
+ - Poor error handling (swallowed errors, generic catches, missing error context)
55
+ - Type safety issues (excessive use of \`any\`, missing type annotations at boundaries)
56
+
57
+ 5. **Report findings.** For each finding, report it in this format:
58
+ \`\`\`
59
+ [CATEGORY] <file>:<line range> — <concise description>
60
+ Why: <why this matters — reference the specific project rule, convention, or best practice>
61
+ Suggestion: <concrete fix or improvement, with a brief code example if helpful>
62
+ \`\`\`
63
+
64
+ Where CATEGORY is one of: \`CLEANLINESS\`, \`STYLE\`, \`ARCHITECTURE\`, \`SECURITY\`, \`READABILITY\`.
65
+
66
+ 6. **Summarize.** At the end, provide:
67
+ - Total findings by category
68
+ - A brief overall assessment of the changes
69
+ - The top 3 most impactful improvements to make (if any)
70
+
71
+ If no issues were found, output:
72
+ \`\`\`
73
+ CLEAN: No issues found — changes look good.
74
+ \`\`\`
75
+
76
+ ## Rules
77
+
78
+ - Do NOT make code changes. This command is read-only — review and report only.
79
+ - Only review the changed lines and their immediate context. Do not audit the entire file or report pre-existing issues unrelated to the diff.
80
+ - Be specific — always include file paths, line numbers or ranges, and concrete suggestions. Vague feedback like "consider refactoring" is not helpful.
81
+ - Do NOT report issues that would be caught by automated linters or formatters if the project has them configured. Focus on what tooling misses.
82
+ - Tailor your review to the project's actual stack and conventions. Do not impose conventions from other ecosystems or frameworks.
83
+ - If the project has no \`AGENTS.md\` or style configuration, review against the standard idioms and best practices of the detected language and framework.
84
+ - Prioritize findings by impact. Lead with issues that could cause bugs, security problems, or architectural drift. Style nits should come last.
85
+ - When reviewing, check the surrounding unchanged code for context before flagging an issue. A pattern that looks wrong in isolation may be consistent with the rest of the codebase.`,
86
+ };
87
+ export default reviewChanges;
88
+ //# sourceMappingURL=review-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-changes.js","sourceRoot":"","sources":["../../../source/ai/prompts/review-changes.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAqB;IACvC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACV,iFAAiF;IAClF,gBAAgB,EAAE,iCAAiC;IACnD,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sLAgF+K;CACrL,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface PromptDefinition {
2
+ readonly name: string;
3
+ readonly description: string;
4
+ readonly shortDescription: string;
5
+ readonly body: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../source/ai/prompts/types.ts"],"names":[],"mappings":""}
package/dist/app.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ command: string;
4
+ flags: {
5
+ dryRun: boolean;
6
+ tickets: boolean;
7
+ specs: boolean;
8
+ updateLocal: boolean;
9
+ recursive: boolean;
10
+ };
11
+ args: string[];
12
+ };
13
+ export default function App({ command, flags, args }: Props): React.JSX.Element;
14
+ export {};
package/dist/app.js ADDED
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { Text } from 'ink';
3
+ import { ErrorProvider } from './contexts/error-context.js';
4
+ import { ConfigProvider } from './contexts/config-context.js';
5
+ import InitCommand from './commands/init.js';
6
+ import StatusCommand from './commands/status.js';
7
+ import GetCommand from './commands/get.js';
8
+ import PullCommand from './commands/pull.js';
9
+ function Command({ command, flags, args }) {
10
+ switch (command) {
11
+ case 'init': {
12
+ return React.createElement(InitCommand, null);
13
+ }
14
+ case 'pull': {
15
+ return (React.createElement(PullCommand, { dryRun: flags.dryRun, tickets: flags.tickets, specs: flags.specs, updateLocal: flags.updateLocal }));
16
+ }
17
+ case 'status': {
18
+ return React.createElement(StatusCommand, null);
19
+ }
20
+ case 'get': {
21
+ const issueKey = args[0];
22
+ if (!issueKey) {
23
+ return (React.createElement(Text, { color: "red" }, "Usage: hai get [--recursive] <issue-key>"));
24
+ }
25
+ return (React.createElement(GetCommand, { issueKey: issueKey, recursive: flags.recursive }));
26
+ }
27
+ default:
28
+ break;
29
+ }
30
+ return (React.createElement(Text, { color: "red" },
31
+ "Unknown command: ",
32
+ command,
33
+ ". Run \"hai --help\" for usage."));
34
+ }
35
+ export default function App({ command, flags, args }) {
36
+ return (React.createElement(ErrorProvider, null,
37
+ React.createElement(ConfigProvider, { isInit: command === 'init' },
38
+ React.createElement(Command, { command: command, flags: flags, args: args }))));
39
+ }
40
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../source/app.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAC5D,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAc7C,SAAS,OAAO,CAAC,EAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAQ;IAC7C,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,CAAC,CAAC;YACb,OAAO,oBAAC,WAAW,OAAG,CAAC;QACxB,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACb,OAAO,CACN,oBAAC,WAAW,IACX,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,WAAW,EAAE,KAAK,CAAC,WAAW,GAC7B,CACF,CAAC;QACH,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACf,OAAO,oBAAC,aAAa,OAAG,CAAC;QAC1B,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO,CACN,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK,+CAEV,CACP,CAAC;YACH,CAAC;YAED,OAAO,CACN,oBAAC,UAAU,IAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAI,CAC9D,CAAC;QACH,CAAC;QAED;YACC,MAAM;IACR,CAAC;IAED,OAAO,CACN,oBAAC,IAAI,IAAC,KAAK,EAAC,KAAK;;QACE,OAAO;0CACnB,CACP,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,EAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAQ;IACxD,OAAO,CACN,oBAAC,aAAa;QACb,oBAAC,cAAc,IAAC,MAAM,EAAE,OAAO,KAAK,MAAM;YACzC,oBAAC,OAAO,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,GAAI,CACvC,CACF,CAChB,CAAC;AACH,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ import React from 'react';
3
+ import { render } from 'ink';
4
+ import meow from 'meow';
5
+ import App from './app.js';
6
+ import { mcp } from './commands/mcp/server.js';
7
+ const cli = meow(`
8
+ Usage
9
+ $ hai <command> [options]
10
+
11
+ Commands
12
+ init Initialize hai in the current project
13
+ pull Sync tickets and specs to local .ai/ directory
14
+ status Show sync status
15
+ get <key> Fetch a specific ticket by key
16
+ mcp Start MCP server (for AI tool integration)
17
+
18
+ Options
19
+ --dry-run Preview changes without writing to disk
20
+ --tickets, -t Pull tickets only
21
+ --specs, -s Pull specs only
22
+ --update-local, -u Remove local files not in remote
23
+ --recursive, -r Fetch linked issues recursively (for get)
24
+
25
+ Examples
26
+ $ hai init
27
+ $ hai pull --tickets
28
+ $ hai get PROJ-123 --recursive
29
+ `, {
30
+ importMeta: import.meta,
31
+ flags: {
32
+ dryRun: {
33
+ type: 'boolean',
34
+ default: false,
35
+ aliases: ['dry-run'],
36
+ },
37
+ tickets: {
38
+ type: 'boolean',
39
+ shortFlag: 't',
40
+ default: false,
41
+ },
42
+ specs: {
43
+ type: 'boolean',
44
+ shortFlag: 's',
45
+ default: false,
46
+ },
47
+ updateLocal: {
48
+ type: 'boolean',
49
+ shortFlag: 'u',
50
+ default: false,
51
+ aliases: ['update-local'],
52
+ },
53
+ recursive: {
54
+ type: 'boolean',
55
+ shortFlag: 'r',
56
+ default: false,
57
+ },
58
+ },
59
+ });
60
+ const command = cli.input[0] ?? 'help';
61
+ // MCP server runs over stdio — must NOT use Ink
62
+ if (command === 'mcp') {
63
+ const workspaceFolder = cli.input[1] ?? process.cwd();
64
+ void mcp(workspaceFolder);
65
+ }
66
+ else if (command === 'help') {
67
+ cli.showHelp();
68
+ }
69
+ else {
70
+ // For pull: if neither --tickets nor --specs is specified, pull both
71
+ const flags = {
72
+ ...cli.flags,
73
+ tickets: cli.flags.tickets || (!cli.flags.tickets && !cli.flags.specs),
74
+ specs: cli.flags.specs || (!cli.flags.tickets && !cli.flags.specs),
75
+ };
76
+ const { waitUntilExit } = render(React.createElement(App, { command: command, flags: flags, args: cli.input.slice(1) }));
77
+ void waitUntilExit();
78
+ }
79
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../source/cli.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC;AAC3B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAC,GAAG,EAAC,MAAM,0BAA0B,CAAC;AAE7C,MAAM,GAAG,GAAG,IAAI,CACf;;;;;;;;;;;;;;;;;;;;;;CAsBA,EACA;IACC,UAAU,EAAE,MAAM,CAAC,IAAI;IACvB,KAAK,EAAE;QACN,MAAM,EAAE;YACP,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,SAAS,CAAC;SACpB;QACD,OAAO,EAAE;YACR,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,KAAK;SACd;QACD,KAAK,EAAE;YACN,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,KAAK;SACd;QACD,WAAW,EAAE;YACZ,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,cAAc,CAAC;SACzB;QACD,SAAS,EAAE;YACV,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,KAAK;SACd;KACD;CACD,CACD,CAAC;AAEF,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;AAEvC,gDAAgD;AAChD,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;IACvB,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtD,KAAK,GAAG,CAAC,eAAe,CAAC,CAAC;AAC3B,CAAC;KAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;IAC/B,GAAG,CAAC,QAAQ,EAAE,CAAC;AAChB,CAAC;KAAM,CAAC;IACP,qEAAqE;IACrE,MAAM,KAAK,GAAG;QACb,GAAG,GAAG,CAAC,KAAK;QACZ,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;QACtE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;KAClE,CAAC;IAEF,MAAM,EAAC,aAAa,EAAC,GAAG,MAAM,CAC7B,oBAAC,GAAG,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAI,CACjE,CAAC;IAEF,KAAK,aAAa,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import '../plugins/index.js';
3
+ type Props = {
4
+ issueKey: string;
5
+ recursive: boolean;
6
+ };
7
+ export default function GetCommand({ issueKey, recursive }: Props): React.JSX.Element;
8
+ export {};
@@ -0,0 +1,73 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Text, Box, useApp } from 'ink';
3
+ import '../plugins/index.js';
4
+ import Spinner from '../ui/spinner.js';
5
+ import ErrorDisplay from '../ui/error-display.js';
6
+ import { useConfigContext } from '../contexts/config-context.js';
7
+ import { resolveTicketProvider } from '../plugins/resolve.js';
8
+ import { renderTicket } from '../components/ticket-renderer.js';
9
+ import { projectFromKey, fetchAllIssues, listLocalTicketKeys, } from '../helpers/tickets.js';
10
+ import { writeFile, mkdir } from 'node:fs/promises';
11
+ import { join } from 'node:path';
12
+ const TICKETS_DIR = '.ai/tickets';
13
+ export default function GetCommand({ issueKey, recursive }) {
14
+ const { exit } = useApp();
15
+ const { error: configError, config } = useConfigContext();
16
+ const [fetching, setFetching] = useState(false);
17
+ const [downloaded, setDownloaded] = useState([]);
18
+ const [error, setError] = useState(null);
19
+ const configLoading = false;
20
+ useEffect(() => {
21
+ if (!config)
22
+ return;
23
+ setFetching(true);
24
+ void (async () => {
25
+ try {
26
+ const provider = resolveTicketProvider(config);
27
+ const tickets = await fetchAllIssues(provider, issueKey, recursive);
28
+ const localFiles = await listLocalTicketKeys(TICKETS_DIR);
29
+ for (const t of tickets) {
30
+ localFiles.add(t.key);
31
+ }
32
+ const paths = [];
33
+ for (const ticket of tickets) {
34
+ const project = projectFromKey(ticket.key);
35
+ const dir = join(TICKETS_DIR, project);
36
+ await mkdir(dir, { recursive: true });
37
+ const filePath = join(dir, `${ticket.key}.md`);
38
+ await writeFile(filePath, renderTicket(ticket, { localFiles }), 'utf-8');
39
+ paths.push(`${ticket.key} -> ${filePath}`);
40
+ }
41
+ setDownloaded(paths);
42
+ setFetching(false);
43
+ setTimeout(() => {
44
+ exit();
45
+ }, 0);
46
+ }
47
+ catch (err) {
48
+ setError(err instanceof Error ? err : new Error(String(err)));
49
+ setFetching(false);
50
+ setTimeout(() => {
51
+ exit();
52
+ }, 0);
53
+ }
54
+ })();
55
+ }, [config]); // eslint-disable-line react-hooks/exhaustive-deps
56
+ if (configLoading)
57
+ return React.createElement(Spinner, { label: "Loading configuration..." });
58
+ if (configError)
59
+ return React.createElement(ErrorDisplay, { error: configError });
60
+ if (error)
61
+ return React.createElement(ErrorDisplay, { error: error });
62
+ if (fetching)
63
+ return React.createElement(Spinner, { label: `Fetching ${issueKey}...` });
64
+ return (React.createElement(Box, { flexDirection: "column" },
65
+ downloaded.map(line => (React.createElement(Text, { key: line, color: "green" },
66
+ "Downloaded ",
67
+ line))),
68
+ downloaded.length > 1 && (React.createElement(Text, { bold: true },
69
+ "Total: ",
70
+ downloaded.length,
71
+ " issues downloaded"))));
72
+ }
73
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../source/commands/get.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAC,MAAM,KAAK,CAAC;AACtC,OAAO,qBAAqB,CAAC;AAC7B,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,YAAY,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAC,YAAY,EAAC,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EACN,cAAc,EACd,cAAc,EACd,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAC,SAAS,EAAE,KAAK,EAAC,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAE/B,MAAM,WAAW,GAAG,aAAa,CAAC;AAOlC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAC,QAAQ,EAAE,SAAS,EAAQ;IAC9D,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,EAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAC,GAAG,gBAAgB,EAAE,CAAC;IACxD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,MAAM,aAAa,GAAG,KAAK,CAAC;IAE5B,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,WAAW,CAAC,IAAI,CAAC,CAAC;QAElB,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACJ,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;gBAC/C,MAAM,OAAO,GAAG,MAAM,cAAc,CACnC,QAAQ,EACR,QAAQ,EACR,SAAS,CACT,CAAC;gBAEF,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;gBAC1D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACzB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAED,MAAM,KAAK,GAAa,EAAE,CAAC;gBAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC9B,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBACvC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;oBACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC;oBAC/C,MAAM,SAAS,CACd,QAAQ,EACR,YAAY,CAAC,MAAM,EAAE,EAAC,UAAU,EAAC,CAAC,EAClC,OAAO,CACP,CAAC;oBACF,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,OAAO,QAAQ,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBAED,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrB,WAAW,CAAC,KAAK,CAAC,CAAC;gBACnB,UAAU,CAAC,GAAG,EAAE;oBACf,IAAI,EAAE,CAAC;gBACR,CAAC,EAAE,CAAC,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACvB,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC9D,WAAW,CAAC,KAAK,CAAC,CAAC;gBACnB,UAAU,CAAC,GAAG,EAAE;oBACf,IAAI,EAAE,CAAC;gBACR,CAAC,EAAE,CAAC,CAAC,CAAC;YACP,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;IACN,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,kDAAkD;IAEhE,IAAI,aAAa;QAAE,OAAO,oBAAC,OAAO,IAAC,KAAK,EAAC,0BAA0B,GAAG,CAAC;IACvE,IAAI,WAAW;QAAE,OAAO,oBAAC,YAAY,IAAC,KAAK,EAAE,WAAW,GAAI,CAAC;IAC7D,IAAI,KAAK;QAAE,OAAO,oBAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,oBAAC,OAAO,IAAC,KAAK,EAAE,YAAY,QAAQ,KAAK,GAAI,CAAC;IAEnE,OAAO,CACN,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;QACzB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACvB,oBAAC,IAAI,IAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAC,OAAO;;YACjB,IAAI,CACV,CACP,CAAC;QACD,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CACzB,oBAAC,IAAI,IAAC,IAAI;;YAAS,UAAU,CAAC,MAAM;iCAA0B,CAC9D,CACI,CACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import '../plugins/index.js';
3
+ export default function InitCommand(): React.JSX.Element;
@@ -0,0 +1,113 @@
1
+ import React, { useState } from 'react';
2
+ import { Text, Box } from 'ink';
3
+ import '../plugins/index.js';
4
+ import PluginSelectStep from '../wizard/plugin-select-step.js';
5
+ import SummaryStep from '../wizard/summary-step.js';
6
+ import { useConfigContext } from '../contexts/config-context.js';
7
+ import { findPluginForCapability, extractPluginData } from '../schemas/config.js';
8
+ import { initializeEnvironment } from '../helpers/init.js';
9
+ import Spinner from '../ui/spinner.js';
10
+ import { useErrorContext } from '../contexts/error-context.js';
11
+ const INITIAL_STEPS = ['ai', 'tickets', 'specs'];
12
+ const STEP_MAP = {
13
+ ai: { capability: 'ai', label: 'AI Provider' },
14
+ tickets: { capability: 'tickets', label: 'Ticket Provider' },
15
+ specs: { capability: 'specs', label: 'Specs Provider' },
16
+ };
17
+ function getCurrentPluginId(capability, config) {
18
+ if (!config)
19
+ return undefined;
20
+ const entry = findPluginForCapability(config, capability);
21
+ if (!entry)
22
+ return undefined;
23
+ return entry.plugin;
24
+ }
25
+ function getPluginData(pluginId, config) {
26
+ if (!config)
27
+ return {};
28
+ for (const plugin of config.plugins) {
29
+ if (plugin.plugin === pluginId) {
30
+ const { plugin: _, provides: _2, ...data } = plugin;
31
+ return { ...data };
32
+ }
33
+ }
34
+ return {};
35
+ }
36
+ function ProviderStep({ capability, label, onComplete, }) {
37
+ const { config } = useConfigContext();
38
+ const [plugin, setPlugin] = useState(null);
39
+ if (!plugin) {
40
+ return (React.createElement(PluginSelectStep, { capability: capability, label: label, currentPluginId: getCurrentPluginId(capability, config), onComplete: setPlugin }));
41
+ }
42
+ const Plugin = plugin;
43
+ const existing = getPluginData(plugin.id, config);
44
+ return (React.createElement(Box, { flexDirection: "column" },
45
+ React.createElement(Text, null,
46
+ React.createElement(Text, { bold: true },
47
+ label,
48
+ ": "),
49
+ React.createElement(Text, { color: "cyan" }, plugin.name)),
50
+ React.createElement(Plugin.InitStep, { capability: capability, existingData: existing, onComplete: data => onComplete(plugin, data) })));
51
+ }
52
+ export default function InitCommand() {
53
+ const { config, setConfig, saveToFile } = useConfigContext();
54
+ const { setError } = useErrorContext();
55
+ const [steps, setSteps] = useState([...INITIAL_STEPS]);
56
+ const [isSaving, setIsSaving] = useState(false);
57
+ if (isSaving || !config) {
58
+ return (React.createElement(Spinner, { label: "Saving configuration and doing initial pull..." }));
59
+ }
60
+ const currentStep = steps[0];
61
+ if (!currentStep) {
62
+ return React.createElement(SummaryStep, null);
63
+ }
64
+ const { capability, label } = STEP_MAP[currentStep];
65
+ return (React.createElement(ProviderStep, { key: currentStep, capability: capability, label: label, onComplete: (plugin, data) => {
66
+ const existingPlugin = config.plugins.find(p => p.plugin === plugin.id);
67
+ const existingData = existingPlugin
68
+ ? extractPluginData(existingPlugin)
69
+ : {};
70
+ const pluginToUpdate = {
71
+ plugin: plugin.id,
72
+ provides: existingPlugin
73
+ ? Array.from(new Set([
74
+ ...existingPlugin.provides,
75
+ capability,
76
+ ]))
77
+ : [capability],
78
+ ...existingData,
79
+ ...data,
80
+ };
81
+ // Remove this capability from any other plugin that previously provided it
82
+ const cleanedPlugins = config.plugins
83
+ .filter(p => p.plugin !== plugin.id)
84
+ .map(p => {
85
+ if (!p.provides.includes(capability))
86
+ return p;
87
+ const provides = p.provides.filter(c => c !== capability);
88
+ return provides.length > 0 ? { ...p, provides } : null;
89
+ })
90
+ .filter((p) => p !== null);
91
+ const updatedConfig = {
92
+ ...config,
93
+ plugins: [...cleanedPlugins, pluginToUpdate],
94
+ };
95
+ setConfig(updatedConfig);
96
+ if (steps.length === 1) {
97
+ setIsSaving(true);
98
+ void saveToFile(updatedConfig)
99
+ .catch(e => {
100
+ setError(e);
101
+ })
102
+ .then(() => initializeEnvironment(updatedConfig))
103
+ .then(() => {
104
+ setIsSaving(false);
105
+ setSteps([]);
106
+ });
107
+ }
108
+ else {
109
+ setSteps(steps.slice(1));
110
+ }
111
+ } }));
112
+ }
113
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../source/commands/init.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare function mcpError(text: string): {
2
+ isError: true;
3
+ content: {
4
+ type: "text";
5
+ text: string;
6
+ }[];
7
+ };
8
+ export declare function mcpSuccess(structuredContent: Record<string, unknown>, text?: string): {
9
+ content: {
10
+ type: "text";
11
+ text: string;
12
+ }[];
13
+ structuredContent: Record<string, unknown>;
14
+ };
15
+ export declare function errorText(error: unknown): string;
@@ -0,0 +1,21 @@
1
+ export function mcpError(text) {
2
+ return {
3
+ isError: true,
4
+ content: [{ type: 'text', text }],
5
+ };
6
+ }
7
+ export function mcpSuccess(structuredContent, text) {
8
+ return {
9
+ content: [
10
+ {
11
+ type: 'text',
12
+ text: text ?? JSON.stringify(structuredContent, null, 2),
13
+ },
14
+ ],
15
+ structuredContent,
16
+ };
17
+ }
18
+ export function errorText(error) {
19
+ return error instanceof Error ? error.message : String(error);
20
+ }
21
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../source/commands/mcp/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,IAAY;IACpC,OAAO;QACN,OAAO,EAAE,IAAa;QACtB,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,MAAe,EAAE,IAAI,EAAC,CAAC;KACxC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACzB,iBAA0C,EAC1C,IAAa;IAEb,OAAO;QACN,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;aACxD;SACD;QACD,iBAAiB;KACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import '../../plugins/index.js';
3
+ export declare function registerPullTool(server: McpServer, workspaceFolder: string): void;
@@ -0,0 +1,85 @@
1
+ import { z } from 'zod';
2
+ import { readConfig } from '../../helpers/config.js';
3
+ import '../../plugins/index.js';
4
+ import { resolveTicketProvider, resolveSpecProvider, hasCapability, } from '../../plugins/resolve.js';
5
+ import { mcpError, mcpSuccess, errorText } from './helpers.js';
6
+ export function registerPullTool(server, workspaceFolder) {
7
+ const syncResultSchema = z.object({
8
+ downloaded: z.array(z.string()).describe('Files downloaded'),
9
+ updated: z.array(z.string()).describe('Files updated'),
10
+ removed: z.array(z.string()).describe('Files removed'),
11
+ });
12
+ const skippedSchema = z.object({
13
+ skipped: z.literal(true),
14
+ message: z.string().describe('Reason the capability was skipped'),
15
+ });
16
+ server.registerTool('pull', {
17
+ description: 'Pull users tickets and/or specs to local markdown files into .ai folder',
18
+ inputSchema: {
19
+ tickets: z
20
+ .boolean()
21
+ .optional()
22
+ .default(true)
23
+ .describe('Pull tickets (default: true)'),
24
+ specs: z
25
+ .boolean()
26
+ .optional()
27
+ .default(true)
28
+ .describe('Pull specs (default: true)'),
29
+ updateLocal: z
30
+ .boolean()
31
+ .optional()
32
+ .default(false)
33
+ .describe('Remove local files that no longer exist remotely'),
34
+ dryRun: z
35
+ .boolean()
36
+ .optional()
37
+ .default(false)
38
+ .describe('Preview changes without writing to disk'),
39
+ },
40
+ outputSchema: {
41
+ tickets: z
42
+ .union([syncResultSchema, skippedSchema])
43
+ .optional()
44
+ .describe('Ticket sync results, if tickets were pulled'),
45
+ specs: z
46
+ .union([syncResultSchema, skippedSchema])
47
+ .optional()
48
+ .describe('Spec sync results, if specs were pulled'),
49
+ },
50
+ }, async ({ tickets, specs, updateLocal, dryRun }) => {
51
+ try {
52
+ const config = await readConfig(`${workspaceFolder}/hai.json`);
53
+ const results = {};
54
+ if (tickets) {
55
+ if (!hasCapability(config, 'tickets')) {
56
+ results['tickets'] = {
57
+ skipped: true,
58
+ message: "No tickets configuration found. Run 'hai init' to set up tickets.",
59
+ };
60
+ }
61
+ else {
62
+ const provider = resolveTicketProvider(config);
63
+ results['tickets'] = await provider.sync(`${workspaceFolder}/.ai/tickets`, { dryRun, updateLocal });
64
+ }
65
+ }
66
+ if (specs) {
67
+ if (!hasCapability(config, 'specs')) {
68
+ results['specs'] = {
69
+ skipped: true,
70
+ message: "No specs configuration found. Run 'hai init' to set up specs.",
71
+ };
72
+ }
73
+ else {
74
+ const provider = resolveSpecProvider(config);
75
+ results['specs'] = await provider.sync(`${workspaceFolder}/.ai/specs`, { dryRun, updateLocal });
76
+ }
77
+ }
78
+ return mcpSuccess(results);
79
+ }
80
+ catch (error) {
81
+ return mcpError(errorText(error));
82
+ }
83
+ });
84
+ }
85
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../source/commands/mcp/pull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import '../../plugins/index.js';
2
+ export declare function mcp(workspaceFolder: string): Promise<void>;