Repository navigation
feat(cli): add init wizard, --json output, and doctor diagnostics - #659
Primex-Tech wants to merge 14 commits into
Conversation
Implements TegoLabs#370 with interactive and non-interactive (--yes) modes. Uses runInitWizard in core/init.ts for testable logic. Writes config.yaml via existing config utils.
- core/init: reject non-integer or non-positive target TTL / threshold values (Number.isSafeInteger) and reject threshold >= target TTL before any DB writes or network calls, matching the guard command constraints - commands/init: stop treating --target-ttl 0 / --threshold 0 as unset (falsy), and only prompt for guard enablement when neither flag is provided - index.ts: restore LF line endings to match the repository convention
- commands/init: remove the --network "testnet" default so the saved network and the interactive network prompt are actually used - commands/init: add --alert-threshold so the alert trigger is independent from the guard threshold; mark --guard-enabled/--guard-disabled as mutually exclusive via Option.conflicts - commands/init: return after every process.exit(1), share the result/save handling between the interactive and non-interactive paths, and skip the guard value prompts when the guard is disabled - commands/init: register built-in channels from the action instead of at module import time - core/init: register built-in channels inside runInitWizard instead of at module import time; validate the alert threshold as a positive integer; wrap the alert-config and policy writes in a single transaction; make repeated init runs idempotent by replacing the contract's alert configs - tests: assert the real saveConfig 0o600 permissions, the saved-network fallback, the --yes missing-flag failure, and the mutually exclusive guard flags; cover the unsupported-channel, watch-failure, idempotent re-run, and independent-alert-threshold branches
- Add bigint replacer to printOutput for inspect --json - Add JSON output for key resolution failures in guard.ts and restore.ts - Add JSON output for dry-run simulation failure in guard.ts
- Remove raw keypairSource (potential secret) from JSON error payloads in guard.ts - Replace process.exit(1) with process.exitCode = 1 in JSON failure branches so printOutput can flush stdout (guard, restore, watch, inspect) - Only start spinners when NOT in --json mode (guard, watch) - Normalize optional targetTtl/threshold values before parsing (guard)
- guard: reject prefix-tolerant parseInt values (e.g. 100foo, 20.5) by validating complete strings as positive integers before storing in extension policy - watch: include complete watchContract result (instance, wasm, wasmWarning) in batch --json output
…c command Implements TegoLabs#371 with checks for Node version, data directory writability, database schema, RPC reachability, and alert-channel credentials.
- core/doctor: replace broken double-quoted strings containing \ placeholders with real template literals so node version, data dir, and error details are interpolated - core/doctor: reuse getSorokeepDir() from utils/config instead of duplicating the ~/.sorokeep path (drop now-unused os/path imports) - index.ts: restore the description string and trailing newline to match the base file
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe CLI adds ChangesInitialization and diagnostics
Structured CLI output
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant initCommand
participant runInitWizard
participant watchContract
participant database
participant saveConfig
initCommand->>runInitWizard: InitAnswers
runInitWizard->>watchContract: watch contract
watchContract-->>runInitWizard: WatchResult
runInitWizard->>database: persist alert and guard settings
runInitWizard-->>initCommand: InitResult
initCommand->>saveConfig: save network and RPC settings
Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/doctor.ts`:
- Around line 17-20: Replace process.exit(1) in the doctor command’s failure
handling with process.exitCode = 1 after results are printed. In
tests/commands/doctor.test.ts, update the Vitest process stub to reset
process.exitCode and assert it becomes 1 instead of expecting process.exit to
throw.
In `@src/commands/init.ts`:
- Line 37: Update the initialization flow around runInitWizard and the option
handling at lines 37, 75-79, 100-101, and 121-131 to keep explicit options
separate from existingConfig defaults. Pass an explicitly supplied network
through unchanged so interactive prompting remains available when it is absent,
while supplying the resolved configuration defaults separately for
initialization; likewise allow the wizard to use the default RPC endpoint
without replacing existingConfig.rpcUrl used by later monitoring commands.
In `@src/commands/watch.ts`:
- Around line 81-91: Update watchContractsFileSchema in the watch configuration
validation to reject empty contract inputs, including both [] and { contracts:
[] }, so watch never produces an empty results array with success: true.
Preserve the existing JSON success calculation for non-empty results.
- Around line 206-210: Update the watch command’s error handling around the
options.json branch so logger.error("Watch command failed", ...) cannot write to
JSON stdout; route that diagnostic to stderr or suppress it when JSON mode uses
printOutput(..., true), while preserving the single JSON payload and exitCode
behavior.
In `@src/core/doctor.ts`:
- Around line 56-70: Update runDiagnostics around getDatabase and the schema
query to catch initialization or SQLite errors, append a failed schema result
with the error detail, and continue returning the diagnostic summary instead of
rejecting. Ensure credential checks are skipped or warned when no database is
available, and add coverage for getDatabase throwing.
In `@tests/commands/doctor.test.ts`:
- Around line 30-44: Update the “exits with code 1 when any check fails” test
around registerDoctorCommand and parseAsync to expect non-forcing failure
handling via process.exitCode rather than a rejected “process.exit called”
error. Assert that exitCode is 1, and reset process.exitCode after the test to
prevent state leaking into other tests.
In `@tests/core/doctor.test.ts`:
- Around line 1-34: Isolate the runDiagnostics tests from real filesystem and
process state by mocking getSorokeepDir() to return a temporary test directory
and cleaning that directory as needed. In beforeEach, capture the original
SOROKEEP_SLACK_TOKEN and SOROKEEP_TELEGRAM_BOT_TOKEN values before modifying
them, then restore both original values in afterEach instead of unconditionally
deleting them.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 76565297-a317-4534-bd3e-4ef50181474c
📒 Files selected for processing (14)
src/cli/program.tssrc/commands/doctor.tssrc/commands/guard.tssrc/commands/init.tssrc/commands/inspect.tssrc/commands/restore.tssrc/commands/watch.tssrc/core/doctor.tssrc/core/init.tssrc/utils/formatting.tstests/commands/doctor.test.tstests/commands/init.test.tstests/core/doctor.test.tstests/core/init.test.ts
📜 Review details
🧰 Additional context used
🪛 ast-grep (0.45.0)
tests/commands/init.test.ts
[warning] 18-18: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(configPath, JSON.stringify(config))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').
(detect-non-literal-fs-filename-typescript)
🔇 Additional comments (28)
src/core/doctor.ts (3)
9-24: LGTM!
26-54: LGTM!
72-120: LGTM!src/commands/doctor.ts (1)
5-16: LGTM!tests/commands/doctor.test.ts (2)
1-28: LGTM!
46-57: LGTM!tests/core/doctor.test.ts (1)
36-64: LGTM!src/commands/inspect.ts (1)
6-6: LGTM!Also applies to: 18-20, 30-51, 96-101
src/commands/restore.ts (1)
7-7: LGTM!Also applies to: 20-31, 41-45, 54-70, 81-112, 136-140, 149-149
src/utils/formatting.ts (2)
3-19: LGTM!
80-80: LGTM!src/commands/guard.ts (12)
7-7: LGTM!
24-75: LGTM!
86-89: LGTM!
109-113: LGTM!
122-126: LGTM!
144-148: LGTM!
161-180: LGTM!
193-197: LGTM!
210-215: LGTM!
225-233: LGTM!
243-268: LGTM!
287-296: LGTM!src/commands/watch.ts (5)
12-15: LGTM!
43-57: LGTM!Also applies to: 70-70
101-110: LGTM!
121-125: LGTM!
135-154: LGTM!
This PR combines three previously separate feature PRs (replaces #561, #559, #564) into one clean, minimal diff.
Rather than merging the old stale branches, this branch was rebuilt fresh from current \main\ (\1e4a880e) by cherry-picking only the real feature commits. It touches 17 files (all feature-relevant) with no unrelated churn.
Features
estore, \inspect* (feat(cli): add --json output flag to watch, guard, restore, and inspect commands #372) - machine-readable output alongside the existing human output.
Review / tooling feedback addressed
pm run build:man\ so \init/\doctor\ (and previously-missing \metrics/\�udit-log) are documented.
Verification
pm audit --audit-level=high\ all pass.
pm run build\ passes.