feat(cli): add daemonless gortex analyze command#84
Conversation
Expose graph analyzers on the CLI without a running daemon. `gortex analyze --kind <k> --path <dir> [--format json|text]` indexes the path entirely in-process (no daemon, no socket) and runs the analyzer against the fresh graph — handy for CI pipelines and one-shot scripts. Supported kinds: `synthesizers`, `resolution_outcomes`. To avoid duplicating logic between the MCP tool and the CLI, the analyzer cores are extracted into a new `internal/analyzer` package as pure calculations (graph in, struct out): - `AnalyzeSynthesizers` - `AnalyzeResolutionOutcomes` / `ClassifyUnresolved` The existing MCP handlers (`handleAnalyzeSynthesizers`, `handleAnalyzeResolutionOutcomes`) are refactored to call these cores; their JSON/compact output shapes are unchanged and the existing MCP-layer tests pass as-is. The resolution-outcome taxonomy constants now live in `internal/analyzer` with thin aliases kept in the mcp package. Tests: unit tests for both cores + an end-to-end index→analyze CLI test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
golangci-lint errcheck flagged the text-format print paths in cmd/gortex/analyze.go. Ignore the return explicitly, matching the codebase idiom. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Hi @zzet 👋 — gentle ping on these four, all ready for review (CI green,
Update on the overlap I flagged earlier: I checked #85 and #87 against the temporal work that already landed in
No rush at all — happy to split or adjust anything further if you'd prefer. Thanks for the project! |
|
Hi @zzet 👋 — overview of the current open batch (all rebased onto latest Docs / infra (independent, low-risk):
Temporal dispatch resolvers (Go) — these all touch
Java cross-language:
LLM:
CLI:
Suggested low-friction start: #94, #92, #88 are the most independent. The temporal-resolver cluster (#87/#89/#90/#98) I'll rebase-on-merge so each lands clean. No rush — thanks for the project! |
|
@zzet — rebase sweep done. After #87 merged (and then #93 change_contract + #95 deps), the temporal-resolver cluster went DIRTY. All affected branches are now rebased onto latest
#84 / #88 / #92 / #94 needed no rebase (#92 verified clean via |
|
Friendly ping @zzet 🙂 — CI is green (10/10) and the branch is |
|
Hey @avfirsov |
|
Thanks @zzet — and totally fair to hold off if you're still exploring an alternative. Let me lay out the concrete cases that pushed me to a daemonless one-shot, so we're optimizing for the same problem (the capability, not necessarily an explicit user-facing "daemonless mode"). The original need: comparing fork vs. original on a large legacy repo. The whole thing started because I wanted a clean A/B — "does the temporal work actually resolve more edges than baseline?" — on a real legacy codebase. Three constraints made the resident daemon awkward there:
So the value I'm actually after is "run an analyzer over a path without standing up a daemon." If you'd rather express that some other way — e.g. the existing daemon path auto-spawning an ephemeral in-process instance when no daemon is reachable, instead of a distinct What does your alternative resolution look like so far? If you can point me at the shape you're leaning toward, I can adapt this PR (or close it and fold the CLI surface into your approach). No rush. |
What
Adds a daemonless
gortex analyzeCLI command:It indexes
--pathentirely in-process — no daemon, no socket — and runs the analyzer against the fresh graph. Useful for CI pipelines and one-shot scripts that want graph analytics without standing up the daemon.Why this shape
To avoid duplicating logic between the MCP tool and the new CLI, the analyzer cores are extracted into a new
internal/analyzerpackage as pure calculations (graph in, struct out):AnalyzeSynthesizersAnalyzeResolutionOutcomes/ClassifyUnresolvedThe existing MCP handlers (
handleAnalyzeSynthesizers,handleAnalyzeResolutionOutcomes) are refactored to call these cores. Output shapes are unchanged — the existing MCP-layer tests pass as-is, which is the safety net for the refactor. The resolution-outcome taxonomy constants now live ininternal/analyzer, with thin aliases retained in themcppackage so existing call sites/tests keep compiling.Tests
internal/analyzer: unit/shape tests for both cores (synthesizer grouping + name filter; the full unresolved-edge taxonomy + reason filter).cmd/gortex: end-to-end index→analyze tests asserting valid JSON for both kinds, plus unsupported-kind validation.internal/mcpanalyze handler tests unchanged and green.go build ./...andgo test ./internal/analyzer/... ./cmd/gortex/... ./internal/mcp/...pass.Notes / scope
synthesizers,resolution_outcomes) — the ones whose cores are extracted here. Easy to extend the dispatcher to more kinds in follow-ups.🤖 Generated with Claude Code