crosscheck-cli 0.0.44 → 0.0.45
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/cli.js +34 -2
- package/dist/cli.js.map +1 -1
- package/dist/doctor.js +51 -1
- package/dist/doctor.js.map +1 -1
- package/dist/keychain.js +185 -7
- package/dist/keychain.js.map +1 -1
- package/dist/keys-browser-flow.js +1 -1
- package/dist/keys-browser-flow.js.map +1 -1
- package/dist/mcp.js +15 -2
- package/dist/mcp.js.map +1 -1
- package/dist/onepassword/config.js +114 -0
- package/dist/onepassword/config.js.map +1 -0
- package/dist/onepassword/op.js +254 -0
- package/dist/onepassword/op.js.map +1 -0
- package/dist/onepassword/reference.js +82 -0
- package/dist/onepassword/reference.js.map +1 -0
- package/dist/onepassword/setup.js +108 -0
- package/dist/onepassword/setup.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `crosscheck keys setup --backend 1password` — validates the config end to
|
|
3
|
+
* end BEFORE ever persisting the backend preference. Never writes anything
|
|
4
|
+
* to 1Password (the backend is read-only); a "test read" only ever proves
|
|
5
|
+
* connectivity — the value is discarded immediately, never printed, never
|
|
6
|
+
* stored.
|
|
7
|
+
*/
|
|
8
|
+
import { loadOnePasswordConfig, configFilePath } from "./config.js";
|
|
9
|
+
import { checkOpVersion, readOpSecret, MIN_OP_VERSION } from "./op.js";
|
|
10
|
+
import { enableOnePasswordBackend } from "../keychain.js";
|
|
11
|
+
/**
|
|
12
|
+
* Validate config → `op` version → test-read every mapped provider.
|
|
13
|
+
* Discloses provider NAMES only, never a full op:// reference — matching
|
|
14
|
+
* the same disclosure discipline as op.ts's error taxonomy. Never touches
|
|
15
|
+
* the persisted backend preference; the caller only does that after seeing
|
|
16
|
+
* `{ ok: true }`.
|
|
17
|
+
*
|
|
18
|
+
* "Success" here means at least one mapped provider resolved — not that
|
|
19
|
+
* every one did. A single bad item/field name is a per-provider config
|
|
20
|
+
* typo the user can fix later; it shouldn't block enabling the backend for
|
|
21
|
+
* every OTHER provider that already works. A systemic problem (op missing,
|
|
22
|
+
* wrong version, or every single provider failing — usually a signed-out
|
|
23
|
+
* or invalid-token case) DOES block, since persisting a backend where
|
|
24
|
+
* nothing works at all isn't useful and would just defer the failure to
|
|
25
|
+
* the next `crosscheck serve`.
|
|
26
|
+
*/
|
|
27
|
+
export async function validateOnePasswordSetup() {
|
|
28
|
+
const cfg = loadOnePasswordConfig();
|
|
29
|
+
if (!cfg.ok) {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
stage: "config",
|
|
33
|
+
detail: `${cfg.error}: ${cfg.detail} (expected at ${configFilePath()})`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const versionCheck = await checkOpVersion();
|
|
37
|
+
if (!versionCheck.ok) {
|
|
38
|
+
return { ok: false, stage: "op-version", detail: versionCheck.detail };
|
|
39
|
+
}
|
|
40
|
+
const providerNames = Object.keys(cfg.config.mappings).sort();
|
|
41
|
+
const results = [];
|
|
42
|
+
for (const provider of providerNames) {
|
|
43
|
+
const ref = cfg.config.mappings[provider];
|
|
44
|
+
const result = await readOpSecret(ref, {
|
|
45
|
+
authMode: cfg.config.authMode,
|
|
46
|
+
serviceAccountToken: cfg.config.authMode === "service-account"
|
|
47
|
+
? process.env.OP_SERVICE_ACCOUNT_TOKEN
|
|
48
|
+
: undefined,
|
|
49
|
+
});
|
|
50
|
+
results.push(result.ok
|
|
51
|
+
? { provider, ok: true }
|
|
52
|
+
: { provider, ok: false, error: `${result.error}: ${result.detail}` });
|
|
53
|
+
}
|
|
54
|
+
if (providerNames.length === 0) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
stage: "no-providers-resolved",
|
|
58
|
+
detail: "no providers are mapped in the config — add at least one before enabling",
|
|
59
|
+
providers: results,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (!results.some((r) => r.ok)) {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
stage: "no-providers-resolved",
|
|
66
|
+
detail: "no configured provider resolved successfully",
|
|
67
|
+
providers: results,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { ok: true, authMode: cfg.config.authMode, providers: results };
|
|
71
|
+
}
|
|
72
|
+
function printProviderResults(results) {
|
|
73
|
+
for (const p of results) {
|
|
74
|
+
process.stdout.write(p.ok ? ` ✓ ${p.provider}\n` : ` ✗ ${p.provider}: ${p.error}\n`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Orchestrates `crosscheck keys setup --backend 1password`: validate, then
|
|
78
|
+
* (only on success) persist the preference and report what's usable. */
|
|
79
|
+
export async function runOnePasswordKeysSetup() {
|
|
80
|
+
process.stdout.write("\nValidating your 1Password configuration...\n");
|
|
81
|
+
const result = await validateOnePasswordSetup();
|
|
82
|
+
if (!result.ok) {
|
|
83
|
+
process.stderr.write(`\n✗ ${result.detail}\n`);
|
|
84
|
+
if (result.stage === "config") {
|
|
85
|
+
process.stderr.write(`\nExpected a config at ${configFilePath()} shaped like:\n` +
|
|
86
|
+
' {\n "authMode": "desktop",\n "mappings": { "anthropic": "op://Vault/Item/field" }\n }\n' +
|
|
87
|
+
'\n(authMode is "desktop" or "service-account"; for service-account mode, set\n' +
|
|
88
|
+
"OP_SERVICE_ACCOUNT_TOKEN in the environment — never store it in this file.)\n");
|
|
89
|
+
}
|
|
90
|
+
if (result.stage === "op-version") {
|
|
91
|
+
process.stderr.write(`\nRequires the 1Password CLI (\`op\`), version >= ${MIN_OP_VERSION}.\n`);
|
|
92
|
+
}
|
|
93
|
+
if (result.providers)
|
|
94
|
+
printProviderResults(result.providers);
|
|
95
|
+
process.stderr.write("\nFix the above, then re-run `crosscheck keys setup --backend 1password`.\n\n");
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
enableOnePasswordBackend();
|
|
100
|
+
process.stdout.write(`\n✓ 1Password backend enabled (authMode: ${result.authMode}).\n\n`);
|
|
101
|
+
printProviderResults(result.providers);
|
|
102
|
+
process.stdout.write("\nMachine-local secrets (activation, HMAC signing key) still use the local\n" +
|
|
103
|
+
"encrypted file, unchanged — only providers marked ✓ above are read from\n" +
|
|
104
|
+
"1Password. Anything else (including a ✗ above) falls back to whatever's\n" +
|
|
105
|
+
"already stored locally, if anything.\n\n" +
|
|
106
|
+
"Run `crosscheck doctor` any time to recheck this.\n\n");
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/onepassword/setup.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crosscheck-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"description": "Crosscheck — multi-LLM orchestration MCP for the terminal. Single-machine activation, BYO upstream LLM keys, content-free telemetry. Installs into Claude Code in one command.",
|
|
5
5
|
"license": "SEE LICENSE.md",
|
|
6
6
|
"type": "module",
|