@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.
- package/README.md +212 -0
- package/dist/ai/agent-info.d.ts +1 -0
- package/dist/ai/agent-info.js +42 -0
- package/dist/ai/agent-info.js.map +1 -0
- package/dist/ai/agents/architect.d.ts +3 -0
- package/dist/ai/agents/architect.js +107 -0
- package/dist/ai/agents/architect.js.map +1 -0
- package/dist/ai/agents/backend-dev.d.ts +3 -0
- package/dist/ai/agents/backend-dev.js +33 -0
- package/dist/ai/agents/backend-dev.js.map +1 -0
- package/dist/ai/agents/frontend-dev.d.ts +3 -0
- package/dist/ai/agents/frontend-dev.js +31 -0
- package/dist/ai/agents/frontend-dev.js.map +1 -0
- package/dist/ai/agents/index.d.ts +3 -0
- package/dist/ai/agents/index.js +17 -0
- package/dist/ai/agents/index.js.map +1 -0
- package/dist/ai/agents/refactorer.d.ts +3 -0
- package/dist/ai/agents/refactorer.js +38 -0
- package/dist/ai/agents/refactorer.js.map +1 -0
- package/dist/ai/agents/researcher.d.ts +3 -0
- package/dist/ai/agents/researcher.js +28 -0
- package/dist/ai/agents/researcher.js.map +1 -0
- package/dist/ai/agents/security-reviewer.d.ts +3 -0
- package/dist/ai/agents/security-reviewer.js +99 -0
- package/dist/ai/agents/security-reviewer.js.map +1 -0
- package/dist/ai/agents/types.d.ts +6 -0
- package/dist/ai/agents/types.js +2 -0
- package/dist/ai/agents/types.js.map +1 -0
- package/dist/ai/agents/verifier.d.ts +3 -0
- package/dist/ai/agents/verifier.js +28 -0
- package/dist/ai/agents/verifier.js.map +1 -0
- package/dist/ai/prompts/document.d.ts +3 -0
- package/dist/ai/prompts/document.js +57 -0
- package/dist/ai/prompts/document.js.map +1 -0
- package/dist/ai/prompts/implement.d.ts +3 -0
- package/dist/ai/prompts/implement.js +128 -0
- package/dist/ai/prompts/implement.js.map +1 -0
- package/dist/ai/prompts/index.d.ts +3 -0
- package/dist/ai/prompts/index.js +17 -0
- package/dist/ai/prompts/index.js.map +1 -0
- package/dist/ai/prompts/optimize-ai.d.ts +3 -0
- package/dist/ai/prompts/optimize-ai.js +104 -0
- package/dist/ai/prompts/optimize-ai.js.map +1 -0
- package/dist/ai/prompts/pull-specs.d.ts +3 -0
- package/dist/ai/prompts/pull-specs.js +10 -0
- package/dist/ai/prompts/pull-specs.js.map +1 -0
- package/dist/ai/prompts/pull-tickets.d.ts +3 -0
- package/dist/ai/prompts/pull-tickets.js +11 -0
- package/dist/ai/prompts/pull-tickets.js.map +1 -0
- package/dist/ai/prompts/pull.d.ts +3 -0
- package/dist/ai/prompts/pull.js +9 -0
- package/dist/ai/prompts/pull.js.map +1 -0
- package/dist/ai/prompts/review-changes.d.ts +3 -0
- package/dist/ai/prompts/review-changes.js +88 -0
- package/dist/ai/prompts/review-changes.js.map +1 -0
- package/dist/ai/prompts/types.d.ts +6 -0
- package/dist/ai/prompts/types.js +2 -0
- package/dist/ai/prompts/types.js.map +1 -0
- package/dist/app.d.ts +14 -0
- package/dist/app.js +40 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +79 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/get.d.ts +8 -0
- package/dist/commands/get.js +73 -0
- package/dist/commands/get.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +113 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp/helpers.d.ts +15 -0
- package/dist/commands/mcp/helpers.js +21 -0
- package/dist/commands/mcp/helpers.js.map +1 -0
- package/dist/commands/mcp/pull.d.ts +3 -0
- package/dist/commands/mcp/pull.js +85 -0
- package/dist/commands/mcp/pull.js.map +1 -0
- package/dist/commands/mcp/server.d.ts +2 -0
- package/dist/commands/mcp/server.js +80 -0
- package/dist/commands/mcp/server.js.map +1 -0
- package/dist/commands/mcp/specs.d.ts +2 -0
- package/dist/commands/mcp/specs.js +325 -0
- package/dist/commands/mcp/specs.js.map +1 -0
- package/dist/commands/mcp/tickets.d.ts +3 -0
- package/dist/commands/mcp/tickets.js +77 -0
- package/dist/commands/mcp/tickets.js.map +1 -0
- package/dist/commands/pull.d.ts +10 -0
- package/dist/commands/pull.js +61 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +102 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/components/ticket-renderer.d.ts +5 -0
- package/dist/components/ticket-renderer.js +89 -0
- package/dist/components/ticket-renderer.js.map +1 -0
- package/dist/contexts/config-context.d.ts +17 -0
- package/dist/contexts/config-context.js +77 -0
- package/dist/contexts/config-context.js.map +1 -0
- package/dist/contexts/error-context.d.ts +12 -0
- package/dist/contexts/error-context.js +28 -0
- package/dist/contexts/error-context.js.map +1 -0
- package/dist/helpers/config.d.ts +4 -0
- package/dist/helpers/config.js +29 -0
- package/dist/helpers/config.js.map +1 -0
- package/dist/helpers/fs.d.ts +8 -0
- package/dist/helpers/fs.js +83 -0
- package/dist/helpers/fs.js.map +1 -0
- package/dist/helpers/init.d.ts +2 -0
- package/dist/helpers/init.js +18 -0
- package/dist/helpers/init.js.map +1 -0
- package/dist/helpers/preflight.d.ts +8 -0
- package/dist/helpers/preflight.js +77 -0
- package/dist/helpers/preflight.js.map +1 -0
- package/dist/helpers/pull.d.ts +9 -0
- package/dist/helpers/pull.js +79 -0
- package/dist/helpers/pull.js.map +1 -0
- package/dist/helpers/symlink.d.ts +9 -0
- package/dist/helpers/symlink.js +104 -0
- package/dist/helpers/symlink.js.map +1 -0
- package/dist/helpers/tickets.d.ts +4 -0
- package/dist/helpers/tickets.js +56 -0
- package/dist/helpers/tickets.js.map +1 -0
- package/dist/hooks/use-async.d.ts +6 -0
- package/dist/hooks/use-async.js +37 -0
- package/dist/hooks/use-async.js.map +1 -0
- package/dist/plugins/atlassian/adf-to-markdown.d.ts +11 -0
- package/dist/plugins/atlassian/adf-to-markdown.js +121 -0
- package/dist/plugins/atlassian/adf-to-markdown.js.map +1 -0
- package/dist/plugins/atlassian/auth-step.d.ts +10 -0
- package/dist/plugins/atlassian/auth-step.js +59 -0
- package/dist/plugins/atlassian/auth-step.js.map +1 -0
- package/dist/plugins/atlassian/confluence-client.d.ts +24 -0
- package/dist/plugins/atlassian/confluence-client.js +250 -0
- package/dist/plugins/atlassian/confluence-client.js.map +1 -0
- package/dist/plugins/atlassian/data.d.ts +18 -0
- package/dist/plugins/atlassian/data.js +12 -0
- package/dist/plugins/atlassian/data.js.map +1 -0
- package/dist/plugins/atlassian/index.d.ts +2 -0
- package/dist/plugins/atlassian/index.js +57 -0
- package/dist/plugins/atlassian/index.js.map +1 -0
- package/dist/plugins/atlassian/init-step.d.ts +11 -0
- package/dist/plugins/atlassian/init-step.js +54 -0
- package/dist/plugins/atlassian/init-step.js.map +1 -0
- package/dist/plugins/atlassian/jira-client.d.ts +38 -0
- package/dist/plugins/atlassian/jira-client.js +308 -0
- package/dist/plugins/atlassian/jira-client.js.map +1 -0
- package/dist/plugins/atlassian/specs-step.d.ts +13 -0
- package/dist/plugins/atlassian/specs-step.js +71 -0
- package/dist/plugins/atlassian/specs-step.js.map +1 -0
- package/dist/plugins/atlassian/tickets-step.d.ts +8 -0
- package/dist/plugins/atlassian/tickets-step.js +45 -0
- package/dist/plugins/atlassian/tickets-step.js.map +1 -0
- package/dist/plugins/claude-code/agents.d.ts +4 -0
- package/dist/plugins/claude-code/agents.js +56 -0
- package/dist/plugins/claude-code/agents.js.map +1 -0
- package/dist/plugins/claude-code/commands.d.ts +4 -0
- package/dist/plugins/claude-code/commands.js +54 -0
- package/dist/plugins/claude-code/commands.js.map +1 -0
- package/dist/plugins/claude-code/index.d.ts +2 -0
- package/dist/plugins/claude-code/index.js +57 -0
- package/dist/plugins/claude-code/index.js.map +1 -0
- package/dist/plugins/cursor/index.d.ts +2 -0
- package/dist/plugins/cursor/index.js +60 -0
- package/dist/plugins/cursor/index.js.map +1 -0
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +16 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/local/index.d.ts +2 -0
- package/dist/plugins/local/index.js +53 -0
- package/dist/plugins/local/index.js.map +1 -0
- package/dist/plugins/local/init-step.d.ts +9 -0
- package/dist/plugins/local/init-step.js +24 -0
- package/dist/plugins/local/init-step.js.map +1 -0
- package/dist/plugins/local/local-spec-provider.d.ts +9 -0
- package/dist/plugins/local/local-spec-provider.js +66 -0
- package/dist/plugins/local/local-spec-provider.js.map +1 -0
- package/dist/plugins/local/local-ticket-provider.d.ts +24 -0
- package/dist/plugins/local/local-ticket-provider.js +89 -0
- package/dist/plugins/local/local-ticket-provider.js.map +1 -0
- package/dist/plugins/none/index.d.ts +2 -0
- package/dist/plugins/none/index.js +78 -0
- package/dist/plugins/none/index.js.map +1 -0
- package/dist/plugins/other-ai/index.d.ts +2 -0
- package/dist/plugins/other-ai/index.js +48 -0
- package/dist/plugins/other-ai/index.js.map +1 -0
- package/dist/plugins/registry.d.ts +4 -0
- package/dist/plugins/registry.js +18 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/resolve.d.ts +8 -0
- package/dist/plugins/resolve.js +23 -0
- package/dist/plugins/resolve.js.map +1 -0
- package/dist/plugins/types.d.ts +36 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/vscode-copilot/agents.d.ts +4 -0
- package/dist/plugins/vscode-copilot/agents.js +51 -0
- package/dist/plugins/vscode-copilot/agents.js.map +1 -0
- package/dist/plugins/vscode-copilot/index.d.ts +2 -0
- package/dist/plugins/vscode-copilot/index.js +59 -0
- package/dist/plugins/vscode-copilot/index.js.map +1 -0
- package/dist/plugins/vscode-copilot/prompts.d.ts +4 -0
- package/dist/plugins/vscode-copilot/prompts.js +60 -0
- package/dist/plugins/vscode-copilot/prompts.js.map +1 -0
- package/dist/schemas/config.d.ts +24 -0
- package/dist/schemas/config.js +38 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/confirm.d.ts +7 -0
- package/dist/ui/confirm.js +19 -0
- package/dist/ui/confirm.js.map +1 -0
- package/dist/ui/error-display.d.ts +6 -0
- package/dist/ui/error-display.js +23 -0
- package/dist/ui/error-display.js.map +1 -0
- package/dist/ui/masked-input.d.ts +9 -0
- package/dist/ui/masked-input.js +25 -0
- package/dist/ui/masked-input.js.map +1 -0
- package/dist/ui/multi-select.d.ts +13 -0
- package/dist/ui/multi-select.js +127 -0
- package/dist/ui/multi-select.js.map +1 -0
- package/dist/ui/select-input.d.ts +12 -0
- package/dist/ui/select-input.js +81 -0
- package/dist/ui/select-input.js.map +1 -0
- package/dist/ui/spinner.d.ts +6 -0
- package/dist/ui/spinner.js +18 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/text-input.d.ts +9 -0
- package/dist/ui/text-input.js +23 -0
- package/dist/ui/text-input.js.map +1 -0
- package/dist/wizard/passthrough-step.d.ts +6 -0
- package/dist/wizard/passthrough-step.js +8 -0
- package/dist/wizard/passthrough-step.js.map +1 -0
- package/dist/wizard/plugin-select-step.d.ts +10 -0
- package/dist/wizard/plugin-select-step.js +31 -0
- package/dist/wizard/plugin-select-step.js.map +1 -0
- package/dist/wizard/summary-step.d.ts +2 -0
- package/dist/wizard/summary-step.js +97 -0
- package/dist/wizard/summary-step.js.map +1 -0
- 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 @@
|
|
|
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
|
package/dist/app.js.map
ADDED
|
@@ -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
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
|
package/dist/cli.js.map
ADDED
|
@@ -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,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":"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"}
|
|
@@ -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,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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"}
|