diff --git a/README.md b/README.md index 7329cdf..6b71fe7 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,8 @@ Package installation is separate from the other setup steps in this repo: Canonical product and architecture memory now lives under `docs/`. Start with `docs/README.md` for the documentation map and authoritative entrypoints. +Agents using the packaged OpenCode `orfe` tool should start with `docs/orfe/opencode-tool-usage.md`. +The package-root `llms.txt` is a lightweight discovery pointer to that canonical tool-usage doc. For operational workflow structure, also see `docs/project/handoffs.md`. ## Requirements @@ -191,6 +193,8 @@ Runtime dependency logging is internal to `orfe`: ## OpenCode plugin +For packaged agent-facing tool guidance, use `docs/orfe/opencode-tool-usage.md`. + Configure OpenCode to load the packaged plugin directly: ```json diff --git a/docs/README.md b/docs/README.md index 26481a5..6730649 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,6 +41,9 @@ Use it to understand what the project is for, which constraints must hold, which ## Detailed reference material +- `docs/orfe/opencode-tool-usage.md` + - canonical agent-facing guide for the packaged OpenCode `orfe` tool + - focused on JSON tool requests, structured responses, caller resolution from `context.agent`, and agent-relevant failure guidance - `docs/orfe/spec.md` - detailed v1 runtime, command, and behavior specification - includes the canonical body-contract model for issue and PR artifact validation/provenance @@ -69,6 +72,7 @@ Use it to understand what the project is for, which constraints must hold, which - "Why is it designed this way?": read the ADRs - "What is intentionally imperfect right now?": read `docs/project/debt.md` - "How should agents hand work to each other?": read `docs/project/handoffs.md` +- "How do I call the packaged OpenCode tool?": read `docs/orfe/opencode-tool-usage.md` - Detailed command/runtime behavior: read `docs/orfe/spec.md` - Repo-defined issue/PR body contract rules: read `docs/orfe/spec.md` and `docs/architecture/invariants.md` diff --git a/docs/orfe/opencode-tool-usage.md b/docs/orfe/opencode-tool-usage.md new file mode 100644 index 0000000..254f66f --- /dev/null +++ b/docs/orfe/opencode-tool-usage.md @@ -0,0 +1,229 @@ +# `orfe` OpenCode tool usage + +This is the canonical agent-facing usage guide for the packaged OpenCode `orfe` tool. + +Scope: + +- OpenCode tool/plugin usage only +- structured JSON requests and responses +- current supported tool contract + +Out of scope: + +- CLI usage +- repository workflow policy +- setup/release walkthroughs + +For the full v1 command and behavior reference, see `docs/orfe/spec.md`. + +## Tool identity + +- Tool name: `orfe` +- Requests are JSON objects +- `command` is required and uses the canonical space-separated command name +- Command-specific fields use `snake_case` +- `repo`, `config`, and `auth_config` are plain input fields when a command supports them +- `body_contract` selects a repository-defined issue or PR body contract when applicable + +Example request shape: + +```json +{ + "command": "issue get", + "issue_number": 123, + "repo": "throw-if-null/orfe" +} +``` + +## Caller identity in OpenCode + +The OpenCode wrapper reads `context.agent` and resolves the caller from OpenCode context: + +- if `context.agent` is a non-empty string, that string is used +- otherwise, if `context.agent.name` is a non-empty string, that name is used + +The wrapper then passes a plain `callerName` string into the shared core runtime. + +Important: + +- agents should not provide CLI-specific caller environment variables +- agents should not send `caller_name` in tool input +- the runtime core does not read `context.agent` directly + +If caller context is missing for a caller-mapped command, the tool returns `caller_context_missing`. + +## Commands that do not require repo config, auth config, or GitHub + +These commands are runtime-only and work without caller context, repo-local config, machine-local auth config, or GitHub access: + +- `runtime info` +- `help` + +Examples: + +```json +{ + "command": "runtime info" +} +``` + +```json +{ + "command": "help" +} +``` + +```json +{ + "command": "help", + "command_name": "issue get" +} +``` + +## Commands that do require repo-local and machine-local configuration + +All other supported tool commands currently run through the shared core path and require: + +- caller identity from OpenCode `context.agent` +- repo-local config, normally `.orfe/config.json` +- machine-local auth config, normally `~/.config/orfe/auth.json` + +Many of these commands call GitHub directly. Some commands, such as `issue validate` and `pr validate`, do not create GitHub side effects, but they still use the shared configured runtime path and should be treated as config-dependent tool commands. + +## Structured responses + +The tool returns the shared `orfe` response envelope. + +Success shape: + +```json +{ + "ok": true, + "command": "issue get", + "repo": "throw-if-null/orfe", + "data": { + "issue_number": 123, + "title": "Add packaged agent-facing OpenCode tool usage docs (`docs/orfe/opencode-tool-usage.md` and `llms.txt`)", + "state": "open", + "html_url": "https://github.com/throw-if-null/orfe/issues/123" + } +} +``` + +Error shape: + +```json +{ + "ok": false, + "command": "issue get", + "error": { + "code": "invalid_usage", + "message": "Command \"issue get\" requires input field \"issue_number\".", + "retryable": false + } +} +``` + +Notes: + +- successful responses always use `ok: true` +- runtime failures use `ok: false` with a typed error object +- `repo` is present for repo-scoped commands and omitted for runtime-only commands such as `help` and `runtime info` +- the wrapper does not redefine field names for the OpenCode path + +## Supported command surface + +Use `{"command":"help"}` for structured discovery. + +Current command families exposed through the tool contract: + +- top-level runtime command: `help` +- `auth`: `auth token` +- `issue`: `issue get`, `issue create`, `issue update`, `issue validate`, `issue comment`, `issue set-state` +- `pr`: `pr get`, `pr validate`, `pr get-or-create`, `pr comment`, `pr submit-review`, `pr reply` +- `project`: `project get-status`, `project set-status` +- `runtime`: `runtime info` + +## Valid JSON request examples + +Read runtime metadata: + +```json +{ + "command": "runtime info" +} +``` + +Discover one command contract: + +```json +{ + "command": "help", + "command_name": "project set-status" +} +``` + +Mint a caller-scoped installation token: + +```json +{ + "command": "auth token", + "repo": "throw-if-null/orfe" +} +``` + +Read one issue: + +```json +{ + "command": "issue get", + "issue_number": 123 +} +``` + +Validate a PR body against the repository contract: + +```json +{ + "command": "pr validate", + "body": "Ref: #123\n\n## Summary\n- Add packaged OpenCode tool usage docs\n\n## Verification\n- Documented current tool contract\n\n## Docs / ADR / debt\n- Added docs; no ADR\n\n## Risks / follow-ups\n- Keep examples aligned with the runtime surface", + "body_contract": "implementation-ready@1.0.0" +} +``` + +Set a project status value: + +```json +{ + "command": "project set-status", + "item_type": "issue", + "item_number": 123, + "status": "In Progress" +} +``` + +## Common agent-relevant failures + +- `invalid_usage` + - unknown command name + - unsupported input field + - missing required field + - wrong input type + - attempted `caller_name` input +- `caller_context_missing` + - OpenCode did not supply usable `context.agent` for a caller-mapped command +- `caller_name_unmapped`, `config_invalid`, `auth_failed` + - local repo/auth setup is incomplete or does not map the resolved caller to a configured bot +- `github_not_found` + - the target issue, PR, or other GitHub resource does not exist in the resolved repo +- `project_item_not_found` + - the target issue or PR is not present on the configured GitHub Project + +If you are unsure which command or fields to use, start with `{"command":"help"}` or targeted help for the exact canonical command name. + +## Deeper reference + +- `docs/orfe/spec.md` is the detailed v1 behavior reference +- `help` returns structured command discovery and command-level examples through the same tool contract + +Keep this file focused on OpenCode tool usage. Treat `docs/orfe/spec.md` as the deeper source for detailed semantics and edge cases. diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000..7e29f8a --- /dev/null +++ b/llms.txt @@ -0,0 +1,7 @@ +# orfe + +Canonical agent-facing OpenCode tool usage guide: `docs/orfe/opencode-tool-usage.md` + +Detailed runtime/spec reference: `docs/orfe/spec.md` + +This file is discovery-only. Do not treat it as a second usage spec. diff --git a/package.json b/package.json index b7bd42a..22f2c02 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ }, "files": [ "dist", - "README.md" + "README.md", + "llms.txt", + "docs/orfe/opencode-tool-usage.md" ], "publishConfig": { "registry": "https://registry.npmjs.org", diff --git a/test/package.test.ts b/test/package.test.ts index 1d5b1bb..b26f370 100644 --- a/test/package.test.ts +++ b/test/package.test.ts @@ -34,6 +34,8 @@ test('package metadata exposes installable orfe CLI wiring', async () => { assert.equal(scripts?.prepack, 'npm run build'); assert.ok(files?.includes('dist')); assert.ok(files?.includes('README.md')); + assert.ok(files?.includes('llms.txt')); + assert.ok(files?.includes('docs/orfe/opencode-tool-usage.md')); assert.ok(!files?.includes('docs')); assert.equal(exportsField?.['./server'], './dist/plugin.js'); assert.equal(publishConfig?.registry, 'https://registry.npmjs.org');