stacklok / stacklok/mecatl

onboarding: `mecated migrate --scan-only` — a read-only inventory that tells an arriving Claude Code user what of their setup already works

Open
#411 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

devex enhancement ux
Dominant language
Go
Stars
152
Forks
16
Avg merge
14h 48m
Merged PRs (30d)
536

Description

onboarding: mecated migrate --scan-only — a read-only inventory that tells an arriving Claude Code user what of their setup already works

Sub-issue of the portability epic (#410) — see the parent for the shared artefact map (what mecatl
does with each part of a Claude Code setup today) and the boundaries this issue inherits.

Problem

Mecatl already honours most of a Claude Code setup, but nothing tells the user that: three of
the most valuable categories (root CLAUDE.md, .claude/rules, .claude/agents) are live
with no action at all, two more are one named flag away, and two cannot transfer. Today the
only way to learn any of that is to read the flag reference.

So the first-run experience for a developer arriving from Claude Code is an empty zero state
and a reasonable suspicion that none of their existing work carries over.

Proposal — scan and report, nothing else

mecated migrate --scan-only: enumerate Claude-Code artefacts at both scopes (~/.claude/**
user, <workspace>/.claude/** + CLAUDE.md project), resolve each against the effective
configuration of this invocation, and print a report. It writes nothing.

Three buckets, a reason mandatory on the latter two:

  • Active now — found, and this configuration already loads it.
  • Available, not enabled — found, supported, needs a named flag; the report prints the
    exact flag (e.g. 14 skills found under ~/.claude/skills — enable with --skills-conventional).
  • Not supported — found, will not be loaded, with the reason
    (hooks: no config lane for global hooks; only agent-def hooks: maps are config-driven,
    mcpServers: 8 of 9 declare stdio; only streamable-HTTP is supported).

Reuse, don't rebuild: internal/app/build.go already emits discovery facts through diagFact
(e.g. internal/app/build.go:2885, :3261) — this command should render that existing
diagnostic surface for a human at the point of arrival, not stand up a parallel resolver.
If the two would drift, that's a defect in one of them.

Explicit non-goals (beyond the epic's shared boundaries)

  • No writes at all — not even the opt-in copies the epic permits elsewhere. This issue is
    read-only end to end.
  • No session import. That's sub-issue B, and its open design questions (compact-summary
    records, dedup key, retention, plaintext duplication) must not ride in on a read-only
    reporting change.
  • No permission-file generation. Sub-issue C.
  • No secrets read or printed. Env values and tokens are never opened; only server names
    and transports are reported.
  • No TUI surface. Sub-issue D, which consumes this report.

Acceptance

  • Run against a fixture home + workspace containing every category: each is reported in
    exactly one bucket, and every "Available, not enabled" line names the enabling flag while
    every "Not supported" line carries a reason string. Bucket assignment is locked by a test
    for hooks, stdio mcpServers, and nested/@import CLAUDE.md (root-only loader).
  • Read-only proven, not asserted: the scan runs to completion against a read-only
    fixture tree, and a test asserts no path under the fixture home or workspace is created or
    modified.
  • No source install (~/.claude absent, no CLAUDE.md) → a clear "nothing found" report and
    exit 0, not an error.
  • No env value, token, or settings.local.json personal rule body appears in the output.
  • The reported enable/active state for skills, commands, agents and permissions matches the
    behaviour of the corresponding flags — a test drives both and compares.
  • Docs: docs/usage/mecated.md gains the subcommand; the ADR-0099 lineage is noted (this is
    the discovery half of the migration story, transcript import being the other).

Sibling sub-issues B (sessions), C (permissions), D (TUI overlay, depends on this) and E
(export) are tracked under the parent.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing discovery facts in internal/app/build.go at the cited diagFact locations, then trace the current migrate command entry point and its effective-configuration handling. Build fixture-based tests for the three required bucket cases, read-only behavior, missing sources, and redaction, and update docs/usage/mecated.md with the subcommand and ADR-0099 lineage. Done means the report reuses discovery results, matches flag behavior, writes nothing, and passes the stated acceptance checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, documentation, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.