kly 0.1.0 → 0.1.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/dist/bin/config-builder-D5EtwOB3.mjs +3 -0
- package/dist/bin/kly.mjs +65 -18
- package/dist/bin/kly.mjs.map +1 -1
- package/dist/bin/launcher-Ex3ynZdE.mjs +3 -0
- package/dist/bin/permissions-C_WgoA3t.mjs +3 -0
- package/dist/bin/permissions-extractor-BfUPS0Tr.mjs +29 -0
- package/dist/bin/permissions-extractor-BfUPS0Tr.mjs.map +1 -0
- package/dist/types.d.mts +18 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/bin/launcher-vTpgdO9n.mjs +0 -3
- package/dist/bin/permissions-2r_7ZqaH.mjs +0 -3
package/dist/bin/kly.mjs
CHANGED
|
@@ -1851,14 +1851,32 @@ const PROTECTED_PATHS = {
|
|
|
1851
1851
|
alwaysDenyRead: [join(homedir(), ".kly")]
|
|
1852
1852
|
};
|
|
1853
1853
|
/**
|
|
1854
|
+
* Resolve filesystem path with special marker support
|
|
1855
|
+
*
|
|
1856
|
+
* Special markers:
|
|
1857
|
+
* - "*": User's home directory (allows access to all non-sensitive files)
|
|
1858
|
+
* - Absolute paths: Used as-is
|
|
1859
|
+
*
|
|
1860
|
+
* @param path - Path to resolve (may contain special markers)
|
|
1861
|
+
* @returns Resolved absolute path, or undefined if path is undefined
|
|
1862
|
+
*/
|
|
1863
|
+
function resolveFilesystemPath(path) {
|
|
1864
|
+
if (!path) return void 0;
|
|
1865
|
+
if (path === "*") return homedir();
|
|
1866
|
+
return path;
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1854
1869
|
* Build a complete SandboxRuntimeConfig from declared app permissions
|
|
1855
1870
|
*
|
|
1856
1871
|
* This merges:
|
|
1857
1872
|
* 1. Default safe configuration
|
|
1858
1873
|
* 2. Automatic LLM domains (if apiKeys: true)
|
|
1859
|
-
* 3. User-declared sandbox config
|
|
1874
|
+
* 3. User-declared sandbox config (with special marker support)
|
|
1860
1875
|
* 4. Mandatory protections (always applied)
|
|
1861
1876
|
*
|
|
1877
|
+
* Special markers in filesystem paths:
|
|
1878
|
+
* - "*": Allows access to all files in user's home directory (except sensitive paths)
|
|
1879
|
+
*
|
|
1862
1880
|
* @param permissions - Declared app permissions
|
|
1863
1881
|
* @returns Complete sandbox configuration ready for SandboxManager
|
|
1864
1882
|
*/
|
|
@@ -1870,10 +1888,16 @@ function buildSandboxConfig(permissions) {
|
|
|
1870
1888
|
if (permissions?.apiKeys) allowedDomains = [...LLM_API_DOMAINS];
|
|
1871
1889
|
if (permissions?.sandbox) {
|
|
1872
1890
|
const userSandbox = permissions.sandbox;
|
|
1873
|
-
if (userSandbox.network?.allowedDomains)
|
|
1891
|
+
if (userSandbox.network?.allowedDomains) {
|
|
1892
|
+
const domains = userSandbox.network.allowedDomains.filter((d) => d !== void 0);
|
|
1893
|
+
allowedDomains = [...allowedDomains, ...domains];
|
|
1894
|
+
}
|
|
1874
1895
|
if (userSandbox.filesystem) {
|
|
1875
|
-
if (userSandbox.filesystem.allowWrite) allowWrite = userSandbox.filesystem.allowWrite;
|
|
1876
|
-
if (userSandbox.filesystem.denyRead)
|
|
1896
|
+
if (userSandbox.filesystem.allowWrite) allowWrite = userSandbox.filesystem.allowWrite.map(resolveFilesystemPath).filter((p) => p !== void 0);
|
|
1897
|
+
if (userSandbox.filesystem.denyRead) {
|
|
1898
|
+
const deniedPaths = userSandbox.filesystem.denyRead.map(resolveFilesystemPath).filter((p) => p !== void 0);
|
|
1899
|
+
denyRead = [...denyRead, ...deniedPaths];
|
|
1900
|
+
}
|
|
1877
1901
|
}
|
|
1878
1902
|
}
|
|
1879
1903
|
return {
|
|
@@ -1904,9 +1928,13 @@ function formatPermissionsSummary(permissions) {
|
|
|
1904
1928
|
summary.push(`• Network: ${domains}${more}`);
|
|
1905
1929
|
}
|
|
1906
1930
|
if (config.filesystem.allowWrite.length > 1 || config.filesystem.allowWrite.length === 1 && config.filesystem.allowWrite[0] !== currentDir) {
|
|
1907
|
-
const
|
|
1908
|
-
|
|
1909
|
-
|
|
1931
|
+
const homeDir = homedir();
|
|
1932
|
+
if (config.filesystem.allowWrite.includes(homeDir)) summary.push("• Filesystem write: All non-sensitive directories");
|
|
1933
|
+
else {
|
|
1934
|
+
const dirs = config.filesystem.allowWrite.map((p) => p === currentDir ? "current directory" : p).slice(0, 2).join(", ");
|
|
1935
|
+
const more = config.filesystem.allowWrite.length > 2 ? ` +${config.filesystem.allowWrite.length - 2} more` : "";
|
|
1936
|
+
summary.push(`• Filesystem write: ${dirs}${more}`);
|
|
1937
|
+
}
|
|
1910
1938
|
}
|
|
1911
1939
|
if (permissions?.sandbox?.filesystem?.denyRead) summary.push(`• Filesystem read denied: ${permissions.sandbox.filesystem.denyRead.length} path(s)`);
|
|
1912
1940
|
return summary;
|
|
@@ -2703,19 +2731,38 @@ async function executeApp(ref, repoPath, args$1, mcp) {
|
|
|
2703
2731
|
const prevRemoteRef = process.env[ENV_VARS.REMOTE_REF];
|
|
2704
2732
|
process.env[ENV_VARS.REMOTE_REF] = remoteRef;
|
|
2705
2733
|
try {
|
|
2706
|
-
const { getAppIdentifier: getAppIdentifier$1, checkApiKeyPermission: checkApiKeyPermission$1, getAppSandboxConfig: getAppSandboxConfig$1 } = await import("./permissions-
|
|
2707
|
-
const { launchSandbox: launchSandbox$1 } = await import("./launcher-
|
|
2734
|
+
const { getAppIdentifier: getAppIdentifier$1, checkApiKeyPermission: checkApiKeyPermission$1, getAppSandboxConfig: getAppSandboxConfig$1 } = await import("./permissions-C_WgoA3t.mjs");
|
|
2735
|
+
const { launchSandbox: launchSandbox$1 } = await import("./launcher-Ex3ynZdE.mjs");
|
|
2736
|
+
const { buildSandboxConfig: buildSandboxConfig$1, formatPermissionsSummary: formatPermissionsSummary$1 } = await import("./config-builder-D5EtwOB3.mjs");
|
|
2737
|
+
const { extractAppPermissions: extractAppPermissions$1 } = await import("./permissions-extractor-BfUPS0Tr.mjs");
|
|
2708
2738
|
const appId = getAppIdentifier$1();
|
|
2739
|
+
console.log("📋 Reading app permissions...");
|
|
2740
|
+
const declaredPermissions = await extractAppPermissions$1(absoluteEntryPath);
|
|
2741
|
+
if (declaredPermissions) {
|
|
2742
|
+
const summary = formatPermissionsSummary$1(declaredPermissions);
|
|
2743
|
+
if (summary.length > 0) {
|
|
2744
|
+
console.log("\nThis app requests the following permissions:");
|
|
2745
|
+
for (const item of summary) console.log(item);
|
|
2746
|
+
console.log("");
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2709
2749
|
console.log("🔐 Checking permissions...");
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2750
|
+
let allowApiKey = false;
|
|
2751
|
+
let sandboxConfig = null;
|
|
2752
|
+
if (declaredPermissions?.apiKeys) {
|
|
2753
|
+
allowApiKey = await checkApiKeyPermission$1(appId);
|
|
2754
|
+
if (!allowApiKey) {
|
|
2755
|
+
console.error("❌ Permission denied: API key access rejected");
|
|
2756
|
+
process.exit(1);
|
|
2757
|
+
}
|
|
2714
2758
|
}
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2759
|
+
if (declaredPermissions) sandboxConfig = buildSandboxConfig$1(declaredPermissions);
|
|
2760
|
+
else {
|
|
2761
|
+
sandboxConfig = await getAppSandboxConfig$1(appId);
|
|
2762
|
+
if (!sandboxConfig) {
|
|
2763
|
+
console.error("❌ Permission denied: Sandbox configuration rejected");
|
|
2764
|
+
process.exit(1);
|
|
2765
|
+
}
|
|
2719
2766
|
}
|
|
2720
2767
|
if (mcp) {
|
|
2721
2768
|
console.warn("⚠️ MCP mode with remote repos not yet fully supported in new architecture");
|
|
@@ -2884,5 +2931,5 @@ main().catch((err) => {
|
|
|
2884
2931
|
});
|
|
2885
2932
|
|
|
2886
2933
|
//#endregion
|
|
2887
|
-
export {
|
|
2934
|
+
export { getAppIdentifier as a, listPermissions as c, savePermissions as d, launchSandbox as f, clearAllPermissions as i, loadPermissions as l, formatPermissionsSummary as n, getAppName as o, checkApiKeyPermission as r, getAppSandboxConfig as s, buildSandboxConfig as t, revokePermission as u };
|
|
2888
2935
|
//# sourceMappingURL=kly.mjs.map
|