neozip-cli 0.90.0 → 0.95.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/AGENTS.md +93 -0
- package/CHANGELOG.md +58 -1
- package/DOCUMENTATION.md +22 -30
- package/README.md +104 -42
- package/dist/src/account/account-state.js +95 -0
- package/dist/src/account/format-account-status.js +62 -0
- package/dist/src/account/identity-provision.js +79 -0
- package/dist/src/account/identity-wrap.js +106 -0
- package/dist/src/account/profile-crypto.js +85 -0
- package/dist/src/account/profile-store.js +129 -0
- package/dist/src/account/require-account.js +32 -0
- package/dist/src/account/types.js +3 -0
- package/dist/src/account/wallet-evm.js +46 -0
- package/dist/src/account/wallet-setup.js +33 -0
- package/dist/src/archive/crypto-self.js +117 -0
- package/dist/src/archive/identity-key.js +217 -0
- package/dist/src/archive/recipient-lookup.js +61 -0
- package/dist/src/cli/output.js +100 -0
- package/dist/src/cli/params.js +122 -0
- package/dist/src/cli/schema.js +186 -0
- package/dist/src/cli/validate.js +119 -0
- package/dist/src/commands/mintTimestampProof.js +26 -14
- package/dist/src/config/ConfigSetup.js +82 -423
- package/dist/src/connect/command.js +364 -0
- package/dist/src/connection/bootstrap.js +50 -0
- package/dist/src/connection/cli-guidance.js +101 -0
- package/dist/src/connection/cli-prefs.js +180 -0
- package/dist/src/connection/cli-settings.js +140 -0
- package/dist/src/connection/cli-types.js +14 -0
- package/dist/src/connection/coordinator.js +83 -0
- package/dist/src/connection/credentials.js +33 -0
- package/dist/src/connection/crypto.js +96 -0
- package/dist/src/connection/dump.js +117 -0
- package/dist/src/connection/funding.js +187 -0
- package/dist/src/connection/incomplete-setup.js +89 -0
- package/dist/src/connection/interactive.js +871 -0
- package/dist/src/connection/legacy-profile-reader.js +87 -0
- package/dist/src/connection/magic-link.js +142 -0
- package/dist/src/connection/migrate.js +115 -0
- package/dist/src/connection/onboarding.js +616 -0
- package/dist/src/connection/origin.js +69 -0
- package/dist/src/connection/phase.js +101 -0
- package/dist/src/connection/phone.js +26 -0
- package/dist/src/connection/promote-active.js +56 -0
- package/dist/src/connection/reset.js +56 -0
- package/dist/src/connection/status-report.js +52 -0
- package/dist/src/connection/store.js +406 -0
- package/dist/src/connection/token-auth.js +44 -0
- package/dist/src/connection/types.js +3 -0
- package/dist/src/connection/wallet-json-migration.js +155 -0
- package/dist/src/connection/wallet-login.js +65 -0
- package/dist/src/connection/wallet-setup.js +83 -0
- package/dist/src/constants/wallet-identity.js +14 -0
- package/dist/src/exit-codes.js +54 -10
- package/dist/src/neolist.js +93 -9
- package/dist/src/neounzip.js +217 -59
- package/dist/src/neozip/blockchain.js +18 -18
- package/dist/src/neozip/createZip.js +114 -91
- package/dist/src/neozip/upgradeZip.js +14 -11
- package/dist/src/neozip.js +252 -75
- package/dist/src/skills/command.js +256 -0
- package/dist/src/skills/locate.js +99 -0
- package/dist/src/util/mask.js +34 -0
- package/dist/src/util/token-service-fetch.js +26 -0
- package/env.example +18 -85
- package/package.json +89 -82
- package/skills/neozip-connect/SKILL.md +95 -0
- package/skills/neozip-create/SKILL.md +57 -0
- package/skills/neozip-extract/SKILL.md +58 -0
- package/skills/neozip-legacy/SKILL.md +48 -0
- package/skills/neozip-list/SKILL.md +56 -0
- package/skills/neozip-shared/SKILL.md +60 -0
- package/dist/src/commands/verifyEmail.js +0 -146
- package/dist/src/config/ConfigStore.js +0 -406
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeConnectionPhaseForId = computeConnectionPhaseForId;
|
|
4
|
+
exports.listReadyConnectionIds = listReadyConnectionIds;
|
|
5
|
+
exports.computeConnectionPhase = computeConnectionPhase;
|
|
6
|
+
exports.resolveConnectionPhase = resolveConnectionPhase;
|
|
7
|
+
exports.accountPhaseFromConnection = accountPhaseFromConnection;
|
|
8
|
+
exports.nextConnectCommand = nextConnectCommand;
|
|
9
|
+
const phone_1 = require("./phone");
|
|
10
|
+
const store_1 = require("./store");
|
|
11
|
+
function shellQuote(value) {
|
|
12
|
+
if (/^[a-zA-Z0-9@._+-]+$/.test(value))
|
|
13
|
+
return value;
|
|
14
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
15
|
+
}
|
|
16
|
+
function phaseFromConnection(meta, secrets) {
|
|
17
|
+
if (!meta || !secrets)
|
|
18
|
+
return "no_profile";
|
|
19
|
+
if (!secrets.accessToken || !meta.emailVerified) {
|
|
20
|
+
return "email_unverified";
|
|
21
|
+
}
|
|
22
|
+
if (meta.phoneE164 && !meta.phoneVerifiedAt) {
|
|
23
|
+
return "phone_required";
|
|
24
|
+
}
|
|
25
|
+
if (!secrets.evmPrivateKeyHex || !meta.evmAddress) {
|
|
26
|
+
return "no_wallet";
|
|
27
|
+
}
|
|
28
|
+
if (!meta.walletId || meta.linkId == null) {
|
|
29
|
+
return "wallet_unlinked";
|
|
30
|
+
}
|
|
31
|
+
if (!meta.identityKeyId) {
|
|
32
|
+
return "identity_missing";
|
|
33
|
+
}
|
|
34
|
+
return "ready";
|
|
35
|
+
}
|
|
36
|
+
function computeConnectionPhaseForId(connectionId) {
|
|
37
|
+
return phaseFromConnection((0, store_1.readConnectionPublic)(connectionId), (0, store_1.readConnectionSecrets)(connectionId));
|
|
38
|
+
}
|
|
39
|
+
function listReadyConnectionIds() {
|
|
40
|
+
return (0, store_1.listConnectionIds)().filter((id) => computeConnectionPhaseForId(id) === "ready");
|
|
41
|
+
}
|
|
42
|
+
function computeConnectionPhase() {
|
|
43
|
+
const connectionId = (0, store_1.getActiveConnectionId)();
|
|
44
|
+
if (!connectionId) {
|
|
45
|
+
return (0, store_1.listConnections)().length > 0 ? "no_profile" : "no_profile";
|
|
46
|
+
}
|
|
47
|
+
return phaseFromConnection((0, store_1.getActiveConnection)(), (0, store_1.readActiveConnectionSecrets)());
|
|
48
|
+
}
|
|
49
|
+
/** Async phase that accounts for coordinator phone requirement. */
|
|
50
|
+
async function resolveConnectionPhase(tokenServiceUrl) {
|
|
51
|
+
const phase = computeConnectionPhase();
|
|
52
|
+
if (phase === "phone_required")
|
|
53
|
+
return phase;
|
|
54
|
+
const meta = (0, store_1.getActiveConnection)();
|
|
55
|
+
if (!meta)
|
|
56
|
+
return phase;
|
|
57
|
+
const origin = tokenServiceUrl?.trim() || meta.tokenServiceOrigin;
|
|
58
|
+
if (await (0, phone_1.needsPhoneVerification)(meta, origin)) {
|
|
59
|
+
return "phone_required";
|
|
60
|
+
}
|
|
61
|
+
return phase;
|
|
62
|
+
}
|
|
63
|
+
function accountPhaseFromConnection() {
|
|
64
|
+
const phase = computeConnectionPhase();
|
|
65
|
+
if (phase === "awaiting_code" || phase === "phone_required") {
|
|
66
|
+
return "email_unverified";
|
|
67
|
+
}
|
|
68
|
+
return phase;
|
|
69
|
+
}
|
|
70
|
+
/** Scriptable next step for incomplete phases (used by CLI JSON and MCP errors). */
|
|
71
|
+
function nextConnectCommand(phase, context) {
|
|
72
|
+
const email = context?.email?.trim().toLowerCase();
|
|
73
|
+
const phone = context?.phoneE164?.trim();
|
|
74
|
+
switch (phase) {
|
|
75
|
+
case "ready":
|
|
76
|
+
return undefined;
|
|
77
|
+
case "no_profile":
|
|
78
|
+
return email
|
|
79
|
+
? `neozip connect register --email ${shellQuote(email)}`
|
|
80
|
+
: "neozip connect register --email user@example.com";
|
|
81
|
+
case "awaiting_code":
|
|
82
|
+
case "email_unverified":
|
|
83
|
+
return email
|
|
84
|
+
? `neozip connect verify --email ${shellQuote(email)} --code 123456`
|
|
85
|
+
: "neozip connect register --email user@example.com";
|
|
86
|
+
case "phone_required":
|
|
87
|
+
return phone
|
|
88
|
+
? `neozip connect phone verify --phone ${shellQuote(phone)} --code 123456`
|
|
89
|
+
: "neozip connect phone request --phone +14155551234";
|
|
90
|
+
case "no_wallet":
|
|
91
|
+
return "neozip connect wallet create --ack-backup";
|
|
92
|
+
case "wallet_unlinked":
|
|
93
|
+
case "identity_missing":
|
|
94
|
+
return "neozip connect finish";
|
|
95
|
+
case "degraded":
|
|
96
|
+
return "neozip connect status";
|
|
97
|
+
default:
|
|
98
|
+
return "neozip connect";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=phase.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPhoneVerified = isPhoneVerified;
|
|
4
|
+
exports.validatePhoneE164 = validatePhoneE164;
|
|
5
|
+
exports.coordinatorRequiresPhone = coordinatorRequiresPhone;
|
|
6
|
+
exports.needsPhoneVerification = needsPhoneVerification;
|
|
7
|
+
const coordinator_1 = require("./coordinator");
|
|
8
|
+
function isPhoneVerified(meta) {
|
|
9
|
+
return meta.phoneVerifiedAt != null;
|
|
10
|
+
}
|
|
11
|
+
function validatePhoneE164(phoneE164) {
|
|
12
|
+
const phone = phoneE164.trim();
|
|
13
|
+
if (!phone.startsWith("+") || phone.length < 8) {
|
|
14
|
+
throw new Error("Phone number must be in E.164 format (e.g. +14155551234).");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function coordinatorRequiresPhone(origin) {
|
|
18
|
+
const config = await (0, coordinator_1.fetchCoordinatorConfigParsed)(origin);
|
|
19
|
+
return config?.cryptoRequirePhoneVerified ?? false;
|
|
20
|
+
}
|
|
21
|
+
async function needsPhoneVerification(meta, origin) {
|
|
22
|
+
if (isPhoneVerified(meta))
|
|
23
|
+
return false;
|
|
24
|
+
return coordinatorRequiresPhone(origin);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=phone.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.promoteReadyActiveConnection = promoteReadyActiveConnection;
|
|
4
|
+
const origin_1 = require("./origin");
|
|
5
|
+
const phase_1 = require("./phase");
|
|
6
|
+
const store_1 = require("./store");
|
|
7
|
+
function promoteReadyActiveConnection(options) {
|
|
8
|
+
if ((0, phase_1.computeConnectionPhase)() === "ready") {
|
|
9
|
+
const active = (0, store_1.getActiveConnectionId)();
|
|
10
|
+
return {
|
|
11
|
+
promoted: false,
|
|
12
|
+
connectionId: active,
|
|
13
|
+
previousConnectionId: null,
|
|
14
|
+
label: active ? ((0, store_1.readConnectionPublic)(active)?.label ?? null) : null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const readyIds = (0, phase_1.listReadyConnectionIds)();
|
|
18
|
+
if (readyIds.length === 0) {
|
|
19
|
+
return {
|
|
20
|
+
promoted: false,
|
|
21
|
+
connectionId: (0, store_1.getActiveConnectionId)(),
|
|
22
|
+
previousConnectionId: null,
|
|
23
|
+
label: null,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
let chosen = readyIds[0];
|
|
27
|
+
const preferred = options?.preferredTokenServiceOrigin?.trim();
|
|
28
|
+
if (preferred) {
|
|
29
|
+
const normalized = (0, origin_1.normalizeTokenServiceOrigin)(preferred);
|
|
30
|
+
const match = readyIds.find((id) => {
|
|
31
|
+
const meta = (0, store_1.readConnectionPublic)(id);
|
|
32
|
+
return meta && (0, origin_1.normalizeTokenServiceOrigin)(meta.tokenServiceOrigin) === normalized;
|
|
33
|
+
});
|
|
34
|
+
if (match)
|
|
35
|
+
chosen = match;
|
|
36
|
+
}
|
|
37
|
+
const previous = (0, store_1.getActiveConnectionId)();
|
|
38
|
+
if (previous === chosen) {
|
|
39
|
+
const meta = (0, store_1.readConnectionPublic)(chosen);
|
|
40
|
+
return {
|
|
41
|
+
promoted: false,
|
|
42
|
+
connectionId: chosen,
|
|
43
|
+
previousConnectionId: previous,
|
|
44
|
+
label: meta?.label ?? null,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const meta = (0, store_1.selectConnection)(chosen);
|
|
48
|
+
(0, store_1.applyActiveConnectionToEnv)();
|
|
49
|
+
return {
|
|
50
|
+
promoted: true,
|
|
51
|
+
connectionId: chosen,
|
|
52
|
+
previousConnectionId: previous,
|
|
53
|
+
label: meta.label,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=promote-active.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resetConnectionStore = resetConnectionStore;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const legacy_profile_reader_1 = require("./legacy-profile-reader");
|
|
39
|
+
const store_1 = require("./store");
|
|
40
|
+
function removeDirIfExists(dir) {
|
|
41
|
+
if (!fs.existsSync(dir))
|
|
42
|
+
return false;
|
|
43
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/** Delete connection file store and legacy MCP profiles so setup can run again. */
|
|
47
|
+
function resetConnectionStore() {
|
|
48
|
+
const connectionDir = (0, store_1.getConnectionDir)();
|
|
49
|
+
return {
|
|
50
|
+
connectionDir,
|
|
51
|
+
legacyMcpDir: legacy_profile_reader_1.LEGACY_MCP_PROFILE_DIR,
|
|
52
|
+
removedConnection: removeDirIfExists(connectionDir),
|
|
53
|
+
removedLegacy: removeDirIfExists(legacy_profile_reader_1.LEGACY_MCP_PROFILE_DIR),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=reset.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAccountDetails = buildAccountDetails;
|
|
4
|
+
exports.buildAllAccountDetails = buildAllAccountDetails;
|
|
5
|
+
exports.formatVerboseStatusText = formatVerboseStatusText;
|
|
6
|
+
const phase_1 = require("./phase");
|
|
7
|
+
const store_1 = require("./store");
|
|
8
|
+
const token_auth_1 = require("./token-auth");
|
|
9
|
+
function buildAccountDetails(meta, activeId) {
|
|
10
|
+
const secrets = (0, store_1.readConnectionSecrets)(meta.id);
|
|
11
|
+
return {
|
|
12
|
+
id: meta.id,
|
|
13
|
+
label: meta.label,
|
|
14
|
+
email: meta.email,
|
|
15
|
+
tokenServiceOrigin: meta.tokenServiceOrigin,
|
|
16
|
+
phase: (0, phase_1.computeConnectionPhaseForId)(meta.id),
|
|
17
|
+
active: meta.id === activeId,
|
|
18
|
+
emailVerified: meta.emailVerified,
|
|
19
|
+
phoneVerified: meta.phoneVerifiedAt != null,
|
|
20
|
+
phoneE164: meta.phoneE164 ?? null,
|
|
21
|
+
onboardingComplete: meta.onboardingCompleteAt != null,
|
|
22
|
+
onboardingExitToApp: meta.onboardingExitToAppAt != null,
|
|
23
|
+
identitySetupDeferralReason: meta.identitySetupDeferralReason ?? null,
|
|
24
|
+
evmAddress: meta.evmAddress,
|
|
25
|
+
hasBearerToken: Boolean(secrets?.accessToken),
|
|
26
|
+
hasWalletKey: Boolean(secrets?.evmPrivateKeyHex),
|
|
27
|
+
accessTokenExpiresAt: secrets?.accessTokenExpiresAt ?? null,
|
|
28
|
+
accessTokenExpired: Boolean(secrets?.accessToken) && (0, token_auth_1.isAccessTokenExpired)(secrets),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function buildAllAccountDetails() {
|
|
32
|
+
const activeId = (0, store_1.getActiveConnectionId)();
|
|
33
|
+
return (0, store_1.listConnections)().map((meta) => buildAccountDetails(meta, activeId));
|
|
34
|
+
}
|
|
35
|
+
function formatVerboseStatusText(details) {
|
|
36
|
+
if (details.length === 0) {
|
|
37
|
+
return `Connection store: ${(0, store_1.getConnectionDir)()}\nNo saved accounts.`;
|
|
38
|
+
}
|
|
39
|
+
const lines = [
|
|
40
|
+
`Connection store: ${(0, store_1.getConnectionDir)()}`,
|
|
41
|
+
`Accounts (${details.length}):`,
|
|
42
|
+
];
|
|
43
|
+
for (const account of details) {
|
|
44
|
+
lines.push(` • ${account.label}${account.active ? " [active]" : ""} (${account.id})`, ` Email: ${account.email ?? "none"} · Phase: ${account.phase}`, ` Token Service: ${account.tokenServiceOrigin}`, ` Phone: ${account.phoneVerified ? account.phoneE164 ?? "verified" : account.phoneE164 ?? "none"}`, ` Onboarding: ${account.onboardingComplete ? "complete" : "incomplete"}${account.onboardingExitToApp ? " · basic mode" : ""}${account.identitySetupDeferralReason ? ` · deferred (${account.identitySetupDeferralReason})` : ""}`, ` Wallet: ${account.evmAddress ?? "none"} · Bearer: ${account.hasBearerToken ? "yes" : "no"} · Key: ${account.hasWalletKey ? "yes" : "no"}`, ` Access token: ${account.accessTokenExpired
|
|
45
|
+
? "EXPIRED — run neozip connect refresh"
|
|
46
|
+
: account.hasBearerToken
|
|
47
|
+
? "valid"
|
|
48
|
+
: "none"}`);
|
|
49
|
+
}
|
|
50
|
+
return lines.join("\n");
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=status-report.js.map
|