Skip to content

Add --json to graphcode projects and graphcode workspaces - #938

Merged
scgopi merged 1 commit into
scgopi:mainfrom
ZekeAranyLucas:cli-json-projects-workspaces
Oct 27, 2026
Merged

scgopi merged 1 commit into
scgopi:mainfrom
ZekeAranyLucas:cli-json-projects-workspaces

Conversation

@ZekeAranyLucas

Copy link
Copy Markdown
Contributor

Summary

Adds --json to graphcode projects and graphcode workspaces, so a tool can enumerate every workspace and the projects in each without scraping text. Follow-up to #925.

Why

An external tool needs to list both. The text output is meant for people: two-space-separated columns, a * marker, and no projects yet instead of an empty list. The two lists get the flag together so they stay consistent.

Before / after (real runs on macOS)

Before (the installed Homebrew graphcode, which predates #925, so workspaces itself is unknown; on main after #925 workspaces --json fails with unknown option: --json, which the earlier PR's own run showed):

$ graphcode projects --json
graphcode: unknown option: --json        (exit 1)
$ graphcode workspaces --json
graphcode: unknown command: workspaces   (exit 1)

After (this branch's graphcode, built with swift build --product graphcode, talking to the running daemon):

$ graphcode workspaces --json
[{"current":true,"name":"Default","path":"/Users/zaranylucas/.graphcode"},{"current":false,"name":"copilotpin","path":"/Users/zaranylucas/.graphcode-copilotpin"}]

$ graphcode projects --json | head -c 160
[{"lastOpenedAt":"2026-10-27T04:20:44Z","name":"odang","path":"/Users/zaranylucas/src/gim/odang"},{"lastOpenedAt":"2026-10-27T04:20:10Z","name":"Loopkeeper",...

$ GRAPHCODE_SUPPORT_DIR=~/.graphcode-copilotpin graphcode projects --json
[]

Text output without --json is unchanged.

How to observe after merge

graphcode workspaces --json | jq -r '.[].path' | while read -r ws; do
  GRAPHCODE_SUPPORT_DIR="$ws" graphcode projects --json
done

Each workspace's projects goes through that workspace's own daemon. A workspace whose daemon isn't running fails as it already did (exit 69, "graphcoded isn't running").

Risks / rollback

Additive. The JSON shape is new and has one consumer. Keys are sorted, dates are ISO 8601 (same as mail --json), and slashes are not escaped. One small behavior change: graphcode projects --help/-h now print help, as every other verb does. Before, --help was rejected as an unknown option and -h was silently ignored. Rollback is a plain revert.

Changes

  • GraphcodeCommand: .listProjects(json:) and .listWorkspaces(json:); both verbs accept --json and treat --help/-h as help; renderJSON for each list, through one shared encoder; help text updated.
  • graphcode-cli/main.swift: prints the JSON renderer when --json is passed.
  • graphcode/Tests/GraphcodeWorkspacesCommandTests.swift renamed to GraphcodeListingCommandTests.swift, now covering both lists: parsing, help, text, JSON shape, empty array.

Test plan

make test was not run. This machine lacks the macOS 15 SDK, the Metal toolchain, and GhosttyKit (make doctor), so the app test bundle can't build here, the same limitation as #925. The test files were compiled and run with swift test from a scratch SwiftPM package that depends on this checkout's GraphcodeKit product. The test sources are identical, but the runner is not Xcode's graphcodeTests bundle.

RED: swift test (scratch harness, graphcode/Tests/GraphcodeListingCommandTests.swift) -> compile failure: type 'GraphcodeCommand' has no member 'renderJSON' (a missing-API compile error, not a behavioral failure)
GREEN: swift test (same harness, same file) -> 8 tests in 1 suite passed
REGRESSION: swift test (harness plus GraphcodeCommandTests, GraphcodeCommandPromoteTests, MailroomCommandTests, WorkspaceTests) -> 97 tests in 5 suites passed; make check -> exit 0, 312 violations, same count as main

Checklist

  • I have read the Contributing Guidelines
  • I have signed off my commits (git commit -s) per the DCO
  • Tests pass locally (make test): not run, see Test plan; the affected suites passed through SwiftPM instead
  • Code follows the existing style (make check)
  • I added the test/contract before the implementation and observed the intended RED failure

Tools that enumerate every workspace and the projects in each had to scrape
two-space-separated text, and `projects` printed "no projects yet" instead of an
empty list. `--json` prints each list as a JSON array: projects carry name,
path and lastOpenedAt; workspaces carry name, path and current.

`projects --help`/`-h` now print help like every other verb, instead of
"unknown option" or a silent listing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 40117320-498b-4a94-9420-19ba4ea5882b
Signed-off-by: Zeke Arany-Lucas <93434462+ZekeAranyLucas@users.noreply.github.com>
@scgopi
scgopi merged commit 0389d7d into scgopi:main Oct 27, 2026
30 of 31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants