Draft
Conversation
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Replace the parameter-only CLI with a subcommand-based ecc command: - ecc init: create project skeleton with ecc.toml template - ecc check: validate project configuration from ecc.toml - ecc run: execute complete rtl2gds flow via existing Python APIs - ecc status: read-only inspection of flow.json run/step state - ecc log: step log discovery with --errors filtering - ecc metrics: metrics JSON reading with key normalization All commands support --json/--jsonl structured output and follow the disclosure-line contract (every summary line includes a runnable command). Module split: config.py (TOML/validation), output.py (formatting), project.py (init/run), inspect.py (status/log/metrics). 50 tests covering all acceptance criteria (positive and negative cases). Console script entry point updated from cli to ecc.
- ecc log without step now discovers both global and step log locations, with disclosure commands on every output line (AC-5, AC-7) - ecc metrics --json/--jsonl return non-zero structured error objects for unknown or missing requested steps instead of empty success (AC-6) - Bazel chipcompiler_cli target now depends on chipcompiler_cli_lib which includes all cli/**/*.py sources (AC-8) - Config parsing handles non-numeric frequency_mhz gracefully instead of crashing with ValueError (AC-2) 6 new tests added covering all review findings.
Instead of reporting step log counts, ecc log without a step now emits one line per discovered step log file with the actual relative path: step=synthesis log=Synthesis_yosys/log/synthesis.log inspect="ecc log synthesis --errors" Strengthened test to assert the file path appears in output.
- Resolve relative pdk.root against project directory before passing to create_workspace, so ecc run --project works from any directory - Restore filelist detection for unknown suffixes by attempting parse_filelist + validate_filelist before falling back to RTL mode - Wrap create_workspace and flow setup in try/except so runtime failures produce clean error output instead of tracebacks
- Update nix/cli/default.nix to reference 'ecc' instead of 'cli' for the wrapped executable and mainProgram, keeping the Nix flake in sync - Derive design name from directory basename in ecc init so paths like /tmp/gcd produce name='gcd' instead of name='/tmp/gcd' - Add test for nested path init verifying basename is used
…malformed TOML - build_log_jsonl now handles omitted step by discovering global and step log locations, matching text mode behavior - Overwrite recovery command includes --project when the user passed it - Malformed ecc.toml produces a clean validation error instead of a TOMLDecodeError traceback - Add test for malformed TOML check
… paths - When pdk.root is empty, validation now checks for CHIPCOMPILER_ICS55_PDK_ROOT or ICS55_PDK_ROOT env vars before rejecting, so freshly initialized projects pass in Bazel/Nix envs - resolve_pdk_root falls back to env vars when config value is empty - _resolve_path expands environment variables ($PDK_ROOT) and user home (~) before resolving relative paths - Legacy CLI compatibility is intentionally not preserved per project decision: there are not enough existing users to justify the effort
- Detect legacy --workspace/--rtl/--design/--top/--clock/--pdk-root args and route to the old parameter-based flow for backward compatibility - Add scripts.cli alias alongside scripts.ecc in pyproject.toml - Reject directory paths in design.rtl during config validation
- design.rtl pointing to a directory now fails validation with a clear error message, matching the old CLI's isfile check - No legacy CLI compatibility — project decision confirmed by owner: not enough existing users to justify compatibility work
…closure - get_run_status now returns 'unstart' when all steps are Unstart instead of 'failed', since no step has actually failed - disclosure_cmd uses shlex.quote for project paths so paths with spaces or shell metacharacters produce executable commands
ecc log --errors without a step token just lists log locations; the --errors filter only applies per-step. Use 'ecc log' instead.
Coerce design/pdk/flow to empty dicts if not dicts in _parse_config. Reject non-dict JSON values in read_flow_json.
…sclosure - _pdk_root_from_env() now normalizes paths with os.path.normpath so Bazel file-location anchors like $(location :README.md)/.. resolve - get_run_status() returns 'ongoing' for in-progress runs instead of lumping them with 'failed' - _check_requested_step() uses disclosure_cmd() for log_cmd so --project is preserved in JSON/JSONL output - Moved disclosure_cmd import to module level in inspect.py
design.rtl = 123 or rtl = [123] no longer crashes with TypeError; non-list values become [], non-string entries are filtered out.
Reuse get_pdk().validate() in _validate_pdk_contents() so ecc check catches missing tech LEF/liberty files instead of reporting success for an unusable PDK root.
…t output - get_run_status() now filters non-dict entries from steps list and handles non-list steps values gracefully - format_field() escapes backslashes and double quotes in quoted values
All status builders (lines/json/jsonl) now filter non-dict step entries instead of only get_run_status doing so.
…nfig fields
- normalize_metric_key fallback regex no longer strips literal 'm' from
unknown metric keys like 'memory_usage' or 'max_delay'
- _parse_config now coerces non-string TOML values to defaults so
pdk.name=[] or flow.preset={} don't crash validation with TypeError
- Consolidate PDK root resolution into _resolve_pdk_root helper, removing duplicate validation branches in validate_project_config - Extract _collect_metrics to deduplicate build_metrics_json/jsonl - Remove unused rc variable in build_metrics_lines - Replace unused rtl_mode with _ in project.py - Use any(c.isspace()) instead of re.search in format_field - Move os import to module level in main.py
…elector
Add read-only debug and traceability CLI commands:
- ecc artifacts [step]: list generated files with role metadata
- ecc config [step] --resolved: show resolved project/step config
- ecc diagnose [step]: emit structured issue metadata with severity
- --run-id selector for status, log, metrics, and new commands
New modules: artifacts.py, config_view.py, diagnose.py
Updated: output.py (disclosure_cmd --run-id), inspect.py (resolve_run_dir),
main.py (subcommand dispatch, --run-id on existing commands)
Tests: 53 new tests in test/cli/test_cli_inspect.py
…se, and run-id - Fix resolve_run_dir: preserve explicit --run-id default in disclosures, handle multi-segment project-relative paths (sweeps/sweep_001/run_004) - Fix artifact/config path rendering: use project_dir as base instead of deriving from run_dir, correct for nested and absolute runs - Fix config --resolved: validate semantically invalid ecc.toml (missing required fields, unsupported pdk/preset), not just TOML parse errors - Fix empty step-config: emit config_status=none sentinel with step token and artifacts disclosure command in text/JSON/JSONL - Fix diagnose step identity: use union of flow.json steps and discovered step dirs, so flow-only steps without directories are diagnosed properly - Fix config-role artifact disclosure: all artifact roles now include at least one disclosure command in text output - Add 10 regression tests covering all Codex findings
…idate_project_config, fix run_dir.value - resolve_run_dir: multi-segment selectors (sweeps/sweep_001/run_004) now resolve from project root, not from runs/ - config_view: replace ad-hoc validation with validate_project_config() for full semantic checking (clock_port, frequency_mhz, rtl, flow.run) - config_view: run_dir.value now uses os.path.relpath unconditionally instead of checking isabs, giving project-relative paths like runs/default - config_view: remove run_id from ecc check disclosures (check has no --run-id) - tests: fix all multi-segment --run-id tests to create workspaces at <project>/sweeps/... not <project>/runs/sweeps/... - tests: assert exact run_dir.value instead of fuzzy matching - tests: add negative tests for unsupported flow.run, empty clock_port, zero frequency_mhz, empty rtl, and no-run-id in invalid config disclosure - tests: mock _validate_pdk_contents for all config --resolved tests
…onfig JSON disclosure, clean output - diagnose: each issue kind now emits its own evidence command (log_errors -> ecc log, missing_metrics -> ecc metrics, missing_artifacts -> ecc artifacts, config_unavailable -> ecc config) - diagnose: clean output now includes status=clean, status_cmd, artifacts, config disclosure fields in text/JSON/JSONL - config_view: run_dir.value preserves absolute paths for external runs (detects ../../ relativization and falls back to absolute) - config_view: all project-level config items now include inspect_cmd so JSON/JSONL consumers get disclosure metadata - tests: add absolute external --run-id config test - tests: add issue-specific evidence assertions for all diagnose issue types - tests: add clean diagnose output assertions for text and JSON - tests: add project-level config JSON inspect_cmd assertion - tests: replace old config validation tests with isolated versions that keep PDK/RTL valid and change only the field under test
…face TOML errors, seed design freq
- Consolidate duplicate type branches in params.py parse_value - Remove unused imports (deepcopy, field, state_severity) - Move deferred imports to top-level (sys, os) - Extract _check_step_artifacts helper in diagnose.py - Dict-based dispatch for param and _render_param_text - List comprehensions replace imperative loops in handlers.py - Simplify get_run_status to single set-based approach - Deduplicate render_log_listing_pretty color/no-color branches - Reuse _maps_to_str in config_view.py
Replace raw key-value default text output with structured pretty blocks using a shared rendering layer. Add --plain flags to init, check, status, metrics, artifacts, config, and diagnose commands for stable machine- readable output. Improve plain key-value rendering with deterministic quoting/escaping. JSON and JSONL output modes remain unchanged.
- render_error() now iterates all records instead of only records[0] - ANSI constants and supports_color() consolidated into pretty.py - main.py, log_view.py, progress.py delegate to shared helpers - Added 8 regression tests for multi-record errors and shared color policy - All 495 CLI tests pass
render_log_listing_pretty() still referenced deleted _BOLD/_RESET/_CYAN/_DIM private names, causing NameError when color=True. Replaced with style() helper and shared constants from pretty.py. Added 3 regression tests for color-enabled listing path.
When _apply_scoped_param_edit replaced a multiline array value, the Extend consumed past the closing newline but the replacement line had none. This concatenated the next key onto the same line, producing invalid TOML. Added trailing newline when the original value was multiline. Strengthened test assertion to verify keys remain on separate lines.
- Add scripts.cli alias alongside scripts.ecc in pyproject.toml - Detect legacy --workspace/--rtl/--design/--top/--clock/--pdk-root args and route to the old parameter-based flow for backward compatibility
…ompat - _is_legacy_args now detects --workspace=ws and --rtl=top.v forms - _resolve_rtl_input routes .f/.fl/.filelist files to input_filelist instead of origin_verilog, matching the old CLI behavior
_resolve_rtl_input now falls back to parse_filelist/validate_filelist for files without known RTL or filelist extensions, matching the old CLI.
_validate_legacy_args checks non-empty required fields, RTL file existence, PDK root directory, and positive frequency before calling create_workspace, matching the old CLI behavior.
…s in log handler - Nix derivation now wraps both ecc and cli executables with the same CHIPCOMPILER_OSS_CAD_DIR and PATH settings - ecc log <step> now checks flow step names as fallback when the step directory is absent, matching metrics/artifacts behavior
os.chmod follows symlinks, which could modify permissions on files outside the workspace. Skip chmod for symlink entries.
…ain dispatch - Remove unused format_value and format_plain_value from pretty.py - Replace _format_value in log_view.py with shared _plain_value from render.py - Simplify _render_log_plain by collapsing two identical render_result branches
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
Signed-off-by: Emin <me@emin.chat>
… run Render all error codes in red via style() instead of status_style() lookup. Color full error log-line content red in render_log_pretty(). Add extract_error_context() with anchor priority (last error > last traceback > last "failed" > last non-empty) and 50-line hard limit. Add format_error_context() for the context block format with compact kind labels and grep-friendly command footer. Integrate into run_flow_with_progress for failed interactive steps only, gated behind existing TEXT-mode check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use splitlines() instead of readlines() in _maybe_render_failure_context() to strip trailing newlines, preventing blank separator lines between numbered context rows in the failure output block. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite test_context_block_no_blank_lines_between_rows to inspect the raw context block slice between the error header and footer without filtering blank lines. The old test discarded blank rows before asserting none existed, so it would pass against the double-spaced readlines() output. Now it slices the block between "error:" and "For more log info:" markers and asserts every body row is non-empty. Verified: test fails against the old readlines() path and passes against the splitlines() fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Emin <me@emin.chat>
The pyproject.toml version pin was bumped to 0.1.0a2 but [tool.uv.sources] and uv.lock still referenced the v0.1.0-alpha.1 wheel, breaking uv sync --frozen and bazel run //:prepare_dev. Update the source URL to the v0.1.0-alpha.2 release and regenerate uv.lock. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… and progress Import _KIND_COLOR and _KIND_LABEL from log_view instead of maintaining duplicate _KIND_COLOR_CONTEXT dict in progress.py. Derive compact labels from log_view labels via .upper() instead of literal dictionary. Remove unused YELLOW/BLUE imports. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.