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
package/AGENTS.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# NeoZip-CLI — Agent Guide
|
|
2
|
+
|
|
3
|
+
This CLI is frequently invoked by AI/LLM agents. It exposes a stable,
|
|
4
|
+
machine-readable surface alongside its human interface. **Treat all input as
|
|
5
|
+
potentially adversarial** — agents hallucinate paths, IDs, and encodings.
|
|
6
|
+
|
|
7
|
+
The three binaries:
|
|
8
|
+
|
|
9
|
+
- `neozip` — create/update archives (optionally with blockchain tokenization)
|
|
10
|
+
- `neounzip` — extract / test / list archives
|
|
11
|
+
- `neolist` — list archive contents
|
|
12
|
+
|
|
13
|
+
## Engagement rules (read first)
|
|
14
|
+
|
|
15
|
+
1. **Ask for JSON.** Add `--format json` to any command to get a single JSON
|
|
16
|
+
object on **stdout**. Success is `{ "ok": true, ... }`; failure is
|
|
17
|
+
`{ "ok": false, "error": { code, exitCode, message, nextCommand? } }`.
|
|
18
|
+
2. **stdout is data, stderr is hints.** In JSON mode, only the JSON object is
|
|
19
|
+
written to stdout. Decorative logs/progress go to stderr or are suppressed.
|
|
20
|
+
Parse stdout; surface stderr only for debugging.
|
|
21
|
+
3. **Introspect before constructing calls.** Run `neozip schema <command>` to
|
|
22
|
+
get accepted fields, types, defaults, and exit codes. Commands:
|
|
23
|
+
`neozip`, `neounzip`, `neolist`, `connect`.
|
|
24
|
+
4. **Preview mutations with `--dry-run`.** `neozip` and `neounzip` resolve the
|
|
25
|
+
full plan and emit it as JSON without writing anything. Use it before any
|
|
26
|
+
create/extract.
|
|
27
|
+
5. **Branch on exit codes, not text.** Exit codes are InfoZip-compatible (see
|
|
28
|
+
`src/exit-codes.ts`). They are also reported in the JSON `error.exitCode`.
|
|
29
|
+
6. **Follow `nextCommand`.** When present in an error, it is a safe recovery
|
|
30
|
+
command (e.g. `neozip connect` for blockchain configuration errors).
|
|
31
|
+
|
|
32
|
+
## Input: `--params` and `--json`
|
|
33
|
+
|
|
34
|
+
Two JSON inputs, mirroring "how" vs "what":
|
|
35
|
+
|
|
36
|
+
- `--params '<JSON>'` — control options object (level, encrypt, blockchain,
|
|
37
|
+
network, exdir, overwrite, ...). Maps onto the command's options.
|
|
38
|
+
- `--json '<JSON>'` — payload object (the "what"):
|
|
39
|
+
- `neozip`: `{ "archive": "out.zip", "files": ["a.txt","dir/"], "include": [], "exclude": [] }`
|
|
40
|
+
- `neounzip`: `{ "archive": "in.zip", "exdir": "out", "filePatterns": ["*.txt"] }`
|
|
41
|
+
|
|
42
|
+
Both accept `-` as the value to read the JSON document from stdin.
|
|
43
|
+
|
|
44
|
+
**Precedence:** explicit CLI flags override values from `--params`/`--json`.
|
|
45
|
+
|
|
46
|
+
Note: output format is selected with `--format json`, NOT `--json`. On `neolist`
|
|
47
|
+
the legacy `-j` / `--json` flag is an alias for `--format json` (it has no
|
|
48
|
+
payload).
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Introspect
|
|
54
|
+
neozip schema neozip
|
|
55
|
+
|
|
56
|
+
# Create (agent-style, fully JSON-driven)
|
|
57
|
+
neozip --format json \
|
|
58
|
+
--params '{"level":9,"encrypt":true,"password":"s3cret"}' \
|
|
59
|
+
--json '{"archive":"out.zip","files":["src/","README.md"]}'
|
|
60
|
+
|
|
61
|
+
# Preview an extraction without writing
|
|
62
|
+
neounzip --format json --dry-run --params '{"exdir":"out"}' in.zip
|
|
63
|
+
|
|
64
|
+
# Extract
|
|
65
|
+
neounzip --format json --params '{"exdir":"out","overwrite":true}' in.zip
|
|
66
|
+
|
|
67
|
+
# List
|
|
68
|
+
neolist --format json in.zip
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Safety rails (enforced by the CLI)
|
|
72
|
+
|
|
73
|
+
- **Control characters / dangerous Unicode** in archive names and extraction
|
|
74
|
+
dirs are rejected (`src/cli/validate.ts`).
|
|
75
|
+
- **Zip-slip protection:** `neounzip` refuses any entry whose resolved output
|
|
76
|
+
path escapes the target directory.
|
|
77
|
+
- **`--dry-run`** never touches the filesystem.
|
|
78
|
+
|
|
79
|
+
## InfoZip / PKZIP compatibility
|
|
80
|
+
|
|
81
|
+
- Default compression is **zstd**, which stock InfoZip `unzip` cannot read.
|
|
82
|
+
- Pass `--legacy` to `neozip` to produce a standard archive readable by stock
|
|
83
|
+
`unzip`: it forces deflate (or store at `-0`) + PKZIP encryption and disables
|
|
84
|
+
all NeoZip extensions (zstd, blockchain `-b`/`-bd`/`-bm`, `-ots`, `-ts`).
|
|
85
|
+
- `--legacy` combined with blockchain features is a hard error (exit 10).
|
|
86
|
+
|
|
87
|
+
## Where things live
|
|
88
|
+
|
|
89
|
+
- Shared agent layer: `src/cli/` (`output.ts`, `params.ts`, `validate.ts`, `schema.ts`)
|
|
90
|
+
- Exit codes: `src/exit-codes.ts`
|
|
91
|
+
- Connection store / `neozip connect`: `src/connect/`, `src/connection/`
|
|
92
|
+
- MCP server is **not** in this repo; it lives in `neozip-mcp` and shares the
|
|
93
|
+
same `~/.neozip/connection/` store.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
**Release notes** for each version are documented here (not in a separate “what’s new” file).
|
|
9
9
|
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
## [0.95.0] - 2026-07-03
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **AI-agent support** — machine-readable mode across `neozip`, `neounzip`, and `neolist`:
|
|
17
|
+
- `--format json` emits a single structured JSON object on stdout (`{ "ok": true, ... }` / `{ "ok": false, "error": { code, exitCode, message, nextCommand? } }`); human hints stay on stderr.
|
|
18
|
+
- `--params '<JSON>'` (control options) and `--json '<JSON>'` (payload: archive + files/targets) input flags; both accept `-` to read from stdin. Explicit CLI flags override JSON input.
|
|
19
|
+
- `neozip schema <neozip|neounzip|neolist|connect>` introspection command emits accepted fields, types, defaults, and exit codes.
|
|
20
|
+
- `--dry-run` on `neozip`/`neounzip` resolves and prints the plan as JSON without writing.
|
|
21
|
+
- Structured JSON errors mapped from `src/exit-codes.ts`, with `nextCommand` recovery hints (InfoZip-compatible exit codes preserved).
|
|
22
|
+
- Input hardening: control-character/Unicode rejection on names and extraction dirs; zip-slip protection refuses entries that escape the extraction directory.
|
|
23
|
+
- Agent docs and skills: [AGENTS.md](AGENTS.md) and [skills/](skills/) (`neozip-shared`, `neozip-create`, `neozip-extract`, `neozip-list`, `neozip-legacy`, `neozip-connect`).
|
|
24
|
+
- **`neozip skills`** — install bundled Agent Skills from the npm package: `path`, `list`, `install` (symlink into `~/.claude/skills` and/or `~/.cursor/skills`), and `pack` (ZIP per skill for Claude Cowork / claude.ai upload). Skills ship in the tarball under `skills/`.
|
|
25
|
+
- **`neozip --legacy`** — produce an InfoZip/PKZIP-compatible archive (forces deflate/store + PKZIP encryption, disables zstd and all blockchain extensions) readable by stock `unzip`. Combining `--legacy` with blockchain features is a parameter error.
|
|
26
|
+
- **`neozip connect refresh`** — renew an expired Token Service access token without disturbing the wallet/identity. Prefers a **silent wallet-signature login** (no email round-trip) when the Token Service supports it, and falls back to the email OTP flow otherwise. `connect status` now reports access-token expiry (`accessTokenExpired` / `accessTokenExpiresAt` in JSON; an "Access token" line in text).
|
|
27
|
+
- **Automatic token renewal for `-ts`** — before a Token Service timestamp, an expired access token is silently renewed via wallet signature when possible, so timestamping "just works" without a manual refresh.
|
|
28
|
+
- **`neozip connect fund`** — request native gas for the local Data Wallet from the Token Service funding API. Subactions: `request` (default; sends the policy-defined grant to your primary linked wallet), `status` (eligibility + recent grants), and `policy` (grant size/cooldown, no auth). Accepts `--network NAME` / `--chain ID` and `--json`; an expired access token is silently renewed via wallet signature first. The recipient is server-authoritative — the client cannot redirect funds. Wallet/insufficient-balance error messages across `-b`, `-ts`, `-ots`, and `--upgrade` now point to `neozip connect fund` (with the public faucet kept as a fallback).
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **Token Service HTTP clients moved to `neozip-blockchain`** — the account-auth (email/code, magic link, silent wallet-login, phone OTP), funding, and wallet/identity-key HTTP clients now live in `neozip-blockchain/token-service` (v0.8.0) and are shared with NeoZip Desktop and MCP. The CLI keeps only the local orchestration that needs the wallet private key (`runWalletEnsureAndAttach` in `src/account/wallet-setup.ts`) and product-specific UX (token-expiry guidance in `src/connection/token-auth.ts`). No user-facing command behavior changes; the library emits generic auth errors and the CLI maps them to `neozip connect refresh` guidance.
|
|
33
|
+
- **Production dependencies** — `neozipkit` and `neozip-blockchain` updated to `^0.8.0` (npm).
|
|
34
|
+
- **Development workflow** — pnpm-only from source (`engines.pnpm` `>=10.0.0`); Yarn config removed. Use `pnpm install`, `pnpm build`, and `pnpm test`.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Blockchain tokenization (`-b`) blocked by an expired Token Service token** — `-b` and on-chain `mint` sign locally with the wallet key and never use the Token Service access token, but the readiness gate required a non-expired token for them. The gate now distinguishes on-chain abilities (wallet only) from Token Service abilities (`-ts`, which still require a current token), and expired-token errors now point to `neozip connect refresh`.
|
|
39
|
+
- **`pack:dry-run` script** — use `npm pack --dry-run` (pnpm has no `--dry-run` flag).
|
|
40
|
+
|
|
10
41
|
## [0.90.0] - 2026-03-18
|
|
11
42
|
|
|
12
43
|
### Added
|
|
13
44
|
|
|
45
|
+
- **`neozip connect`** — Token Service account setup subcommand (status, register, verify, wallet, finish, migrate). Shares `~/.neozip/connection/` with NeoZip Desktop and MCP (`neozip-connect` from neozip-mcp).
|
|
46
|
+
- **Connection store bootstrap** — non-blocking startup read of active connection; gated operations (`-ts`, mint) require connect readiness with actionable guidance.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **Unified wallet** — all blockchain operations (`-b`, `-ts`, mint) use the connection store wallet (`secrets.enc`); `wallet.json` retired. `neozip init` is an alias for `neozip connect`. On-chain prefs (`defaultNetwork`, RPC, gas) live on `public.json`.
|
|
51
|
+
- **Token Service configuration** — URL, verified email, and access token are read **only** from the connection store (`~/.neozip/connection/`), not from `wallet.json`, env vars, or CLI flags.
|
|
52
|
+
- **Package manager** — development workflow uses pnpm (`packageManager: pnpm@10.12.1`); use `pnpm install` and `pnpm build` from source.
|
|
53
|
+
|
|
54
|
+
### Removed
|
|
55
|
+
|
|
56
|
+
- **`~/.neozip/wallet.json`** — migrate via `neozip connect migrate`; archived as `wallet.json.migrated`.
|
|
57
|
+
- **`NEOZIP_WALLET_PASSKEY`** as user-facing configuration (connection store only; `-w` remains for one-off overrides).
|
|
58
|
+
|
|
59
|
+
- **`neozip verify-email`** command and `npm run verify-email` script — use `neozip connect` instead.
|
|
60
|
+
- **`--timestamp-email`** flag and `wallet.json` `tokenService.timestampEmail` — configure via `neozip connect`.
|
|
61
|
+
- **`TOKEN_SERVICE_URL`**, **`NEOZIP_TIMESTAMP_EMAIL`** runtime env vars for Token Service operations.
|
|
62
|
+
|
|
63
|
+
### Added (encryption)
|
|
64
|
+
|
|
14
65
|
- **Full AES-256 encryption support** — create, list, and extract password-protected archives with WinZip-compatible AES-256 (default) or legacy PKZIP encryption.
|
|
15
66
|
|
|
16
67
|
#### Creating encrypted archives
|
|
@@ -62,6 +113,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
62
113
|
|
|
63
114
|
See [README.md](README.md) and [DOCUMENTATION.md](DOCUMENTATION.md) for more examples.
|
|
64
115
|
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- **Dependencies**: `neozipkit` and `neozip-blockchain` updated to **^0.7.2** (latest).
|
|
119
|
+
- **Token service API**: imports migrated from `neozip-blockchain/zipstamp-server` to `neozip-blockchain/token-service`; `getZipStampServerUrl()` replaced by `getTokenServiceUrl()`. Configure the server with `TOKEN_SERVICE_URL` (see `env.example`).
|
|
120
|
+
- **ZipStamp → Token Service rename**: all user-facing "Zipstamp" terminology replaced with "Token Service"; `wallet.json` key `zipstamp.timestampEmail` removed in favor of `tokenService.timestampEmail`; CLI flags `--zipstamp-auto-upgrade` / `--zipstamp-skip-upgrade` replaced with `--token-service-auto-upgrade` / `--token-service-skip-upgrade`.
|
|
121
|
+
|
|
65
122
|
---
|
|
66
123
|
|
|
67
124
|
## [0.80.0] - 2026-03-04
|
|
@@ -79,7 +136,7 @@ See [README.md](README.md) and [DOCUMENTATION.md](DOCUMENTATION.md) for more exa
|
|
|
79
136
|
|
|
80
137
|
### Fixed
|
|
81
138
|
|
|
82
|
-
- `neozip config` / `neozip init` no longer fail with "Cannot find module './config/ConfigSetup.js'" when run via `
|
|
139
|
+
- `neozip config` / `neozip init` no longer fail with "Cannot find module './config/ConfigSetup.js'" when run via `pnpm neozip-config` or ts-node
|
|
83
140
|
|
|
84
141
|
---
|
|
85
142
|
|
package/DOCUMENTATION.md
CHANGED
|
@@ -119,16 +119,16 @@ neolist --help # Show listing help
|
|
|
119
119
|
- Cryptographic proof of archive existence
|
|
120
120
|
- Timestamp verification
|
|
121
121
|
|
|
122
|
-
- **
|
|
123
|
-
- Ethereum blockchain timestamping via
|
|
122
|
+
- **Token Service**
|
|
123
|
+
- Ethereum blockchain timestamping via NeoZip Token Service
|
|
124
|
+
- Account setup via `neozip connect` (shared store at `~/.neozip/connection/`)
|
|
124
125
|
- Pending timestamps (TS-SUBMIT.NZIP) can be upgraded to confirmed (TIMESTAMP.NZIP)
|
|
125
126
|
- Use `neozip upgrade <archive> [output] [--wait]` to upgrade pending timestamps
|
|
126
127
|
|
|
127
128
|
- **Wallet Integration**
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
- Secure wallet key storage
|
|
129
|
+
- Token Service account and wallet via `neozip connect` (alias: `neozip init`)
|
|
130
|
+
- Connection dashboard (`neozip config`) and `neozip connect settings` for on-chain prefs
|
|
131
|
+
- Wallet key in encrypted `secrets.enc` under `~/.neozip/connection/`
|
|
132
132
|
|
|
133
133
|
### Advanced Features
|
|
134
134
|
|
|
@@ -142,44 +142,36 @@ neolist --help # Show listing help
|
|
|
142
142
|
|
|
143
143
|
## 🔧 Configuration
|
|
144
144
|
|
|
145
|
-
###
|
|
146
|
-
|
|
147
|
-
For blockchain features, configure your wallet:
|
|
145
|
+
### Account, wallet, and on-chain preferences
|
|
148
146
|
|
|
149
147
|
```bash
|
|
150
|
-
#
|
|
151
|
-
neozip
|
|
152
|
-
|
|
153
|
-
#
|
|
154
|
-
neozip
|
|
148
|
+
neozip connect # Setup (alias: neozip init)
|
|
149
|
+
neozip connect status
|
|
150
|
+
neozip connect settings # default network, RPC, gas
|
|
151
|
+
neozip config # dashboard
|
|
152
|
+
neozip connect migrate # legacy wallet.json → connection store
|
|
155
153
|
|
|
156
|
-
# Upgrade pending
|
|
154
|
+
# Upgrade pending Token Service timestamp
|
|
157
155
|
neozip upgrade archive.nzip [output.nzip] [--wait]
|
|
158
156
|
```
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
- Wallet private key
|
|
162
|
-
- Network selection (testnet/mainnet)
|
|
163
|
-
- Custom RPC endpoints
|
|
164
|
-
- Gas settings
|
|
165
|
-
- Debug options
|
|
158
|
+
Store: `~/.neozip/connection/` (see [dev_doc/CONNECTION_CLI_PREFS.md](dev_doc/CONNECTION_CLI_PREFS.md)).
|
|
166
159
|
|
|
167
|
-
### Environment Variables
|
|
160
|
+
### Environment Variables (optional session overrides)
|
|
168
161
|
|
|
169
|
-
|
|
170
|
-
- `
|
|
171
|
-
- `
|
|
172
|
-
- `
|
|
173
|
-
- `NEOZIP_VERBOSE`
|
|
174
|
-
- `NEOZIP_DEBUG` - Enable debug mode
|
|
162
|
+
See [env.example](env.example):
|
|
163
|
+
- `NEOZIP_NETWORK` — override default network for this process
|
|
164
|
+
- `NEOZIP_BASE_SEPOLIA_RPC_URL` — override RPC for this process
|
|
165
|
+
- `NEOZIP_CONNECTION_DIR`, `NEOZIP_UNLOCK_PASSPHRASE` — connection store
|
|
166
|
+
- `NEOZIP_VERBOSE`, `NEOZIP_DEBUG`, `NEOZIP_GAS_MULTIPLIER`, `NEOZIP_MAX_GAS_PRICE`
|
|
175
167
|
|
|
176
168
|
## 📚 Reading Order
|
|
177
169
|
|
|
178
170
|
1. **Start with** [README.md](README.md) for installation and basic usage
|
|
179
171
|
2. **Read** [WHY_NEOZIP.md](WHY_NEOZIP.md) to understand the project vision
|
|
180
172
|
3. **Review** [CHANGELOG.md](CHANGELOG.md) for version history and known issues
|
|
181
|
-
4. **Configure**
|
|
182
|
-
5. **Reference** [env.example](env.example) for environment
|
|
173
|
+
4. **Configure** via `neozip connect` for blockchain features
|
|
174
|
+
5. **Reference** [env.example](env.example) for optional environment overrides
|
|
183
175
|
|
|
184
176
|
## 🔗 Related Links
|
|
185
177
|
|
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ NeoZip CLI is a modern, full-featured ZIP utility that provides:
|
|
|
50
50
|
### Blockchain Features
|
|
51
51
|
- **Tokenization**: Create on-chain tokens for archives
|
|
52
52
|
- **OpenTimestamp**: Bitcoin blockchain timestamping
|
|
53
|
-
- **
|
|
53
|
+
- **Token Service**: Ethereum blockchain timestamping (NeoZip Token Service)
|
|
54
54
|
- **Integrity Verification**: Verify archive integrity on-chain
|
|
55
55
|
- **Network Support**: Base Sepolia, Base Mainnet, Arbitrum, and more
|
|
56
56
|
|
|
@@ -69,7 +69,8 @@ NeoZip CLI is a modern, full-featured ZIP utility that provides:
|
|
|
69
69
|
### Prerequisites
|
|
70
70
|
|
|
71
71
|
- Node.js 16.0.0 or higher
|
|
72
|
-
-
|
|
72
|
+
- [pnpm](https://pnpm.io/) 10+ (required for development from source)
|
|
73
|
+
- npm (optional — for global install of the published package only)
|
|
73
74
|
|
|
74
75
|
### Install from npm
|
|
75
76
|
|
|
@@ -164,11 +165,11 @@ neozip -b tokenized.nzip file.txt
|
|
|
164
165
|
# Tokenize with OpenTimestamp proof (Bitcoin)
|
|
165
166
|
neozip -ots timestamped.nzip file.txt
|
|
166
167
|
|
|
167
|
-
# Create
|
|
168
|
-
neozip -ts
|
|
168
|
+
# Create Token Service timestamp (Ethereum)
|
|
169
|
+
neozip -ts timestamped.nzip file.txt
|
|
169
170
|
|
|
170
|
-
# Upgrade pending
|
|
171
|
-
neozip upgrade
|
|
171
|
+
# Upgrade pending Token Service timestamp to confirmed
|
|
172
|
+
neozip upgrade timestamped.nzip [output.nzip] [--wait]
|
|
172
173
|
|
|
173
174
|
# Extract and verify blockchain integrity
|
|
174
175
|
neounzip tokenized.nzip tests/extracted/
|
|
@@ -196,17 +197,16 @@ neozip [options] <archive> [files...]
|
|
|
196
197
|
- `--pkzip` - Use legacy PKZIP encryption (weak, for compatibility only)
|
|
197
198
|
- `-b, --blockchain` - Enable blockchain tokenization
|
|
198
199
|
- `-ots, --opentimestamp` - Enable OpenTimestamp proof (Bitcoin)
|
|
199
|
-
- `-ts, --timestamp` - Enable
|
|
200
|
-
- `--timestamp-email <email>` - Email for Zipstamp server (some servers require verified email)
|
|
200
|
+
- `-ts, --timestamp` - Enable Token Service timestamp (Ethereum; requires `neozip connect`)
|
|
201
201
|
- `-T, --test-integrity` - Test archive after creation
|
|
202
202
|
- `-v, --verbose` - Enable verbose output
|
|
203
203
|
- `-q, --quiet` - Suppress output
|
|
204
204
|
|
|
205
205
|
**Configuration Commands:**
|
|
206
206
|
```bash
|
|
207
|
-
neozip
|
|
208
|
-
neozip config #
|
|
209
|
-
neozip upgrade <archive> [output] [--wait] # Upgrade pending
|
|
207
|
+
neozip connect # Token Service account + wallet setup (alias: neozip init)
|
|
208
|
+
neozip config # Connection dashboard (status, prefs, migrate)
|
|
209
|
+
neozip upgrade <archive> [output] [--wait] # Upgrade pending Token Service timestamp to confirmed
|
|
210
210
|
```
|
|
211
211
|
|
|
212
212
|
**Examples:**
|
|
@@ -301,41 +301,26 @@ neolist -1 archive.nzip
|
|
|
301
301
|
|
|
302
302
|
## Configuration
|
|
303
303
|
|
|
304
|
-
###
|
|
304
|
+
### Account and wallet setup
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
All wallet identity and Token Service credentials live in the shared connection store (`~/.neozip/connection/`). Use the same profile as NeoZip Desktop and MCP.
|
|
307
307
|
|
|
308
308
|
```bash
|
|
309
|
-
# Interactive setup
|
|
310
|
-
neozip
|
|
309
|
+
neozip connect # Interactive setup (alias: neozip init)
|
|
310
|
+
neozip connect status # Show connection phase and credentials
|
|
311
|
+
neozip connect settings # Default network, RPC overrides, gas prefs
|
|
312
|
+
neozip connect migrate # Import legacy wallet.json / MCP profiles
|
|
313
|
+
neozip config # Connection dashboard (status, prefs, migrate)
|
|
311
314
|
```
|
|
312
315
|
|
|
313
|
-
|
|
314
|
-
1. Creating or importing a wallet
|
|
315
|
-
2. Selecting a blockchain network
|
|
316
|
-
3. Saving configuration to `~/.neozip/wallet.json`
|
|
316
|
+
On-chain preferences (`defaultNetwork`, custom RPC URLs, gas) are stored in each connection's `public.json`.
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
You can also configure via environment variables:
|
|
318
|
+
Optional overrides:
|
|
321
319
|
|
|
322
320
|
```bash
|
|
323
|
-
export
|
|
324
|
-
export
|
|
325
|
-
export
|
|
326
|
-
export NEOZIP_TIMESTAMP_EMAIL="your@email.com" # Email for Zipstamp (some servers require verified email)
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Configuration File
|
|
330
|
-
|
|
331
|
-
Configuration is stored in `~/.neozip/wallet.json`:
|
|
332
|
-
|
|
333
|
-
```json
|
|
334
|
-
{
|
|
335
|
-
"walletKey": "0x...",
|
|
336
|
-
"network": "base-sepolia",
|
|
337
|
-
"rpcUrl": "https://..."
|
|
338
|
-
}
|
|
321
|
+
export NEOZIP_CONNECTION_DIR="/path/to/connection" # Store path override
|
|
322
|
+
export NEOZIP_UNLOCK_PASSPHRASE="..." # Decrypt secrets.enc non-interactively
|
|
323
|
+
export NEOZIP_NETWORK="base-sepolia" # Override default network for this session
|
|
339
324
|
```
|
|
340
325
|
|
|
341
326
|
## Advanced Examples
|
|
@@ -427,6 +412,73 @@ neozip -X archive.nzip ./files/
|
|
|
427
412
|
neozip -y archive.nzip ./symlinks/
|
|
428
413
|
```
|
|
429
414
|
|
|
415
|
+
## For AI agents
|
|
416
|
+
|
|
417
|
+
NeoZip ships an agent-friendly surface. See [AGENTS.md](AGENTS.md) and the
|
|
418
|
+
[skills/](skills/) directory for the full guide.
|
|
419
|
+
|
|
420
|
+
### Install Agent Skills
|
|
421
|
+
|
|
422
|
+
Six bundled skills (`neozip-shared`, `neozip-create`, `neozip-extract`, `neozip-list`,
|
|
423
|
+
`neozip-connect`, `neozip-legacy`) ship inside the npm package. Install them into
|
|
424
|
+
Claude Code or Cursor after `npm install -g neozip-cli`:
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# Symlink bundled skills into ~/.claude/skills and ~/.cursor/skills
|
|
428
|
+
neozip skills install
|
|
429
|
+
|
|
430
|
+
# Claude Code only
|
|
431
|
+
neozip skills install --target claude
|
|
432
|
+
|
|
433
|
+
# Show where skills live in your install
|
|
434
|
+
neozip skills path
|
|
435
|
+
neozip skills list
|
|
436
|
+
|
|
437
|
+
# ZIP files for Claude Cowork / claude.ai upload (Customize > Skills)
|
|
438
|
+
neozip skills pack --output-dir ./neozip-skills-zips
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Alternative (skills registry, same format as Google Workspace CLI):
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
npx skills add https://github.com/NeoWareInc/neozip-cli
|
|
445
|
+
npx skills add https://github.com/NeoWareInc/neozip-cli/tree/main/skills/neozip-create
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### CLI conventions
|
|
449
|
+
|
|
450
|
+
- **Machine-readable output:** add `--format json` to any command to get a
|
|
451
|
+
single JSON object on stdout (`{ "ok": true, ... }` or
|
|
452
|
+
`{ "ok": false, "error": { ... } }`). Human hints go to stderr.
|
|
453
|
+
- **JSON input:** `--params '<JSON>'` (options) and `--json '<JSON>'` (payload:
|
|
454
|
+
archive + files/targets). Either accepts `-` to read from stdin. Explicit CLI
|
|
455
|
+
flags override JSON input.
|
|
456
|
+
- **Schema introspection:** `neozip schema <neozip|neounzip|neolist|connect>`
|
|
457
|
+
emits the accepted fields, types, defaults, and exit codes.
|
|
458
|
+
- **Dry-run:** `neozip`/`neounzip` accept `--dry-run` to resolve and print the
|
|
459
|
+
plan as JSON without writing anything.
|
|
460
|
+
- **Safety:** archive names and extraction dirs are validated for control
|
|
461
|
+
characters; `neounzip` refuses zip-slip (entries escaping the target dir).
|
|
462
|
+
- **Exit codes:** InfoZip-compatible and echoed in `error.exitCode`.
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Introspect, then create fully from JSON
|
|
466
|
+
neozip schema neozip
|
|
467
|
+
neozip --format json \
|
|
468
|
+
--params '{"level":9,"encrypt":true,"password":"s3cret"}' \
|
|
469
|
+
--json '{"archive":"out.zip","files":["src/","README.md"]}'
|
|
470
|
+
|
|
471
|
+
# Preview an extraction, then run it
|
|
472
|
+
neounzip --format json --dry-run --params '{"exdir":"out"}' in.zip
|
|
473
|
+
neounzip --format json --params '{"exdir":"out","overwrite":true}' in.zip
|
|
474
|
+
|
|
475
|
+
# List as JSON
|
|
476
|
+
neolist --format json in.zip
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
For an archive that stock InfoZip `unzip` can read, add `--legacy` (forces
|
|
480
|
+
deflate/store + PKZIP, disables NeoZip extensions).
|
|
481
|
+
|
|
430
482
|
## Requirements
|
|
431
483
|
|
|
432
484
|
- **Node.js**: 16.0.0 or higher
|
|
@@ -479,11 +531,11 @@ neozip new-archive.nzip original-files/
|
|
|
479
531
|
|
|
480
532
|
**Blockchain errors:**
|
|
481
533
|
```bash
|
|
482
|
-
# Check
|
|
483
|
-
neozip
|
|
534
|
+
# Check connection status
|
|
535
|
+
neozip connect status
|
|
484
536
|
|
|
485
|
-
#
|
|
486
|
-
neozip
|
|
537
|
+
# Re-run setup
|
|
538
|
+
neozip connect
|
|
487
539
|
```
|
|
488
540
|
|
|
489
541
|
**Encryption errors:**
|
|
@@ -503,6 +555,16 @@ We welcome feedback and contributions:
|
|
|
503
555
|
2. **Suggest Features**: Share your ideas and use cases
|
|
504
556
|
3. **Test and Provide Feedback**: Help us improve by testing and reporting your experience
|
|
505
557
|
|
|
558
|
+
### Development setup
|
|
559
|
+
|
|
560
|
+
Requires [pnpm](https://pnpm.io/) (`packageManager: pnpm@10.12.1`):
|
|
561
|
+
|
|
562
|
+
```bash
|
|
563
|
+
pnpm install
|
|
564
|
+
pnpm build
|
|
565
|
+
pnpm test
|
|
566
|
+
```
|
|
567
|
+
|
|
506
568
|
**Important**: Please test thoroughly and report issues. See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
507
569
|
|
|
508
570
|
## License
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeAccountPhase = computeAccountPhase;
|
|
4
|
+
exports.buildAccountStatusReport = buildAccountStatusReport;
|
|
5
|
+
const token_service_1 = require("neozip-blockchain/token-service");
|
|
6
|
+
const mask_1 = require("../util/mask");
|
|
7
|
+
const profile_store_1 = require("./profile-store");
|
|
8
|
+
const token_auth_1 = require("../connection/token-auth");
|
|
9
|
+
function nextStepsForPhase(phase) {
|
|
10
|
+
switch (phase) {
|
|
11
|
+
case "no_profile":
|
|
12
|
+
return (0, profile_store_1.listProfiles)().length > 0
|
|
13
|
+
? ["account_select", "account_list", "account_create"]
|
|
14
|
+
: ["account_create", "account_list"];
|
|
15
|
+
case "email_unverified":
|
|
16
|
+
return ["account_register_email", "account_verify_email"];
|
|
17
|
+
case "no_wallet":
|
|
18
|
+
return ["account_create_wallet", "account_import_wallet"];
|
|
19
|
+
case "wallet_unlinked":
|
|
20
|
+
return ["account_link_wallet"];
|
|
21
|
+
case "identity_missing":
|
|
22
|
+
return ["account_provision_identity"];
|
|
23
|
+
case "ready":
|
|
24
|
+
return ["account_logout"];
|
|
25
|
+
case "degraded":
|
|
26
|
+
return ["account_status"];
|
|
27
|
+
default:
|
|
28
|
+
return ["account_status"];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function computeAccountPhase() {
|
|
32
|
+
const profileId = (0, profile_store_1.getActiveProfileId)();
|
|
33
|
+
if (!profileId) {
|
|
34
|
+
return "no_profile";
|
|
35
|
+
}
|
|
36
|
+
const profile = (0, profile_store_1.getActiveProfile)();
|
|
37
|
+
const secrets = (0, profile_store_1.readActiveSecrets)();
|
|
38
|
+
if (!profile || !secrets)
|
|
39
|
+
return "no_profile";
|
|
40
|
+
if (!secrets.accessToken || !profile.emailVerified) {
|
|
41
|
+
return "email_unverified";
|
|
42
|
+
}
|
|
43
|
+
if (!secrets.evmPrivateKey || !profile.evmAddress) {
|
|
44
|
+
return "no_wallet";
|
|
45
|
+
}
|
|
46
|
+
if (!profile.walletId || profile.linkId == null) {
|
|
47
|
+
return "wallet_unlinked";
|
|
48
|
+
}
|
|
49
|
+
if (!profile.identityKeyId) {
|
|
50
|
+
return "identity_missing";
|
|
51
|
+
}
|
|
52
|
+
return "ready";
|
|
53
|
+
}
|
|
54
|
+
async function buildAccountStatusReport(options) {
|
|
55
|
+
const profile = (0, profile_store_1.getActiveProfile)();
|
|
56
|
+
const secrets = (0, profile_store_1.readActiveSecrets)();
|
|
57
|
+
const phase = computeAccountPhase();
|
|
58
|
+
const tokenExpiresAt = secrets?.accessTokenExpiresAt ?? null;
|
|
59
|
+
const tokenExpired = Boolean(secrets?.accessToken) && (0, token_auth_1.isAccessTokenExpired)(secrets);
|
|
60
|
+
const tokenServiceUrl = (0, token_service_1.getTokenServiceUrl)({
|
|
61
|
+
serverUrl: profile?.tokenServiceUrl || undefined,
|
|
62
|
+
});
|
|
63
|
+
let tokenServiceReachable = null;
|
|
64
|
+
if (options?.probeTokenService !== false) {
|
|
65
|
+
try {
|
|
66
|
+
tokenServiceReachable = await (0, token_service_1.fetchCoordinatorConfig)(tokenServiceUrl);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
tokenServiceReachable = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const nextSteps = nextStepsForPhase(tokenServiceReachable === false && phase !== "ready" ? "degraded" : phase);
|
|
73
|
+
const reloadRequired = phase === "ready" &&
|
|
74
|
+
Boolean(profile &&
|
|
75
|
+
(!process.env.NEOZIP_TOKEN_SERVICE_ACCESS_TOKEN ||
|
|
76
|
+
!process.env.NEOZIP_WALLET_PASSKEY));
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
phase: tokenServiceReachable === false && phase !== "ready" ? "degraded" : phase,
|
|
80
|
+
activeProfileId: (0, profile_store_1.getActiveProfileId)(),
|
|
81
|
+
profile: profile
|
|
82
|
+
? {
|
|
83
|
+
...profile,
|
|
84
|
+
email: profile.email ? (0, mask_1.maskEmail)(profile.email) : null,
|
|
85
|
+
}
|
|
86
|
+
: null,
|
|
87
|
+
tokenServiceReachable,
|
|
88
|
+
tokenServiceUrl,
|
|
89
|
+
tokenExpiresAt,
|
|
90
|
+
tokenExpired,
|
|
91
|
+
nextSteps,
|
|
92
|
+
reloadRequired,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=account-state.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatAccountStatusText = formatAccountStatusText;
|
|
4
|
+
function formatExpiry(expiresAt) {
|
|
5
|
+
const deltaMs = expiresAt - Date.now();
|
|
6
|
+
const abs = Math.abs(deltaMs);
|
|
7
|
+
const minutes = Math.round(abs / 60000);
|
|
8
|
+
const hours = Math.round(abs / 3600000);
|
|
9
|
+
const days = Math.round(abs / 86400000);
|
|
10
|
+
let rel;
|
|
11
|
+
if (abs < 3600000)
|
|
12
|
+
rel = `${minutes} min`;
|
|
13
|
+
else if (abs < 86400000)
|
|
14
|
+
rel = `${hours} hr`;
|
|
15
|
+
else
|
|
16
|
+
rel = `${days} day${days === 1 ? "" : "s"}`;
|
|
17
|
+
const when = new Date(expiresAt).toISOString();
|
|
18
|
+
return deltaMs >= 0 ? `in ${rel} (${when})` : `${rel} ago (${when})`;
|
|
19
|
+
}
|
|
20
|
+
function formatAccountStatusText(report) {
|
|
21
|
+
const lines = [];
|
|
22
|
+
lines.push("NeoZip account status");
|
|
23
|
+
lines.push(`Phase: ${report.phase}`);
|
|
24
|
+
lines.push(`Token Service: ${report.tokenServiceUrl}`);
|
|
25
|
+
if (report.tokenServiceReachable != null) {
|
|
26
|
+
lines.push(`Token Service reachable: ${report.tokenServiceReachable ? "yes" : "no"}`);
|
|
27
|
+
}
|
|
28
|
+
if (report.tokenExpired) {
|
|
29
|
+
lines.push("Access token: EXPIRED — run neozip connect refresh");
|
|
30
|
+
}
|
|
31
|
+
else if (report.tokenExpiresAt != null) {
|
|
32
|
+
lines.push(`Access token: valid (expires ${formatExpiry(report.tokenExpiresAt)})`);
|
|
33
|
+
}
|
|
34
|
+
if (report.activeProfileId) {
|
|
35
|
+
lines.push(`Active profile: ${report.activeProfileId}`);
|
|
36
|
+
}
|
|
37
|
+
if (report.profile) {
|
|
38
|
+
lines.push(`Label: ${report.profile.label}`);
|
|
39
|
+
if (report.profile.email)
|
|
40
|
+
lines.push(`Email: ${report.profile.email}`);
|
|
41
|
+
if (report.profile.evmAddress) {
|
|
42
|
+
lines.push(`EVM address: ${report.profile.evmAddress}`);
|
|
43
|
+
}
|
|
44
|
+
if (report.profile.walletId != null) {
|
|
45
|
+
lines.push(`Wallet ID: ${report.profile.walletId}`);
|
|
46
|
+
}
|
|
47
|
+
if (report.profile.identityKeyId != null) {
|
|
48
|
+
lines.push(`Identity key ID: ${report.profile.identityKeyId}`);
|
|
49
|
+
}
|
|
50
|
+
if (report.profile.x25519Fingerprint) {
|
|
51
|
+
lines.push(`X25519 fingerprint: ${report.profile.x25519Fingerprint}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (report.nextSteps.length) {
|
|
55
|
+
lines.push(`Next steps: ${report.nextSteps.join(", ")}`);
|
|
56
|
+
}
|
|
57
|
+
if (report.reloadRequired) {
|
|
58
|
+
lines.push("Reload MCP in Cursor so the active connection credentials are loaded into this session.");
|
|
59
|
+
}
|
|
60
|
+
return lines.join("\n");
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=format-account-status.js.map
|