@genoventures-labs/deckhand 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -0
  3. package/agent/agent.ts +5 -0
  4. package/agent/instructions.md +23 -0
  5. package/agent/schedules/workspace_scan.md +5 -0
  6. package/agent/skills/conflict-triage.md +7 -0
  7. package/agent/skills/git-sync.md +11 -0
  8. package/agent/skills/github-entities.md +7 -0
  9. package/agent/tools/draft_commit_message.ts +12 -0
  10. package/agent/tools/gh_actions_list.ts +12 -0
  11. package/agent/tools/gh_actions_run.ts +17 -0
  12. package/agent/tools/gh_actions_watch.ts +14 -0
  13. package/agent/tools/gh_checks.ts +12 -0
  14. package/agent/tools/gh_issue_create.ts +16 -0
  15. package/agent/tools/gh_pr_create.ts +17 -0
  16. package/agent/tools/gh_project_create.ts +15 -0
  17. package/agent/tools/gh_repo_create.ts +18 -0
  18. package/agent/tools/git_add.ts +15 -0
  19. package/agent/tools/git_branch.ts +15 -0
  20. package/agent/tools/git_commit.ts +14 -0
  21. package/agent/tools/git_conflicts.ts +15 -0
  22. package/agent/tools/git_pull.ts +12 -0
  23. package/agent/tools/git_push.ts +16 -0
  24. package/agent/tools/git_status.ts +13 -0
  25. package/dist/cli.d.ts +2 -0
  26. package/dist/cli.js +262 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/commands/runs.d.ts +2 -0
  29. package/dist/commands/runs.js +80 -0
  30. package/dist/commands/runs.js.map +1 -0
  31. package/dist/eve-dev.d.ts +1 -0
  32. package/dist/eve-dev.js +41 -0
  33. package/dist/eve-dev.js.map +1 -0
  34. package/dist/lib/config.d.ts +8 -0
  35. package/dist/lib/config.js +28 -0
  36. package/dist/lib/config.js.map +1 -0
  37. package/dist/lib/doctor.d.ts +6 -0
  38. package/dist/lib/doctor.js +42 -0
  39. package/dist/lib/doctor.js.map +1 -0
  40. package/dist/lib/env.d.ts +5 -0
  41. package/dist/lib/env.js +26 -0
  42. package/dist/lib/env.js.map +1 -0
  43. package/dist/lib/gh.d.ts +34 -0
  44. package/dist/lib/gh.js +52 -0
  45. package/dist/lib/gh.js.map +1 -0
  46. package/dist/lib/git.d.ts +26 -0
  47. package/dist/lib/git.js +131 -0
  48. package/dist/lib/git.js.map +1 -0
  49. package/dist/lib/model.d.ts +4 -0
  50. package/dist/lib/model.js +60 -0
  51. package/dist/lib/model.js.map +1 -0
  52. package/dist/lib/ollama.d.ts +4 -0
  53. package/dist/lib/ollama.js +65 -0
  54. package/dist/lib/ollama.js.map +1 -0
  55. package/dist/lib/paths.d.ts +2 -0
  56. package/dist/lib/paths.js +9 -0
  57. package/dist/lib/paths.js.map +1 -0
  58. package/dist/lib/run.d.ts +21 -0
  59. package/dist/lib/run.js +75 -0
  60. package/dist/lib/run.js.map +1 -0
  61. package/dist/lib/runs.d.ts +55 -0
  62. package/dist/lib/runs.js +168 -0
  63. package/dist/lib/runs.js.map +1 -0
  64. package/dist/lib/watch.d.ts +12 -0
  65. package/dist/lib/watch.js +38 -0
  66. package/dist/lib/watch.js.map +1 -0
  67. package/dist/lib/workspace.d.ts +1 -0
  68. package/dist/lib/workspace.js +5 -0
  69. package/dist/lib/workspace.js.map +1 -0
  70. package/dist/ui/format.d.ts +16 -0
  71. package/dist/ui/format.js +82 -0
  72. package/dist/ui/format.js.map +1 -0
  73. package/dist/ui/help.d.ts +7 -0
  74. package/dist/ui/help.js +197 -0
  75. package/dist/ui/help.js.map +1 -0
  76. package/dist/ui/table.d.ts +4 -0
  77. package/dist/ui/table.js +39 -0
  78. package/dist/ui/table.js.map +1 -0
  79. package/dist/ui/theme.d.ts +14 -0
  80. package/dist/ui/theme.js +22 -0
  81. package/dist/ui/theme.js.map +1 -0
  82. package/package.json +55 -0
  83. package/templates/github-actions/gated-sync.yml +35 -0
  84. package/templates/github-actions/morning-pull.yml +42 -0
  85. package/templates/github-actions/nightly-checks.yml +33 -0
  86. package/templates/github-actions/weekday-status.yml +17 -0
  87. package/templates/runs/gated-sync.yaml +19 -0
  88. package/templates/runs/morning-pull.yaml +17 -0
  89. package/templates/runs/nightly-checks.yaml +17 -0
  90. package/templates/runs/weekday-status.yaml +17 -0
  91. package/templates/schema/gated-run.v1.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bobby Backlogs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Deckhand
2
+
3
+ <p align="center">
4
+ <img src="./assets/lockup.png" alt="Deckhand" width="400" height="350">
5
+ </p>
6
+
7
+ ![Vercel AI Gateway](https://img.shields.io/badge/AI_Gateway-000000?style=for-the-badge&logo=vercel&logoColor=white)
8
+ ![Vercel Eve](https://img.shields.io/badge/Eve-000000?style=for-the-badge&logo=vercel&logoColor=white)
9
+ ![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
10
+ ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white)
11
+ ![GitHub](https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white)
12
+ ![GitHub CLI](https://img.shields.io/badge/GitHub_CLI-2088FF?style=for-the-badge&logo=github&logoColor=white)
13
+
14
+ > An intelligent CLI automation framework bridging Vercel Eve and AI Gateway directly to the GitHub CLI (`gh`).
15
+
16
+ The npm package is **`@genoventures-labs/deckhand`**. The CLI binary is **`deckhand`**.
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ **Deckhand** orchestrates local repository management and automated GitHub workflows. Built on Vercel's Eve framework, it routes model calls through [AI Gateway](https://vercel.com/docs/ai-gateway) and uses the official GitHub CLI (`gh`) for version control, issue triage, and CI/CD triggers.
23
+
24
+ ---
25
+
26
+ ## Install
27
+
28
+ Requires Node.js 20+ (Node 24+ for `deckhand agent` / Eve), plus `git` and `gh`.
29
+
30
+ ```bash
31
+ npm install
32
+ npm run build
33
+ ```
34
+
35
+ That puts `deckhand` on `./node_modules/.bin`. From another machine or a global install:
36
+
37
+ ```bash
38
+ npm install -g @genoventures-labs/deckhand
39
+ # or, without publishing yet:
40
+ npm install -g .
41
+ ```
42
+
43
+ Authenticate GitHub and AI Gateway:
44
+
45
+ ```bash
46
+ gh auth login
47
+ cp .env.example .env.local
48
+ # Put your AI Gateway key in .env.local, or:
49
+ # vercel link && vercel env pull .env.local
50
+ ```
51
+
52
+ Copy `deckhand.example.json` to `deckhand.json` to pin workspaces and the `provider/model` slug (default `openai/gpt-5.6-luna-fast`).
53
+
54
+ ---
55
+
56
+ ## CLI
57
+
58
+ ```bash
59
+ deckhand # overview + command tables
60
+ deckhand help # same overview
61
+ deckhand help topics # help catalog
62
+ deckhand help runs # gated-run guide
63
+ deckhand doctor # dependency table
64
+ deckhand status # repo + change tables
65
+ deckhand watch # directory monitoring
66
+ deckhand sync # add + Gateway commit message + push
67
+ deckhand pull # git pull --ff-only
68
+ deckhand branch <name>
69
+ deckhand conflicts # conflict list + model guidance
70
+ deckhand pr create -t "..."
71
+ deckhand issue create -t "..."
72
+ deckhand repo create <name>
73
+ deckhand project create -t "..." -o <owner>
74
+ deckhand checks
75
+ deckhand actions list
76
+ deckhand actions watch [runId]
77
+ deckhand actions run <workflow>
78
+ deckhand runs list # gated YAML templates
79
+ deckhand agent # Eve terminal session
80
+ ```
81
+
82
+ `deckhand sync` writes a commit message through AI Gateway from the current diff. Pass `-m` to skip generation, or `--no-push` to commit only.
83
+
84
+ ---
85
+
86
+ ## Gated runs
87
+
88
+ YAML templates declare *what* runs and *when*. GitHub Environments (`deckhand-gate`) hold the execute job until a reviewer approves.
89
+
90
+ ```bash
91
+ deckhand runs list
92
+ deckhand runs init morning-pull
93
+ deckhand runs install-workflow morning-pull
94
+ deckhand runs apply morning-pull --approve
95
+ ```
96
+
97
+ | Template | Cron (local TZ) | Action | Gate |
98
+ | :--- | :--- | :--- | :--- |
99
+ | `morning-pull` | `0 5 * * *` America/Los_Angeles | `git pull --ff-only` | `deckhand-gate` |
100
+ | `weekday-status` | `0 8 * * 1-5` | `status` | off |
101
+ | `gated-sync` | `0 18 * * 1-5` | commit, no push | `deckhand-gate` |
102
+ | `nightly-checks` | `0 23 * * *` | PR checks | `deckhand-gate` |
103
+
104
+ Copy the YAML into `.deckhand/runs/` and the matching workflow into `.github/workflows/`. Then in the GitHub repo: **Settings → Environments → `deckhand-gate` → Required reviewers**.
105
+
106
+ GitHub Actions cron is UTC (`0 13 * * *` ≈ 5am PST). Self-hosted or `deckhand runs apply` honor the YAML `timezone` as documentation of intent; wire a local scheduler (Task Scheduler, cron) if you want true local 5am without GitHub.
107
+
108
+ Schema: `templates/schema/gated-run.v1.json`.
109
+
110
+
111
+ ---
112
+
113
+ ## Features
114
+
115
+ ### Automated Change Detection & Sync
116
+
117
+ - **Directory Monitoring:** Scans configured local workspaces to detect file updates and status changes (`deckhand watch`).
118
+ - **Intelligent Git Operations:** Stages, commits, pushes, and fast-forward pulls from detected diffs (`deckhand sync` / `pull`).
119
+ - **Status Reporting:** Prints whether the tree is clean and when a sync finishes.
120
+
121
+ ### Repository & Workflow Management
122
+
123
+ - **Entity Generation:** Branches, pull requests, issues, repositories, and GitHub Projects via `gh`.
124
+ - **Assisted Resolution:** Conflict listing plus a gateway-model write-up of resolution options.
125
+ - **CI/CD Integration:** Trigger, list, watch, and surface GitHub Actions runs and PR checks.
126
+ - **Gated runs:** YAML templates for scheduled pulls, status, sync, and checks, with a GitHub Environment approval gate.
127
+
128
+ ### Eve agent
129
+
130
+ `agent/` is a filesystem-first Eve app. Tools wrap the same git/`gh` helpers as the CLI. `deckhand agent` starts `eve dev` with `DECKHAND_CWD` pointed at your repo. Push, repo creation, and workflow triggers ask for approval.
131
+
132
+ ---
133
+
134
+ ## Architecture & Dependencies
135
+
136
+ | Tool | Role | Reference |
137
+ | :--- | :--- | :--- |
138
+ | **Vercel Eve** | Core AI Framework | [eve.dev/docs](https://eve.dev/docs) |
139
+ | **Vercel AI Gateway** | Model routing | [vercel.com/docs/ai-gateway](https://vercel.com/docs/ai-gateway) |
140
+ | **GitHub CLI (`gh`)** | GitHub Interface Layer | [cli.github.com](https://cli.github.com/) |
141
+ | **GitHub Actions** | CI/CD Pipeline Automation | [github.com/features/actions](https://github.com/features/actions) |
142
+
143
+ ---
144
+
145
+ ## Scripts
146
+
147
+ | Script | What it does |
148
+ | :--- | :--- |
149
+ | `npm install` | Install CLI + Eve runtime dependencies |
150
+ | `npm run build` | Compile `src/` to `dist/` |
151
+ | `npm run dev` | Run the CLI through `tsx` |
152
+ | `npm run eve:dev` | Start Eve against `./agent` |
package/agent/agent.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { defineAgent } from "eve";
2
+
3
+ export default defineAgent({
4
+ model: "openai/gpt-5.6-luna-fast",
5
+ });
@@ -0,0 +1,23 @@
1
+ # Deckhand
2
+
3
+ You are Deckhand (CLI: `deckhand`), a Git and GitHub operator.
4
+
5
+ ## Runtime
6
+
7
+ - The user's workspace is `DECKHAND_CWD` when set, otherwise the process working directory.
8
+ - Prefer the authored tools over guessing shell flags.
9
+ - GitHub work goes through `gh`. Do not invent API tokens or curl GitHub REST yourself.
10
+ - Models route through Vercel AI Gateway. If a model call fails, tell the user to run `deckhand doctor` and set `AI_GATEWAY_API_KEY` or refresh `VERCEL_OIDC_TOKEN` with `vercel env pull`.
11
+
12
+ ## Git safety
13
+
14
+ - Never force-push, never skip hooks, never rewrite published history.
15
+ - Prefer `--ff-only` pulls.
16
+ - Require a clear user request before `push`, `repo create`, or triggering workflows.
17
+ - For merge conflicts, list files, explain options, and do not overwrite conflict markers unless the user asked to apply a specific resolution.
18
+
19
+ ## Style
20
+
21
+ - Be concise in the terminal.
22
+ - After git operations, report whether the tree is clean and whether the branch is ahead or behind.
23
+ - When creating issues, PRs, or projects, draft a short title and body, then call the matching tool.
@@ -0,0 +1,5 @@
1
+ ---
2
+ cron: "*/15 * * * *"
3
+ ---
4
+
5
+ Scan the user workspace git status. If the tree is dirty, summarize changed files. If it is clean, say so in one line. Do not commit or push unless the session was started for a sync.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Analyze merge conflicts and issue workflows without destroying local work.
3
+ ---
4
+
5
+ # Conflict and issue triage
6
+
7
+ Call `git_conflicts` first. Explain resolution order. Do not recommend `git push --force`. For issues, read `gh` output and propose labels or next commands without closing anything unless asked.
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Detect diffs and run add, commit, push, or pull with safe git defaults.
3
+ ---
4
+
5
+ # Git sync
6
+
7
+ 1. Call `git_status`. If clean, stop.
8
+ 2. Summarize changes for the user.
9
+ 3. On explicit sync: `git_add`, draft a conventional commit with `draft_commit_message`, then `git_commit`.
10
+ 4. Push only when asked. If push needs an upstream, say so and use setUpstream.
11
+ 5. Pull with fast-forward only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Create branches, pull requests, issues, repositories, and GitHub Projects through gh.
3
+ ---
4
+
5
+ # GitHub entities
6
+
7
+ Use `gh_*` tools. Confirm titles before create calls. Draft bodies with the draft tool when the user did not supply one. For CI, use `gh_actions_list`, `gh_actions_watch`, `gh_actions_run`, and `gh_checks`.
@@ -0,0 +1,12 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { generateCommitMessage } from "../../src/lib/model.js";
4
+
5
+ export default defineTool({
6
+ description: "Ask the AI Gateway model to draft a conventional commit message from the current diff.",
7
+ inputSchema: z.object({}),
8
+ label: { start: () => "Draft commit message" },
9
+ async execute() {
10
+ return { message: await generateCommitMessage() };
11
+ },
12
+ });
@@ -0,0 +1,12 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { listRuns } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "List recent GitHub Actions workflow runs.",
7
+ inputSchema: z.object({}),
8
+ label: { start: () => "List Actions runs" },
9
+ async execute() {
10
+ return { result: await listRuns() };
11
+ },
12
+ });
@@ -0,0 +1,17 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { always } from "eve/tools/approval";
3
+ import { z } from "zod";
4
+ import { triggerWorkflow } from "../../src/lib/gh.js";
5
+
6
+ export default defineTool({
7
+ description: "Trigger a GitHub Actions workflow with gh workflow run.",
8
+ inputSchema: z.object({
9
+ workflow: z.string().min(1),
10
+ ref: z.string().optional(),
11
+ }),
12
+ approval: always(),
13
+ label: { start: ({ workflow }) => `Trigger ${workflow}` },
14
+ async execute(input) {
15
+ return { result: await triggerWorkflow(input) };
16
+ },
17
+ });
@@ -0,0 +1,14 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { watchRun } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "Watch a GitHub Actions run until it completes.",
7
+ inputSchema: z.object({
8
+ runId: z.string().optional(),
9
+ }),
10
+ label: { start: ({ runId }) => (runId ? `Watch run ${runId}` : "Watch latest run") },
11
+ async execute({ runId }) {
12
+ return { result: await watchRun(runId) };
13
+ },
14
+ });
@@ -0,0 +1,12 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { listChecks } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "Show GitHub Actions / status checks for the current pull request.",
7
+ inputSchema: z.object({}),
8
+ label: { start: () => "Read PR checks" },
9
+ async execute() {
10
+ return { result: await listChecks() };
11
+ },
12
+ });
@@ -0,0 +1,16 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { createIssue } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "Create a GitHub issue with gh issue create.",
7
+ inputSchema: z.object({
8
+ title: z.string().min(1),
9
+ body: z.string().min(1),
10
+ labels: z.array(z.string()).default([]),
11
+ }),
12
+ label: { start: ({ title }) => `Open issue: ${title}` },
13
+ async execute(input) {
14
+ return { result: await createIssue(input) };
15
+ },
16
+ });
@@ -0,0 +1,17 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { createPullRequest } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "Create a GitHub pull request with gh pr create.",
7
+ inputSchema: z.object({
8
+ title: z.string().min(1),
9
+ body: z.string().min(1),
10
+ base: z.string().optional(),
11
+ draft: z.boolean().default(false),
12
+ }),
13
+ label: { start: ({ title }) => `Open PR: ${title}` },
14
+ async execute(input) {
15
+ return { result: await createPullRequest(input) };
16
+ },
17
+ });
@@ -0,0 +1,15 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { createProject } from "../../src/lib/gh.js";
4
+
5
+ export default defineTool({
6
+ description: "Create a GitHub Project with gh project create.",
7
+ inputSchema: z.object({
8
+ title: z.string().min(1),
9
+ owner: z.string().min(1),
10
+ }),
11
+ label: { start: ({ title }) => `Create project ${title}` },
12
+ async execute(input) {
13
+ return { result: await createProject(input) };
14
+ },
15
+ });
@@ -0,0 +1,18 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { always } from "eve/tools/approval";
3
+ import { z } from "zod";
4
+ import { createRepo } from "../../src/lib/gh.js";
5
+
6
+ export default defineTool({
7
+ description: "Create a GitHub repository from the current directory with gh repo create.",
8
+ inputSchema: z.object({
9
+ name: z.string().min(1),
10
+ description: z.string().optional(),
11
+ privateRepo: z.boolean().default(false),
12
+ }),
13
+ approval: always(),
14
+ label: { start: ({ name }) => `Create repo ${name}` },
15
+ async execute(input) {
16
+ return { result: await createRepo(input) };
17
+ },
18
+ });
@@ -0,0 +1,15 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { gitAdd } from "../../src/lib/git.js";
4
+
5
+ export default defineTool({
6
+ description: "Stage files with git add. Pass an empty list to stage the whole workspace.",
7
+ inputSchema: z.object({
8
+ paths: z.array(z.string()).default([]),
9
+ }),
10
+ label: { start: ({ paths }) => (paths.length ? `Stage ${paths.join(", ")}` : "Stage all changes") },
11
+ async execute({ paths }) {
12
+ await gitAdd(paths);
13
+ return { staged: paths.length ? paths : ["."] };
14
+ },
15
+ });
@@ -0,0 +1,15 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { gitCheckoutBranch } from "../../src/lib/git.js";
4
+
5
+ export default defineTool({
6
+ description: "Create or switch a git branch.",
7
+ inputSchema: z.object({
8
+ name: z.string().min(1),
9
+ create: z.boolean().default(true),
10
+ }),
11
+ label: { start: ({ name, create }) => (create ? `Create branch ${name}` : `Switch to ${name}`) },
12
+ async execute({ name, create }) {
13
+ return { result: await gitCheckoutBranch(name, create) };
14
+ },
15
+ });
@@ -0,0 +1,14 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { gitCommit } from "../../src/lib/git.js";
4
+
5
+ export default defineTool({
6
+ description: "Create a git commit with the given message. Does not skip hooks.",
7
+ inputSchema: z.object({
8
+ message: z.string().min(1),
9
+ }),
10
+ label: { start: ({ message }) => `Commit: ${message.split("\n")[0]}` },
11
+ async execute({ message }) {
12
+ return { result: await gitCommit(message) };
13
+ },
14
+ });
@@ -0,0 +1,15 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { gitConflictFiles } from "../../src/lib/git.js";
4
+ import { suggestConflictResolution } from "../../src/lib/model.js";
5
+
6
+ export default defineTool({
7
+ description: "List conflicted files and return AI Gateway guidance for resolving them.",
8
+ inputSchema: z.object({}),
9
+ label: { start: () => "Inspect merge conflicts" },
10
+ async execute() {
11
+ const files = await gitConflictFiles();
12
+ const guidance = files.length ? await suggestConflictResolution(files) : "No merge conflicts.";
13
+ return { files, guidance };
14
+ },
15
+ });
@@ -0,0 +1,12 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { gitPull } from "../../src/lib/git.js";
4
+
5
+ export default defineTool({
6
+ description: "Fast-forward pull from the remote tracking branch.",
7
+ inputSchema: z.object({}),
8
+ label: { start: () => "Pull --ff-only" },
9
+ async execute() {
10
+ return { result: await gitPull() };
11
+ },
12
+ });
@@ -0,0 +1,16 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { always } from "eve/tools/approval";
3
+ import { z } from "zod";
4
+ import { gitPush } from "../../src/lib/git.js";
5
+
6
+ export default defineTool({
7
+ description: "Push the current branch to origin. Never force-pushes.",
8
+ inputSchema: z.object({
9
+ setUpstream: z.boolean().default(false),
10
+ }),
11
+ approval: always(),
12
+ label: { start: () => "Push to origin" },
13
+ async execute({ setUpstream }) {
14
+ return { result: await gitPush(undefined, setUpstream) };
15
+ },
16
+ });
@@ -0,0 +1,13 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+ import { formatStatus, gitStatus } from "../../src/lib/git.js";
4
+
5
+ export default defineTool({
6
+ description: "Read git status for the Deckhand workspace, including branch tracking and file changes.",
7
+ inputSchema: z.object({}),
8
+ label: { start: () => "Check git status" },
9
+ async execute() {
10
+ const status = await gitStatus();
11
+ return { ...status, summary: formatStatus(status) };
12
+ },
13
+ });
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};