@simonfestl/husky-cli 1.25.3 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/auth.js +9 -47
- package/dist/commands/business.d.ts +2 -0
- package/dist/commands/business.js +865 -0
- package/dist/commands/config.js +33 -45
- package/dist/commands/interactive/business.js +3 -0
- package/dist/commands/interactive/infra.js +3 -0
- package/dist/commands/interactive/pr.js +5 -0
- package/dist/commands/interactive/tasks.js +5 -0
- package/dist/commands/interactive/vm-sessions.js +9 -0
- package/dist/commands/task.js +90 -293
- package/dist/index.js +2 -0
- package/dist/lib/worker.d.ts +3 -3
- package/dist/lib/worker.js +37 -39
- package/package.json +3 -1
package/dist/commands/auth.js
CHANGED
|
@@ -1,50 +1,11 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { getConfig, setSessionConfig, clearSessionConfig, getSessionConfig, fetchAndCacheRole } from "./config.js";
|
|
3
3
|
import { getPermissions, clearPermissionsCache, getCacheStatus, hasPermission, canAccessKnowledgeBase } from "../lib/permissions-cache.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getApiClient } from "../lib/api-client.js";
|
|
5
5
|
const API_KEY_ROLES = [
|
|
6
6
|
"admin", "supervisor", "worker", "reviewer", "support",
|
|
7
7
|
"purchasing", "ops", "e2e_agent", "pr_agent"
|
|
8
8
|
];
|
|
9
|
-
/**
|
|
10
|
-
* Sanitize error messages to prevent sensitive data leakage.
|
|
11
|
-
* Truncates long messages and removes potential secrets.
|
|
12
|
-
*/
|
|
13
|
-
function sanitizeErrorMessage(message, maxLength = 200) {
|
|
14
|
-
if (!message)
|
|
15
|
-
return "Unknown error";
|
|
16
|
-
// Remove potential secrets (patterns like API keys, tokens, etc.)
|
|
17
|
-
let sanitized = message
|
|
18
|
-
.replace(/[a-zA-Z0-9_-]{32,}/g, "[REDACTED]") // Long alphanumeric strings
|
|
19
|
-
.replace(/Bearer\s+[^\s]+/gi, "Bearer [REDACTED]") // Bearer tokens
|
|
20
|
-
.replace(/key[=:]\s*[^\s,}]+/gi, "key=[REDACTED]"); // key=value patterns
|
|
21
|
-
// Truncate if too long
|
|
22
|
-
if (sanitized.length > maxLength) {
|
|
23
|
-
sanitized = sanitized.substring(0, maxLength) + "...";
|
|
24
|
-
}
|
|
25
|
-
return sanitized;
|
|
26
|
-
}
|
|
27
|
-
async function apiRequest(path, options = {}) {
|
|
28
|
-
const config = getConfig();
|
|
29
|
-
if (!config.apiUrl || !config.apiKey) {
|
|
30
|
-
throw new Error("API not configured. Run: husky config set api-url <url> && husky config set api-key <key>");
|
|
31
|
-
}
|
|
32
|
-
const url = new URL(path, config.apiUrl);
|
|
33
|
-
const res = await fetch(url.toString(), {
|
|
34
|
-
method: options.method || "GET",
|
|
35
|
-
headers: {
|
|
36
|
-
"x-api-key": config.apiKey,
|
|
37
|
-
"Content-Type": "application/json",
|
|
38
|
-
},
|
|
39
|
-
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
40
|
-
});
|
|
41
|
-
if (!res.ok) {
|
|
42
|
-
const error = await res.json().catch(() => ({ error: res.statusText }));
|
|
43
|
-
const rawMessage = error.message || error.error || `HTTP ${res.status}`;
|
|
44
|
-
throw new Error(sanitizeErrorMessage(rawMessage));
|
|
45
|
-
}
|
|
46
|
-
return res.json();
|
|
47
|
-
}
|
|
48
9
|
export const authCommand = new Command("auth")
|
|
49
10
|
.description("Manage API keys and authentication");
|
|
50
11
|
authCommand
|
|
@@ -54,8 +15,9 @@ authCommand
|
|
|
54
15
|
.option("--json", "Output as JSON")
|
|
55
16
|
.action(async (options) => {
|
|
56
17
|
try {
|
|
18
|
+
const api = getApiClient();
|
|
57
19
|
const query = options.includeRevoked ? "?includeRevoked=true" : "";
|
|
58
|
-
const data = await
|
|
20
|
+
const data = await api.get(`/api/auth/keys${query}`);
|
|
59
21
|
if (options.json) {
|
|
60
22
|
console.log(JSON.stringify(data.keys, null, 2));
|
|
61
23
|
return;
|
|
@@ -111,10 +73,8 @@ authCommand
|
|
|
111
73
|
}
|
|
112
74
|
body.expiresInDays = days;
|
|
113
75
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
body,
|
|
117
|
-
});
|
|
76
|
+
const api = getApiClient();
|
|
77
|
+
const result = await api.post("/api/auth/keys", body);
|
|
118
78
|
if (options.json) {
|
|
119
79
|
console.log(JSON.stringify(result, null, 2));
|
|
120
80
|
return;
|
|
@@ -146,7 +106,8 @@ authCommand
|
|
|
146
106
|
.option("--json", "Output as JSON")
|
|
147
107
|
.action(async (id, options) => {
|
|
148
108
|
try {
|
|
149
|
-
const
|
|
109
|
+
const api = getApiClient();
|
|
110
|
+
const result = await api.delete(`/api/auth/keys/${id}`);
|
|
150
111
|
if (options.json) {
|
|
151
112
|
console.log(JSON.stringify(result, null, 2));
|
|
152
113
|
return;
|
|
@@ -165,7 +126,8 @@ authCommand
|
|
|
165
126
|
.option("--json", "Output as JSON")
|
|
166
127
|
.action(async (options) => {
|
|
167
128
|
try {
|
|
168
|
-
const
|
|
129
|
+
const api = getApiClient();
|
|
130
|
+
const data = await api.get("/api/auth/whoami");
|
|
169
131
|
if (options.json) {
|
|
170
132
|
console.log(JSON.stringify(data, null, 2));
|
|
171
133
|
return;
|