maistro 1.0.402 → 1.0.410
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 +90 -53
- package/dist/apiKeyValidator.d.ts +58 -0
- package/dist/apiKeyValidator.d.ts.map +1 -0
- package/dist/apiKeyValidator.js +235 -0
- package/dist/apiKeyValidator.js.map +1 -0
- package/dist/app.d.ts +13 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +191 -61
- package/dist/app.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/dependencyDetector.d.ts +3 -1
- package/dist/dependencyDetector.d.ts.map +1 -1
- package/dist/dependencyDetector.js +103 -4
- package/dist/dependencyDetector.js.map +1 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +13 -14
- package/dist/executor.js.map +1 -1
- package/dist/git.d.ts +7 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +34 -0
- package/dist/git.js.map +1 -1
- package/dist/logger.d.ts +7 -10
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +45 -24
- package/dist/logger.js.map +1 -1
- package/dist/logo.d.ts +20 -0
- package/dist/logo.d.ts.map +1 -0
- package/dist/logo.js +57 -0
- package/dist/logo.js.map +1 -0
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +38 -6
- package/dist/orchestrator.js.map +1 -1
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +0 -3
- package/dist/planner.js.map +1 -1
- package/dist/screen.d.ts +1 -1
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +3 -22
- package/dist/screen.js.map +1 -1
- package/dist/types.d.ts +17 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/validator.d.ts +6 -34
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +256 -344
- package/dist/validator.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,106 +1,143 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mAIstro
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```
|
|
4
|
+
▓▓▓▓
|
|
5
|
+
██ ██ █▀▀▀█
|
|
6
|
+
█ ▀▀ █ █▌█ █▐█
|
|
7
|
+
▐█ █▌ █▄▄▄█
|
|
8
|
+
█░░░░█ ▀ ▀
|
|
9
|
+
██ ██
|
|
10
|
+
```
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
A small CLI for orchestrating Claude Code tasks when one-shot prompts and limited context aren't enough.
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
mAIstro helps you break large work into explicit, sequential steps, keeping important requirements visible as tasks execute — so Claude Code doesn't lose context or skip constraints.
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
This is a free tool built to scratch a personal itch and shared for feedback.
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
## Why mAIstro exists
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
Claude Code works well for focused tasks.
|
|
21
|
+
It becomes harder when:
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
- tasks grow beyond a single prompt
|
|
24
|
+
- important requirements fall out of context
|
|
25
|
+
- earlier decisions get forgotten mid-execution
|
|
26
|
+
- the model "optimizes away" steps you actually need
|
|
27
|
+
|
|
28
|
+
mAIstro introduces a thin orchestration layer that:
|
|
29
|
+
|
|
30
|
+
- controls execution order
|
|
31
|
+
- limits active context per step
|
|
32
|
+
- keeps critical constraints explicit
|
|
33
|
+
|
|
34
|
+
This makes larger tasks more reliable without increasing prompt complexity.
|
|
35
|
+
|
|
36
|
+
## What it does
|
|
37
|
+
|
|
38
|
+
- Breaks large work into bounded tasks
|
|
39
|
+
- Executes tasks sequentially
|
|
40
|
+
- Keeps only relevant context active per step
|
|
41
|
+
- Preserves requirements and constraints across steps
|
|
42
|
+
- Keeps task status visible while execution progresses
|
|
43
|
+
- Allows human intervention between tasks
|
|
44
|
+
|
|
45
|
+
## What it does not do
|
|
46
|
+
|
|
47
|
+
- No web UI
|
|
48
|
+
- No SaaS backend
|
|
49
|
+
- No long-term memory system
|
|
50
|
+
- No autonomous "set it and forget it" agents
|
|
51
|
+
|
|
52
|
+
mAIstro is intentionally small and explicit.
|
|
19
53
|
|
|
20
54
|
## Installation
|
|
21
55
|
|
|
56
|
+
Install globally:
|
|
57
|
+
|
|
22
58
|
```bash
|
|
23
59
|
npm install -g maistro
|
|
24
60
|
```
|
|
25
61
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm update -g maistro
|
|
30
|
-
```
|
|
62
|
+
## Basic usage
|
|
31
63
|
|
|
32
|
-
|
|
64
|
+
Run mAIstro from your project directory:
|
|
33
65
|
|
|
34
66
|
```bash
|
|
35
67
|
maistro
|
|
36
68
|
```
|
|
37
69
|
|
|
38
|
-
|
|
70
|
+
Typical flow:
|
|
39
71
|
|
|
40
|
-
1.
|
|
41
|
-
2.
|
|
42
|
-
3.
|
|
43
|
-
4.
|
|
44
|
-
5.
|
|
72
|
+
1. Describe your goal or project
|
|
73
|
+
2. mAIstro analyzes and breaks it into bounded tasks
|
|
74
|
+
3. Review and refine the plan
|
|
75
|
+
4. Tasks execute one at a time
|
|
76
|
+
5. Each step sees only the context it needs
|
|
77
|
+
6. Requirements stay visible throughout execution
|
|
45
78
|
|
|
46
|
-
##
|
|
79
|
+
## Example use cases
|
|
47
80
|
|
|
48
|
-
|
|
81
|
+
- Large refactors with strict constraints
|
|
82
|
+
- Multi-step feature implementation
|
|
83
|
+
- Codebase analysis → planning → execution
|
|
84
|
+
- Any workflow where losing context breaks correctness
|
|
49
85
|
|
|
50
|
-
|
|
51
|
-
|---------|--------|
|
|
52
|
-
| `run` | Start or resume execution |
|
|
53
|
-
| `plan` | View and modify the task plan |
|
|
54
|
-
| `retry` | Retry a failed task |
|
|
55
|
-
| `claude` | Open Claude Code in a new terminal |
|
|
56
|
-
| `exit` | Exit maistro |
|
|
86
|
+
## Design principles
|
|
57
87
|
|
|
58
|
-
|
|
88
|
+
- Context discipline over giant prompts
|
|
89
|
+
- Explicit sequencing over autonomy
|
|
90
|
+
- CLI-first and inspectable
|
|
91
|
+
- Human-in-the-loop by default
|
|
59
92
|
|
|
60
|
-
|
|
61
|
-
|-----|--------|
|
|
62
|
-
| `Enter` | Submit input |
|
|
63
|
-
| `Shift+Enter` | New line in input |
|
|
64
|
-
| `Up/Down` | Navigate input history |
|
|
65
|
-
| `Escape` (2x) | Clear input |
|
|
93
|
+
## Who this is for
|
|
66
94
|
|
|
67
|
-
|
|
95
|
+
- Developers already using Claude Code
|
|
96
|
+
- People hitting context limits on larger tasks
|
|
97
|
+
- Anyone tired of repeating requirements in every prompt
|
|
68
98
|
|
|
69
|
-
|
|
70
|
-
- `state.json` - Task list and progress
|
|
71
|
-
- `logs/` - Execution logs per task
|
|
72
|
-
- `images/` - Attached images (if any)
|
|
99
|
+
If you want a fully autonomous agent with hidden state, this is probably not it.
|
|
73
100
|
|
|
74
|
-
|
|
101
|
+
## Status
|
|
75
102
|
|
|
103
|
+
- actively used
|
|
104
|
+
- lightly tested
|
|
105
|
+
- evolving through real-world workflows
|
|
76
106
|
|
|
77
|
-
|
|
107
|
+
Expect rough edges.
|
|
78
108
|
|
|
79
|
-
|
|
109
|
+
## Claude Code
|
|
80
110
|
|
|
81
|
-
|
|
111
|
+
### How Integration Works
|
|
112
|
+
|
|
113
|
+
mAIstro uses Claude Code CLI to execute each task on your plan. Tasks run non-interactively with:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
82
116
|
claude --dangerously-skip-permissions --chrome
|
|
83
117
|
```
|
|
84
118
|
|
|
85
119
|
- `--dangerously-skip-permissions` - Allows autonomous execution without confirmation prompts
|
|
86
120
|
- `--chrome` - Enables browser integration for real-time feedback via Chrome extension
|
|
87
121
|
|
|
88
|
-
> **Warning:** Once execution starts,
|
|
122
|
+
> **Warning:** Once execution starts, mAIstro runs autonomously without confirmation prompts. It will attempt to complete all tasks on the plan without asking for permission. Use responsibly and preferably in sandboxed environments (containers, VMs, or isolated directories).
|
|
89
123
|
|
|
90
124
|
### Claude Code Chrome Extension (Recommended)
|
|
91
125
|
|
|
92
126
|
For the fastest feedback loop, install the Chrome extension:
|
|
93
127
|
|
|
94
|
-
|
|
128
|
+
[Claude Code Chrome Extension](https://chromewebstore.google.com/detail/claude-code/oadoelpjdnpbmmdfgpmfnncjgihofjgc)
|
|
95
129
|
|
|
96
130
|
This enables real-time browser automation and visual feedback during task execution.
|
|
97
131
|
|
|
132
|
+
## Feedback
|
|
133
|
+
|
|
134
|
+
This tool exists to answer one question:
|
|
98
135
|
|
|
99
|
-
|
|
136
|
+
> Does explicit orchestration help manage Claude Code context for larger tasks?
|
|
100
137
|
|
|
101
|
-
|
|
138
|
+
If you try it and decide the answer is "no", that feedback is just as valuable.
|
|
102
139
|
|
|
103
|
-
|
|
140
|
+
Issues, ideas, and criticism are welcome. Send them my way at contact@dreamteam-mobile.com
|
|
104
141
|
|
|
105
142
|
## License
|
|
106
143
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Key Validator - validates user-provided API keys against their respective services
|
|
3
|
+
*
|
|
4
|
+
* Design principles:
|
|
5
|
+
* - Never block the user: network/timeout errors result in skipped validation, not failure
|
|
6
|
+
* - Lightweight: uses minimal read-only endpoints
|
|
7
|
+
* - Graceful: unknown key types are skipped with informative messages
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Result of validating a single API key
|
|
11
|
+
*/
|
|
12
|
+
export interface ValidationResult {
|
|
13
|
+
/** Whether the key is valid (true if valid or skipped) */
|
|
14
|
+
valid: boolean;
|
|
15
|
+
/** Human-readable status message */
|
|
16
|
+
message: string;
|
|
17
|
+
/** Error details if validation failed */
|
|
18
|
+
error?: string;
|
|
19
|
+
/** Whether validation was skipped (timeout, network error, unknown key type) */
|
|
20
|
+
skipped?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Aggregated validation results
|
|
24
|
+
*/
|
|
25
|
+
export interface ValidationSummary {
|
|
26
|
+
/** All validation results keyed by env var name */
|
|
27
|
+
results: Record<string, ValidationResult>;
|
|
28
|
+
/** Number of keys that passed validation */
|
|
29
|
+
passedCount: number;
|
|
30
|
+
/** Number of keys that failed validation */
|
|
31
|
+
failedCount: number;
|
|
32
|
+
/** Number of keys where validation was skipped */
|
|
33
|
+
skippedCount: number;
|
|
34
|
+
/** Whether all validated keys passed (excludes skipped) */
|
|
35
|
+
allPassed: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for validateApiKeys function
|
|
39
|
+
*/
|
|
40
|
+
export interface ValidateApiKeysOptions {
|
|
41
|
+
/** Timeout for each validation request in ms (default: 5000) */
|
|
42
|
+
timeout?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validator function type for a specific service
|
|
46
|
+
*/
|
|
47
|
+
type KeyValidator = (value: string, timeout: number) => Promise<ValidationResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Validate multiple API keys in parallel
|
|
50
|
+
*
|
|
51
|
+
* @param values - Record of env var names to their values
|
|
52
|
+
* @param options - Validation options
|
|
53
|
+
* @returns Summary of validation results
|
|
54
|
+
*/
|
|
55
|
+
export declare function validateApiKeys(values: Record<string, string>, options?: ValidateApiKeysOptions): Promise<ValidationSummary>;
|
|
56
|
+
export declare const _validators: Record<string, KeyValidator>;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=apiKeyValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKeyValidator.d.ts","sourceRoot":"","sources":["../src/apiKeyValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,KAAK,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1C,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AA2LlF;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CA+C5B;AAGD,eAAO,MAAM,WAAW,8BAAa,CAAC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Key Validator - validates user-provided API keys against their respective services
|
|
3
|
+
*
|
|
4
|
+
* Design principles:
|
|
5
|
+
* - Never block the user: network/timeout errors result in skipped validation, not failure
|
|
6
|
+
* - Lightweight: uses minimal read-only endpoints
|
|
7
|
+
* - Graceful: unknown key types are skipped with informative messages
|
|
8
|
+
*/
|
|
9
|
+
// Default timeout for validation requests
|
|
10
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
11
|
+
/**
|
|
12
|
+
* Validate an Anthropic API key
|
|
13
|
+
* Endpoint: GET https://api.anthropic.com/v1/models
|
|
14
|
+
*/
|
|
15
|
+
async function validateAnthropicKey(key, timeout) {
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch('https://api.anthropic.com/v1/models', {
|
|
18
|
+
method: 'GET',
|
|
19
|
+
headers: {
|
|
20
|
+
'x-api-key': key,
|
|
21
|
+
'anthropic-version': '2023-06-01',
|
|
22
|
+
},
|
|
23
|
+
signal: AbortSignal.timeout(timeout),
|
|
24
|
+
});
|
|
25
|
+
if (response.ok) {
|
|
26
|
+
return { valid: true, message: 'API key is valid' };
|
|
27
|
+
}
|
|
28
|
+
if (response.status === 401) {
|
|
29
|
+
return { valid: false, message: 'Invalid API key', error: 'Authentication failed' };
|
|
30
|
+
}
|
|
31
|
+
return { valid: false, message: 'Validation failed', error: `HTTP ${response.status}` };
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return handleFetchError(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validate an OpenAI API key
|
|
39
|
+
* Endpoint: GET https://api.openai.com/v1/models
|
|
40
|
+
*/
|
|
41
|
+
async function validateOpenAIKey(key, timeout) {
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch('https://api.openai.com/v1/models', {
|
|
44
|
+
method: 'GET',
|
|
45
|
+
headers: {
|
|
46
|
+
Authorization: `Bearer ${key}`,
|
|
47
|
+
},
|
|
48
|
+
signal: AbortSignal.timeout(timeout),
|
|
49
|
+
});
|
|
50
|
+
if (response.ok) {
|
|
51
|
+
return { valid: true, message: 'API key is valid' };
|
|
52
|
+
}
|
|
53
|
+
if (response.status === 401) {
|
|
54
|
+
return { valid: false, message: 'Invalid API key', error: 'Authentication failed' };
|
|
55
|
+
}
|
|
56
|
+
return { valid: false, message: 'Validation failed', error: `HTTP ${response.status}` };
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return handleFetchError(error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate a GitHub token
|
|
64
|
+
* Endpoint: GET https://api.github.com/user
|
|
65
|
+
*/
|
|
66
|
+
async function validateGitHubToken(token, timeout) {
|
|
67
|
+
try {
|
|
68
|
+
const response = await fetch('https://api.github.com/user', {
|
|
69
|
+
method: 'GET',
|
|
70
|
+
headers: {
|
|
71
|
+
Authorization: `Bearer ${token}`,
|
|
72
|
+
Accept: 'application/vnd.github+json',
|
|
73
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
74
|
+
},
|
|
75
|
+
signal: AbortSignal.timeout(timeout),
|
|
76
|
+
});
|
|
77
|
+
if (response.ok) {
|
|
78
|
+
return { valid: true, message: 'Token is valid' };
|
|
79
|
+
}
|
|
80
|
+
if (response.status === 401) {
|
|
81
|
+
return { valid: false, message: 'Invalid token', error: 'Authentication failed' };
|
|
82
|
+
}
|
|
83
|
+
return { valid: false, message: 'Validation failed', error: `HTTP ${response.status}` };
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return handleFetchError(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validate a Stripe API key
|
|
91
|
+
* Endpoint: GET https://api.stripe.com/v1/balance
|
|
92
|
+
*/
|
|
93
|
+
async function validateStripeKey(key, timeout) {
|
|
94
|
+
try {
|
|
95
|
+
const response = await fetch('https://api.stripe.com/v1/balance', {
|
|
96
|
+
method: 'GET',
|
|
97
|
+
headers: {
|
|
98
|
+
Authorization: `Bearer ${key}`,
|
|
99
|
+
},
|
|
100
|
+
signal: AbortSignal.timeout(timeout),
|
|
101
|
+
});
|
|
102
|
+
if (response.ok) {
|
|
103
|
+
return { valid: true, message: 'API key is valid' };
|
|
104
|
+
}
|
|
105
|
+
if (response.status === 401) {
|
|
106
|
+
return { valid: false, message: 'Invalid API key', error: 'Authentication failed' };
|
|
107
|
+
}
|
|
108
|
+
return { valid: false, message: 'Validation failed', error: `HTTP ${response.status}` };
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return handleFetchError(error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Validate a SendGrid API key
|
|
116
|
+
* Endpoint: GET https://api.sendgrid.com/v3/scopes
|
|
117
|
+
*/
|
|
118
|
+
async function validateSendGridKey(key, timeout) {
|
|
119
|
+
try {
|
|
120
|
+
const response = await fetch('https://api.sendgrid.com/v3/scopes', {
|
|
121
|
+
method: 'GET',
|
|
122
|
+
headers: {
|
|
123
|
+
Authorization: `Bearer ${key}`,
|
|
124
|
+
},
|
|
125
|
+
signal: AbortSignal.timeout(timeout),
|
|
126
|
+
});
|
|
127
|
+
if (response.ok) {
|
|
128
|
+
return { valid: true, message: 'API key is valid' };
|
|
129
|
+
}
|
|
130
|
+
if (response.status === 401 || response.status === 403) {
|
|
131
|
+
return { valid: false, message: 'Invalid API key', error: 'Authentication failed' };
|
|
132
|
+
}
|
|
133
|
+
return { valid: false, message: 'Validation failed', error: `HTTP ${response.status}` };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return handleFetchError(error);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Handle fetch errors gracefully - never block the user
|
|
141
|
+
*/
|
|
142
|
+
function handleFetchError(error) {
|
|
143
|
+
if (error instanceof Error) {
|
|
144
|
+
// Timeout errors
|
|
145
|
+
if (error.name === 'AbortError' || error.name === 'TimeoutError') {
|
|
146
|
+
return {
|
|
147
|
+
valid: true,
|
|
148
|
+
skipped: true,
|
|
149
|
+
message: 'Validation timed out - key saved without verification',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// Network errors
|
|
153
|
+
if (error.message.includes('ENOTFOUND') ||
|
|
154
|
+
error.message.includes('network') ||
|
|
155
|
+
error.message.includes('fetch')) {
|
|
156
|
+
return {
|
|
157
|
+
valid: true,
|
|
158
|
+
skipped: true,
|
|
159
|
+
message: 'Network error - key saved without verification',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Unknown errors - don't block the user
|
|
164
|
+
return {
|
|
165
|
+
valid: true,
|
|
166
|
+
skipped: true,
|
|
167
|
+
message: 'Validation error - key saved without verification',
|
|
168
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Registry of validators by env var name
|
|
173
|
+
*/
|
|
174
|
+
const validators = {
|
|
175
|
+
ANTHROPIC_API_KEY: validateAnthropicKey,
|
|
176
|
+
OPENAI_API_KEY: validateOpenAIKey,
|
|
177
|
+
GITHUB_TOKEN: validateGitHubToken,
|
|
178
|
+
GITHUB_ACCESS_TOKEN: validateGitHubToken,
|
|
179
|
+
GH_TOKEN: validateGitHubToken,
|
|
180
|
+
STRIPE_SECRET_KEY: validateStripeKey,
|
|
181
|
+
STRIPE_API_KEY: validateStripeKey,
|
|
182
|
+
SENDGRID_API_KEY: validateSendGridKey,
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Validate multiple API keys in parallel
|
|
186
|
+
*
|
|
187
|
+
* @param values - Record of env var names to their values
|
|
188
|
+
* @param options - Validation options
|
|
189
|
+
* @returns Summary of validation results
|
|
190
|
+
*/
|
|
191
|
+
export async function validateApiKeys(values, options) {
|
|
192
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
|
|
193
|
+
// Run all validations in parallel
|
|
194
|
+
const entries = Object.entries(values);
|
|
195
|
+
const results = {};
|
|
196
|
+
const validationPromises = entries.map(async ([envVar, value]) => {
|
|
197
|
+
const validator = validators[envVar];
|
|
198
|
+
if (!validator) {
|
|
199
|
+
// No validator for this key type - skip
|
|
200
|
+
results[envVar] = {
|
|
201
|
+
valid: true,
|
|
202
|
+
skipped: true,
|
|
203
|
+
message: 'No validator available for this key type',
|
|
204
|
+
};
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
results[envVar] = await validator(value, timeout);
|
|
208
|
+
});
|
|
209
|
+
await Promise.all(validationPromises);
|
|
210
|
+
// Calculate summary
|
|
211
|
+
let passedCount = 0;
|
|
212
|
+
let failedCount = 0;
|
|
213
|
+
let skippedCount = 0;
|
|
214
|
+
for (const result of Object.values(results)) {
|
|
215
|
+
if (result.skipped) {
|
|
216
|
+
skippedCount++;
|
|
217
|
+
}
|
|
218
|
+
else if (result.valid) {
|
|
219
|
+
passedCount++;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
failedCount++;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
results,
|
|
227
|
+
passedCount,
|
|
228
|
+
failedCount,
|
|
229
|
+
skippedCount,
|
|
230
|
+
allPassed: failedCount === 0,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
// Export validators for testing
|
|
234
|
+
export const _validators = validators;
|
|
235
|
+
//# sourceMappingURL=apiKeyValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKeyValidator.js","sourceRoot":"","sources":["../src/apiKeyValidator.ts"],"names":[],"mappings":"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"}
|
package/dist/app.d.ts
CHANGED
|
@@ -23,10 +23,15 @@ export declare class MaistroApp {
|
|
|
23
23
|
* Prompts user to update if a new version is available
|
|
24
24
|
*/
|
|
25
25
|
private handleUpdateCheck;
|
|
26
|
+
/**
|
|
27
|
+
* Restart maistro after update by spawning a new process and exiting
|
|
28
|
+
*/
|
|
29
|
+
private restartAfterUpdate;
|
|
26
30
|
/**
|
|
27
31
|
* Run doctor check - verify Claude Code CLI installation and authentication
|
|
32
|
+
* @param fullCheck - If true, always run interaction test (step 3). If false, skip if already passed once.
|
|
28
33
|
*/
|
|
29
|
-
handleDoctor(): Promise<boolean>;
|
|
34
|
+
handleDoctor(fullCheck?: boolean): Promise<boolean>;
|
|
30
35
|
/**
|
|
31
36
|
* Handle attaching an image
|
|
32
37
|
* Supports: /attach <path> [as <name>] or /attach <url> [as <name>]
|
|
@@ -79,9 +84,15 @@ export declare class MaistroApp {
|
|
|
79
84
|
private askDiscoveryQuestion;
|
|
80
85
|
/**
|
|
81
86
|
* Detect and collect missing external dependencies
|
|
87
|
+
* @param goal - The user's goal text to detect mentioned dependencies
|
|
82
88
|
* Returns the collected values or null if user cancelled
|
|
83
89
|
*/
|
|
84
90
|
private handleDependencyDetection;
|
|
91
|
+
/**
|
|
92
|
+
* Validate collected API keys against their respective services
|
|
93
|
+
* Returns the validated values (possibly updated after retries), or 'cancel' if user cancelled
|
|
94
|
+
*/
|
|
95
|
+
private validateCollectedKeys;
|
|
85
96
|
/**
|
|
86
97
|
* Save collected dependency values to .env file
|
|
87
98
|
*/
|
|
@@ -187,7 +198,7 @@ export declare class MaistroApp {
|
|
|
187
198
|
private interactivePlanReview;
|
|
188
199
|
private displayTasks;
|
|
189
200
|
/**
|
|
190
|
-
* Handle clear plan command - clears goal
|
|
201
|
+
* Handle clear plan command - clears goal, all tasks, and logs
|
|
191
202
|
* Returns true if plan was cleared and should return to init flow
|
|
192
203
|
*/
|
|
193
204
|
private handleClearPlan;
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAiOA,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,cAAc,CAA+B;gBAEzC,WAAW,GAAE,MAAY;IAsBrC,OAAO,CAAC,eAAe;IASvB;;;OAGG;YACW,qBAAqB;IA+CnC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+F5B;;;OAGG;YACW,iBAAiB;IA8D/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;;OAGG;IACG,YAAY,CAAC,SAAS,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqFtD;;;OAGG;YACW,iBAAiB;IAwD/B;;OAEG;YACW,sBAAsB;IAsCpC;;;OAGG;YACW,iBAAiB;IAoB/B;;;OAGG;YACW,oBAAoB;IAkClC;;OAEG;YACW,qBAAqB;IA4BnC;;OAEG;YACW,gBAAgB;IAoB9B;;;OAGG;YACW,qBAAqB;IAoEnC;;;OAGG;YACW,eAAe;IAwG7B;;;OAGG;YACW,uBAAuB;IAyDrC;;OAEG;YACW,4BAA4B;IAiE1C;;OAEG;YACW,oBAAoB;IA8DlC;;;;OAIG;YACW,yBAAyB;IAgIvC;;;OAGG;YACW,qBAAqB;IAqGnC;;OAEG;YACW,qBAAqB;IAiDnC;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,UAAU;IAQlB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IA0J7B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;OAGG;YACW,YAAY;IAoS1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;YACW,aAAa;IA0lB3B;;;OAGG;YACW,eAAe;IAkN7B;;;OAGG;YACW,iBAAiB;IAgI/B;;OAEG;YACW,cAAc;IAwU5B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,aAAa,CAAS;IAE9B;;OAEG;YACW,gBAAgB;IAkB9B;;OAEG;YACW,gBAAgB;IAe9B;;;OAGG;YACW,WAAW;IAsEzB;;;OAGG;YACW,mBAAmB;IA4BjC;;;OAGG;YACW,cAAc;IAiB5B;;;;OAIG;YACW,6BAA6B;IAwH3C;;;OAGG;YACW,aAAa;IA+B3B;;;;OAIG;YACW,sBAAsB;IA4LpC;;;OAGG;YACW,gBAAgB;IAqF9B;;;;OAIG;YACW,sBAAsB;YAwGtB,UAAU;YAyHV,qBAAqB;IA4fnC,OAAO,CAAC,YAAY;IAiEpB;;;OAGG;YACW,eAAe;IAmD7B;;OAEG;YACW,cAAc;IAsO5B;;OAEG;YACW,oBAAoB;IAwBlC;;OAEG;YACW,eAAe;IAU7B;;OAEG;YACW,wBAAwB;YAsBxB,gBAAgB;IA4B9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsD;IAEpF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAQ/B;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;YAoEhB,SAAS;YAmJT,sBAAsB;CAgbrC"}
|