@moda-ai/cli 1.55.9 → 1.55.11
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/agent-n0ch2j90.js +459 -0
- package/dist/cli-11fevr8y.js +811 -0
- package/dist/{cli-mx9r1689.js → cli-429zt7g4.js} +1 -65
- package/dist/cli-4qe6n8am.js +345 -0
- package/dist/cli-97fnztpy.js +140 -0
- package/dist/{cli-sjc132j8.js → cli-fq7kk77e.js} +18 -1733
- package/dist/cli-fwec3m42.js +946 -0
- package/dist/cli-g7ferymy.js +496 -0
- package/dist/cli-k5qqj2bp.js +70 -0
- package/dist/cli-m16taf4z.js +30 -0
- package/dist/{cli-4af3thx7.js → cli-m857n028.js} +195 -976
- package/dist/{cli-fhfdnvh4.js → cli-n9gexgma.js} +2 -2
- package/dist/{cli-tw8jj190.js → cli-t4jjhn3g.js} +5 -7
- package/dist/cli-tmqd1f0m.js +159 -0
- package/dist/cli.js +1410 -7193
- package/dist/doctor-spvy2zb3.js +23 -0
- package/dist/fix-ax6bbg37.js +1444 -0
- package/dist/{harness-github-actions-73a08nct.js → harness-github-actions-mtksqp3c.js} +7 -2
- package/dist/{harness-yshh2pgj.js → harness-jbqpbp6n.js} +7 -2
- package/dist/{index-f3k9jgrt.js → index-2d0q94sv.js} +35 -36
- package/dist/production-intelligence-1tf98n79.js +1802 -0
- package/dist/profile-commands-f6599bcx.js +481 -0
- package/dist/prompt-source-mcp.js +8 -3
- package/dist/prompts-y3xd9heh.js +40 -0
- package/dist/{provision-parsn3xg.js → provision-cjpsswa9.js} +7 -5
- package/dist/registry-1dvxsekd.js +1201 -0
- package/dist/skills-1k0hbkaf.js +19 -0
- package/dist/sync-by81xqk4.js +54 -0
- package/package.json +6 -7
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +2 -2
- package/hooks/moda-snapshot.sh +0 -41
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
authFetch,
|
|
3
3
|
getCachedLoginContext
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-t4jjhn3g.js";
|
|
5
5
|
import {
|
|
6
6
|
CliAccessError,
|
|
7
7
|
CliInputError,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolveTenantIdFromActiveProfile,
|
|
17
17
|
saveCliConfig,
|
|
18
18
|
writeSecretJsonFile
|
|
19
|
-
} from "./cli-
|
|
19
|
+
} from "./cli-429zt7g4.js";
|
|
20
20
|
|
|
21
21
|
// src/init/tenant.ts
|
|
22
22
|
import { randomUUID } from "node:crypto";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
saveProfileConfig,
|
|
9
9
|
secretFilePathFromRef,
|
|
10
10
|
writeSecretJsonFile
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-429zt7g4.js";
|
|
12
12
|
import {
|
|
13
13
|
__require
|
|
14
14
|
} from "./cli-0v6na3yp.js";
|
|
@@ -157,12 +157,6 @@ function clearAuthSession(options = {}) {
|
|
|
157
157
|
rmSync(tokenPath(options), { force: true });
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
// src/auth.ts
|
|
161
|
-
import { createServer } from "node:http";
|
|
162
|
-
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
163
|
-
import { hostname } from "node:os";
|
|
164
|
-
import { createInterface } from "node:readline";
|
|
165
|
-
|
|
166
160
|
// src/cli-session.ts
|
|
167
161
|
import { request as httpRequest } from "node:http";
|
|
168
162
|
import { request as httpsRequest } from "node:https";
|
|
@@ -270,6 +264,10 @@ async function revokeCliSessionToken(options = {}) {
|
|
|
270
264
|
}
|
|
271
265
|
|
|
272
266
|
// src/auth.ts
|
|
267
|
+
import { createServer } from "node:http";
|
|
268
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
269
|
+
import { hostname } from "node:os";
|
|
270
|
+
import { createInterface } from "node:readline";
|
|
273
271
|
var CALLBACK_PORT = 8432;
|
|
274
272
|
var CALLBACK_PORT_LADDER = [CALLBACK_PORT, 8433, 8434, 8435];
|
|
275
273
|
var DEFAULT_AUTH_TIMEOUT_MS = 600000;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiKeyHeaders
|
|
3
|
+
} from "./cli-m16taf4z.js";
|
|
4
|
+
import {
|
|
5
|
+
recordApiRequest,
|
|
6
|
+
resolveApiKey,
|
|
7
|
+
resolveModaBaseUrl
|
|
8
|
+
} from "./cli-429zt7g4.js";
|
|
9
|
+
|
|
10
|
+
// src/api-client.ts
|
|
11
|
+
var REQUEST_TIMEOUT_MS = 30000;
|
|
12
|
+
var MAX_RETRIES = 3;
|
|
13
|
+
var INITIAL_BACKOFF_MS = 500;
|
|
14
|
+
var NETWORK_RETRY_DELAY_MS = 1000;
|
|
15
|
+
|
|
16
|
+
class ApiError extends Error {
|
|
17
|
+
statusCode;
|
|
18
|
+
responseBody;
|
|
19
|
+
code;
|
|
20
|
+
suggestions;
|
|
21
|
+
readable;
|
|
22
|
+
constructor(message, statusCode, responseBody) {
|
|
23
|
+
const typed = parseTypedErrorBody(responseBody);
|
|
24
|
+
const platform = platformFailure(responseBody);
|
|
25
|
+
const readable = typed?.code === "audit_too_large" || platform !== null;
|
|
26
|
+
super(readable ? `API error (${statusCode}): ${typed?.message ?? platform?.message}` : message);
|
|
27
|
+
this.statusCode = statusCode;
|
|
28
|
+
this.responseBody = responseBody;
|
|
29
|
+
this.name = "ApiError";
|
|
30
|
+
this.code = typed?.code ?? platform?.code;
|
|
31
|
+
this.suggestions = typed?.suggestions;
|
|
32
|
+
this.readable = readable;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function parseTypedErrorBody(body) {
|
|
36
|
+
if (!body.trimStart().startsWith("{"))
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(body);
|
|
40
|
+
if (typeof parsed.code !== "string")
|
|
41
|
+
return null;
|
|
42
|
+
const suggestions = Array.isArray(parsed.suggestions) ? parsed.suggestions.filter((s) => typeof s === "string") : undefined;
|
|
43
|
+
return {
|
|
44
|
+
code: parsed.code,
|
|
45
|
+
message: typeof parsed.message === "string" ? parsed.message : undefined,
|
|
46
|
+
suggestions
|
|
47
|
+
};
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var DETERMINISTIC_PLATFORM_FAILURES = [
|
|
53
|
+
"FUNCTION_INVOCATION_FAILED",
|
|
54
|
+
"FUNCTION_RESPONSE_PAYLOAD_TOO_LARGE"
|
|
55
|
+
];
|
|
56
|
+
function platformFailure(body) {
|
|
57
|
+
const code = DETERMINISTIC_PLATFORM_FAILURES.find((c) => body.includes(c));
|
|
58
|
+
if (!code)
|
|
59
|
+
return null;
|
|
60
|
+
const requestId = /\b([a-z]{3}\d::[A-Za-z0-9:-]+)/.exec(body)?.[1];
|
|
61
|
+
const cause = code === "FUNCTION_RESPONSE_PAYLOAD_TOO_LARGE" ? "the response was larger than the hosting platform allows" : "the server function crashed (typically out of memory or an oversized response)";
|
|
62
|
+
return {
|
|
63
|
+
code,
|
|
64
|
+
message: `The Moda API could not complete this request: ${cause} [${code}` + `${requestId ? `, request ${requestId}` : ""}]. Retrying the same request will fail the same way; ` + "narrow it (a smaller --limit, a single trace, or fewer results) and report it with `moda feedback` if it persists."
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function isRetryableResponse(status, body) {
|
|
68
|
+
if (!isRetryable(status))
|
|
69
|
+
return false;
|
|
70
|
+
return platformFailure(body) === null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
class NetworkError extends Error {
|
|
74
|
+
constructor(message) {
|
|
75
|
+
super(message);
|
|
76
|
+
this.name = "NetworkError";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function networkErrorMessage(error, url) {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
const cause = error instanceof Error ? error.cause : undefined;
|
|
82
|
+
const code = typeof cause?.code === "string" ? `: ${cause.code}` : "";
|
|
83
|
+
return `Network error: ${message} (could not reach ${url.split("?")[0]}${code})`;
|
|
84
|
+
}
|
|
85
|
+
function isRetryable(status) {
|
|
86
|
+
return status === 429 || status >= 500;
|
|
87
|
+
}
|
|
88
|
+
async function callDataAPI(endpoint, init = { method: "GET" }, requestOptions = {}) {
|
|
89
|
+
const url = `${resolveModaBaseUrl()}/api/v1/data${endpoint}`;
|
|
90
|
+
return callModaAPI(url, init, {}, requestOptions);
|
|
91
|
+
}
|
|
92
|
+
async function callControlAPI(endpoint, options = {}, profileOptions = {}, requestOptions = {}) {
|
|
93
|
+
const url = `${resolveModaBaseUrl(profileOptions)}/api${endpoint}`;
|
|
94
|
+
return callModaAPI(url, options, profileOptions, requestOptions);
|
|
95
|
+
}
|
|
96
|
+
async function callModaAPI(url, options, profileOptions = {}, requestOptions = {}) {
|
|
97
|
+
const timeoutMs = requestOptions.timeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
98
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
99
|
+
const maxRetries = requestOptions.retries ?? (method === "GET" || method === "HEAD" ? MAX_RETRIES : 0);
|
|
100
|
+
const initialNetworkRetryBudget = requestOptions.retryOnceOnNetworkError ? 1 : 0;
|
|
101
|
+
let networkRetryBudget = initialNetworkRetryBudget;
|
|
102
|
+
let connectionClose = false;
|
|
103
|
+
const maxAttempts = maxRetries + initialNetworkRetryBudget + 1;
|
|
104
|
+
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
105
|
+
if (attempt > 0) {
|
|
106
|
+
const backoff = connectionClose ? requestOptions.networkRetryDelayMs ?? NETWORK_RETRY_DELAY_MS : INITIAL_BACKOFF_MS * Math.pow(2, attempt - 1);
|
|
107
|
+
await new Promise((resolve) => setTimeout(resolve, backoff));
|
|
108
|
+
}
|
|
109
|
+
const controller = new AbortController;
|
|
110
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
111
|
+
try {
|
|
112
|
+
recordApiRequest();
|
|
113
|
+
const response = await fetch(url, {
|
|
114
|
+
...options,
|
|
115
|
+
headers: {
|
|
116
|
+
...apiKeyHeaders(resolveApiKey(profileOptions) ?? "", profileOptions, url),
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
...options.headers ?? {},
|
|
119
|
+
...connectionClose ? { Connection: "close" } : {}
|
|
120
|
+
},
|
|
121
|
+
signal: controller.signal
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
const errorText = await response.text();
|
|
125
|
+
const error = new ApiError(`API error (${response.status}): ${errorText}`, response.status, errorText);
|
|
126
|
+
if (isRetryableResponse(response.status, errorText) && attempt < maxRetries) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
if (response.status === 204)
|
|
132
|
+
return null;
|
|
133
|
+
if (typeof response.text !== "function")
|
|
134
|
+
return response.json();
|
|
135
|
+
const text = await response.text();
|
|
136
|
+
return text.trim() === "" ? null : JSON.parse(text);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (error instanceof ApiError)
|
|
139
|
+
throw error;
|
|
140
|
+
const isAbort = error instanceof DOMException && error.name === "AbortError";
|
|
141
|
+
const wrapped = isAbort ? new Error(`Request timed out after ${timeoutMs}ms: ${url}`) : new NetworkError(networkErrorMessage(error, url));
|
|
142
|
+
if (attempt < maxRetries) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (!isAbort && networkRetryBudget > 0) {
|
|
146
|
+
networkRetryBudget -= 1;
|
|
147
|
+
connectionClose = true;
|
|
148
|
+
requestOptions.onNetworkRetry?.();
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
throw wrapped;
|
|
152
|
+
} finally {
|
|
153
|
+
clearTimeout(timeout);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
throw new NetworkError(`Request retries exhausted: ${url}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { ApiError, callDataAPI, callControlAPI };
|