kly 0.3.0 → 0.3.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 +14 -2
- package/dist/ai/context.mjs.map +1 -1
- package/dist/ai/storage.mjs.map +1 -1
- package/dist/bin/bin-registry-Cj1PddZ1.mjs +3 -0
- package/dist/bin/kly.mjs +56 -37
- package/dist/bin/kly.mjs.map +1 -1
- package/dist/bin/{permissions-extractor-ySRyhQut.mjs → permissions-extractor-B3XI8JLv.mjs} +2 -2
- package/dist/bin/{permissions-extractor-ySRyhQut.mjs.map → permissions-extractor-B3XI8JLv.mjs.map} +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/define-app.mjs.map +1 -1
- package/dist/mcp/schema-converter.mjs.map +1 -1
- package/dist/mcp/server.d.mts.map +1 -1
- package/dist/mcp/server.mjs.map +1 -1
- package/dist/permissions/index.mjs.map +1 -1
- package/dist/sandbox/bundled-executor.mjs.map +1 -1
- package/dist/sandbox/ipc-client.mjs.map +1 -1
- package/dist/sandbox/sandboxed-context.mjs.map +1 -1
- package/dist/tool.d.mts.map +1 -1
- package/dist/tool.mjs.map +1 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ui/components/confirm.d.mts.map +1 -1
- package/dist/ui/components/confirm.mjs.map +1 -1
- package/dist/ui/components/form.d.mts.map +1 -1
- package/dist/ui/components/form.mjs.map +1 -1
- package/dist/ui/components/table.d.mts.map +1 -1
- package/dist/ui/components/table.mjs.map +1 -1
- package/dist/ui/utils/colors.d.mts.map +1 -1
- package/dist/ui/utils/colors.mjs.map +1 -1
- package/dist/ui/utils/tty.mjs.map +1 -1
- package/package.json +17 -16
- package/dist/bin/bin-registry-DOBspniG.mjs +0 -3
- package/dist/bin/remote-tQeFZX9o.mjs +0 -3
- /package/dist/bin/{config-builder-VSUaGlaV.mjs → config-builder-CkkAqWMY.mjs} +0 -0
- /package/dist/bin/{launcher-DD6vpEFb.mjs → launcher-CSdy4_ZV.mjs} +0 -0
- /package/dist/bin/{permissions-D7-M2lRi.mjs → permissions-DOOzghc5.mjs} +0 -0
package/README.md
CHANGED
|
@@ -2,8 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/kly)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
A CLI framework with sandbox isolation and MCP support.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun install -g kly
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
kly run ./app.ts # Run local app
|
|
17
|
+
kly run user/repo # Run remote app
|
|
18
|
+
kly mcp ./app.ts # Run as MCP server
|
|
7
19
|
```
|
|
8
20
|
|
|
9
21
|
## License
|
package/dist/ai/context.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/ai/context.ts"],"sourcesContent":["import { checkApiKeyPermission, getAppIdentifier } from \"../permissions\";\nimport type { ModelConfig, ModelInfo, ModelsContext } from \"../types\";\nimport { getCurrentModelConfig, listModels } from \"./storage\";\n\n/**\n * Create models context for ExecuteContext\n * Provides access to configured LLM models and their credentials (with permission checks)\n */\nexport function createModelsContext(): ModelsContext {\n // Track if permission has been checked in this process\n let permissionChecked = false;\n let permissionGranted = false;\n\n /**\n * Check permission before allowing access to API keys\n */\n async function ensurePermission(): Promise<void> {\n if (permissionChecked) {\n if (!permissionGranted) {\n throw new Error(\
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/ai/context.ts"],"sourcesContent":["import { checkApiKeyPermission, getAppIdentifier } from \"../permissions\";\nimport type { ModelConfig, ModelInfo, ModelsContext } from \"../types\";\nimport { getCurrentModelConfig, listModels } from \"./storage\";\n\n/**\n * Create models context for ExecuteContext\n * Provides access to configured LLM models and their credentials (with permission checks)\n */\nexport function createModelsContext(): ModelsContext {\n // Track if permission has been checked in this process\n let permissionChecked = false;\n let permissionGranted = false;\n\n /**\n * Check permission before allowing access to API keys\n */\n async function ensurePermission(): Promise<void> {\n if (permissionChecked) {\n if (!permissionGranted) {\n throw new Error(\"Permission denied: This app does not have permission to access API keys.\");\n }\n return;\n }\n\n const appId = getAppIdentifier();\n permissionGranted = await checkApiKeyPermission(appId);\n permissionChecked = true;\n\n if (!permissionGranted) {\n throw new Error(\"Permission denied: This app does not have permission to access API keys.\");\n }\n }\n\n return {\n list(): ModelInfo[] {\n return listModels().map((m) => ({\n name: m.name,\n provider: m.config.provider,\n model: m.config.model,\n isCurrent: m.isCurrent,\n }));\n },\n\n getCurrent(): ModelInfo | null {\n const models = listModels();\n const current = models.find((m) => m.isCurrent);\n if (!current) return null;\n\n return {\n name: current.name,\n provider: current.config.provider,\n model: current.config.model,\n isCurrent: true,\n };\n },\n\n get(name: string): ModelInfo | null {\n const models = listModels();\n const found = models.find((m) => m.name === name);\n if (!found) return null;\n\n return {\n name: found.name,\n provider: found.config.provider,\n model: found.config.model,\n isCurrent: found.isCurrent,\n };\n },\n\n async getConfigAsync(name?: string): Promise<ModelConfig | null> {\n // Check permission first\n await ensurePermission();\n\n if (name) {\n const models = listModels();\n const found = models.find((m) => m.name === name);\n if (!found) return null;\n\n return {\n provider: found.config.provider,\n model: found.config.model,\n apiKey: found.config.apiKey,\n baseURL: found.config.baseURL,\n };\n }\n\n const current = getCurrentModelConfig();\n if (!current) return null;\n\n return {\n provider: current.provider,\n model: current.model,\n apiKey: current.apiKey,\n baseURL: current.baseURL,\n };\n },\n };\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,sBAAqC;CAEnD,IAAI,oBAAoB;CACxB,IAAI,oBAAoB;;;;CAKxB,eAAe,mBAAkC;AAC/C,MAAI,mBAAmB;AACrB,OAAI,CAAC,kBACH,OAAM,IAAI,MAAM,2EAA2E;AAE7F;;AAIF,sBAAoB,MAAM,sBADZ,kBAAkB,CACsB;AACtD,sBAAoB;AAEpB,MAAI,CAAC,kBACH,OAAM,IAAI,MAAM,2EAA2E;;AAI/F,QAAO;EACL,OAAoB;AAClB,UAAO,YAAY,CAAC,KAAK,OAAO;IAC9B,MAAM,EAAE;IACR,UAAU,EAAE,OAAO;IACnB,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE;IACd,EAAE;;EAGL,aAA+B;GAE7B,MAAM,UADS,YAAY,CACJ,MAAM,MAAM,EAAE,UAAU;AAC/C,OAAI,CAAC,QAAS,QAAO;AAErB,UAAO;IACL,MAAM,QAAQ;IACd,UAAU,QAAQ,OAAO;IACzB,OAAO,QAAQ,OAAO;IACtB,WAAW;IACZ;;EAGH,IAAI,MAAgC;GAElC,MAAM,QADS,YAAY,CACN,MAAM,MAAM,EAAE,SAAS,KAAK;AACjD,OAAI,CAAC,MAAO,QAAO;AAEnB,UAAO;IACL,MAAM,MAAM;IACZ,UAAU,MAAM,OAAO;IACvB,OAAO,MAAM,OAAO;IACpB,WAAW,MAAM;IAClB;;EAGH,MAAM,eAAe,MAA4C;AAE/D,SAAM,kBAAkB;AAExB,OAAI,MAAM;IAER,MAAM,QADS,YAAY,CACN,MAAM,MAAM,EAAE,SAAS,KAAK;AACjD,QAAI,CAAC,MAAO,QAAO;AAEnB,WAAO;KACL,UAAU,MAAM,OAAO;KACvB,OAAO,MAAM,OAAO;KACpB,QAAQ,MAAM,OAAO;KACrB,SAAS,MAAM,OAAO;KACvB;;GAGH,MAAM,UAAU,uBAAuB;AACvC,OAAI,CAAC,QAAS,QAAO;AAErB,UAAO;IACL,UAAU,QAAQ;IAClB,OAAO,QAAQ;IACf,QAAQ,QAAQ;IAChB,SAAS,QAAQ;IAClB;;EAEJ"}
|
package/dist/ai/storage.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.mjs","names":[],"sources":["../../src/ai/storage.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { error } from \"../ui\";\nimport type { LLMConfig, LLMProvider } from \"./types\";\n\nconst CONFIG_DIR = join(homedir(), \".kly\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport interface KlyConfig {\n currentModel?: string;\n models: Record<string, LLMConfig>;\n}\n\n/**\n * Ensure config directory exists\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/**\n * Load configuration from ~/.kly/config.json\n */\nexport function loadConfig(): KlyConfig {\n ensureConfigDir();\n\n if (!existsSync(CONFIG_FILE)) {\n return { models: {} };\n }\n\n try {\n const content = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(content);\n } catch (err) {\n error(`Failed to parse config file: ${err}`);\n return { models: {} };\n }\n}\n\n/**\n * Save configuration to ~/.kly/config.json\n */\nexport function saveConfig(config: KlyConfig): void {\n ensureConfigDir();\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n/**\n * Get current active model configuration\n */\nexport function getCurrentModelConfig(): LLMConfig | null {\n const config = loadConfig();\n\n if (!config.currentModel) {\n return null;\n }\n\n return config.models[config.currentModel] || null;\n}\n\n/**\n * Set a model as current\n */\nexport function setCurrentModel(modelName: string): void {\n const config = loadConfig();\n\n if (!config.models[modelName]) {\n throw new Error(`Model '${modelName}' not found in config`);\n }\n\n config.currentModel = modelName;\n saveConfig(config);\n}\n\n/**\n * Add or update a model configuration\n */\nexport function saveModelConfig(
|
|
1
|
+
{"version":3,"file":"storage.mjs","names":[],"sources":["../../src/ai/storage.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { error } from \"../ui\";\nimport type { LLMConfig, LLMProvider } from \"./types\";\n\nconst CONFIG_DIR = join(homedir(), \".kly\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport interface KlyConfig {\n currentModel?: string;\n models: Record<string, LLMConfig>;\n}\n\n/**\n * Ensure config directory exists\n */\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/**\n * Load configuration from ~/.kly/config.json\n */\nexport function loadConfig(): KlyConfig {\n ensureConfigDir();\n\n if (!existsSync(CONFIG_FILE)) {\n return { models: {} };\n }\n\n try {\n const content = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(content);\n } catch (err) {\n error(`Failed to parse config file: ${err}`);\n return { models: {} };\n }\n}\n\n/**\n * Save configuration to ~/.kly/config.json\n */\nexport function saveConfig(config: KlyConfig): void {\n ensureConfigDir();\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n/**\n * Get current active model configuration\n */\nexport function getCurrentModelConfig(): LLMConfig | null {\n const config = loadConfig();\n\n if (!config.currentModel) {\n return null;\n }\n\n return config.models[config.currentModel] || null;\n}\n\n/**\n * Set a model as current\n */\nexport function setCurrentModel(modelName: string): void {\n const config = loadConfig();\n\n if (!config.models[modelName]) {\n throw new Error(`Model '${modelName}' not found in config`);\n }\n\n config.currentModel = modelName;\n saveConfig(config);\n}\n\n/**\n * Add or update a model configuration\n */\nexport function saveModelConfig(modelName: string, modelConfig: LLMConfig): void {\n const config = loadConfig();\n\n config.models[modelName] = modelConfig;\n\n // Set as current if it's the first model\n if (!config.currentModel) {\n config.currentModel = modelName;\n }\n\n saveConfig(config);\n}\n\n/**\n * Remove a model configuration\n */\nexport function removeModelConfig(modelName: string): void {\n const config = loadConfig();\n\n delete config.models[modelName];\n\n // Clear current if it was removed\n if (config.currentModel === modelName) {\n config.currentModel = undefined;\n }\n\n saveConfig(config);\n}\n\n/**\n * List all configured models\n */\nexport function listModels(): Array<{\n name: string;\n config: LLMConfig;\n isCurrent: boolean;\n}> {\n const config = loadConfig();\n\n return Object.entries(config.models).map(([name, modelConfig]) => ({\n name,\n config: modelConfig,\n isCurrent: name === config.currentModel,\n }));\n}\n\n/**\n * Get provider display name\n */\nexport function getProviderDisplayName(provider: LLMProvider): string {\n const displayNames: Record<LLMProvider, string> = {\n openai: \"OpenAI\",\n anthropic: \"Anthropic\",\n google: \"Google\",\n deepseek: \"DeepSeek\",\n ollama: \"Ollama\",\n groq: \"Groq\",\n mistral: \"Mistral\",\n cohere: \"Cohere\",\n \"openai-compatible\": \"OpenAI Compatible\",\n };\n return displayNames[provider];\n}\n"],"mappings":";;;;;;AAMA,MAAM,aAAa,KAAK,SAAS,EAAE,OAAO;AAC1C,MAAM,cAAc,KAAK,YAAY,cAAc;;;;AAUnD,SAAS,kBAAwB;AAC/B,KAAI,CAAC,WAAW,WAAW,CACzB,WAAU,YAAY,EAAE,WAAW,MAAM,CAAC;;;;;AAO9C,SAAgB,aAAwB;AACtC,kBAAiB;AAEjB,KAAI,CAAC,WAAW,YAAY,CAC1B,QAAO,EAAE,QAAQ,EAAE,EAAE;AAGvB,KAAI;EACF,MAAM,UAAU,aAAa,aAAa,QAAQ;AAClD,SAAO,KAAK,MAAM,QAAQ;UACnB,KAAK;AACZ,QAAM,gCAAgC,MAAM;AAC5C,SAAO,EAAE,QAAQ,EAAE,EAAE;;;;;;AAezB,SAAgB,wBAA0C;CACxD,MAAM,SAAS,YAAY;AAE3B,KAAI,CAAC,OAAO,aACV,QAAO;AAGT,QAAO,OAAO,OAAO,OAAO,iBAAiB;;;;;AAoD/C,SAAgB,aAIb;CACD,MAAM,SAAS,YAAY;AAE3B,QAAO,OAAO,QAAQ,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,kBAAkB;EACjE;EACA,QAAQ;EACR,WAAW,SAAS,OAAO;EAC5B,EAAE"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { A as writeRegistry, C as removeShim, D as listCommands, E as getRegistryPath, M as isCommandAvailable, O as readRegistry, S as getShimDir, T as getCommand, _ as autoRegisterBins, b as createShim, g as setupPath, h as isKlyBinInPath, j as detectBins, k as removeCommand, m as getShellConfigFile, p as checkPathSetup, v as shouldReregisterLocal, w as addCommand, x as generateShimPath, y as unregisterCommand } from "./kly.mjs";
|
|
2
|
+
|
|
3
|
+
export { autoRegisterBins };
|
package/dist/bin/kly.mjs
CHANGED
|
@@ -619,7 +619,7 @@ async function fetchModelsDevData(forceRefresh = false) {
|
|
|
619
619
|
if (!forceRefresh && existsSync(CACHE_FILE)) try {
|
|
620
620
|
const cached = JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
|
|
621
621
|
if (Date.now() - cached.timestamp < CACHE_TTL) return cached;
|
|
622
|
-
} catch
|
|
622
|
+
} catch {}
|
|
623
623
|
try {
|
|
624
624
|
const response = await fetch(MODELS_DEV_API);
|
|
625
625
|
if (!response.ok) return null;
|
|
@@ -629,9 +629,9 @@ async function fetchModelsDevData(forceRefresh = false) {
|
|
|
629
629
|
};
|
|
630
630
|
try {
|
|
631
631
|
writeFileSync(CACHE_FILE, JSON.stringify(cachedData, null, 2), "utf-8");
|
|
632
|
-
} catch
|
|
632
|
+
} catch {}
|
|
633
633
|
return cachedData;
|
|
634
|
-
} catch
|
|
634
|
+
} catch {
|
|
635
635
|
if (existsSync(CACHE_FILE)) try {
|
|
636
636
|
return JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
|
|
637
637
|
} catch {}
|
|
@@ -2270,7 +2270,7 @@ async function checkForUpdates(ref, metadata) {
|
|
|
2270
2270
|
//#region src/remote/index.ts
|
|
2271
2271
|
init_parser();
|
|
2272
2272
|
/** Current kly CLI version */
|
|
2273
|
-
const KLY_VERSION = "0.3.
|
|
2273
|
+
const KLY_VERSION = "0.3.1";
|
|
2274
2274
|
/**
|
|
2275
2275
|
* Run a remote GitHub repository as a kly app
|
|
2276
2276
|
*/
|
|
@@ -2302,7 +2302,7 @@ async function runRemote(input, options = {}) {
|
|
|
2302
2302
|
await installDependencies(repoPath);
|
|
2303
2303
|
}
|
|
2304
2304
|
if (!options.skipRegister) {
|
|
2305
|
-
const { autoRegisterBins: autoRegisterBins$1 } = await import("./bin-registry-
|
|
2305
|
+
const { autoRegisterBins: autoRegisterBins$1 } = await import("./bin-registry-Cj1PddZ1.mjs");
|
|
2306
2306
|
await autoRegisterBins$1(repoPath, {
|
|
2307
2307
|
type: "remote",
|
|
2308
2308
|
remoteRef: formatRepoUrl(ref),
|
|
@@ -2455,10 +2455,10 @@ async function executeApp(ref, repoPath, args$1, mcp) {
|
|
|
2455
2455
|
const prevRemoteRef = process.env[ENV_VARS.REMOTE_REF];
|
|
2456
2456
|
process.env[ENV_VARS.REMOTE_REF] = remoteRef;
|
|
2457
2457
|
try {
|
|
2458
|
-
const { getAppIdentifier: getAppIdentifier$1, checkApiKeyPermission: checkApiKeyPermission$1, getAppSandboxConfig: getAppSandboxConfig$1 } = await import("./permissions-
|
|
2459
|
-
const { launchSandbox: launchSandbox$1 } = await import("./launcher-
|
|
2460
|
-
const { buildSandboxConfig: buildSandboxConfig$1, formatPermissionsSummary: formatPermissionsSummary$1 } = await import("./config-builder-
|
|
2461
|
-
const { extractAppPermissions: extractAppPermissions$1 } = await import("./permissions-extractor-
|
|
2458
|
+
const { getAppIdentifier: getAppIdentifier$1, checkApiKeyPermission: checkApiKeyPermission$1, getAppSandboxConfig: getAppSandboxConfig$1 } = await import("./permissions-DOOzghc5.mjs");
|
|
2459
|
+
const { launchSandbox: launchSandbox$1 } = await import("./launcher-CSdy4_ZV.mjs");
|
|
2460
|
+
const { buildSandboxConfig: buildSandboxConfig$1, formatPermissionsSummary: formatPermissionsSummary$1 } = await import("./config-builder-CkkAqWMY.mjs");
|
|
2461
|
+
const { extractAppPermissions: extractAppPermissions$1 } = await import("./permissions-extractor-B3XI8JLv.mjs");
|
|
2462
2462
|
const appId = getAppIdentifier$1();
|
|
2463
2463
|
const declaredPermissions = await extractAppPermissions$1(absoluteEntryPath);
|
|
2464
2464
|
if (declaredPermissions) {
|
|
@@ -2505,6 +2505,7 @@ async function executeApp(ref, repoPath, args$1, mcp) {
|
|
|
2505
2505
|
|
|
2506
2506
|
//#endregion
|
|
2507
2507
|
//#region src/bin-registry/commands.ts
|
|
2508
|
+
init_parser();
|
|
2508
2509
|
async function installCommand(args$1) {
|
|
2509
2510
|
const target = args$1[0];
|
|
2510
2511
|
if (!target) throw new ExitError("Missing target\nUsage: kly install <file|user/repo[@ref]>\n or: kly install --setup-path");
|
|
@@ -2512,13 +2513,11 @@ async function installCommand(args$1) {
|
|
|
2512
2513
|
await setupPath();
|
|
2513
2514
|
return;
|
|
2514
2515
|
}
|
|
2515
|
-
if (isRemoteRef(target)) {
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
});
|
|
2521
|
-
} else {
|
|
2516
|
+
if (isRemoteRef(target)) await runRemote(target, {
|
|
2517
|
+
args: args$1.slice(1),
|
|
2518
|
+
skipRegister: false
|
|
2519
|
+
});
|
|
2520
|
+
else {
|
|
2522
2521
|
const absolutePath = resolve(process.cwd(), target);
|
|
2523
2522
|
const detection = detectBins(absolutePath);
|
|
2524
2523
|
if (!detection.hasBin) {
|
|
@@ -2541,17 +2540,34 @@ async function uninstallCommand(args$1) {
|
|
|
2541
2540
|
await unregisterCommand(commandName, { skipConfirm: false });
|
|
2542
2541
|
}
|
|
2543
2542
|
async function linkCommand(args$1) {
|
|
2544
|
-
const
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2543
|
+
const target = args$1[0] || process.cwd();
|
|
2544
|
+
if (isRemoteRef(target)) {
|
|
2545
|
+
const ref = parseRemoteRef(target);
|
|
2546
|
+
if (!ref) throw new ExitError(`Invalid remote reference: ${target}`);
|
|
2547
|
+
const repoPath = getRepoCachePath(ref);
|
|
2548
|
+
if (!checkCache(ref).valid) throw new ExitError(`Remote package not cached. Run 'kly run ${target}' first to download it.`);
|
|
2549
|
+
const detection = detectBins(repoPath);
|
|
2550
|
+
if (!detection.hasBin) throw new ExitError("No bin field found in package.json");
|
|
2551
|
+
log.step(`Linking ${detection.projectName}...`);
|
|
2552
|
+
await autoRegisterBins(repoPath, {
|
|
2553
|
+
type: "remote",
|
|
2554
|
+
remoteRef: target,
|
|
2555
|
+
force: true,
|
|
2556
|
+
skipConfirm: true
|
|
2557
|
+
});
|
|
2558
|
+
log.success("Linked successfully!");
|
|
2559
|
+
} else {
|
|
2560
|
+
const absolutePath = resolve(process.cwd(), target);
|
|
2561
|
+
const detection = detectBins(absolutePath);
|
|
2562
|
+
if (!detection.hasBin) throw new ExitError("No bin field found in package.json");
|
|
2563
|
+
log.step(`Linking ${detection.projectName}...`);
|
|
2564
|
+
await autoRegisterBins(absolutePath, {
|
|
2565
|
+
type: "local",
|
|
2566
|
+
force: true,
|
|
2567
|
+
skipConfirm: true
|
|
2568
|
+
});
|
|
2569
|
+
log.success("Linked successfully!");
|
|
2570
|
+
}
|
|
2555
2571
|
}
|
|
2556
2572
|
async function listCommand() {
|
|
2557
2573
|
const commands = listCommands();
|
|
@@ -3382,7 +3398,8 @@ function buildSandboxConfig(permissions) {
|
|
|
3382
3398
|
const userSandbox = permissions.sandbox;
|
|
3383
3399
|
if (userSandbox.network?.allowedDomains) {
|
|
3384
3400
|
const domains = userSandbox.network.allowedDomains.filter((d) => d !== void 0);
|
|
3385
|
-
allowedDomains =
|
|
3401
|
+
if (domains.includes("*")) allowedDomains = void 0;
|
|
3402
|
+
else allowedDomains = [...allowedDomains ?? [], ...domains];
|
|
3386
3403
|
}
|
|
3387
3404
|
if (userSandbox.filesystem) {
|
|
3388
3405
|
if (userSandbox.filesystem.allowWrite) allowWrite = userSandbox.filesystem.allowWrite.map(resolveFilesystemPath).filter((p$1) => p$1 !== void 0);
|
|
@@ -3393,7 +3410,7 @@ function buildSandboxConfig(permissions) {
|
|
|
3393
3410
|
}
|
|
3394
3411
|
}
|
|
3395
3412
|
return {
|
|
3396
|
-
network: {
|
|
3413
|
+
network: allowedDomains === void 0 ? { deniedDomains: [] } : {
|
|
3397
3414
|
allowedDomains,
|
|
3398
3415
|
deniedDomains: []
|
|
3399
3416
|
},
|
|
@@ -3414,10 +3431,11 @@ function formatPermissionsSummary(permissions) {
|
|
|
3414
3431
|
if (permissions?.apiKeys) summary.push("• API Keys access (to call LLM APIs)");
|
|
3415
3432
|
const config = buildSandboxConfig(permissions);
|
|
3416
3433
|
const currentDir = process.cwd();
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
const
|
|
3434
|
+
const allowedDomains = config.network.allowedDomains;
|
|
3435
|
+
if (allowedDomains === void 0) summary.push("• Network: All domains (unrestricted)");
|
|
3436
|
+
else if (allowedDomains.length > 0) {
|
|
3437
|
+
const domains = allowedDomains.slice(0, 3).join(", ");
|
|
3438
|
+
const more = allowedDomains.length > 3 ? ` +${allowedDomains.length - 3} more` : "";
|
|
3421
3439
|
summary.push(`• Network: ${domains}${more}`);
|
|
3422
3440
|
}
|
|
3423
3441
|
if (config.filesystem.allowWrite.length > 1 || config.filesystem.allowWrite.length === 1 && config.filesystem.allowWrite[0] !== currentDir) {
|
|
@@ -3467,7 +3485,8 @@ async function extractAppPermissions(scriptPath) {
|
|
|
3467
3485
|
*/
|
|
3468
3486
|
function needsPermissionPrompt(permissions, sandboxConfig) {
|
|
3469
3487
|
if (permissions?.apiKeys) return true;
|
|
3470
|
-
|
|
3488
|
+
const allowedDomains = sandboxConfig.network.allowedDomains;
|
|
3489
|
+
if (allowedDomains === void 0 || allowedDomains.length > 0) return true;
|
|
3471
3490
|
if (permissions?.sandbox?.filesystem) return true;
|
|
3472
3491
|
return false;
|
|
3473
3492
|
}
|
|
@@ -3542,7 +3561,7 @@ function checkStoredPermission(appId) {
|
|
|
3542
3561
|
const args = process.argv.slice(2);
|
|
3543
3562
|
const command = args[0];
|
|
3544
3563
|
async function main() {
|
|
3545
|
-
intro(`${colors.bgHex("#dc7702")(colors.black(` Kly ${colors.italic("0.3.
|
|
3564
|
+
intro(`${colors.bgHex("#dc7702")(colors.black(` Kly ${colors.italic("0.3.1")} `))}`);
|
|
3546
3565
|
if (!command || command === "--help" || command === "-h") {
|
|
3547
3566
|
showHelp();
|
|
3548
3567
|
return;
|
|
@@ -3714,7 +3733,7 @@ Examples:
|
|
|
3714
3733
|
kly install --setup-path`);
|
|
3715
3734
|
}
|
|
3716
3735
|
function showVersion() {
|
|
3717
|
-
log.message("0.3.
|
|
3736
|
+
log.message("0.3.1");
|
|
3718
3737
|
}
|
|
3719
3738
|
main().then(() => {
|
|
3720
3739
|
outro(`ヾ( ̄▽ ̄)Bye~`);
|
|
@@ -3731,5 +3750,5 @@ main().then(() => {
|
|
|
3731
3750
|
});
|
|
3732
3751
|
|
|
3733
3752
|
//#endregion
|
|
3734
|
-
export {
|
|
3753
|
+
export { writeRegistry as A, removeShim as C, listCommands as D, getRegistryPath as E, isCommandAvailable as M, log as N, readRegistry as O, getShimDir as S, getCommand as T, autoRegisterBins as _, getAppIdentifier as a, createShim as b, listPermissions as c, savePermissions as d, launchSandbox as f, setupPath as g, isKlyBinInPath as h, clearAllPermissions as i, detectBins as j, removeCommand as k, loadPermissions as l, getShellConfigFile as m, formatPermissionsSummary as n, getAppName as o, checkPathSetup as p, checkApiKeyPermission as r, getAppSandboxConfig as s, buildSandboxConfig as t, revokePermission as u, shouldReregisterLocal as v, addCommand as w, generateShimPath as x, unregisterCommand as y };
|
|
3735
3754
|
//# sourceMappingURL=kly.mjs.map
|