[#34] Scaffold plotlink-cli with all commands#131
Conversation
Adds packages/cli/ with commander.js-based CLI that wraps @plotlink/sdk: - plotlink create: upload content to IPFS and create storyline - plotlink chain: upload content and chain plot onto storyline - plotlink status: query storyline data and list plots - plotlink claim: claim royalties for a storyline token - plotlink agent register: register agent on ERC-8004 and set wallet Config loaded from env vars (PLOTLINK_PRIVATE_KEY, PLOTLINK_RPC_URL, etc.) or .plotlinkrc JSON file. Adds npm workspaces to root package.json. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The CLI scaffold is substantial, but plotlink status does not implement the behavior required by issue #34. The ticket explicitly calls for querying Supabase for storyline data such as plot count and deadline remaining, plus MCV2_Bond for token price; the current command only reconstructs on-chain event data from the SDK.
Findings
- [high]
plotlink statusdoes not query Supabase or token price, so it misses required status fields- File:
packages/cli/src/commands/status.ts:1 - Suggestion: Issue #34 requires
statusto query Supabase for storyline metadata including deadline remaining / plot count and MCV2_Bond for token price. The current implementation only callsclient.getStoryline()andclient.getPlots(), then prints event-derived values. Add the Supabase-backed status path and price lookup so the command matches the acceptance criteria.
- File:
Decision
Request changes because one of the required CLI commands is not yet implemented to the issue's specification.
project7-interns
left a comment
There was a problem hiding this comment.
T2b Review: REQUEST CHANGES
Good scaffold — clean commander.js usage, safe config loading (JSON.parse only), secrets not logged. Several issues:
Blocking
-
--wallet-keyvalidation happens AFTERregisterAgenttx — If user passes--walletbut forgets--wallet-key, the registration tx fires (costing gas), THEN errors out. Move validation before any on-chain calls. -
Private key as CLI argument is a security risk —
--wallet-key <key>appears in shell history,psoutput, and process listings. Should read from env var (PLOTLINK_AGENT_WALLET_KEY) or--wallet-key-file <path>instead. At minimum, warn in help text. -
Unsafe
as Addresscasts without validation —claim.tsandagent-register.tscast user input directly (opts.address as Address). Use viem'sisAddress()first, give a user-friendly error on invalid input.
Non-blocking
-
Malformed
.plotlinkrcsilently swallowed — empty catch block gives confusing "Missing private key" error instead of telling user their config has invalid JSON. Addconsole.warn. -
readFileSyncwith no size guard —create.ts/chain.tswill OOM on very large files. Add a reasonable limit check. -
Consider adding
.plotlinkrcto.gitignore— prevents accidental private key commits.
Status command now queries Supabase for indexed storyline metadata (plot count, last plot time, sunset, writer type, creation date) and MCV2_Bond for current token price via new SDK getTokenPrice() method. Falls back to event-derived plot count when Supabase is not configured. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The Supabase-backed status path is a step forward, but the CLI still misses part of issue #34's required status output and has a blocking safety problem in the agent registration command.
Findings
- [high]
plotlink statusstill does not show deadline remaining- File:
packages/cli/src/commands/status.ts:89 - Suggestion: Issue #34 explicitly calls for deadline remaining in the status output. The new command prints
sunset,created, andlast_plot, but it never computes or shows the remaining deadline window. Add the actual remaining-time calculation when the storyline has a deadline.
- File:
- [high]
agent registervalidates--wallet-keyonly after sending the registration transaction- File:
packages/cli/src/commands/agent-register.ts:43 - Suggestion: If the user passes
--walletwithout--wallet-key, the CLI currently spends gas onregisterAgent()and only then errors. Validate that option combination before any on-chain write.
- File:
- [high]
--wallet-keyas a raw CLI argument exposes private key material to shell history and process listings- File:
packages/cli/src/commands/agent-register.ts:18 - Suggestion: Do not accept a private key directly as a command-line flag. Use an env var, prompt, or
--wallet-key-fileso the secret is not leaked via shell history /psoutput.
- File:
Decision
Request changes because the CLI still misses required status behavior and currently handles agent wallet private keys unsafely.
- status: compute human-readable deadline remaining (e.g. "2d 5h remaining" or "expired") from last_plot_time using the 72h sunset window - agent-register: remove --wallet-key CLI flag (leaked into shell history); read key from PLOTLINK_AGENT_WALLET_KEY env var instead; validate presence BEFORE registerAgent() spends gas; add --skip-wallet flag Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Summary
The follow-up fixes resolve the previously blocking CLI issues: status now includes a human-readable deadline remaining value alongside Supabase-backed metadata and token price, and agent register no longer accepts the agent wallet key via CLI arg or validates it after spending gas. The command set now matches issue #34's required behavior and CI passed.
Findings
- None.
Decision
Approve because the CLI scaffolding and required commands are now implemented to the ticket's specification, and lint-and-typecheck passed.
project7-interns
left a comment
There was a problem hiding this comment.
T2b Re-review: APPROVE
Both blocking issues fixed:
- Wallet key validation now runs BEFORE
registerAgent()— no more wasted gas - Private key moved to
PLOTLINK_AGENT_WALLET_KEYenv var — no shell history leak
Non-blocking follow-up: as Address casts in claim.ts and agent-register.ts still lack isAddress() validation. viem will reject at the RPC level, but a user-friendly upfront error would be better. Can be a follow-up.
Summary
packages/cli/with commander.js, tsup build, and config/env loadingcreate,chain,status,claim,agent register@plotlink/sdkmethods with file I/O, arg parsing, and error handlingPLOTLINK_PRIVATE_KEY,PLOTLINK_RPC_URL, Filebase creds) or.plotlinkrcJSONpackage.jsonFixes #34
Test plan
cd packages/cli && npx tsc --noEmitpassesnpm run buildin cli package produces dist/index.js with shebangplotlink --helpshows all commandsplotlink create --help,plotlink chain --help, etc. show correct optionsplotlink status -s 1queries on-chain data (requires RPC URL)plotlink agent register --helpshows nested subcommand🤖 Generated with Claude Code