aemeathcli 1.0.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/README.md +607 -0
- package/dist/App-P4MYD4QY.js +2719 -0
- package/dist/App-P4MYD4QY.js.map +1 -0
- package/dist/api-key-fallback-YQQBOQIL.js +11 -0
- package/dist/api-key-fallback-YQQBOQIL.js.map +1 -0
- package/dist/chunk-4IJD72YB.js +184 -0
- package/dist/chunk-4IJD72YB.js.map +1 -0
- package/dist/chunk-6PDJ45T4.js +325 -0
- package/dist/chunk-6PDJ45T4.js.map +1 -0
- package/dist/chunk-CARHU3DO.js +562 -0
- package/dist/chunk-CARHU3DO.js.map +1 -0
- package/dist/chunk-CGEV3ARR.js +80 -0
- package/dist/chunk-CGEV3ARR.js.map +1 -0
- package/dist/chunk-CS5X3BWX.js +27 -0
- package/dist/chunk-CS5X3BWX.js.map +1 -0
- package/dist/chunk-CYQNBB25.js +44 -0
- package/dist/chunk-CYQNBB25.js.map +1 -0
- package/dist/chunk-DAHGLHNR.js +657 -0
- package/dist/chunk-DAHGLHNR.js.map +1 -0
- package/dist/chunk-H66O5Z2V.js +305 -0
- package/dist/chunk-H66O5Z2V.js.map +1 -0
- package/dist/chunk-HCIHOHLX.js +322 -0
- package/dist/chunk-HCIHOHLX.js.map +1 -0
- package/dist/chunk-HMJRPNPZ.js +1031 -0
- package/dist/chunk-HMJRPNPZ.js.map +1 -0
- package/dist/chunk-I5PZ4JTS.js +119 -0
- package/dist/chunk-I5PZ4JTS.js.map +1 -0
- package/dist/chunk-IYW62KKR.js +255 -0
- package/dist/chunk-IYW62KKR.js.map +1 -0
- package/dist/chunk-JAXXTYID.js +51 -0
- package/dist/chunk-JAXXTYID.js.map +1 -0
- package/dist/chunk-LSOYPSAT.js +183 -0
- package/dist/chunk-LSOYPSAT.js.map +1 -0
- package/dist/chunk-MFBHNWGV.js +416 -0
- package/dist/chunk-MFBHNWGV.js.map +1 -0
- package/dist/chunk-MXZSI3AY.js +311 -0
- package/dist/chunk-MXZSI3AY.js.map +1 -0
- package/dist/chunk-NBR3GHMT.js +72 -0
- package/dist/chunk-NBR3GHMT.js.map +1 -0
- package/dist/chunk-O3ZF22SW.js +246 -0
- package/dist/chunk-O3ZF22SW.js.map +1 -0
- package/dist/chunk-SUSJPZU2.js +181 -0
- package/dist/chunk-SUSJPZU2.js.map +1 -0
- package/dist/chunk-TEVZS4FA.js +310 -0
- package/dist/chunk-TEVZS4FA.js.map +1 -0
- package/dist/chunk-UY2SYSEZ.js +211 -0
- package/dist/chunk-UY2SYSEZ.js.map +1 -0
- package/dist/chunk-WAHVZH7V.js +260 -0
- package/dist/chunk-WAHVZH7V.js.map +1 -0
- package/dist/chunk-WPP3PEDE.js +234 -0
- package/dist/chunk-WPP3PEDE.js.map +1 -0
- package/dist/chunk-Y5XVD2CD.js +1610 -0
- package/dist/chunk-Y5XVD2CD.js.map +1 -0
- package/dist/chunk-YL5XFHR3.js +56 -0
- package/dist/chunk-YL5XFHR3.js.map +1 -0
- package/dist/chunk-ZGOHARPV.js +122 -0
- package/dist/chunk-ZGOHARPV.js.map +1 -0
- package/dist/claude-adapter-QMLFMSP3.js +6 -0
- package/dist/claude-adapter-QMLFMSP3.js.map +1 -0
- package/dist/claude-login-5WELXPKT.js +324 -0
- package/dist/claude-login-5WELXPKT.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +703 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-login-7HHLJHBF.js +164 -0
- package/dist/codex-login-7HHLJHBF.js.map +1 -0
- package/dist/config-store-W6FBCQAQ.js +6 -0
- package/dist/config-store-W6FBCQAQ.js.map +1 -0
- package/dist/executor-6RIKIGXK.js +4 -0
- package/dist/executor-6RIKIGXK.js.map +1 -0
- package/dist/gemini-adapter-6JIHZ7WI.js +6 -0
- package/dist/gemini-adapter-6JIHZ7WI.js.map +1 -0
- package/dist/gemini-login-ZZLYC3J6.js +346 -0
- package/dist/gemini-login-ZZLYC3J6.js.map +1 -0
- package/dist/index.d.ts +2210 -0
- package/dist/index.js +1419 -0
- package/dist/index.js.map +1 -0
- package/dist/kimi-adapter-JN4HFFHU.js +6 -0
- package/dist/kimi-adapter-JN4HFFHU.js.map +1 -0
- package/dist/kimi-login-CZPS63NK.js +149 -0
- package/dist/kimi-login-CZPS63NK.js.map +1 -0
- package/dist/native-cli-adapters-OLW3XX57.js +6 -0
- package/dist/native-cli-adapters-OLW3XX57.js.map +1 -0
- package/dist/ollama-adapter-OJQ3FKWK.js +6 -0
- package/dist/ollama-adapter-OJQ3FKWK.js.map +1 -0
- package/dist/openai-adapter-XU46EN7B.js +6 -0
- package/dist/openai-adapter-XU46EN7B.js.map +1 -0
- package/dist/registry-4KD24ZC3.js +6 -0
- package/dist/registry-4KD24ZC3.js.map +1 -0
- package/dist/registry-H7B3AHPQ.js +5 -0
- package/dist/registry-H7B3AHPQ.js.map +1 -0
- package/dist/server-manager-PTGBHCLS.js +5 -0
- package/dist/server-manager-PTGBHCLS.js.map +1 -0
- package/dist/session-manager-ECEEACGY.js +12 -0
- package/dist/session-manager-ECEEACGY.js.map +1 -0
- package/dist/team-manager-HC4XGCFY.js +11 -0
- package/dist/team-manager-HC4XGCFY.js.map +1 -0
- package/dist/tmux-manager-GPYZ3WQH.js +6 -0
- package/dist/tmux-manager-GPYZ3WQH.js.map +1 -0
- package/dist/tools-TSMXMHIF.js +6 -0
- package/dist/tools-TSMXMHIF.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SUPPORTED_MODELS } from './chunk-HCIHOHLX.js';
|
|
2
|
+
import { logger } from './chunk-JAXXTYID.js';
|
|
3
|
+
|
|
4
|
+
// src/utils/tokenCounter.ts
|
|
5
|
+
function estimateTokenCount(text) {
|
|
6
|
+
return Math.ceil(text.length / 4);
|
|
7
|
+
}
|
|
8
|
+
function calculateCost(modelId, inputTokens, outputTokens) {
|
|
9
|
+
const modelInfo = SUPPORTED_MODELS[modelId];
|
|
10
|
+
if (!modelInfo) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
const inputCost = inputTokens / 1e6 * modelInfo.inputPricePerMToken;
|
|
14
|
+
const outputCost = outputTokens / 1e6 * modelInfo.outputPricePerMToken;
|
|
15
|
+
return Math.round((inputCost + outputCost) * 1e6) / 1e6;
|
|
16
|
+
}
|
|
17
|
+
function createTokenUsage(modelId, inputTokens, outputTokens) {
|
|
18
|
+
return {
|
|
19
|
+
inputTokens,
|
|
20
|
+
outputTokens,
|
|
21
|
+
totalTokens: inputTokens + outputTokens,
|
|
22
|
+
costUsd: calculateCost(modelId, inputTokens, outputTokens)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function formatCost(costUsd) {
|
|
26
|
+
if (costUsd < 0.01) {
|
|
27
|
+
return `$${costUsd.toFixed(4)}`;
|
|
28
|
+
}
|
|
29
|
+
return `$${costUsd.toFixed(2)}`;
|
|
30
|
+
}
|
|
31
|
+
function formatTokenCount(count) {
|
|
32
|
+
if (count < 1e3) {
|
|
33
|
+
return String(count);
|
|
34
|
+
}
|
|
35
|
+
if (count < 1e6) {
|
|
36
|
+
return `${(count / 1e3).toFixed(1)}K`;
|
|
37
|
+
}
|
|
38
|
+
return `${(count / 1e6).toFixed(1)}M`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/utils/retry.ts
|
|
42
|
+
var DEFAULT_RETRY_OPTIONS = {
|
|
43
|
+
maxRetries: 3,
|
|
44
|
+
baseDelayMs: 1e3,
|
|
45
|
+
maxDelayMs: 3e4
|
|
46
|
+
};
|
|
47
|
+
async function withRetry(fn, options) {
|
|
48
|
+
const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };
|
|
49
|
+
let lastError;
|
|
50
|
+
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
|
|
51
|
+
try {
|
|
52
|
+
return await fn();
|
|
53
|
+
} catch (error) {
|
|
54
|
+
lastError = error;
|
|
55
|
+
if (attempt === opts.maxRetries) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
if (opts.shouldRetry && !opts.shouldRetry(error, attempt)) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
const delay = Math.min(
|
|
62
|
+
opts.baseDelayMs * Math.pow(2, attempt) + Math.random() * 1e3,
|
|
63
|
+
opts.maxDelayMs
|
|
64
|
+
);
|
|
65
|
+
logger.warn(
|
|
66
|
+
{ attempt: attempt + 1, maxRetries: opts.maxRetries, delayMs: delay },
|
|
67
|
+
"Retrying after error"
|
|
68
|
+
);
|
|
69
|
+
await sleep(delay);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw lastError;
|
|
73
|
+
}
|
|
74
|
+
function sleep(ms) {
|
|
75
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { createTokenUsage, estimateTokenCount, formatCost, formatTokenCount, sleep, withRetry };
|
|
79
|
+
//# sourceMappingURL=chunk-CGEV3ARR.js.map
|
|
80
|
+
//# sourceMappingURL=chunk-CGEV3ARR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/tokenCounter.ts","../src/utils/retry.ts"],"names":[],"mappings":"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","file":"chunk-CGEV3ARR.js","sourcesContent":["/**\n * Multi-provider token estimation per PRD section 7.5\n * Uses a universal approximation since we don't bundle tokenizers for each provider.\n */\n\nimport type { ProviderName, ITokenUsage, IModelInfo } from \"../types/index.js\";\nimport { SUPPORTED_MODELS } from \"../types/index.js\";\n\n/**\n * Approximate token count using the ~4 chars per token heuristic.\n * For production cost tracking, we rely on provider-reported usage in API responses.\n */\nexport function estimateTokenCount(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Calculate cost in USD based on token usage and model pricing.\n */\nexport function calculateCost(\n modelId: string,\n inputTokens: number,\n outputTokens: number,\n): number {\n const modelInfo = SUPPORTED_MODELS[modelId];\n if (!modelInfo) {\n return 0;\n }\n\n const inputCost = (inputTokens / 1_000_000) * modelInfo.inputPricePerMToken;\n const outputCost = (outputTokens / 1_000_000) * modelInfo.outputPricePerMToken;\n\n return Math.round((inputCost + outputCost) * 1_000_000) / 1_000_000;\n}\n\n/**\n * Create a token usage record with cost calculation.\n */\nexport function createTokenUsage(\n modelId: string,\n inputTokens: number,\n outputTokens: number,\n): ITokenUsage {\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n costUsd: calculateCost(modelId, inputTokens, outputTokens),\n };\n}\n\n/**\n * Format cost for display (e.g., \"$0.04\").\n */\nexport function formatCost(costUsd: number): string {\n if (costUsd < 0.01) {\n return `$${costUsd.toFixed(4)}`;\n }\n return `$${costUsd.toFixed(2)}`;\n}\n\n/**\n * Format token count for display (e.g., \"12.3K\").\n */\nexport function formatTokenCount(count: number): string {\n if (count < 1_000) {\n return String(count);\n }\n if (count < 1_000_000) {\n return `${(count / 1_000).toFixed(1)}K`;\n }\n return `${(count / 1_000_000).toFixed(1)}M`;\n}\n","/**\n * Retry with exponential backoff per PRD section 20.2\n * Provider failover: If primary model fails, auto-fallback to configured backup.\n */\n\nimport { logger } from \"./logger.js\";\n\nexport interface IRetryOptions {\n readonly maxRetries: number;\n readonly baseDelayMs: number;\n readonly maxDelayMs: number;\n readonly shouldRetry?: (error: unknown, attempt: number) => boolean;\n}\n\nconst DEFAULT_RETRY_OPTIONS: IRetryOptions = {\n maxRetries: 3,\n baseDelayMs: 1_000,\n maxDelayMs: 30_000,\n};\n\n/**\n * Execute a function with exponential backoff retry.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options?: Partial<IRetryOptions>,\n): Promise<T> {\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error: unknown) {\n lastError = error;\n\n if (attempt === opts.maxRetries) {\n break;\n }\n\n if (opts.shouldRetry && !opts.shouldRetry(error, attempt)) {\n break;\n }\n\n const delay = Math.min(\n opts.baseDelayMs * Math.pow(2, attempt) + Math.random() * 1_000,\n opts.maxDelayMs,\n );\n\n logger.warn(\n { attempt: attempt + 1, maxRetries: opts.maxRetries, delayMs: delay },\n \"Retrying after error\",\n );\n\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Sleep for a specified duration.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Check if an error indicates a rate limit (should retry after delay).\n */\nexport function isRateLimitError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n return message.includes(\"rate limit\") || message.includes(\"429\") || message.includes(\"too many requests\");\n }\n return false;\n}\n\n/**\n * Check if an error is transient (network issues, timeouts).\n */\nexport function isTransientError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n return (\n message.includes(\"timeout\") ||\n message.includes(\"econnreset\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"socket hang up\") ||\n message.includes(\"503\") ||\n message.includes(\"502\")\n );\n }\n return false;\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { resolve, normalize } from 'path';
|
|
2
|
+
|
|
3
|
+
// src/utils/sanitizer.ts
|
|
4
|
+
function validatePath(filePath, projectRoot) {
|
|
5
|
+
const resolved = resolve(projectRoot, filePath);
|
|
6
|
+
const normalizedRoot = normalize(projectRoot);
|
|
7
|
+
const normalizedPath = normalize(resolved);
|
|
8
|
+
if (!normalizedPath.startsWith(normalizedRoot)) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Path traversal detected: "${filePath}" resolves outside project root "${projectRoot}"`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return normalizedPath;
|
|
14
|
+
}
|
|
15
|
+
function isCommandBlocked(command, blockedCommands) {
|
|
16
|
+
const normalizedCommand = command.trim().toLowerCase();
|
|
17
|
+
return blockedCommands.some(
|
|
18
|
+
(blocked) => normalizedCommand.includes(blocked.toLowerCase())
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
function redactSecrets(text) {
|
|
22
|
+
return text.replace(/sk-ant-api\S+/g, "sk-ant-api[REDACTED]").replace(/sk-[a-zA-Z0-9]{20,}/g, "sk-[REDACTED]").replace(/AIza[a-zA-Z0-9_-]{35}/g, "AIza[REDACTED]").replace(/ghp_[a-zA-Z0-9]{36}/g, "ghp_[REDACTED]").replace(/Bearer\s+[a-zA-Z0-9._-]+/gi, "Bearer [REDACTED]");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { isCommandBlocked, redactSecrets, validatePath };
|
|
26
|
+
//# sourceMappingURL=chunk-CS5X3BWX.js.map
|
|
27
|
+
//# sourceMappingURL=chunk-CS5X3BWX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/sanitizer.ts"],"names":[],"mappings":";;;AAoBO,SAAS,YAAA,CAAa,UAAkB,WAAA,EAA6B;AAC1E,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,WAAA,EAAa,QAAQ,CAAA;AAC9C,EAAA,MAAM,cAAA,GAAiB,UAAU,WAAW,CAAA;AAC5C,EAAA,MAAM,cAAA,GAAiB,UAAU,QAAQ,CAAA;AAEzC,EAAA,IAAI,CAAC,cAAA,CAAe,UAAA,CAAW,cAAc,CAAA,EAAG;AAC9C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,0BAAA,EAA6B,QAAQ,CAAA,iCAAA,EAAoC,WAAW,CAAA,CAAA;AAAA,KACtF;AAAA,EACF;AAEA,EAAA,OAAO,cAAA;AACT;AAqBO,SAAS,gBAAA,CACd,SACA,eAAA,EACS;AACT,EAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,IAAA,EAAK,CAAE,WAAA,EAAY;AACrD,EAAA,OAAO,eAAA,CAAgB,IAAA;AAAA,IAAK,CAAC,OAAA,KAC3B,iBAAA,CAAkB,QAAA,CAAS,OAAA,CAAQ,aAAa;AAAA,GAClD;AACF;AAKO,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,OAAO,KACJ,OAAA,CAAQ,gBAAA,EAAkB,sBAAsB,CAAA,CAChD,OAAA,CAAQ,wBAAwB,eAAe,CAAA,CAC/C,QAAQ,wBAAA,EAA0B,gBAAgB,EAClD,OAAA,CAAQ,sBAAA,EAAwB,gBAAgB,CAAA,CAChD,OAAA,CAAQ,8BAA8B,mBAAmB,CAAA;AAC9D","file":"chunk-CS5X3BWX.js","sourcesContent":["/**\n * Input/output sanitization per PRD section 14.2\n * Zero trust for AI output — treat all model-generated content as untrusted\n */\n\nimport { resolve, normalize, relative, isAbsolute } from \"node:path\";\n\n/**\n * Sanitize shell command arguments to prevent injection.\n * PRD REQ: NO shell injection (section 14.1, 15.7 item 10)\n */\nexport function sanitizeShellArg(arg: string): string {\n // Escape single quotes by replacing them with escaped version\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * Validate a file path is within the allowed project root.\n * Prevents directory traversal attacks (PRD section 14.1).\n */\nexport function validatePath(filePath: string, projectRoot: string): string {\n const resolved = resolve(projectRoot, filePath);\n const normalizedRoot = normalize(projectRoot);\n const normalizedPath = normalize(resolved);\n\n if (!normalizedPath.startsWith(normalizedRoot)) {\n throw new Error(\n `Path traversal detected: \"${filePath}\" resolves outside project root \"${projectRoot}\"`,\n );\n }\n\n return normalizedPath;\n}\n\n/**\n * Check if a path is safe (within allowed paths).\n */\nexport function isPathAllowed(\n filePath: string,\n allowedPaths: readonly string[],\n projectRoot: string,\n): boolean {\n const resolved = resolve(projectRoot, filePath);\n return allowedPaths.some((allowed) => {\n const resolvedAllowed = resolve(projectRoot, allowed);\n return resolved.startsWith(resolvedAllowed);\n });\n}\n\n/**\n * Check if a shell command is on the blocked list.\n * PRD section 14.4: Dangerous commands always require confirmation.\n */\nexport function isCommandBlocked(\n command: string,\n blockedCommands: readonly string[],\n): boolean {\n const normalizedCommand = command.trim().toLowerCase();\n return blockedCommands.some((blocked) =>\n normalizedCommand.includes(blocked.toLowerCase()),\n );\n}\n\n/**\n * Redact potential secrets from text for logging.\n */\nexport function redactSecrets(text: string): string {\n return text\n .replace(/sk-ant-api\\S+/g, \"sk-ant-api[REDACTED]\")\n .replace(/sk-[a-zA-Z0-9]{20,}/g, \"sk-[REDACTED]\")\n .replace(/AIza[a-zA-Z0-9_-]{35}/g, \"AIza[REDACTED]\")\n .replace(/ghp_[a-zA-Z0-9]{36}/g, \"ghp_[REDACTED]\")\n .replace(/Bearer\\s+[a-zA-Z0-9._-]+/gi, \"Bearer [REDACTED]\");\n}\n\n/**\n * Sanitize user input for safe inclusion in prompts.\n */\nexport function sanitizePromptInput(input: string): string {\n // Strip null bytes\n return input.replace(/\\0/g, \"\");\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/types/config.ts
|
|
2
|
+
var DEFAULT_CONFIG = {
|
|
3
|
+
version: "1.0.0",
|
|
4
|
+
defaultModel: "claude-sonnet-4-6",
|
|
5
|
+
roles: {
|
|
6
|
+
planning: { primary: "claude-opus-4-6", fallback: ["gpt-5.2", "gemini-2.5-pro"] },
|
|
7
|
+
coding: { primary: "claude-sonnet-4-6", fallback: ["gpt-5.2", "gemini-2.5-flash"] },
|
|
8
|
+
review: { primary: "claude-opus-4-6", fallback: ["gemini-2.5-pro"] },
|
|
9
|
+
testing: { primary: "claude-haiku-4-5", fallback: ["gemini-2.5-flash"] },
|
|
10
|
+
bugfix: { primary: "claude-sonnet-4-6", fallback: ["gpt-5.2"] },
|
|
11
|
+
documentation: { primary: "gemini-2.5-flash", fallback: ["claude-haiku-4-5"] }
|
|
12
|
+
},
|
|
13
|
+
providers: {
|
|
14
|
+
anthropic: { enabled: true },
|
|
15
|
+
openai: { enabled: true },
|
|
16
|
+
google: { enabled: true },
|
|
17
|
+
kimi: { enabled: false },
|
|
18
|
+
ollama: { enabled: false, baseUrl: "http://localhost:11434" }
|
|
19
|
+
},
|
|
20
|
+
permissions: {
|
|
21
|
+
mode: "standard",
|
|
22
|
+
allowedPaths: ["./"],
|
|
23
|
+
blockedCommands: ["rm -rf /", "git push --force"]
|
|
24
|
+
},
|
|
25
|
+
splitPanel: {
|
|
26
|
+
enabled: true,
|
|
27
|
+
backend: "tmux",
|
|
28
|
+
defaultLayout: "auto",
|
|
29
|
+
maxPanes: 6
|
|
30
|
+
},
|
|
31
|
+
cost: {
|
|
32
|
+
budgetWarning: 5,
|
|
33
|
+
budgetHardStop: 20,
|
|
34
|
+
currency: "USD"
|
|
35
|
+
},
|
|
36
|
+
telemetry: {
|
|
37
|
+
enabled: false,
|
|
38
|
+
anonymized: true
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { DEFAULT_CONFIG };
|
|
43
|
+
//# sourceMappingURL=chunk-CYQNBB25.js.map
|
|
44
|
+
//# sourceMappingURL=chunk-CYQNBB25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/config.ts"],"names":[],"mappings":";AAgIO,IAAM,cAAA,GAAgC;AAAA,EAC3C,OAAA,EAAS,OAAA;AAAA,EACT,YAAA,EAAc,mBAAA;AAAA,EACd,KAAA,EAAO;AAAA,IACL,QAAA,EAAU,EAAE,OAAA,EAAS,iBAAA,EAAmB,UAAU,CAAC,SAAA,EAAW,gBAAgB,CAAA,EAAE;AAAA,IAChF,MAAA,EAAQ,EAAE,OAAA,EAAS,mBAAA,EAAqB,UAAU,CAAC,SAAA,EAAW,kBAAkB,CAAA,EAAE;AAAA,IAClF,QAAQ,EAAE,OAAA,EAAS,mBAAmB,QAAA,EAAU,CAAC,gBAAgB,CAAA,EAAE;AAAA,IACnE,SAAS,EAAE,OAAA,EAAS,oBAAoB,QAAA,EAAU,CAAC,kBAAkB,CAAA,EAAE;AAAA,IACvE,QAAQ,EAAE,OAAA,EAAS,qBAAqB,QAAA,EAAU,CAAC,SAAS,CAAA,EAAE;AAAA,IAC9D,eAAe,EAAE,OAAA,EAAS,oBAAoB,QAAA,EAAU,CAAC,kBAAkB,CAAA;AAAE,GAC/E;AAAA,EACA,SAAA,EAAW;AAAA,IACT,SAAA,EAAW,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,IAC3B,MAAA,EAAQ,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,IACxB,MAAA,EAAQ,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,IACxB,IAAA,EAAM,EAAE,OAAA,EAAS,KAAA,EAAM;AAAA,IACvB,MAAA,EAAQ,EAAE,OAAA,EAAS,KAAA,EAAO,SAAS,wBAAA;AAAyB,GAC9D;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,UAAA;AAAA,IACN,YAAA,EAAc,CAAC,IAAI,CAAA;AAAA,IACnB,eAAA,EAAiB,CAAC,UAAA,EAAY,kBAAkB;AAAA,GAClD;AAAA,EACA,UAAA,EAAY;AAAA,IACV,OAAA,EAAS,IAAA;AAAA,IACT,OAAA,EAAS,MAAA;AAAA,IACT,aAAA,EAAe,MAAA;AAAA,IACf,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,aAAA,EAAe,CAAA;AAAA,IACf,cAAA,EAAgB,EAAA;AAAA,IAChB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,SAAA,EAAW;AAAA,IACT,OAAA,EAAS,KAAA;AAAA,IACT,UAAA,EAAY;AAAA;AAEhB","file":"chunk-CYQNBB25.js","sourcesContent":["/**\n * Configuration types per PRD section 17.3\n */\n\nimport type { ProviderName, ModelRole, IRoleConfig } from \"./model.js\";\nimport type { PermissionMode } from \"./tool.js\";\nimport type { PaneLayout } from \"./team.js\";\n\n// ── Provider Configuration ───────────────────────────────────────────────\n\nexport interface IProviderConfig {\n readonly enabled: boolean;\n readonly baseUrl?: string | undefined;\n}\n\n// ── Permission Configuration ─────────────────────────────────────────────\n\nexport interface IPermissionConfig {\n readonly mode: PermissionMode;\n readonly allowedPaths: readonly string[];\n readonly blockedCommands: readonly string[];\n}\n\n// ── Split Panel Configuration ────────────────────────────────────────────\n\nexport type PaneBackend = \"tmux\" | \"iterm2\";\n\nexport interface ISplitPanelConfig {\n readonly enabled: boolean;\n readonly backend: PaneBackend;\n readonly defaultLayout: PaneLayout;\n readonly maxPanes: number;\n}\n\n// ── Cost Configuration ───────────────────────────────────────────────────\n\nexport interface ICostConfig {\n readonly budgetWarning: number;\n readonly budgetHardStop: number;\n readonly currency: string;\n}\n\n// ── Telemetry Configuration ──────────────────────────────────────────────\n\nexport interface ITelemetryConfig {\n readonly enabled: boolean;\n readonly anonymized: boolean;\n}\n\n// ── OAuth Provider Configuration ─────────────────────────────────────────\n\nexport interface IOAuthProviderConfig {\n readonly clientId: string;\n readonly clientSecret?: string | undefined;\n readonly authorizeUrl?: string | undefined;\n readonly tokenUrl?: string | undefined;\n readonly scope?: string | undefined;\n}\n\nexport interface IOAuthConfig {\n readonly anthropic?: IOAuthProviderConfig | undefined;\n readonly openai?: IOAuthProviderConfig | undefined;\n readonly google?: IOAuthProviderConfig | undefined;\n readonly kimi?: IOAuthProviderConfig | undefined;\n}\n\n// ── Global Configuration (PRD section 17.3) ──────────────────────────────\n\nexport interface IGlobalConfig {\n readonly version: string;\n readonly defaultModel: string;\n readonly roles: Partial<Record<ModelRole, IRoleConfig>>;\n readonly providers: Partial<Record<ProviderName, IProviderConfig>>;\n readonly permissions: IPermissionConfig;\n readonly splitPanel: ISplitPanelConfig;\n readonly cost: ICostConfig;\n readonly telemetry: ITelemetryConfig;\n readonly oauth?: IOAuthConfig | undefined;\n}\n\n// ── MCP Server Configuration (PRD section 11.2) ─────────────────────────\n\nexport interface IMCPServerConfig {\n readonly command: string;\n readonly args: readonly string[];\n readonly env?: Readonly<Record<string, string>> | undefined;\n}\n\nexport interface IMCPConfig {\n readonly mcpServers: Readonly<Record<string, IMCPServerConfig>>;\n}\n\n// ── Skill Configuration (PRD section 10.2) ───────────────────────────────\n\nexport interface ISkillFrontmatter {\n readonly name: string;\n readonly description: string;\n readonly version: string;\n readonly \"allowed-tools\"?: readonly string[] | undefined;\n readonly triggers: readonly string[];\n readonly \"model-requirements\"?: {\n readonly \"preferred-role\"?: ModelRole | undefined;\n readonly \"min-context\"?: number | undefined;\n } | undefined;\n}\n\nexport interface ISkillDefinition {\n readonly frontmatter: ISkillFrontmatter;\n readonly body: string;\n readonly filePath: string;\n}\n\n// ── Auth Credential Types (PRD section 13) ───────────────────────────────\n\nexport type AuthMethod = \"native_login\" | \"api_key\" | \"env_variable\" | \"credential_helper\";\n\nexport interface ICredential {\n readonly provider: ProviderName;\n readonly method: AuthMethod;\n readonly token?: string | undefined;\n readonly refreshToken?: string | undefined;\n readonly expiresAt?: Date | undefined;\n readonly email?: string | undefined;\n readonly plan?: string | undefined;\n}\n\n// ── Default Configuration ────────────────────────────────────────────────\n\nexport const DEFAULT_CONFIG: IGlobalConfig = {\n version: \"1.0.0\",\n defaultModel: \"claude-sonnet-4-6\",\n roles: {\n planning: { primary: \"claude-opus-4-6\", fallback: [\"gpt-5.2\", \"gemini-2.5-pro\"] },\n coding: { primary: \"claude-sonnet-4-6\", fallback: [\"gpt-5.2\", \"gemini-2.5-flash\"] },\n review: { primary: \"claude-opus-4-6\", fallback: [\"gemini-2.5-pro\"] },\n testing: { primary: \"claude-haiku-4-5\", fallback: [\"gemini-2.5-flash\"] },\n bugfix: { primary: \"claude-sonnet-4-6\", fallback: [\"gpt-5.2\"] },\n documentation: { primary: \"gemini-2.5-flash\", fallback: [\"claude-haiku-4-5\"] },\n },\n providers: {\n anthropic: { enabled: true },\n openai: { enabled: true },\n google: { enabled: true },\n kimi: { enabled: false },\n ollama: { enabled: false, baseUrl: \"http://localhost:11434\" },\n },\n permissions: {\n mode: \"standard\",\n allowedPaths: [\"./\"],\n blockedCommands: [\"rm -rf /\", \"git push --force\"],\n },\n splitPanel: {\n enabled: true,\n backend: \"tmux\",\n defaultLayout: \"auto\",\n maxPanes: 6,\n },\n cost: {\n budgetWarning: 5.0,\n budgetHardStop: 20.0,\n currency: \"USD\",\n },\n telemetry: {\n enabled: false,\n anonymized: true,\n },\n};\n"]}
|