Skip to content

feat(config): multi-developer support via automation.json + companion /whoami#76

Open
marcoaperez wants to merge 2 commits into
petrowsky:mainfrom
Taiko-Solutions:feat/multi-developer-whoami
Open

feat(config): multi-developer support via automation.json + companion /whoami#76
marcoaperez wants to merge 2 commits into
petrowsky:mainfrom
Taiko-Solutions:feat/multi-developer-whoami

Conversation

@marcoaperez

Copy link
Copy Markdown
Contributor

Lets multiple developers work against the same FMS-hosted solution, each from their own machine with their own companion server, without hardcoding If Get(AccountName) = "..." branches into the FM script.

This follows up on #30, which was a design-only writeup closed without comment — this time with working, testable code instead of just a proposal doc.

What this adds

  • automation.json.example documents an optional users section, keyed by FileMaker account name (Get(AccountName)), holding each developer's repo path and companion host/port.
  • companion_server.py gets GET /whoami?account=<name>, which resolves that block from automation.json. Returns 400 with a clear message when the account isn't configured (or automation.json has no users section at all) — callers fall back to the existing folder-picker/cached-global behavior.
  • filemaker/README.md documents the setup under a new "Multi-developer setup" section.

Scope

This PR covers the config + companion side only, which is fully testable outside of a live FileMaker instance (see test plan below). Wiring this into Get agentic-fm path / Explode XML on the FM script side — so it calls /whoami instead of relying solely on the folder-picker dialog — is a natural follow-up once this direction lands. Happy to iterate on that once this part is reviewed. The existing folder-picker flow is untouched and keeps working exactly as before; users is entirely optional and backward-compatible.

Test plan

$ curl "http://127.0.0.1:8765/whoami?account=testuser"
{"account": "testuser", "repo_path": "/tmp/x", "companion_host": "10.0.0.5", "companion_port": 8765}

$ curl -w "\nHTTP %{http_code}\n" "http://127.0.0.1:8765/whoami?account=nobody"
{"error": "Account 'nobody' not configured"}
HTTP 400

$ curl -w "\nHTTP %{http_code}\n" "http://127.0.0.1:8765/whoami"
{"error": "Missing required 'account' query parameter"}
HTTP 400
  • Known account returns its configured block
  • Unknown account returns 400 with a clear message
  • Missing account query param returns 400
  • No users section in automation.json at all → same 400 path, no crash

@agentic-fm

Copy link
Copy Markdown
Collaborator

Thank you, @marcoaperez — this is a good direction, and the implementation is clean (optional users block, 400 on an unknown account, folder-picker flow untouched, backward-compatible).

I want to hold it briefly rather than merge piecemeal. This PR introduces a per-developer companion_host / companion_port schema in automation.json, and we have a closely related need surfacing right now: the companion host/port is currently spread across a hardcoded default, an env var, a --port flag, automation.json's companion_url, and (with this PR) the users block — no single source of truth, which is why things like the session-start health check break when someone runs a non-default port.

Rather than land two overlapping port-config mechanisms, we're going to design one canonical companion config that both your /whoami path and the base companion/startup checks consume, with your users[account] block as the per-developer override layer on top of it. Your work here is a core input to that — nothing is wasted; it just gets folded into a coherent whole so we don't ship a half-wired endpoint (the /whoami consumer, the "Get agentic-fm path" FM script, is still deferred here anyway).

Marking triage/later and keeping it open. I'll follow up with the config shape so you (or we) can rebase this onto it. Appreciate you pushing this forward. 🙏

@agentic-fm agentic-fm added the triage/later Valid; revisit later label Jul 15, 2026
@agentic-fm

agentic-fm commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

The base companion config this PR's override layer was deferred to design against has landed in acc480e. It ships the users block schema in agent/config/companion.json.example (per-account repo_path, companion_host, companion_port, keyed by Get(AccountName)), so the /whoami override can now be built on a settled base without a schema redesign.

How it slots in (see agent/docs/COMPANION_SERVER.md):

  • users[<account>] sits in client-reach resolution, above the base advertise_host + port — it changes what a client dials, never how the server binds. Keep it out of the server-bind chain.
  • GET /whoami?account=<name> resolves the users entry over the base companion block and returns the reach host/port + repo_path.
  • Plug-in detection is per-companion, not per-Get(AccountName)/health carries no account and the detection cache is process-global. /whoami must not attempt to route plug-in detection per account; the companion brokers the one plug-in it shares a macOS login with.

One divergence to settle: this PR's title puts users in automation.json, but acc480e ships the users schema in companion.json (the single companion-config source in COMPANION_SERVER.md). Please align /whoami to read users from companion.json — or push back here if automation.json is preferred — so we commit to one location before merge.

marcoaperez and others added 2 commits July 16, 2026 18:10
… /whoami

Lets multiple developers work against the same FMS-hosted solution, each
from their own machine with their own companion server, without hardcoding
`If Get(AccountName) = "..."` branches into the FM script.

- automation.json.example documents an optional `users` section, keyed by
  FileMaker account name, holding each developer's repo path and companion
  host/port.
- companion_server.py gets GET /whoami?account=<name>, which resolves that
  block from automation.json. Returns 400 with a clear message when the
  account isn't configured (or automation.json has no `users` section at
  all) — callers fall back to the existing folder-picker/cached-global
  behavior.
- filemaker/README.md documents the setup.

This PR covers the config + companion side only, which is fully testable
outside of a live FileMaker instance (see test plan). Wiring this into
`Get agentic-fm path` / `Explode XML` on the FM script side is a natural
follow-up once the direction lands — happy to iterate on that once this
part is reviewed. The existing folder-picker flow is untouched and keeps
working exactly as before; `users` is entirely optional.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Per maintainer review: acc480e landed agent/config/companion.json as the
canonical companion config and already ships the `users[<account>]`
schema in companion.json.example, so this PR's override layer builds on
that settled base instead of introducing a second, overlapping
port-config mechanism in automation.json.

- Reverted the `users` block I'd added to automation.json.example — no
  longer needed, the schema already lives in companion.json.example.
- companion_server.py: replaced the `_load_automation_config()` helper I'd
  added — it collided with an existing, unrelated function of the same
  name already in the file (a real duplicate-definition bug, worth fixing
  regardless of this PR) — with `_load_companion_users()`, a sibling of
  the existing `_load_companion_config()` that reads the same
  companion.json file's `users` block instead of its `companion` block.
  `/whoami` now resolves through it.
- agent/docs/COMPANION_SERVER.md: added a "Multi-developer override"
  section documenting the `users[<account>]` config shape, where it sits
  in the client-reach precedence chain (above `advertise_host`+`port`,
  below `COMPANION_URL`), and — per review — makes explicit that it is
  client-reach-only and never routes plug-in detection (`/health` carries
  no account; the detection cache is process-global; one plug-in per
  companion regardless of which account asks).
- filemaker/README.md: "Multi-developer setup" now points at that doc
  section instead of duplicating the config example against the wrong
  file.

Verified end-to-end against a live companion with a companion.json
`users` block: known account resolves correctly, unknown account and
missing `account` param both 400 with a clear message, and /health
(plugin block) is unaffected.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@marcoaperez
marcoaperez force-pushed the feat/multi-developer-whoami branch from ead5966 to accaf7e Compare July 16, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage/later Valid; revisit later

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants