Documentation
¶
Overview ¶
`a-novel core bot-comment <org> <repo> <number> --body <text>` — post a PR/issue/review comment as the org's GitHub App bot, or many at once with `--batch`.
The bot's signing key never lives on a dev machine. Instead this command hands the comment (body + target metadata) to the per-org `bot-comment` workflow_dispatch (one dispatcher per org — see botDispatchRepos), triggered with the operator's own gh token. The workflow holds the App key, mints a scoped short-lived token, and posts as <app-slug>[bot]. See .github/workflows/bot-comment.yaml.
Why a workflow instead of minting locally:
- No local app tokens. A user only needs gh + actions:write on the dispatcher repo; they never handle a .pem. Revocation is per-user.
- Comment-only by design. The workflow can only post a comment, so a compromised trigger cannot push, merge, or author a PR — there is no skeleton-key token locally to misuse.
- Separation of duties. The trigger token cannot change what the workflow does — that is code on the protected master branch.
The command waits for each dispatched run synchronously (gh run watch --exit-status) and surfaces failures, so callers can react to errors.
`a-novel repo` — create and configure GitHub repositories from the editable templates in internal/repocfg. Writes are interactive (human-only, TTY-gated like publish); `--dry-run` prints the API operations that would run and is safe to use anywhere.
Package cli wires every subcommand the a-novel binary exposes. The standalone `test` and `build` commands are wrapped from cmd/a-novel/main.go, which owns their flag parsing; the daemon-backed verbs under `run` are implemented here directly against the daemon's rpc client.
`a-novel secrets` — a local, encrypted secrets manager. Secrets are stored AES-256-GCM-encrypted at rest under a 0600 local key, set interactively with no echo, and never printed by any command. They are injected into a child process's environment only — by `secrets exec`, and automatically by `test`/`run`/`ui` via the value-free per-repo manifest (.a-novel/secrets.yaml).
The goal is to prevent accidental exposure of API secrets (e.g. OPENAI_API_KEY) when a developer — or an AI agent — runs the toolchain: the value is never seen on a terminal, in a log, in git, or as a CLI argument.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsDaemonReexec ¶ added in v1.0.1
IsDaemonReexec reports whether args (typically os.Args) invoke the hidden daemon re-exec — `a-novel core __daemon`. main() uses it to skip the version-update check in the detached, long-lived daemon process (which has no user watching and must not phone home on shutdown).
func NewRoot ¶
func NewRoot(legacy LegacyHandlers) *cobra.Command
NewRoot builds the root a-novel command with every subcommand attached. The caller supplies the standalone test/build handlers, since their flag parsing lives in the cmd/a-novel package.
Types ¶
type ExitError ¶
type ExitError struct{ Code int }
ExitError signals an explicit os.Exit code. Cobra's exec returns the error; main.go inspects it for the precise code.
type LegacyHandlers ¶
LegacyHandlers carries the entrypoints for the standalone capabilities (test, build), which run their own flag parsers rather than Cobra's. cmd/a-novel injects them so that flag-parsing code stays in that package; the daemon-backed verbs under `run` live entirely in this one.
There is no `Run` handler: `run` is the parent namespace for the daemon-backed verbs, so a standalone run capability would collide with it.