neozip-cli 0.80.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.
Files changed (74) hide show
  1. package/AGENTS.md +93 -0
  2. package/CHANGELOG.md +117 -12
  3. package/DOCUMENTATION.md +33 -38
  4. package/README.md +137 -63
  5. package/dist/src/account/account-state.js +95 -0
  6. package/dist/src/account/format-account-status.js +62 -0
  7. package/dist/src/account/identity-provision.js +79 -0
  8. package/dist/src/account/identity-wrap.js +106 -0
  9. package/dist/src/account/profile-crypto.js +85 -0
  10. package/dist/src/account/profile-store.js +129 -0
  11. package/dist/src/account/require-account.js +32 -0
  12. package/dist/src/account/types.js +3 -0
  13. package/dist/src/account/wallet-evm.js +46 -0
  14. package/dist/src/account/wallet-setup.js +33 -0
  15. package/dist/src/archive/crypto-self.js +117 -0
  16. package/dist/src/archive/identity-key.js +217 -0
  17. package/dist/src/archive/recipient-lookup.js +61 -0
  18. package/dist/src/cli/output.js +100 -0
  19. package/dist/src/cli/params.js +122 -0
  20. package/dist/src/cli/schema.js +186 -0
  21. package/dist/src/cli/validate.js +119 -0
  22. package/dist/src/commands/mintTimestampProof.js +26 -14
  23. package/dist/src/config/ConfigSetup.js +82 -423
  24. package/dist/src/connect/command.js +364 -0
  25. package/dist/src/connection/bootstrap.js +50 -0
  26. package/dist/src/connection/cli-guidance.js +101 -0
  27. package/dist/src/connection/cli-prefs.js +180 -0
  28. package/dist/src/connection/cli-settings.js +140 -0
  29. package/dist/src/connection/cli-types.js +14 -0
  30. package/dist/src/connection/coordinator.js +83 -0
  31. package/dist/src/connection/credentials.js +33 -0
  32. package/dist/src/connection/crypto.js +96 -0
  33. package/dist/src/connection/dump.js +117 -0
  34. package/dist/src/connection/funding.js +187 -0
  35. package/dist/src/connection/incomplete-setup.js +89 -0
  36. package/dist/src/connection/interactive.js +871 -0
  37. package/dist/src/connection/legacy-profile-reader.js +87 -0
  38. package/dist/src/connection/magic-link.js +142 -0
  39. package/dist/src/connection/migrate.js +115 -0
  40. package/dist/src/connection/onboarding.js +616 -0
  41. package/dist/src/connection/origin.js +69 -0
  42. package/dist/src/connection/phase.js +101 -0
  43. package/dist/src/connection/phone.js +26 -0
  44. package/dist/src/connection/promote-active.js +56 -0
  45. package/dist/src/connection/reset.js +56 -0
  46. package/dist/src/connection/status-report.js +52 -0
  47. package/dist/src/connection/store.js +406 -0
  48. package/dist/src/connection/token-auth.js +44 -0
  49. package/dist/src/connection/types.js +3 -0
  50. package/dist/src/connection/wallet-json-migration.js +155 -0
  51. package/dist/src/connection/wallet-login.js +65 -0
  52. package/dist/src/connection/wallet-setup.js +83 -0
  53. package/dist/src/constants/wallet-identity.js +14 -0
  54. package/dist/src/exit-codes.js +54 -10
  55. package/dist/src/neolist.js +100 -10
  56. package/dist/src/neounzip.js +236 -65
  57. package/dist/src/neozip/blockchain.js +18 -18
  58. package/dist/src/neozip/createZip.js +118 -94
  59. package/dist/src/neozip/upgradeZip.js +14 -11
  60. package/dist/src/neozip.js +269 -91
  61. package/dist/src/skills/command.js +256 -0
  62. package/dist/src/skills/locate.js +99 -0
  63. package/dist/src/util/mask.js +34 -0
  64. package/dist/src/util/token-service-fetch.js +26 -0
  65. package/env.example +18 -85
  66. package/package.json +89 -73
  67. package/skills/neozip-connect/SKILL.md +95 -0
  68. package/skills/neozip-create/SKILL.md +57 -0
  69. package/skills/neozip-extract/SKILL.md +58 -0
  70. package/skills/neozip-legacy/SKILL.md +48 -0
  71. package/skills/neozip-list/SKILL.md +56 -0
  72. package/skills/neozip-shared/SKILL.md +60 -0
  73. package/dist/src/commands/verifyEmail.js +0 -146
  74. package/dist/src/config/ConfigStore.js +0 -406
@@ -0,0 +1,87 @@
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.LEGACY_MCP_PROFILE_DIR = void 0;
37
+ exports.listLegacyProfiles = listLegacyProfiles;
38
+ exports.getLegacyActiveProfileId = getLegacyActiveProfileId;
39
+ exports.readLegacySecrets = readLegacySecrets;
40
+ exports.hasLegacyMcpProfiles = hasLegacyMcpProfiles;
41
+ const fs = __importStar(require("node:fs"));
42
+ const os = __importStar(require("node:os"));
43
+ const path = __importStar(require("node:path"));
44
+ const profile_crypto_1 = require("../account/profile-crypto");
45
+ exports.LEGACY_MCP_PROFILE_DIR = process.env.NEOZIP_MCP_PROFILE_DIR?.trim() ||
46
+ path.join(os.homedir(), ".neozip", "mcp");
47
+ const PROFILES_PATH = () => path.join(exports.LEGACY_MCP_PROFILE_DIR, "profiles.json");
48
+ const ACTIVE_PATH = () => path.join(exports.LEGACY_MCP_PROFILE_DIR, "active.json");
49
+ const SECRETS_DIR = () => path.join(exports.LEGACY_MCP_PROFILE_DIR, "secrets");
50
+ function readProfilesFile() {
51
+ if (!fs.existsSync(PROFILES_PATH())) {
52
+ return { version: 1, profiles: [] };
53
+ }
54
+ return JSON.parse(fs.readFileSync(PROFILES_PATH(), "utf8"));
55
+ }
56
+ function listLegacyProfiles() {
57
+ return readProfilesFile().profiles;
58
+ }
59
+ function getLegacyActiveProfileId() {
60
+ if (!fs.existsSync(ACTIVE_PATH()))
61
+ return null;
62
+ const active = JSON.parse(fs.readFileSync(ACTIVE_PATH(), "utf8"));
63
+ return active.profileId;
64
+ }
65
+ function readLegacySecrets(profileId) {
66
+ const sp = path.join(SECRETS_DIR(), `${profileId}.json.enc`);
67
+ if (!fs.existsSync(sp))
68
+ return null;
69
+ try {
70
+ return (0, profile_crypto_1.decryptJson)(fs.readFileSync(sp, "utf8"));
71
+ }
72
+ catch {
73
+ return null;
74
+ }
75
+ }
76
+ function hasLegacyMcpProfiles() {
77
+ if (!fs.existsSync(PROFILES_PATH()))
78
+ return false;
79
+ try {
80
+ const data = readProfilesFile();
81
+ return data.profiles.length > 0;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ //# sourceMappingURL=legacy-profile-reader.js.map
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ /**
3
+ * Parse user-pasted email verification input (aligned with neozip-desktop magicLinkToken.ts).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.normalizeMagicLinkTokenInput = normalizeMagicLinkTokenInput;
7
+ exports.extractEmailCodePair = extractEmailCodePair;
8
+ const DIGIT_CODE_REGEX = /^\d{4,10}$/;
9
+ function safeDecodeURIComponent(s) {
10
+ try {
11
+ if (/%[0-9A-Fa-f]{2}/.test(s))
12
+ return decodeURIComponent(s);
13
+ }
14
+ catch {
15
+ /* keep */
16
+ }
17
+ return s;
18
+ }
19
+ function extractEmailCodeFromHttpUrl(s) {
20
+ try {
21
+ const u = new URL(s);
22
+ const email = u.searchParams.get("email");
23
+ const code = u.searchParams.get("code");
24
+ if (email || code) {
25
+ return {
26
+ email: email ? safeDecodeURIComponent(email).trim().toLowerCase() : undefined,
27
+ code: code ? safeDecodeURIComponent(code).replace(/\D/g, "") : undefined,
28
+ };
29
+ }
30
+ if (u.hash && u.hash.length > 2) {
31
+ const h = u.hash.startsWith("#") ? u.hash.slice(1) : u.hash;
32
+ const hp = new URLSearchParams(h);
33
+ const he = hp.get("email");
34
+ const hc = hp.get("code");
35
+ if (he || hc) {
36
+ return {
37
+ email: he ? safeDecodeURIComponent(he).trim().toLowerCase() : undefined,
38
+ code: hc ? safeDecodeURIComponent(hc).replace(/\D/g, "") : undefined,
39
+ };
40
+ }
41
+ }
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ return null;
47
+ }
48
+ function extractFromHttpUrl(s) {
49
+ try {
50
+ const u = new URL(s);
51
+ const fromQuery = u.searchParams.get("token") ??
52
+ u.searchParams.get("t") ??
53
+ u.searchParams.get("code") ??
54
+ u.searchParams.get("verifyToken") ??
55
+ u.searchParams.get("verification") ??
56
+ u.searchParams.get("key");
57
+ if (fromQuery)
58
+ return safeDecodeURIComponent(fromQuery);
59
+ const pathParts = u.pathname.split("/").filter(Boolean);
60
+ const lastSeg = pathParts[pathParts.length - 1];
61
+ if (lastSeg &&
62
+ lastSeg.split(".").length === 3 &&
63
+ lastSeg.split(".").every((x) => x.length > 0)) {
64
+ return lastSeg;
65
+ }
66
+ if (u.hash && u.hash.length > 2) {
67
+ const h = u.hash.startsWith("#") ? u.hash.slice(1) : u.hash;
68
+ const hp = new URLSearchParams(h);
69
+ const fromHash = hp.get("token") ?? hp.get("t") ?? hp.get("code") ?? hp.get("access_token");
70
+ if (fromHash)
71
+ return safeDecodeURIComponent(fromHash);
72
+ }
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ return null;
78
+ }
79
+ /** Extract opaque token for POST /auth/exchange-token. */
80
+ function normalizeMagicLinkTokenInput(raw) {
81
+ let s = String(raw ?? "")
82
+ .trim()
83
+ .replace(/[\u00a0\u200b\uFEFF]/g, "")
84
+ .replace(/^["']|["']$/g, "");
85
+ if (!s)
86
+ return "";
87
+ if (/^https?:\/\//i.test(s)) {
88
+ s = s.replace(/[\n\r\t]+/g, "");
89
+ }
90
+ else {
91
+ s = s.replace(/\s/g, "");
92
+ }
93
+ if (/^https?:\/\//i.test(s)) {
94
+ const extracted = extractFromHttpUrl(s);
95
+ if (extracted)
96
+ return extracted;
97
+ }
98
+ const fromToken = s.match(/(?:^|[?&#])token=([^&\s#]+)/i);
99
+ if (fromToken?.[1]) {
100
+ return safeDecodeURIComponent(fromToken[1]);
101
+ }
102
+ const fromCode = s.match(/(?:^|[?&#])code=([^&\s#]+)/i);
103
+ if (fromCode?.[1] && !/^https?:\/\//i.test(s)) {
104
+ return safeDecodeURIComponent(fromCode[1]);
105
+ }
106
+ return safeDecodeURIComponent(s);
107
+ }
108
+ /** Extract { email, code } for POST /auth/verify-email-code. */
109
+ function extractEmailCodePair(raw) {
110
+ let s = String(raw ?? "")
111
+ .trim()
112
+ .replace(/[\u00a0\u200b\uFEFF]/g, "")
113
+ .replace(/^["']|["']$/g, "");
114
+ if (!s)
115
+ return {};
116
+ const isUrl = /^https?:\/\//i.test(s);
117
+ if (isUrl) {
118
+ s = s.replace(/[\n\r\t]+/g, "");
119
+ const fromUrl = extractEmailCodeFromHttpUrl(s);
120
+ if (fromUrl)
121
+ return fromUrl;
122
+ return {};
123
+ }
124
+ const emailMatch = s.match(/(?:^|[?&#])email=([^&\s#]+)/i);
125
+ const codeMatch = s.match(/(?:^|[?&#])code=([^&\s#]+)/i);
126
+ if (emailMatch || codeMatch) {
127
+ return {
128
+ email: emailMatch
129
+ ? safeDecodeURIComponent(emailMatch[1]).trim().toLowerCase()
130
+ : undefined,
131
+ code: codeMatch
132
+ ? safeDecodeURIComponent(codeMatch[1]).replace(/\D/g, "")
133
+ : undefined,
134
+ };
135
+ }
136
+ const digitsOnly = s.replace(/[\s-]/g, "");
137
+ if (DIGIT_CODE_REGEX.test(digitsOnly)) {
138
+ return { code: digitsOnly };
139
+ }
140
+ return {};
141
+ }
142
+ //# sourceMappingURL=magic-link.js.map
@@ -0,0 +1,115 @@
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.migrateFromWalletJson = exports.hasLegacyMcpProfiles = void 0;
37
+ exports.migrateFromMcpProfileStore = migrateFromMcpProfileStore;
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const crypto_1 = require("./crypto");
41
+ const legacy_profile_reader_1 = require("./legacy-profile-reader");
42
+ Object.defineProperty(exports, "hasLegacyMcpProfiles", { enumerable: true, get: function () { return legacy_profile_reader_1.hasLegacyMcpProfiles; } });
43
+ const store_1 = require("./store");
44
+ const wallet_json_migration_1 = require("./wallet-json-migration");
45
+ Object.defineProperty(exports, "migrateFromWalletJson", { enumerable: true, get: function () { return wallet_json_migration_1.migrateFromWalletJson; } });
46
+ function migrateFromMcpProfileStore() {
47
+ if ((0, store_1.listConnectionIds)().length > 0) {
48
+ return {
49
+ migrated: 0,
50
+ skipped: (0, legacy_profile_reader_1.listLegacyProfiles)().length,
51
+ connectionDir: (0, store_1.getConnectionDir)(),
52
+ activeConnectionId: (0, store_1.getActiveConnectionId)(),
53
+ };
54
+ }
55
+ const profiles = (0, legacy_profile_reader_1.listLegacyProfiles)();
56
+ if (profiles.length === 0) {
57
+ return {
58
+ migrated: 0,
59
+ skipped: 0,
60
+ connectionDir: (0, store_1.getConnectionDir)(),
61
+ activeConnectionId: null,
62
+ };
63
+ }
64
+ const activeLegacyId = (0, legacy_profile_reader_1.getLegacyActiveProfileId)();
65
+ let activeConnectionId = null;
66
+ let migrated = 0;
67
+ for (const profile of profiles) {
68
+ const secrets = (0, legacy_profile_reader_1.readLegacySecrets)(profile.id);
69
+ const conn = (0, store_1.createConnection)({
70
+ label: profile.label,
71
+ tokenServiceUrl: profile.tokenServiceUrl,
72
+ });
73
+ const legacyExtras = profile;
74
+ (0, store_1.updateConnection)(conn.id, {
75
+ email: profile.email,
76
+ emailVerified: profile.emailVerified,
77
+ emailVerifiedAt: legacyExtras.emailVerifiedAt ??
78
+ (profile.emailVerified ? profile.updatedAt : null),
79
+ evmAddress: profile.evmAddress,
80
+ walletId: profile.walletId,
81
+ linkId: profile.linkId,
82
+ identityKeyId: profile.identityKeyId,
83
+ x25519PublicKeySpkiB64: legacyExtras.x25519PublicKeySpkiB64 ?? null,
84
+ x25519Fingerprint: profile.x25519Fingerprint,
85
+ onboardingCompleteAt: profile.identityKeyId != null ? profile.updatedAt : null,
86
+ });
87
+ if (secrets) {
88
+ const sp = path.join((0, store_1.getConnectionDir)(), "connections", conn.id, "secrets.enc");
89
+ fs.writeFileSync(sp, (0, crypto_1.encryptSecrets)({
90
+ accessToken: secrets.accessToken,
91
+ accessTokenObtainedAt: secrets.accessTokenObtainedAt,
92
+ accessTokenExpiresAt: null,
93
+ evmPrivateKeyHex: secrets.evmPrivateKey?.replace(/^0x/i, "") ?? null,
94
+ }), { mode: 0o600 });
95
+ }
96
+ if (profile.id === activeLegacyId) {
97
+ (0, store_1.selectConnection)(conn.id);
98
+ activeConnectionId = conn.id;
99
+ }
100
+ else if (!activeConnectionId) {
101
+ activeConnectionId = conn.id;
102
+ }
103
+ migrated++;
104
+ }
105
+ if (activeLegacyId && activeConnectionId) {
106
+ (0, store_1.selectConnection)(activeConnectionId);
107
+ }
108
+ return {
109
+ migrated,
110
+ skipped: 0,
111
+ connectionDir: (0, store_1.getConnectionDir)(),
112
+ activeConnectionId: (0, store_1.getActiveConnectionId)(),
113
+ };
114
+ }
115
+ //# sourceMappingURL=migrate.js.map