Commit Graph

63 Commits

Author SHA1 Message Date
792039e016 Merge pull request 'docs(cli): sync CLAUDE.md — remove stale template text' (#7) from fix/sync-claude-md-state into main 2026-05-11 03:55:41 +00:00
d03845c4ff docs(cli): sync CLAUDE.md — remove stale template text
- Repo state: remove "(2026-04-16): Thin/stub" description
- Section 2: remove "Run tests (none yet...)" and "There is no main.go" notes
- Section 8: mark "Unit tests" and "molecule init" as implemented

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 03:46:55 +00:00
438a04a380 Merge pull request 'docs(cli): update KI-005 — tests now exist (32 integration tests)' (#6) from fix/ki-005-cli-tests-known-issues into main 2026-05-11 03:19:26 +00:00
022cab0dbb docs(cli): update KI-005 — tests now exist (32 integration tests)
known-issues.md claimed "There are no tests at all" but cmd/molecule/
molecule_test.go ships 32 table-driven integration tests covering the
full CLI command surface (workspace CRUD, agent ops, delegation, config,
completion, error paths). Mark KI-005 as resolved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 03:15:47 +00:00
fd66cb201e Merge pull request 'ci: rename .github/workflows -> .gitea/workflows (post-suspension sweep)' (#5) from ci-rename-github-to-gitea into main
All checks were successful
CI / Test / test (push) Successful in 3m41s
2026-05-10 21:18:07 +00:00
861b562d12 ci: rename .github/workflows -> .gitea/workflows (post-suspension sweep)
All checks were successful
CI / Test / test (pull_request) Successful in 1m39s
Release Go binaries / test (pull_request) Successful in 2m27s
Release Go binaries / release (pull_request) Has been skipped
GitHub org Molecule-AI was suspended 2026-05-06; SCM moved to Gitea
(git.moleculesai.app). The wholesale `git push --mirror` migration left
workflow files under .github/workflows/, which Gitea Actions does NOT
read - it reads .gitea/workflows/ exclusively.

This rename + the cross-repo `uses:` path rewrite are the minimum
edits to make CI fire on this repo again. The workflow content itself
is not modified (other than the path rewrites and lowercasing of the
old `Molecule-AI` org reference to the post-suspension `molecule-ai`).

Refs: feedback_post_suspension_migration_must_sweep_dormant_repos
2026-05-10 14:12:49 -07:00
7badce1740 chore(ci): verify auth fix (revert me) 2026-05-10 20:20:21 +00:00
e562b60d1b chore(ci): auth-test 2 (revert me) 2026-05-10 20:04:17 +00:00
4a84eb3a6b chore(ci): auth-test marker (revert me) 2026-05-10 20:01:54 +00:00
d4ed094c7b chore(ci): remove recovery marker (rerun delivered, see internal#233) 2026-05-10 19:52:10 +00:00
ed089b0c68 chore(ci): re-fire after incident recovery 2026-05-10 (see internal#233; revert me) 2026-05-10 19:51:30 +00:00
09ea1f9ed6 fix(ci): add dedicated CI test workflow (#3)
All checks were successful
CI / Test / test (push) Successful in 10m2s
[sdk-lead-agent] Closes the gap where Go tests only ran on tag push. New ci.yml mirrors release.yml test job (Go 1.25, vet, test -race) on PRs + main pushes; path filters scoped correctly. Self-validation of the workflow passed (1m36s, race-enabled). Approved + merged.
Co-authored-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
Co-committed-by: Molecule AI SDK-Dev <sdk-dev@agents.moleculesai.app>
2026-05-10 09:16:19 +00:00
d587919d17 Merge pull request '[migrate] vanity import go.moleculesai.app/cli (internal#71 phase 2)' (#2) from migrate/issue-71-vanity-imports into main 2026-05-09 00:59:40 +00:00
claude-ceo-assistant
15d8cec45f lint: extend gate to .json files (internal#71 — package metadata drift)
All checks were successful
Release Go binaries / test (pull_request) Successful in 6m18s
Release Go binaries / release (pull_request) Has been skipped
2026-05-07 22:57:16 +00:00
claude-ceo-assistant
76f37d928f fix(post-suspension): vanity import path go.moleculesai.app/cli (closes molecule-ai/internal#71 phase 2)
All checks were successful
Release Go binaries / test (pull_request) Successful in 1m37s
Release Go binaries / release (pull_request) Has been skipped
Migrates go.mod + 22 Go imports + README + comments + generated config
templates off the dead github.com/Molecule-AI/ identity onto the vanity
host go.moleculesai.app, owned by us.

Surfaces touched:
- go.mod module declaration: github.com/Molecule-AI/molecule-cli ->
  go.moleculesai.app/cli
- Every Go import statement under cmd/ + internal/
- README install section: rewritten to lead with the vanity install
  command (the previous text was migration-in-progress hedging)
- Comment URLs in internal/backends/backend.go + internal/cmd/connect.go
  (https://github.com/Molecule-AI/molecule-cli/issues/10) -> point at
  git.moleculesai.app/molecule-ai/molecule-cli
- Generated config templates in internal/cmd/init.go +
  internal/cmd/config.go: header URL updated so new users land on the
  live SCM
- Adds internal/lint/import_path_lint_test.go — structural test that
  walks every *.go / *.mod / Dockerfile / *.md / *.sh / *.yml in the
  module and rejects future references to github.com/Molecule-AI/ or
  Molecule-AI/molecule-monorepo. Mutation-tested before commit.

Test plan
- go build ./... clean
- go test ./... green (cmd/molecule + 5 internal packages + new lint
  gate, all pass)
- TestNoLegacyGitHubImportPaths fails on injected canary, passes on
  clean tree (no tautology)

Open dependency
- go.moleculesai.app responder must be deployed before
  'go install go.moleculesai.app/cli/cmd/molecule@latest' works
  externally. Internal builds + 'go build ./cmd/molecule' from a fresh
  clone work today (self-referential module path).
- Responder code prepared (worker.js, vendor-portable for CF Workers /
  Vercel Edge); deploy tracked separately under internal#71 phase 1.

Pairs with parallel migrations of plugin-gh-identity (#3) +
molecule-controlplane + molecule-core under the same internal#71 sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:26:45 +00:00
51fb38e063 Merge pull request 'docs(install): document upcoming Go-module migration + replace install command (#37)' (#1) from fix/install-path-gitea into main 2026-05-07 06:47:07 +00:00
documentation-specialist
2ee3b42d6b docs(install): document upcoming Go-module migration + replace install command (#37)
This PR is README-only. The Go module-path migration
(github.com/Molecule-AI/molecule-cli → git.moleculesai.app/molecule-ai/
molecule-cli in go.mod + every internal import) is filed separately as
a cross-repo Go-module migration PR (parked follow-up on internal#37).

Changes here:
- Install section: keep the go install command but switch to the
  Gitea path + add a "Migration in progress" callout pointing at the
  build-from-source workaround until the Go-module PR lands.
- Releases link: removed the broken github.com/.../releases URL
  (releases pipeline being restored on Gitea Actions).
- RFC #10 link: rewritten to git.moleculesai.app form with note that
  the original issue lived on the suspended GitHub org.

Files NOT touched in this PR (left for the cross-repo Go-module PR):
- go.mod (module declaration)
- 25+ .go files with github.com/Molecule-AI/molecule-cli/internal/...
  import paths
- known-issues.md L96 (describes current module path; consistent with
  go.mod)
- CLAUDE.md L37 (declares current module path; consistent with go.mod)

These edits maintain consistency with go.mod while documenting the
upcoming change to users. Bundling them with the doc edit would create
a half-state where docs say one path and go.mod says another.

Refs: molecule-ai/internal#37, molecule-ai/internal#38
2026-05-06 23:32:47 -07:00
Hongming Wang
9efcc6ad1a
Merge pull request #15 from Molecule-AI/auto/readme-connect
docs(readme): lead with `molecule connect` for external workspaces
2026-04-30 07:49:19 -07:00
Hongming Wang
324087e6bb docs(readme): lead with molecule connect for external workspaces
The README still described molecule-cli as a "TUI dashboard" and used
the old `molecli` binary name. After M1 (RFC #10), the primary entry
point is `molecule connect <workspace-id>` — the out-of-box bridge
between an external-runtime workspace and a local agent backend.

Rewritten to:
  - lead with the connect quick-start (token + API URL + invocation)
  - document the three built-in backends (claude-code, exec, mock)
    with --backend-opt examples
  - list the flags external-workspace operators actually need
    (--mode, --interval-ms, --since-secs, --dry-run)
  - note the state-file location (cursor resume across restarts)
  - link RFC #10 for the full design
  - fix the binary name (`molecule`, not `molecli`)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 07:46:39 -07:00
Hongming Wang
b38b3d3c67
Merge pull request #14 from Molecule-AI/auto/connect-m1-release-workflow
ci(release): switch to GoReleaser + race-detector tests
2026-04-30 06:31:19 -07:00
Hongming Wang
76569b7c9e ci(release): switch release.yml to GoReleaser + race-detector tests
After this PR the release pipeline produces a real out-of-box install
story for molecule-cli — multi-OS binaries with checksums, archived
with shell completions, plus a CI gate that catches races in the
new connect orchestrator.

What changed:

- `.github/workflows/release.yml`
  * Vet now scans `./...` (was: three packages); silently let
    regressions in internal/backends/ + internal/connect/ ship.
  * Test now runs `-race -count=1 ./...` (was: just `cmd/molecule`
    without race). The connect orchestrator runs heartbeat + poll
    goroutines concurrently — a race here would corrupt cursor state.
  * Release job switches from inline `go build` per matrix entry to
    `goreleaser release --clean`. Same multi-OS output, plus
    auto-generated changelog, checksum files, and one config file
    that future channels (brew tap, scoop, choco) hook into without
    new workflow steps.
  * `goreleaser check` runs first so a broken .goreleaser.yaml fails
    fast at validation, not partway through a build.
  * Path filter expanded so .goreleaser.yaml edits trigger CI.

- `.goreleaser.yaml`
  * Pre-generate shell completions in the before: hook so the archive
    can include them. (`molecule completion <shell>` still works at
    runtime — this just ships the files for users who prefer a
    drop-in setup.)
  * Update archive `formats:` (plural) for goreleaser v2 — `format:`
    was deprecated.
  * Drop the redundant per-archive checksum block; the top-level
    `checksum:` covers it.
  * Header comment rewritten to reflect that this is now the
    canonical release path (was: "wire it up when ready").

Test plan:

- [x] yaml parses for both files
- [x] `go test -race -count=1 ./...` green
- [ ] CI on this PR exercises the new test job (vet ./..., -race ./...)
- [ ] First tag push (v0.1.0) exercises the release job

After merge, cutting v0.1.0 is:
  git tag v0.1.0 && git push origin v0.1.0
  # → Release artifacts auto-built and published to GitHub Releases

This is M1.4 of [RFC #10](https://github.com/Molecule-AI/molecule-cli/issues/10).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 05:30:31 -07:00
Hongming Wang
9c4091e0d9
Merge pull request #13 from Molecule-AI/auto/connect-m1-exec-backend
feat(connect): M1.3 — exec + claude-code backends
2026-04-30 05:25:21 -07:00
Hongming Wang
b7a3c887c0 feat(connect): M1.3 — exec + claude-code backends
After this PR `molecule connect <id>` actually does something useful:
the default `--backend claude-code` runs `claude -p` as a subprocess
per inbound message, capturing stdout as the reply. The general
`--backend exec --backend-opt cmd="..."` lets operators bridge to any
program that reads stdin and writes stdout (Ollama, custom Python,
shell pipelines).

What's in:

- `internal/backends/exec/exec.go` — generic exec backend.
  - cmd  (required): shell command, run via /bin/sh -c (or cmd /c).
  - timeout (default 60s): per-message wall clock; subprocess is
    killed on timeout and the dispatcher keeps the message queued.
  - pass_meta (default false): when true, populates env with
    MOLECULE_WORKSPACE_ID / CALLER_ID / MESSAGE_ID / TASK_ID / METHOD.
  - Stdin = joined text parts; stdout = reply text.
  - Stderr is captured + surfaced in error messages so operators can
    see what their command printed.
  - Honours ctx cancellation — SIGTERM kills the subprocess immediately.

- `internal/backends/claudecode/claudecode.go` — thin shorthand.
  Translates {bin, args, timeout, pass_meta} into the equivalent exec
  config. Defaults: bin=claude, timeout=5m, pass_meta=true.
  Reusing exec means timeout/stdin/env handling stays in one place.

- `internal/cmd/connect.go` — registers both backends so `--help`
  shows them and the default `--backend claude-code` works without
  flag tuning.

Test plan:

- exec: cmd-required, bad-timeout, zero-timeout, echo-stdin-to-stdout,
  text-only-part-concat, non-zero-exit-surfaces-stderr, timeout-kills-
  runaway, pass_meta-injects-env, no-pass_meta-leaves-env-untouched,
  parent-env-inherited-when-pass_meta-off, ctx-cancel-kills-command.
- claude-code: registered, bin/args translation produces "echo -p hello",
  bad-timeout-surfaces, default-config-builds.
- All Unix tests gated on `requireUnix(t)` — Windows-shell semantics
  diverge; cross-platform coverage is M3 work (brew/scoop/winget).
- Full suite green under -race.

UX after this PR:

  # default — Claude Code on PATH
  molecule connect ws_01HF... --token $T

  # custom handler
  molecule connect ws_01HF... --backend exec \
      --backend-opt cmd="python myhandler.py"

  # different model via Claude Code
  molecule connect ws_01HF... \
      --backend-opt args="--model claude-sonnet-4-6"

  # CI smoke
  molecule connect ws_01HF... --backend mock --backend-opt reply=ok

Out of scope (M1.4 + later):

- M1.4: GoReleaser tag-triggered release.yml workflow
- stdio backend (one persistent subprocess + line-delimited JSON-RPC)
  — moved to M2 since exec covers the common case
- openai / mcp backends — M4 per RFC

RFC: https://github.com/Molecule-AI/molecule-cli/issues/10

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 04:23:36 -07:00
Hongming Wang
e9e234d750
Merge pull request #12 from Molecule-AI/auto/connect-m1-loops
feat(connect): M1.2 — heartbeat + activity poll loops
2026-04-30 04:17:22 -07:00
Hongming Wang
db6b196631 feat(connect): M1.2 — heartbeat + activity poll loops
Implements the runtime side of `molecule connect <id>`. After this PR
the CLI can actually attach to an external workspace and round-trip
inter-agent messages through any registered backend.

What's in:

- `internal/connect/client.go` — platform-API client with bearer auth.
  Endpoints: POST /registry/register (delivery_mode=poll, no URL),
  POST /registry/heartbeat, GET /workspaces/:id/activity?type=a2a_receive,
  POST /workspaces/:id/a2a (reply target).
  Errors split into TransientError (network/5xx — retry with backoff)
  and PermanentError (4xx — abort with clear message).

- `internal/connect/state.go` — atomic cursor persistence at
  ~/.config/molecule/state/<workspace-id>.json. Mode 0o600 (owner-only)
  from day 1 because future state additions may include rotated tokens.
  Atomic write-then-rename so a crash mid-write can never produce a
  half-written cursor.

- `internal/connect/connect.go` — Run() orchestrator. Wires register-
  with-bounded-retry, then heartbeat goroutine + poll goroutine.
  Both respect ctx cancellation for clean SIGTERM.

  Robustness contract per RFC #10:
    * Cursor advances AFTER successful dispatch — crash mid-batch
      re-delivers, never drops.
    * 410 on cursor lookup → reset to "" and re-fetch (don't deadlock
      on a pruned cursor).
    * Heartbeat permanent error stops the heartbeat loop only; poll
      loop keeps running so the operator sees "stopped" + reason in
      logs and can SIGTERM.
    * Backend dispatch is sequential within a batch (avoids out-of-
      order replies for in-flight conversations).
    * Inter-agent reply path: POST envelope to /workspaces/<source>/a2a.
    * Canvas-origin reply (source_id == nil) logs + skips for now —
      M1.3 wires that via the task_update activity convention.

- `internal/cmd/connect.go` — runConnect now actually calls
  connect.Run() (was a placeholder ctx-wait in M1.1).

Test plan:

- httptest workspace-server stub covers register / heartbeat / activity
  / a2a reply endpoints.
- TestRun_RoundTrip_AgentReply: end-to-end ping → mock backend → pong
  reply lands at source, cursor saved.
- TestRun_CanvasOriginMessageNotReplied: source_id=nil → backend fires
  but no reply post; cursor still advances.
- TestRun_CursorPruned410ResetsAndContinues: server returns 410 once,
  cursor resets to "", next poll dispatches the fresh row.
- TestRun_PermanentRegisterErrorAborts: 401 surfaces immediately.
- TestRun_TransientRegisterErrorRetries: 503 then 200 → register
  succeeds on second attempt.
- TestRun_OptionsValidation: missing Backend / WorkspaceID surface
  before any I/O.
- State: round-trip, file mode 0o600, atomic-rename leaves no .tmp
  artifacts, corrupted file surfaces error.
- All tests green under -race.

Out of scope (next PRs in this stack):

- M1.3: claude-code backend (canvas-origin reply convention rides
  with this)
- M1.4: GoReleaser tag-triggered release.yml workflow
- Push-mode (--mode push currently surfaces a clear "M4" error)

RFC: https://github.com/Molecule-AI/molecule-cli/issues/10

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 03:15:51 -07:00
Hongming Wang
268e0cd9ed
Merge pull request #11 from Molecule-AI/auto/connect-m1-foundation
feat(connect): M1.1 — Backend interface + connect skeleton + mock backend
2026-04-30 03:08:00 -07:00
Hongming Wang
3a6a7eb495 feat(connect): M1.1 — Backend interface + connect skeleton + mock backend
First step toward `molecule connect <id>` — the out-of-box external-
runtime workspace connector specified in RFC #10.

What's in this PR (foundational, ~300 LOC of code + matching tests):

- `internal/backends.Backend` — the seam every concrete handler
  implements: HandleA2A(ctx, Request) → Response, Close(). Two methods,
  no inheritance, no surprise side effects. Concurrency-safe by
  contract (poll dispatch may parallelise).
- Request/Response/Part/Config types — lossless JSON-RPC mirror so
  backends can re-issue downstream without re-parsing.
- Compile-time registry — `Register("name", factory)` from each
  backend's init(); `Build(name, cfg)` selects at runtime. Panics
  on duplicate registration so drift fails loudly at startup, not
  on first message.
- `mock` backend — single-template echo for CI smoke + tests + demos.
  `--backend-opt reply="<template>"` with `%s` for inbound text.
- `molecule connect <workspace-id>` cobra command — flag surface,
  validation, --dry-run for smoke. Loops (heartbeat, activity poll,
  dispatch) land in M1.2 in internal/connect/.

Coverage:
- Registry: duplicate-name panic, empty-name panic, nil-factory panic,
  Build unknown-name error includes registered list.
- Mock: default template, custom template, text-part concatenation,
  Final=true on terminal response.
- Connect: --backend-opt KEY=VALUE parser (incl. value with =),
  flag validation (missing token, bad mode, bad opt, unknown
  backend), --dry-run happy path.

All tests pass under -race.

Out of scope (subsequent M1 PRs):
- M1.2: heartbeat + activity poll loops in internal/connect/
- M1.3: claude-code backend (wraps molecule-mcp-claude-channel)
- M1.4: GoReleaser tag-triggered release.yml workflow

RFC: https://github.com/Molecule-AI/molecule-cli/issues/10

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 02:05:12 -07:00
Hongming Wang
6127b4c77b
Merge pull request #8 from Molecule-AI/fix/yaml-output-support
fix(cli): implement true YAML output support
2026-04-24 13:26:39 -07:00
Hongming Wang
7dde287e58
Merge pull request #7 from Molecule-AI/feat/init-force-flag
feat(cli): add --force flag to molecule init
2026-04-24 13:26:36 -07:00
Hongming Wang
38d7618085
Merge pull request #6 from Molecule-AI/feat/cli-full-command-tree
feat(cli): implement full CLI command tree
2026-04-24 13:25:23 -07:00
Hongming Wang
57802aa22f fix(ci): sync auto-promote workflow (ff-only, no-gates mode) 2026-04-24 08:35:20 -07:00
Hongming Wang
f378f20760
Merge pull request #9 from Molecule-AI/chore/add-auto-promote-staging
chore(ci): add auto-promote-staging workflow
2026-04-24 08:18:49 -07:00
Hongming Wang
2539d007e5 chore(ci): add auto-promote-staging workflow 2026-04-24 07:44:02 -07:00
211b57b5b3 fix(cli): remove stray brace in runPlatformHealth causing syntax error
The yaml-output-support refactor removed the combined json/yaml if-block
but left a dangling `}` that closed runPlatformHealth prematurely,
putting the tabwriter block outside the function body.

Removes the stray brace at line 137. CI vet was failing with:
  platform.go:138:2: syntax error: non-declaration statement outside function body

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 05:23:40 +00:00
ab91b652ef fix(cli): implement true YAML output support
The `--output yaml` flag was accepted but aliased to JSON since
printYAML() was never defined. Add printYAML() using gopkg.in/yaml.v3
(already an indirect dep via viper) and split all output format
branches into explicit json/yaml/table paths.

Affected commands: workspace list/create/inspect/audit,
agent list/inspect/peers, platform audit/health.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 03:47:00 +00:00
e835eec6e8 feat(cli): add --force flag to molecule init
Allows re-scaffolding an existing molecule.yaml without manual deletion.
Exit code 1 preserved for existing file without --force (usage error path).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:17:36 +00:00
bf29d8b00a fix(cli): rename root command mol→molecule, register initCmd, fix config scaffold path
- Change rootCmd Use/Short/Long from 'mol' to 'molecule'
- Register initCmd in root so 'molecule init' works
- Update viper config name lookup from 'mol' to 'molecule'
- Fix config init/set to write molecule.yaml instead of mol.yaml
- Update all user-facing strings mol→molecule

Fixes TestCLI_Version, TestCLI_Init, TestCLI_ConfigInit, TestCLI_Completion_GeneratesScript
2026-04-23 19:24:12 +00:00
230934561c feat: implement full CLI command tree
Implement the core CLI for molecule-cli:

- cmd/molecule/main.go: entry point calling cmd.Execute()
- internal/cmd/root.go: cobra root with global flags (--api-url,
  --verbose, --output, --config), registers all 4 command groups
- internal/cmd/workspace.go: 7 subcommands (list, create, inspect,
  delete, restart, audit, delegate)
- internal/cmd/agent.go: 4 subcommands (list, inspect, send, peers)
- internal/cmd/platform.go: 2 subcommands (audit, health)
- internal/cmd/config.go: 5 subcommands (list, get, set, init, view)
- internal/cmd/http.go: runHTTP helper shared by agent send and
  workspace delegate
- internal/client/platform.go: control plane HTTP client with
  workspace/agent/health/audit operations

All 18 subcommands wire to platform API via MOLECULE_API_URL.
Binary builds to ./bin/mol. Resolves KI-001, KI-002 (partial),
KI-003.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:44:24 +00:00
1ebe5fa999 fix(cli): build from module root ("go build .") instead of "./cmd/molecule"
Go 1.25 resolves "./cmd/molecule" relative to cmd.Dir as an absolute path
under the CWD, producing the doubled "cmd/molecule/cmd/molecule" error.
Building the whole module from the root and relying on the binary name
from -o is the idiomatic Go approach and avoids path arithmetic entirely.

Also tightened error message to match the new command.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 19:12:49 +00:00
7b254c926c fix(cli): use cwd as repoRoot instead of os.Executable path
os.Executable() in Go 1.x parallel tests resolves to <TempDir>/0/molecule.test
making path-based traversal from the binary back to the repo root unreliable.
Switch to os.Getwd() which always returns the repo checkout root in CI
(where `go test ./cmd/molecule/...` is invoked), and skip any path arithmetic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 19:06:30 +00:00
9dfb5f9aa4 fix(cli): replace runtime.GOEXE with hardcoded "go" in test
runtime.GOEXE is not available in Go 1.25 standard library.
Replace with the standard "go" binary name which is on PATH in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 19:03:36 +00:00
6d1bcc007f fix(cli): add missing runtime import to test file
go vet reports: cmd/molecule/molecule_test.go:209:11: undefined: runtime

runtime.GOEXE is used in mol() to find the Go binary for building the
test binary. The runtime package was referenced but not imported.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 19:02:08 +00:00
1c9a207444 fix(cli): fix undefined v in runConfigSet
v.SafeWriteConfig() was called without a local viper instance.
Create a fresh viper scoped to the target config file, read any
existing values, set the new key, then atomically write via SafeWriteConfig.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 18:52:05 +00:00
2f4296f98e fix(cli): replace v.Marshal with v.SafeWriteConfig in config set
viper.Viper has no Marshal method in v1.21. Use SafeWriteConfig instead
which atomically writes only explicitly-set keys to the config file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 18:37:28 +00:00
a1dacff202 fix(cli): remove unused _ = workspaceID, fix repoRoot() path for test binary
- workspace.go: remove no-op _ = workspaceID (workspaceID consumed in runHTTP call)
- molecule_test.go: replace hardcoded /workspace/repos/clone-cli path with
  dynamic exe-based resolution so tests pass when built by CI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 18:35:43 +00:00
1471cad4c1 feat(cli): add molecule completion [bash|zsh|fish|powershell] subcommand
Wires shell completion for all 4 shells via Cobra's built-in generators.
Covers the remaining item from the implementation status checklist.

Adds:
- internal/cmd/completion.go: cobra.GenXxxCompletion wrappers with
  usage examples for each shell
- 5 new integration tests in cmd/molecule/molecule_test.go:
  - TestCLI_Completion_Help (4 shells × help flag)
  - TestCLI_Completion_GeneratesScript (4 shells × script output)
  - TestCLI_Completion_InvalidShell (exit code 2 on bad shell)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 18:06:02 +00:00
47692cfb36 fix(cli): complete "mol" → "molecule" rename in test error messages
All test.Fatalf messages referenced "mol <subcommand>" but the binary
is now "molecule". Also fix configSet to use os.WriteFile atomic write
instead of viper.WriteConfig (avoids file-permission edge cases).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 07:35:31 +00:00
3afa0d8c0a docs(cli): sync CLAUDE.md command tree with actual implementation
- Update Section 2 build/test commands to reflect current state
- Rename Section 8 command tree from "mol" to "molecule" throughout
- Add --api-url flag to Global Flags table, remove --platform-url
- Update error examples to use "molecule" command name
- Replace Section 11 "Early / Stub" checklist with accurate status
- Mark all implemented commands and tests as done, keep remaining todos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 07:02:39 +00:00
ea69db8bfc fix(cli): complete "mol" → "molecule" rename across all cmd packages
Rename all user-facing "mol" references to "molecule" to match the
published binary name (binary: molecule in .goreleaser.yaml):
- root.go: Use string, versionInfo, viper config name, flag descriptions
- init.go: section comment, Short, Long, cfgPath, scaffolded message
- config.go: Long description, Shorts, configFile, WriteFile, Stat check
- molecule_test.go: binary name, version output check, mol.yaml → molecule.yaml

Also fix test helper to use runtime.GOEXE instead of hardcoded /tmp/go/bin/go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 06:36:42 +00:00
f654a2dff9 fix(cli): align rootCmd.Use to goreleaser binary name
rootCmd.Use was "mol" while .goreleaser.yaml sets binary: "molecule".
Align to "molecule" to match the published binary name, test
invocations, and docs. Also fix test helper to use runtime.GOEXE
instead of hardcoded /tmp/go/bin/go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 05:36:07 +00:00