opencode-config/.opencode/tools/_shared.ts
Sergey 15fc7d014d
refactor(tools): add repo parameter + shared module + tunnel tests (#65)
* refactor(tools): extract shared module for gh spawnSync logic

* feat(tools): add repo parameter to 5 GitHub tools

* test(tools): add tunnel tool tests

* test(tools): add repo parameter test cases for 5 tools

* docs(handoff): scaffold handoff and ADR for PR

* docs(handoff): set PR number

* docs(project-map): update after PR#65 structural changes

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-25 19:19:19 +03:00

39 lines
No EOL
1.6 KiB
TypeScript

import { spawnSync } from "child_process"
/**
* Build the `--repo <owner/repo>` argv fragment for `gh`.
*
* If `repo` is provided, returns `["--repo", repo]` (explicit target).
* If omitted, returns `[]` so `gh` auto-detects the repo from its `cwd`
* (set to `context.worktree` by `runGh`). Auto-detect is the default and
* backward-compatible behaviour for all 5 GitHub tools (create-issue,
* create-pr, post-review, post-docs-review, merge-pr) — see ADR-027.
*/
export function parseRepo(repo?: string): string[] {
if (repo) return ["--repo", repo]
return []
}
/**
* Run `gh` with the given subcommand args, optionally targeting an explicit
* repo. When `repo` is omitted, `gh` auto-detects the repo from `opts.cwd`
* (callers pass `context.worktree`). Returns the raw spawnSync result so the
* caller can inspect `status`/`stdout`/`stderr` directly, or pass it to
* `formatResult` for the standard error string.
*/
export function runGh(args: string[], repo?: string, opts?: { cwd?: string }) {
const fullArgs = [...parseRepo(repo), ...args]
return spawnSync("gh", fullArgs, { encoding: "utf-8", cwd: opts?.cwd })
}
/**
* Standard success/error formatter for GitHub tools.
*
* On success (exit 0) returns `stdout.trim()`. On failure returns the
* canonical error string `⚠️ <toolName> failed (exit <code>): <stderr or
* stdout>`, matching the format previously duplicated across 5 tools.
*/
export function formatResult(r: { status: number | null; stdout: string; stderr: string }, toolName: string): string {
if (r.status === 0) return r.stdout.trim()
return `⚠️ ${toolName} failed (exit ${r.status}): ${r.stderr || r.stdout}`
}