Skip to content

chore: track shared .claude settings, drop TimeActivity skill doc - #13

Closed
bcarlso-lt wants to merge 15 commits into
voska:mainfrom
leantechniques:chore/claude-config-and-skill-cleanup
Closed

bcarlso-lt wants to merge 15 commits into
voska:mainfrom
leantechniques:chore/claude-config-and-skill-cleanup

Conversation

@bcarlso-lt

Copy link
Copy Markdown

Summary

  • Track .claude/settings.json (beads plugin + bd prime SessionStart hook) so the team shares the same config; ignore .claude/settings.local.json (personal) and .claude/scheduled_tasks.lock (runtime state).
  • Remove skills/qbo/references/TIMEACTIVITY-EXAMPLES.md and its link in SKILL.md — it was specific to our own workflow and doesn't belong in the general-purpose skill.

Test plan

  • git status clean after commits
  • Confirmed no remaining references to the removed doc (grep -rn TIMEACTIVITY-EXAMPLES)
  • .claude/settings.json validated as well-formed JSON
  • Pre-commit code review pass (no findings)

🤖 Generated with Claude Code

bcarlso-lt and others added 15 commits August 19, 2026 12:35
The file backend previously encrypted tokens and client credentials with
an empty passphrase, making the on-disk encryption a no-op. Now the
passphrase comes from QBO_KEYRING_FILE_PASSWORD or an interactive prompt
(memoized per process so multi-open commands prompt once), and headless
invocations fail loudly when neither is available. --no-input suppresses
the prompt. A set-but-empty env var is rejected explicitly, and a wrong
passphrase surfaces as a config error naming the variable instead of
'not authenticated'.

BREAKING: entries stored by older versions used the empty passphrase and
can no longer be decrypted — re-run qbo auth login (and qbo auth
set-client) once after upgrading.

Co-authored-by: Claude Fable 5 <[email protected]>
The save path for qbo download without -o comes from the API response,
which anyone with write access to the QBO company controls. Previously
os.Create silently truncated whatever that name pointed at in the
working directory.

Now the destination is created with O_EXCL and an existing file (or
planted symlink) is a usage error unless --force is passed; the
existence check runs before any API calls are spent. API-supplied names
are reduced to a safe basename (both separator styles) and hidden-file
names like .envrc are refused outright. --force writes to a temp file
and renames into place, so a mid-stream failure preserves the original
and a symlinked name is replaced rather than written through. Close
errors now fail the command instead of reporting a corrupt file as
saved.

Co-authored-by: Claude Fable 5 <[email protected]>
QBO string fields (customer names, memos, line descriptions) are often
populated by external parties and were rendered verbatim in human and
plain modes, letting embedded ANSI/OSC sequences rewrite or spoof
terminal output — the same class git, gh, and kubectl have patched.

Table cells and headers now drop C0/C1 controls and DEL, strip bidi
overrides/isolates and zero-width characters, and flatten CR/LF/tab to
spaces so hostile values can't forge rows or TSV columns. The stderr
helpers (Hint/Success/Warn/ErrorMsg) sanitize too, covering API error
bodies and API-supplied file names; message newlines are preserved.
JSON mode is unchanged — encoding/json already escapes control chars.

Co-authored-by: Claude Fable 5 <[email protected]>
Read /Library/Application Support/qbo/bootstrap.json (installed by device
management) carrying vault URL, secret name, and Entra tenant/client ID so
a first login can fetch Intuit client creds from Azure Key Vault without
the binary carrying org-specific values. auth status reports the tier
(bootstrap-pending/bootstrap/bootstrap-error) and now emits credential
diagnostics even before a company exists; auth login names the vault on
provisioned machines and fails loudly (exit 10) on a malformed bootstrap
file. Keyring creds gain an origin marker for the upcoming vault self-heal.

Co-Authored-By: Claude Fable 5 <[email protected]>
Check the os.Unsetenv return in token_test.go and replace a raw invisible
U+009B control character in write_test.go with its Unicode escape sequence.

Co-Authored-By: Claude Fable 5 <[email protected]>
Ignore local Dolt/beads state and add the bd init workflow block to
AGENTS.md. The duplicate Codex-flavored block from bd setup codex was
removed along with the .codex and .agents artifacts.

Co-Authored-By: Claude Fable 5 <[email protected]>
On a provisioned machine with no configured client creds, qbo auth login
now signs in to Entra ID (pure-Go MSAL, browser or --device-code, token
cache in the qbo keyring) and fetches the Intuit client credentials from
the org's Key Vault, storing them with origin=bootstrap before the Intuit
OAuth flow. --no-input allows only the cached silent path (exit 4).

The bearer token is only ever sent to https Azure Key Vault hosts; sign-in
failures map onto the exit-code contract (6 for Conditional Access blocks
and vault 403s, 4 for cancellations, 8 for network, 10 for misprovisioned
secrets). set-client --clear also removes the cached Entra session.

Closes qbo-cli-iyj.2.

Co-Authored-By: Claude Fable 5 <[email protected]>
When a token refresh fails with invalid_client (typed RFC 6749 check, not
string matching) and the credentials are vault-owned — bootstrap origin in
the keyring with no env overrides — silently re-fetch them from Key Vault
using the cached Entra session and retry once per invocation, preserving
the stored redirect URI. User-supplied credentials are never auto-replaced;
any other failure guides re-login (exit 4).

The Entra browser wait now times out after 5 minutes like the Intuit flow,
every MSAL network leg is bounded by a 30s HTTP client so headless
self-heal can't hang, the silent path picks the cached account matching
the configured tenant, and a stalled vault fetch is retryable (exit 8).

Closes qbo-cli-iyj.3, qbo-cli-iyj.4.

Co-Authored-By: Claude Fable 5 <[email protected]>
Intuit production apps reject http://localhost redirect URIs, so a hosted
HTTPS page must receive the callback and forward it to the CLI. Route all
redirect URIs through the local listener: a non-local redirect_uri is sent
to Intuit (auth URL and token exchange) while the callback is still caught
on localhost:8844. The --manual flag, previously declared but unused, now
explicitly selects the paste-the-callback-URL flow. Skill docs updated to
match.

Also fix a latent race (callback handler signaled the result/error channels
before writing the HTTP response, letting server.Close() kill the connection
mid-response) and a listener leak on the GenerateState error path.

Co-Authored-By: Claude Fable 5 <[email protected]>
Bash(qbo *) pre-authorized mutating commands (create/update/delete/batch)
whenever the skill was active, bypassing the permission prompt. Reads stay
frictionless; writes now require explicit user approval.

Co-Authored-By: Claude Fable 5 <[email protected]>
Weekday-cron workflow that merges voska/qbo-cli upstream changes into a
SHA-keyed sync branch, runs the quality gates (build/test/vet/lint), and
opens a review-gated PR. Dirty merges are resolved by claude-code-action
authenticated via workload identity federation (no repo secrets), running
without ambient git credentials, then re-verified deterministically —
including that fork history and LT customizations survived — before the
PR opens.

Co-Authored-By: Claude Fable 5 <[email protected]>
Removes skills/qbo/references/TIMEACTIVITY-EXAMPLES.md and its link in
SKILL.md — content was specific to our own use case and doesn't belong
in the general-purpose skill.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Commit the project-level settings.json (beads plugin + bd prime hook)
so it's shared across the team. Ignore settings.local.json (personal
preference) and scheduled_tasks.lock (runtime state) — neither belongs
in version control.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@bcarlso-lt bcarlso-lt closed this Aug 31, 2026
@bcarlso-lt
bcarlso-lt deleted the chore/claude-config-and-skill-cleanup branch August 31, 2026 17:30
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.

1 participant