@topolo/cli 0.12.1 → 0.12.3
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/index.js +81 -30
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { platform as platform2 } from "os";
|
|
|
9
9
|
import { createInterface } from "readline/promises";
|
|
10
10
|
import { stdin as input } from "process";
|
|
11
11
|
|
|
12
|
-
// node_modules/@topolo/sdk/dist/index.js
|
|
12
|
+
// node_modules/.pnpm/@topolo+sdk@0.21.2/node_modules/@topolo/sdk/dist/index.js
|
|
13
13
|
function applyAuthHeaders(headers, credential) {
|
|
14
14
|
if (credential.kind === "api_key") {
|
|
15
15
|
headers.set("X-Api-Key", credential.apiKey);
|
|
@@ -3342,7 +3342,7 @@ function createTopolo(options) {
|
|
|
3342
3342
|
};
|
|
3343
3343
|
}
|
|
3344
3344
|
|
|
3345
|
-
// node_modules/@topolo/sdk/dist/node/credential-store.js
|
|
3345
|
+
// node_modules/.pnpm/@topolo+sdk@0.21.2/node_modules/@topolo/sdk/dist/node/credential-store.js
|
|
3346
3346
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2, chmod as chmod2, rm as rm2, stat } from "fs/promises";
|
|
3347
3347
|
import { existsSync as existsSync2 } from "fs";
|
|
3348
3348
|
import { homedir as homedir2, platform } from "os";
|
|
@@ -3760,6 +3760,24 @@ function topoloServiceOrigins2(serviceUrls, environment) {
|
|
|
3760
3760
|
);
|
|
3761
3761
|
}
|
|
3762
3762
|
var KEYCHAIN_SERVICE = "topolo-external-agent-installation";
|
|
3763
|
+
var MACOS_KEYCHAIN_CHUNK_SIZE = 96;
|
|
3764
|
+
var MACOS_KEYCHAIN_CHUNK_PREFIX = "topolo-keychain-chunks:v1:";
|
|
3765
|
+
var MACOS_KEYCHAIN_WRITE_SCRIPT = [
|
|
3766
|
+
"log_user 0",
|
|
3767
|
+
"set timeout 10",
|
|
3768
|
+
"set secret [gets stdin]",
|
|
3769
|
+
"spawn -noecho /usr/bin/security add-generic-password -U -a $env(TOPOLO_KEYCHAIN_ACCOUNT) -s $env(TOPOLO_KEYCHAIN_SERVICE) -w",
|
|
3770
|
+
"for {set prompt 0} {$prompt < 2} {incr prompt} {",
|
|
3771
|
+
" expect {",
|
|
3772
|
+
' -re {(?i)password} { send -- "$secret\\r" }',
|
|
3773
|
+
" timeout { exit 70 }",
|
|
3774
|
+
" eof { exit 71 }",
|
|
3775
|
+
" }",
|
|
3776
|
+
"}",
|
|
3777
|
+
"expect eof",
|
|
3778
|
+
"set result [wait]",
|
|
3779
|
+
"exit [lindex $result 3]"
|
|
3780
|
+
].join("\n");
|
|
3763
3781
|
function installationStorePath() {
|
|
3764
3782
|
const override = process.env.TOPOLO_INSTALLATIONS_PATH?.trim();
|
|
3765
3783
|
if (override) return override;
|
|
@@ -3784,40 +3802,73 @@ function createPlatformInstallationSecretBackend(options = {}) {
|
|
|
3784
3802
|
const spawn2 = options.spawn ?? ((command, args, spawnOptions) => spawnSync(command, args, spawnOptions));
|
|
3785
3803
|
const root = options.root ?? installationStorePath();
|
|
3786
3804
|
if (platform22 === "darwin") {
|
|
3805
|
+
const write = (account, value) => runOrThrow(spawn2("/usr/bin/expect", ["-c", MACOS_KEYCHAIN_WRITE_SCRIPT], {
|
|
3806
|
+
input: `${value}
|
|
3807
|
+
`,
|
|
3808
|
+
encoding: "utf8",
|
|
3809
|
+
env: {
|
|
3810
|
+
...process.env,
|
|
3811
|
+
TOPOLO_KEYCHAIN_ACCOUNT: account,
|
|
3812
|
+
TOPOLO_KEYCHAIN_SERVICE: KEYCHAIN_SERVICE
|
|
3813
|
+
}
|
|
3814
|
+
}), "macOS Keychain write");
|
|
3815
|
+
const read = (account) => {
|
|
3816
|
+
const result = spawn2("security", [
|
|
3817
|
+
"find-generic-password",
|
|
3818
|
+
"-a",
|
|
3819
|
+
account,
|
|
3820
|
+
"-s",
|
|
3821
|
+
KEYCHAIN_SERVICE,
|
|
3822
|
+
"-w"
|
|
3823
|
+
], { encoding: "utf8" });
|
|
3824
|
+
if (result.status === 44) return null;
|
|
3825
|
+
return runOrThrow(result, "macOS Keychain read");
|
|
3826
|
+
};
|
|
3827
|
+
const remove = (account) => {
|
|
3828
|
+
const result = spawn2("security", [
|
|
3829
|
+
"delete-generic-password",
|
|
3830
|
+
"-a",
|
|
3831
|
+
account,
|
|
3832
|
+
"-s",
|
|
3833
|
+
KEYCHAIN_SERVICE
|
|
3834
|
+
], { encoding: "utf8" });
|
|
3835
|
+
if (result.status !== 44) runOrThrow(result, "macOS Keychain delete");
|
|
3836
|
+
};
|
|
3837
|
+
const chunkAccount = (account, index) => `${account}:chunk:${index}`;
|
|
3838
|
+
const chunkCount = (value) => {
|
|
3839
|
+
if (!value?.startsWith(MACOS_KEYCHAIN_CHUNK_PREFIX)) return 0;
|
|
3840
|
+
const count = Number(value.slice(MACOS_KEYCHAIN_CHUNK_PREFIX.length));
|
|
3841
|
+
if (!Number.isSafeInteger(count) || count < 1) throw new Error("macOS Keychain chunk manifest is invalid.");
|
|
3842
|
+
return count;
|
|
3843
|
+
};
|
|
3787
3844
|
return {
|
|
3788
3845
|
async set(account, value) {
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3846
|
+
const previousCount = chunkCount(read(account));
|
|
3847
|
+
const chunks = Array.from(
|
|
3848
|
+
{ length: Math.max(1, Math.ceil(value.length / MACOS_KEYCHAIN_CHUNK_SIZE)) },
|
|
3849
|
+
(_, index) => value.slice(index * MACOS_KEYCHAIN_CHUNK_SIZE, (index + 1) * MACOS_KEYCHAIN_CHUNK_SIZE)
|
|
3850
|
+
);
|
|
3851
|
+
try {
|
|
3852
|
+
chunks.forEach((chunk, index) => write(chunkAccount(account, index), chunk));
|
|
3853
|
+
write(account, `${MACOS_KEYCHAIN_CHUNK_PREFIX}${chunks.length}`);
|
|
3854
|
+
for (let index = chunks.length; index < previousCount; index += 1) remove(chunkAccount(account, index));
|
|
3855
|
+
} catch (error) {
|
|
3856
|
+
chunks.forEach((_, index) => remove(chunkAccount(account, index)));
|
|
3857
|
+
throw error;
|
|
3858
|
+
}
|
|
3799
3859
|
},
|
|
3800
3860
|
async get(account) {
|
|
3801
|
-
const
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
"-w"
|
|
3808
|
-
], { encoding: "utf8" });
|
|
3809
|
-
if (result.status === 44) return null;
|
|
3810
|
-
return runOrThrow(result, "macOS Keychain read");
|
|
3861
|
+
const manifest = read(account);
|
|
3862
|
+
const count = chunkCount(manifest);
|
|
3863
|
+
if (!count) return manifest;
|
|
3864
|
+
const chunks = Array.from({ length: count }, (_, index) => read(chunkAccount(account, index)));
|
|
3865
|
+
if (chunks.some((chunk) => chunk === null)) throw new Error("macOS Keychain installation secret is incomplete.");
|
|
3866
|
+
return chunks.join("");
|
|
3811
3867
|
},
|
|
3812
3868
|
async delete(account) {
|
|
3813
|
-
const
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
account,
|
|
3817
|
-
"-s",
|
|
3818
|
-
KEYCHAIN_SERVICE
|
|
3819
|
-
], { encoding: "utf8" });
|
|
3820
|
-
if (result.status !== 44) runOrThrow(result, "macOS Keychain delete");
|
|
3869
|
+
const count = chunkCount(read(account));
|
|
3870
|
+
for (let index = 0; index < count; index += 1) remove(chunkAccount(account, index));
|
|
3871
|
+
remove(account);
|
|
3821
3872
|
}
|
|
3822
3873
|
};
|
|
3823
3874
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/cli",
|
|
3
3
|
"packageManager": "pnpm@10.17.1",
|
|
4
|
-
"version": "0.12.
|
|
5
|
-
"topoloPublishedVersion": "0.12.
|
|
4
|
+
"version": "0.12.3",
|
|
5
|
+
"topoloPublishedVersion": "0.12.3",
|
|
6
6
|
"description": "Public command-line interface for Topolo customer organizations, developers, and agents.",
|
|
7
7
|
"license": "UNLICENSED",
|
|
8
8
|
"author": "Topolo",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
31
|
-
"@topolo/mcp": "0.13.
|
|
32
|
-
"@topolo/sdk": "0.21.
|
|
31
|
+
"@topolo/mcp": "0.13.2",
|
|
32
|
+
"@topolo/sdk": "0.21.2",
|
|
33
33
|
"commander": "^12.1.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|