Expand description
External tracker sync: orchestration for tix export / tix import,
the Tool selector, the CommandRunner spawn seam, and the pure
mapping / conflict-resolution rules.
WP05 wires the CLI to glab (GitLab) and linear-cli (Linear) under
contracts/external-tools.md. Tokens are resolved through
token::resolve with env precedence, injected only as an env pair (never
argv), and every error/report surface scrubs the secret as <token>.
The orchestration lives here so it is testable at module granularity by
pointing PATH at fake tool scripts; export / import are pure in the
sense that they take the store, tool, config and an output sink, and the
only externally visible side effects are local issue files, tix.toml,
the tool subprocesses, and what is written to out.
Modules§
- glab
- GitLab adapter: shells out to the
glabCLI undercontracts/external-tools.md(GitLab row). Every contract fabricate template’s command shape is reproduced; the only additions are--output json(needed to parse the create/list responses) and the token env injection. - linear
- Linear adapter: shells out to the
linear-cliCLI undercontracts/external-tools.md(Linear row). - token
- Token resolution with the contract’s precedence: env var, then
tix.toml[export], then the CLI’s native auth.
Structs§
- Command
Outcome - The captured result of a spawned external tool.
- Process
Runner - Production runner:
std::process::Commandwith a synchronous output wait. - Remote
Issue - A remote issue parsed from the tracker’s JSON list output.
Enums§
- Tool
- The supported external tracker, selected via
--target gitlab|linear.
Traits§
- Command
Runner - Spawn seam: production uses
ProcessRunner; tests inject aFakeRunnerthat records argv/env without spawning anything. - Tracker
Adapter - Common surface both tracker adapters implement so the orchestration is tool-agnostic.
Functions§
- date_
to_ epoch_ days - Parse
YYYY-MM-DDinto days since the Unix epoch. - days_
from_ civil - The inverse of
model::civil_from_days(Howard Hinnant’sdays_from_civil): calendar date → days since the Unix epoch. - export
tix export: mirror local issues to the remote tracker, recording the remote id back into the localgitlab_id/linear_idso a re-run updates instead of creating duplicates (idempotency, FR-Remote-sync).- import
tix import: pull open remote issues into local files.- is_
remote_ newer - The conflict rule: the remote wins when its
updated_atis strictly later than the local issue’supdated(aYYYY-MM-DDinterpreted as end of day). A remote timestamp that cannot be parsed counts as not newer, so the local issue is kept. - iso_
to_ epoch_ secs - Parse an ISO-8601 remote timestamp into epoch seconds. Accepts
YYYY-MM-DDTHH:MM:SS(theTmay be a space) with optional fractional seconds and aZor±HH:MMzone. - local_
to_ remote_ status - Map a local column to the remote state/label sent to the tracker
(
contracts/external-tools.mdmapping table). - remote_
status_ is_ done - Whether the computed remote status conveys “done”.
- remote_
to_ local_ status - Map a remote state/label back onto a local column. Closed/Done maps to the effective done column; anything else lands in the column whose name matches (case-insensitive), else the first column — per the contract’s “whose name matches, else into the first column”.
- scrub_
secret - Redact a resolved secret from text flowing through error/report surfaces.