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.
Files changed (74) hide show
  1. package/AGENTS.md +93 -0
  2. package/CHANGELOG.md +58 -1
  3. package/DOCUMENTATION.md +22 -30
  4. package/README.md +104 -42
  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 +93 -9
  56. package/dist/src/neounzip.js +217 -59
  57. package/dist/src/neozip/blockchain.js +18 -18
  58. package/dist/src/neozip/createZip.js +114 -91
  59. package/dist/src/neozip/upgradeZip.js +14 -11
  60. package/dist/src/neozip.js +252 -75
  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 -82
  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
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 `yarn neozip-config` or ts-node
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
- - **Zipstamp**
123
- - Ethereum blockchain timestamping via Zipstamp server
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
- - Interactive wallet setup wizard (`neozip init`)
129
- - Configuration management (`neozip config`)
130
- - Environment variable support
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
- ### Wallet Setup
146
-
147
- For blockchain features, configure your wallet:
145
+ ### Account, wallet, and on-chain preferences
148
146
 
149
147
  ```bash
150
- # Interactive setup wizard
151
- neozip init
152
-
153
- # View or modify configuration
154
- neozip config
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 Zipstamp timestamp to confirmed
154
+ # Upgrade pending Token Service timestamp
157
155
  neozip upgrade archive.nzip [output.nzip] [--wait]
158
156
  ```
159
157
 
160
- Configuration is stored in `~/.neozip/wallet.json` and supports:
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
- You can also configure via environment variables (see [env.example](env.example)):
170
- - `NEOZIP_WALLET_PASSKEY` - Wallet private key
171
- - `NEOZIP_NETWORK` - Blockchain network
172
- - `NEOZIP_BASE_SEPOLIA_RPC_URL` - Custom RPC endpoints
173
- - `NEOZIP_VERBOSE` - Enable verbose logging
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** wallet using `neozip init` for blockchain features
182
- 5. **Reference** [env.example](env.example) for environment variable configuration
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
- - **Zipstamp**: Ethereum blockchain timestamping (Zipstamp server)
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
- - npm or yarn package manager
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 Zipstamp timestamp (Ethereum)
168
- neozip -ts zipstamp.nzip file.txt
168
+ # Create Token Service timestamp (Ethereum)
169
+ neozip -ts timestamped.nzip file.txt
169
170
 
170
- # Upgrade pending Zipstamp timestamp to confirmed
171
- neozip upgrade zipstamp.nzip [output.nzip] [--wait]
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 Zipstamp timestamp (Ethereum)
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 init # Interactive wallet setup wizard
208
- neozip config # Show current configuration
209
- neozip upgrade <archive> [output] [--wait] # Upgrade pending Zipstamp timestamp to confirmed
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
- ### Wallet Setup (for Blockchain Features)
304
+ ### Account and wallet setup
305
305
 
306
- To use blockchain features, you need to configure a wallet:
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 wizard
310
- neozip init
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
- This will guide you through:
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
- ### Environment Variables
319
-
320
- You can also configure via environment variables:
318
+ Optional overrides:
321
319
 
322
320
  ```bash
323
- export NEOZIP_WALLET_PASSKEY="your-wallet-key"
324
- export NEOZIP_NETWORK="base-sepolia" # or base-mainnet, arbitrum-sepolia, etc.
325
- export ZIPSTAMP_SERVER_URL="https://zipstamp-dev.neozip.io" # Zipstamp server (optional)
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 wallet configuration
483
- neozip config
534
+ # Check connection status
535
+ neozip connect status
484
536
 
485
- # Reconfigure wallet
486
- neozip init
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