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. This replaces the old bot-gh deny-list (a soft wrapper guard) with a structural one.
- 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 existing `test` / `build` / `run` commands are wrapped from cmd/a-novel/main.go's legacy implementations; new daemon-backed verbs (core, ps, start, kill, logs, env, volume, ...) are implemented here directly against internal/client/rpc.
`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
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.